int SyncTransferThread::do_touch_local_file_with_time(QString fileName, QDateTime time) { // Linux 上可以使用 utime 或者 utimes 函数, - change file last access and modification times // Windows 上文件 SetFileTime()函数设置文件的创建时间、最近一次访问时间以及最近一次修改的时间等 // Windows 目录 两个函数GetDirTime()和SetDirTime()来实现对文件夹时间信息 // Qt 中好像是没有修改文件时间属性的方法。 int ret; QFileInfo fi(fileName); #ifdef WIN32 // method 1, ok QFile q_file(fileName); if (!q_file.open(QIODevice::ReadWrite)) { q_debug()<<"open file error:"<<q_file.errorString(); } else { int fp = q_file.handle(); struct _utimbuf ub; ub.actime = fi.lastRead().toTime_t(); ub.modtime = time.toTime_t(); ret = _futime(fp, &ub); q_debug()<<"_futime ret: "<<ret<<fileName <<strerror(ret); q_file.close(); } return 0; // method 2, english ok, chinese faild const char *filePathName = gOpt->locale_codec->fromUnicode(QDir::toNativeSeparators(fileName)).constData(); struct _utimbuf ub; ub.actime = fi.lastRead().toTime_t(); ub.modtime = time.toTime_t(); ret = _utime(filePathName, &ub); q_debug()<<"_utime ret: "<<ret<<filePathName<<fileName <<strerror(ret); return 0; // method 2, english ok, chinese faild QString appPath = QCoreApplication::applicationDirPath(); QString procFilePath = appPath + "/touch.exe"; QStringList args; args<<"-m"; args<<"-t"; args<<time.toString("yyyyMMddhhmm.ss"); args<<QDir::toNativeSeparators(fileName); q_debug()<<args; QProcess proc; proc.start(procFilePath, args); ret = proc.waitForFinished(); #else struct timeval tv[2] = {{0,0}, {0,0}}; tv[0].tv_sec = fi.lastRead().toTime_t(); tv[1].tv_sec = time.toTime_t(); ret = utimes(GlobalOption::instance()->locale_codec->fromUnicode(fileName), tv); assert(ret == 0); #endif return 0; }
int _RTL_FUNC _utime(const char *path, struct _utimbuf *times) { int handle; int rv; if ((handle = open (path, O_RDWR)) == -1) return -1; rv = _futime(handle, times); close (handle); return rv; }
void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) { int result; struct _utimbuf b = {(time_t)atime, (time_t)mtime}; result = _futime(file, &b); SET_REQ_RESULT(req, result); }
void do_one_file(const char *iname, char *oname) { int r; struct stat st; memset(&st, 0, sizeof(st)); #if (HAVE_LSTAT) r = lstat(iname, &st); #else r = stat(iname, &st); #endif if (r != 0) { if (errno == ENOENT) throw FileNotFoundException(iname, errno); else throwIOException(iname, errno); } if (!(S_ISREG(st.st_mode))) throwIOException("not a regular file -- skipped"); #if defined(__unix__) // no special bits may be set if ((st.st_mode & (S_ISUID | S_ISGID | S_ISVTX)) != 0) throwIOException("file has special permissions -- skipped"); #endif if (st.st_size <= 0) throwIOException("empty file -- skipped"); if (st.st_size < 512) throwIOException("file is too small -- skipped"); if (!mem_size_valid_bytes(st.st_size)) throwIOException("file is too large -- skipped"); if ((st.st_mode & S_IWUSR) == 0) { bool skip = true; if (opt->output_name) skip = false; else if (opt->to_stdout) skip = false; else if (opt->backup) skip = false; if (skip) throwIOException("file is write protected -- skipped"); } InputFile fi; fi.st = st; fi.sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR); #if (USE_FTIME) struct ftime fi_ftime; memset(&fi_ftime, 0, sizeof(fi_ftime)); if (opt->preserve_timestamp) { if (getftime(fi.getFd(), &fi_ftime) != 0) throwIOException("cannot determine file timestamp"); } #endif // open output file OutputFile fo; if (opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS) { if (opt->to_stdout) { if (!fo.openStdout(1, opt->force ? true : false)) throwIOException("data not written to a terminal; Use '-f' to force."); } else { char tname[ACC_FN_PATH_MAX+1]; if (opt->output_name) strcpy(tname,opt->output_name); else { if (!maketempname(tname, sizeof(tname), iname, ".upx")) throwIOException("could not create a temporary file name"); } if (opt->force >= 2) { #if (HAVE_CHMOD) r = chmod(tname, 0777); IGNORE_ERROR(r); #endif r = unlink(tname); IGNORE_ERROR(r); } int flags = O_CREAT | O_WRONLY | O_BINARY; if (opt->force) flags |= O_TRUNC; else flags |= O_EXCL; int shmode = SH_DENYWR; #if defined(__MINT__) flags |= O_TRUNC; shmode = O_DENYRW; #endif // cannot rely on open() because of umask //int omode = st.st_mode | 0600; int omode = 0600; if (!opt->preserve_mode) omode = 0666; fo.sopen(tname,flags,shmode,omode); // open succeeded - now set oname[] strcpy(oname,tname); } } // handle command PackMaster pm(&fi, opt); if (opt->cmd == CMD_COMPRESS) pm.pack(&fo); else if (opt->cmd == CMD_DECOMPRESS) pm.unpack(&fo); else if (opt->cmd == CMD_TEST) pm.test(); else if (opt->cmd == CMD_LIST) pm.list(); else if (opt->cmd == CMD_FILEINFO) pm.fileInfo(); else throwInternalError("invalid command"); // copy time stamp if (opt->preserve_timestamp && oname[0] && fo.isOpen()) { #if (USE_FTIME) r = setftime(fo.getFd(), &fi_ftime); IGNORE_ERROR(r); #elif (USE__FUTIME) struct _utimbuf u; u.actime = st.st_atime; u.modtime = st.st_mtime; r = _futime(fo.getFd(), &u); IGNORE_ERROR(r); #endif } // close files fo.closex(); fi.closex(); // rename or delete files if (oname[0] && !opt->output_name) { // FIXME: .exe or .cof etc. if (!opt->backup) { #if (HAVE_CHMOD) r = chmod(iname, 0777); IGNORE_ERROR(r); #endif File::unlink(iname); } else { // make backup char bakname[ACC_FN_PATH_MAX+1]; if (!makebakname(bakname, sizeof(bakname), iname)) throwIOException("could not create a backup file name"); File::rename(iname,bakname); } File::rename(oname,iname); } // copy file attributes if (oname[0]) { oname[0] = 0; const char *name = opt->output_name ? opt->output_name : iname; UNUSED(name); #if (USE_UTIME) // copy time stamp if (opt->preserve_timestamp) { struct utimbuf u; u.actime = st.st_atime; u.modtime = st.st_mtime; r = utime(name, &u); IGNORE_ERROR(r); } #endif #if (HAVE_CHMOD) // copy permissions if (opt->preserve_mode) { r = chmod(name, st.st_mode); IGNORE_ERROR(r); } #endif #if (HAVE_CHOWN) // copy the ownership if (opt->preserve_ownership) { r = chown(name, st.st_uid, st.st_gid); IGNORE_ERROR(r); } #endif } UiPacker::uiConfirmUpdate(); }