/** * Queries information about the object using a specific view, internal version. * * @return IPRT status code. * @param enmView View to use for querying information. Currently ignored. */ int DnDURIObject::queryInfoInternal(View enmView) { RT_NOREF(enmView); int rc; switch (m_enmType) { case Type_File: AssertMsgReturn(RTFileIsValid(u.File.hFile), ("Object has invalid file handle\n"), VERR_INVALID_STATE); rc = RTFileQueryInfo(u.File.hFile, &u.File.objInfo, RTFSOBJATTRADD_NOTHING); break; case Type_Directory: AssertMsgReturn(RTDirIsValid(u.Dir.hDir), ("Object has invalid directory handle\n"), VERR_INVALID_STATE); rc = RTDirQueryInfo(u.Dir.hDir, &u.Dir.objInfo, RTFSOBJATTRADD_NOTHING); break; default: rc = VERR_NOT_IMPLEMENTED; break; } return rc; }
RTR3DECL(int) RTFileSetTimes(RTFILE hFile, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) { /* * We can only set AccessTime and ModificationTime, so if neither * are specified we can return immediately. */ if (!pAccessTime && !pModificationTime) return VINF_SUCCESS; /* * Convert the input to timeval, getting the missing one if necessary, * and call the API which does the change. */ struct timeval aTimevals[2]; if (pAccessTime && pModificationTime) { RTTimeSpecGetTimeval(pAccessTime, &aTimevals[0]); RTTimeSpecGetTimeval(pModificationTime, &aTimevals[1]); } else { RTFSOBJINFO ObjInfo; int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_UNIX); if (RT_FAILURE(rc)) return rc; RTTimeSpecGetTimeval(pAccessTime ? pAccessTime : &ObjInfo.AccessTime, &aTimevals[0]); RTTimeSpecGetTimeval(pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]); } if (futimes(RTFileToNative(hFile), aTimevals)) { int rc = RTErrConvertFromErrno(errno); Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", hFile, pAccessTime, pModificationTime, rc)); return rc; } return VINF_SUCCESS; }
RTR3DECL(int) RTFileSetTimes(RTFILE hFile, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) { NOREF(pChangeTime); NOREF(pBirthTime); /* * We can only set AccessTime and ModificationTime, so if neither * are specified we can return immediately. */ if (!pAccessTime && !pModificationTime) return VINF_SUCCESS; #ifdef USE_FUTIMENS struct timespec aTimespecs[2]; if (pAccessTime && pModificationTime) { memcpy(&aTimespecs[0], pAccessTime, sizeof(struct timespec)); memcpy(&aTimespecs[1], pModificationTime, sizeof(struct timespec)); } else { RTFSOBJINFO ObjInfo; int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_UNIX); if (RT_FAILURE(rc)) return rc; memcpy(&aTimespecs[0], pAccessTime ? pAccessTime : &ObjInfo.AccessTime, sizeof(struct timespec)); memcpy(&aTimespecs[1], pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, sizeof(struct timespec)); } if (futimens(RTFileToNative(hFile), aTimespecs)) { int rc = RTErrConvertFromErrno(errno); Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", hFile, pAccessTime, pModificationTime, rc)); return rc; } #else /* * Convert the input to timeval, getting the missing one if necessary, * and call the API which does the change. */ struct timeval aTimevals[2]; if (pAccessTime && pModificationTime) { RTTimeSpecGetTimeval(pAccessTime, &aTimevals[0]); RTTimeSpecGetTimeval(pModificationTime, &aTimevals[1]); } else { RTFSOBJINFO ObjInfo; int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_UNIX); if (RT_FAILURE(rc)) return rc; RTTimeSpecGetTimeval(pAccessTime ? pAccessTime : &ObjInfo.AccessTime, &aTimevals[0]); RTTimeSpecGetTimeval(pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]); } /* XXX this falls back to utimes("/proc/self/fd/...",...) for older kernels/glibcs and this * will not work for hardened builds where this directory is owned by root.root and mode 0500 */ if (futimes(RTFileToNative(hFile), aTimevals)) { int rc = RTErrConvertFromErrno(errno); Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", hFile, pAccessTime, pModificationTime, rc)); return rc; } #endif return VINF_SUCCESS; }
int DnDURIObject::OpenEx(const RTCString &strPath, Type enmType, Dest enmDest, uint64_t fOpen /* = 0 */, uint32_t fMode /* = 0 */, uint32_t fFlags /* = 0 */) { int rc = VINF_SUCCESS; switch (enmDest) { case Source: m_strSrcPath = strPath; break; case Target: m_strTgtPath = strPath; break; default: rc = VERR_NOT_IMPLEMENTED; break; } if ( RT_SUCCESS(rc) && fOpen) /* Opening mode specified? */ { switch (enmType) { case File: { if (!u.m_hFile) { /* * Open files on the source with RTFILE_O_DENY_WRITE to prevent races * where the OS writes to the file while the destination side transfers * it over. */ rc = RTFileOpen(&u.m_hFile, strPath.c_str(), fOpen); LogFlowThisFunc(("strPath=%s, fOpen=0x%x, enmType=%RU32, enmDest=%RU32, rc=%Rrc\n", strPath.c_str(), fOpen, enmType, enmDest, rc)); if (RT_SUCCESS(rc)) rc = RTFileGetSize(u.m_hFile, &m_cbSize); if (RT_SUCCESS(rc)) { if ( (fOpen & RTFILE_O_WRITE) /* Only set the file mode on write. */ && fMode /* Some file mode to set specified? */) { rc = RTFileSetMode(u.m_hFile, fMode); if (RT_SUCCESS(rc)) m_fMode = fMode; } else if (fOpen & RTFILE_O_READ) { #if 0 /** @todo Enable this as soon as RTFileGetMode is implemented. */ rc = RTFileGetMode(u.m_hFile, &m_fMode); #else RTFSOBJINFO ObjInfo; rc = RTFileQueryInfo(u.m_hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING); if (RT_SUCCESS(rc)) m_fMode = ObjInfo.Attr.fMode; #endif } } if (RT_SUCCESS(rc)) { LogFlowThisFunc(("cbSize=%RU64, fMode=0x%x\n", m_cbSize, m_fMode)); m_cbProcessed = 0; } } else rc = VINF_SUCCESS; break; } case Directory: rc = VINF_SUCCESS; break; default: rc = VERR_NOT_IMPLEMENTED; break; } } if (RT_SUCCESS(rc)) m_Type = enmType; LogFlowFuncLeaveRC(rc); return rc; }