diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fileio.c | 51 | ||||
-rw-r--r-- | src/sysdep.c | 15 | ||||
-rw-r--r-- | src/systime.h | 3 | ||||
-rw-r--r-- | src/w32.c | 15 |
4 files changed, 41 insertions, 43 deletions
diff --git a/src/fileio.c b/src/fileio.c index 2532f5233c4..82fd7989206 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2253,9 +2253,8 @@ permissions. */) if (!NILP (keep_time)) { - struct timespec atime = get_stat_atime (&st); - struct timespec mtime = get_stat_mtime (&st); - if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime) != 0) + struct timespec ts[] = { get_stat_atime (&st), get_stat_mtime (&st) }; + if (futimens (ofd, ts) != 0) xsignal2 (Qfile_date_error, build_string ("Cannot set file date"), newname); } @@ -3430,39 +3429,41 @@ The value is an integer. */) } -DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 2, 0, +DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 3, 0, doc: /* Set times of file FILENAME to TIMESTAMP. -Set both access and modification times. -Return t on success, else nil. -Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of -`current-time'. */) - (Lisp_Object filename, Lisp_Object timestamp) +If optional FLAG is `nofollow', do not follow FILENAME if it is a +symbolic link. Set both access and modification times. Return t on +success, else nil. Use the current time if TIMESTAMP is nil. +TIMESTAMP is in the format of `current-time'. */) + (Lisp_Object filename, Lisp_Object timestamp, Lisp_Object flag) { - Lisp_Object absname, encoded_absname; - Lisp_Object handler; - struct timespec t = lisp_time_argument (timestamp); + int nofollow = symlink_nofollow_flag (flag); - absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)); + struct timespec ts[2]; + if (!NILP (timestamp)) + ts[0] = ts[1] = lisp_time_argument (timestamp); + else + ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW; /* If the file name has special constructs in it, call the corresponding file name handler. */ - handler = Ffind_file_name_handler (absname, Qset_file_times); + Lisp_Object + absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)), + handler = Ffind_file_name_handler (absname, Qset_file_times); if (!NILP (handler)) - return call3 (handler, Qset_file_times, absname, timestamp); + return call4 (handler, Qset_file_times, absname, timestamp, flag); - encoded_absname = ENCODE_FILE (absname); + Lisp_Object encoded_absname = ENCODE_FILE (absname); - { - if (set_file_times (-1, SSDATA (encoded_absname), t, t) != 0) - { + if (utimensat (AT_FDCWD, SSDATA (encoded_absname), ts, nofollow) != 0) + { #ifdef MSDOS - /* Setting times on a directory always fails. */ - if (file_directory_p (encoded_absname)) - return Qnil; + /* Setting times on a directory always fails. */ + if (file_directory_p (encoded_absname)) + return Qnil; #endif - report_file_error ("Setting file times", absname); - } - } + report_file_error ("Setting file times", absname); + } return Qt; } diff --git a/src/sysdep.c b/src/sysdep.c index e8e8bbfb502..149d80f19ec 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2752,21 +2752,6 @@ emacs_perror (char const *message) errno = err; } -/* Set the access and modification time stamps of FD (a.k.a. FILE) to be - ATIME and MTIME, respectively. - FD must be either negative -- in which case it is ignored -- - or a file descriptor that is open on FILE. - If FD is nonnegative, then FILE can be NULL. */ -int -set_file_times (int fd, const char *filename, - struct timespec atime, struct timespec mtime) -{ - struct timespec timespec[2]; - timespec[0] = atime; - timespec[1] = mtime; - return fdutimens (fd, filename, timespec); -} - /* Rename directory SRCFD's entry SRC to directory DSTFD's entry DST. This is like renameat except that it fails if DST already exists, or if this operation is not supported atomically. Return 0 if diff --git a/src/systime.h b/src/systime.h index 00ca4a1c58d..b59a3d1c690 100644 --- a/src/systime.h +++ b/src/systime.h @@ -67,9 +67,6 @@ timespec_valid_p (struct timespec t) return t.tv_nsec >= 0; } -/* defined in sysdep.c */ -extern int set_file_times (int, const char *, struct timespec, struct timespec); - /* defined in keyboard.c */ extern void set_waiting_for_input (struct timespec *); diff --git a/src/w32.c b/src/w32.c index cf1a3b37678..40f286ad6cf 100644 --- a/src/w32.c +++ b/src/w32.c @@ -3189,6 +3189,21 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) } } +/* Set the access and modification time stamps of FD (a.k.a. FILE) to be + ATIME and MTIME, respectively. + FD must be either negative -- in which case it is ignored -- + or a file descriptor that is open on FILE. + If FD is nonnegative, then FILE can be NULL. */ +static int +set_file_times (int fd, const char *filename, + struct timespec atime, struct timespec mtime) +{ + struct timespec timespec[2]; + timespec[0] = atime; + timespec[1] = mtime; + return fdutimens (fd, filename, timespec); +} + /* ------------------------------------------------------------------------- */ /* IO support and wrapper functions for the Windows API. */ |