aboutsummaryrefslogtreecommitdiffstats
path: root/m4
diff options
context:
space:
mode:
authorPaul Eggert2020-03-07 12:04:05 -0800
committerPaul Eggert2020-03-07 12:15:43 -0800
commit5d4cf1fef85bc24bc4cd9705ebb14150263ad707 (patch)
treeaf696ed3ba7d2d0ab31951eba9482443d36c1456 /m4
parent9f4b260c2b98ea05a02e0ab7213156ce2e60e5a9 (diff)
downloademacs-5d4cf1fef85bc24bc4cd9705ebb14150263ad707.tar.gz
emacs-5d4cf1fef85bc24bc4cd9705ebb14150263ad707.zip
Add ‘nofollow’ flag to set-file-times
This is a companion to the recent set-file-modes patch. It adds support for a ‘nofollow’ flag to set-file-times (Bug#39773). Like the set-file-modes patch, it needs work in the w32 port. * admin/merge-gnulib (GNULIB_MODULES): Add futimens, utimensat. Remove utimens. * doc/lispref/files.texi (Changing Files): * etc/NEWS: Mention the change. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lisp/files.el (copy-directory): * lisp/gnus/gnus-cloud.el (gnus-cloud-replace-file): * lisp/net/tramp-adb.el (tramp-adb-handle-copy-file): * lisp/net/tramp-smb.el (tramp-smb-handle-copy-file): * lisp/tar-mode.el (tar-copy): * test/lisp/filenotify-tests.el (file-notify-test03-events): * test/lisp/files-tests.el: (files-tests-file-name-non-special-set-file-times): * test/lisp/net/tramp-tests.el (tramp-test22-file-times): When setting file times, avoid following symbolic links when the file is not supposed to be a symbolic link. * lib/futimens.c, lib/utimensat.c, m4/futimens.m4, m4/utimensat.m4: New files, copied from Gnulib. * lisp/gnus/gnus-cloud.el (gnus-cloud-replace-file): When creating a file that is not supposed to exist already, use the excl flag to check this. * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-times): * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-times): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-times): Accept an optional FLAG arg that is currently ignored, and add a FIXME comment for it. * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-times): * src/fileio.c (Fset_file_times): Support an optional FLAG arg. * src/fileio.c (Fcopy_file): Use futimens instead of set_file_times, as it’s simpler and is a POSIX API. * src/sysdep.c (set_file_times): Move from here ... * src/w32.c (set_file_times): ... to here, and make it static, since it is now used only in w32.c. Presumably w32.c should also add support for futimens and utimensat (the POSIX APIs, which Emacs now uses) and it can remove fdutimens (the Gnulib API, which Emacs no longer uses).
Diffstat (limited to 'm4')
-rw-r--r--m4/futimens.m465
-rw-r--r--m4/gnulib-comp.m438
-rw-r--r--m4/utimensat.m469
3 files changed, 171 insertions, 1 deletions
diff --git a/m4/futimens.m4 b/m4/futimens.m4
new file mode 100644
index 00000000000..dc5cfa94119
--- /dev/null
+++ b/m4/futimens.m4
@@ -0,0 +1,65 @@
1# serial 8
2# See if we need to provide futimens replacement.
3
4dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
5dnl This file is free software; the Free Software Foundation
6dnl gives unlimited permission to copy and/or distribute it,
7dnl with or without modifications, as long as this notice is preserved.
8
9# Written by Eric Blake.
10
11AC_DEFUN([gl_FUNC_FUTIMENS],
12[
13 AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
14 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
15 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
16 AC_CHECK_FUNCS_ONCE([futimens])
17 if test $ac_cv_func_futimens = no; then
18 HAVE_FUTIMENS=0
19 else
20 AC_CACHE_CHECK([whether futimens works],
21 [gl_cv_func_futimens_works],
22 [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
23#include <fcntl.h>
24#include <sys/stat.h>
25#include <unistd.h>
26#include <errno.h>
27]], [[struct timespec ts[2];
28 int fd = creat ("conftest.file", 0600);
29 struct stat st;
30 if (fd < 0) return 1;
31 ts[0].tv_sec = 1;
32 ts[0].tv_nsec = UTIME_OMIT;
33 ts[1].tv_sec = 1;
34 ts[1].tv_nsec = UTIME_NOW;
35 errno = 0;
36 if (futimens (AT_FDCWD, NULL) == 0) return 2;
37 if (errno != EBADF) return 3;
38 if (futimens (fd, ts)) return 4;
39 sleep (1);
40 ts[0].tv_nsec = UTIME_NOW;
41 ts[1].tv_nsec = UTIME_OMIT;
42 if (futimens (fd, ts)) return 5;
43 if (fstat (fd, &st)) return 6;
44 if (st.st_ctime < st.st_atime) return 7;
45 ]])],
46 [gl_cv_func_futimens_works=yes],
47 [gl_cv_func_futimens_works=no],
48 [case "$host_os" in
49 # Guess no on glibc systems.
50 *-gnu* | gnu*) gl_cv_func_futimens_works="guessing no" ;;
51 # Guess no on musl systems.
52 *-musl*) gl_cv_func_futimens_works="guessing no" ;;
53 # Guess yes otherwise.
54 *) gl_cv_func_futimens_works="guessing yes" ;;
55 esac
56 ])
57 rm -f conftest.file])
58 case "$gl_cv_func_futimens_works" in
59 *yes) ;;
60 *)
61 REPLACE_FUTIMENS=1
62 ;;
63 esac
64 fi
65])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 1465ce811b8..3228aa42b57 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -95,6 +95,7 @@ AC_DEFUN([gl_EARLY],
95 # Code from module fstatat: 95 # Code from module fstatat:
96 # Code from module fsusage: 96 # Code from module fsusage:
97 # Code from module fsync: 97 # Code from module fsync:
98 # Code from module futimens:
98 # Code from module getdtablesize: 99 # Code from module getdtablesize:
99 # Code from module getgroups: 100 # Code from module getgroups:
100 # Code from module getloadavg: 101 # Code from module getloadavg:
@@ -179,6 +180,7 @@ AC_DEFUN([gl_EARLY],
179 # Code from module unlocked-io: 180 # Code from module unlocked-io:
180 # Code from module update-copyright: 181 # Code from module update-copyright:
181 # Code from module utimens: 182 # Code from module utimens:
183 # Code from module utimensat:
182 # Code from module vararrays: 184 # Code from module vararrays:
183 # Code from module verify: 185 # Code from module verify:
184 # Code from module vla: 186 # Code from module vla:
@@ -297,6 +299,11 @@ AC_DEFUN([gl_INIT],
297 gl_PREREQ_FSYNC 299 gl_PREREQ_FSYNC
298 fi 300 fi
299 gl_UNISTD_MODULE_INDICATOR([fsync]) 301 gl_UNISTD_MODULE_INDICATOR([fsync])
302 gl_FUNC_FUTIMENS
303 if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
304 AC_LIBOBJ([futimens])
305 fi
306 gl_SYS_STAT_MODULE_INDICATOR([futimens])
300 gl_GETLOADAVG 307 gl_GETLOADAVG
301 if test $HAVE_GETLOADAVG = 0; then 308 if test $HAVE_GETLOADAVG = 0; then
302 AC_LIBOBJ([getloadavg]) 309 AC_LIBOBJ([getloadavg])
@@ -466,7 +473,11 @@ AC_DEFUN([gl_INIT],
466 gl_TIMESPEC 473 gl_TIMESPEC
467 gl_UNISTD_H 474 gl_UNISTD_H
468 gl_FUNC_GLIBC_UNLOCKED_IO 475 gl_FUNC_GLIBC_UNLOCKED_IO
469 gl_UTIMENS 476 gl_FUNC_UTIMENSAT
477 if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
478 AC_LIBOBJ([utimensat])
479 fi
480 gl_SYS_STAT_MODULE_INDICATOR([utimensat])
470 AC_C_VARARRAYS 481 AC_C_VARARRAYS
471 gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false 482 gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
472 gl_gnulib_enabled_cloexec=false 483 gl_gnulib_enabled_cloexec=false
@@ -485,6 +496,7 @@ AC_DEFUN([gl_INIT],
485 gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false 496 gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false
486 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false 497 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
487 gl_gnulib_enabled_strtoll=false 498 gl_gnulib_enabled_strtoll=false
499 gl_gnulib_enabled_utimens=false
488 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false 500 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
489 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b () 501 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b ()
490 { 502 {
@@ -663,6 +675,13 @@ AC_DEFUN([gl_INIT],
663 gl_gnulib_enabled_strtoll=true 675 gl_gnulib_enabled_strtoll=true
664 fi 676 fi
665 } 677 }
678 func_gl_gnulib_m4code_utimens ()
679 {
680 if ! $gl_gnulib_enabled_utimens; then
681 gl_UTIMENS
682 gl_gnulib_enabled_utimens=true
683 fi
684 }
666 func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec () 685 func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec ()
667 { 686 {
668 if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then 687 if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then
@@ -705,6 +724,9 @@ AC_DEFUN([gl_INIT],
705 if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then 724 if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
706 func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7 725 func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
707 fi 726 fi
727 if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
728 func_gl_gnulib_m4code_utimens
729 fi
708 if test $REPLACE_GETOPT = 1; then 730 if test $REPLACE_GETOPT = 1; then
709 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 731 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36
710 fi 732 fi
@@ -729,6 +751,15 @@ AC_DEFUN([gl_INIT],
729 if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then 751 if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then
730 func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31 752 func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31
731 fi 753 fi
754 if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
755 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
756 fi
757 if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
758 func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
759 fi
760 if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
761 func_gl_gnulib_m4code_utimens
762 fi
732 m4_pattern_allow([^gl_GNULIB_ENABLED_]) 763 m4_pattern_allow([^gl_GNULIB_ENABLED_])
733 AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b]) 764 AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
734 AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec]) 765 AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec])
@@ -747,6 +778,7 @@ AC_DEFUN([gl_INIT],
747 AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7]) 778 AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7])
748 AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) 779 AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c])
749 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) 780 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
781 AM_CONDITIONAL([gl_GNULIB_ENABLED_utimens], [$gl_gnulib_enabled_utimens])
750 AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec]) 782 AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec])
751 # End of code from modules 783 # End of code from modules
752 m4_ifval(gl_LIBSOURCES_LIST, [ 784 m4_ifval(gl_LIBSOURCES_LIST, [
@@ -956,6 +988,7 @@ AC_DEFUN([gl_FILE_LIST], [
956 lib/fsync.c 988 lib/fsync.c
957 lib/ftoastr.c 989 lib/ftoastr.c
958 lib/ftoastr.h 990 lib/ftoastr.h
991 lib/futimens.c
959 lib/get-permissions.c 992 lib/get-permissions.c
960 lib/getdtablesize.c 993 lib/getdtablesize.c
961 lib/getgroups.c 994 lib/getgroups.c
@@ -1063,6 +1096,7 @@ AC_DEFUN([gl_FILE_LIST], [
1063 lib/unlocked-io.h 1096 lib/unlocked-io.h
1064 lib/utimens.c 1097 lib/utimens.c
1065 lib/utimens.h 1098 lib/utimens.h
1099 lib/utimensat.c
1066 lib/verify.h 1100 lib/verify.h
1067 lib/vla.h 1101 lib/vla.h
1068 lib/warn-on-use.h 1102 lib/warn-on-use.h
@@ -1103,6 +1137,7 @@ AC_DEFUN([gl_FILE_LIST], [
1103 m4/fstatat.m4 1137 m4/fstatat.m4
1104 m4/fsusage.m4 1138 m4/fsusage.m4
1105 m4/fsync.m4 1139 m4/fsync.m4
1140 m4/futimens.m4
1106 m4/getdtablesize.m4 1141 m4/getdtablesize.m4
1107 m4/getgroups.m4 1142 m4/getgroups.m4
1108 m4/getloadavg.m4 1143 m4/getloadavg.m4
@@ -1184,6 +1219,7 @@ AC_DEFUN([gl_FILE_LIST], [
1184 m4/unistd_h.m4 1219 m4/unistd_h.m4
1185 m4/unlocked-io.m4 1220 m4/unlocked-io.m4
1186 m4/utimens.m4 1221 m4/utimens.m4
1222 m4/utimensat.m4
1187 m4/utimes.m4 1223 m4/utimes.m4
1188 m4/vararrays.m4 1224 m4/vararrays.m4
1189 m4/warn-on-use.m4 1225 m4/warn-on-use.m4
diff --git a/m4/utimensat.m4 b/m4/utimensat.m4
new file mode 100644
index 00000000000..2bc1bfebb5d
--- /dev/null
+++ b/m4/utimensat.m4
@@ -0,0 +1,69 @@
1# serial 6
2# See if we need to provide utimensat replacement.
3
4dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
5dnl This file is free software; the Free Software Foundation
6dnl gives unlimited permission to copy and/or distribute it,
7dnl with or without modifications, as long as this notice is preserved.
8
9# Written by Eric Blake.
10
11AC_DEFUN([gl_FUNC_UTIMENSAT],
12[
13 AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
14 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
15 AC_CHECK_FUNCS_ONCE([utimensat])
16 if test $ac_cv_func_utimensat = no; then
17 HAVE_UTIMENSAT=0
18 else
19 AC_CACHE_CHECK([whether utimensat works],
20 [gl_cv_func_utimensat_works],
21 [AC_RUN_IFELSE(
22 [AC_LANG_PROGRAM([[
23#include <fcntl.h>
24#include <sys/stat.h>
25#include <unistd.h>
26]], [[int result = 0;
27 const char *f = "conftest.file";
28 if (close (creat (f, 0600)))
29 return 1;
30 /* Test whether the AT_SYMLINK_NOFOLLOW flag is supported. */
31 {
32 if (utimensat (AT_FDCWD, f, NULL, AT_SYMLINK_NOFOLLOW))
33 result |= 2;
34 }
35 /* Test whether UTIME_NOW and UTIME_OMIT work. */
36 {
37 struct timespec ts[2];
38 ts[0].tv_sec = 1;
39 ts[0].tv_nsec = UTIME_OMIT;
40 ts[1].tv_sec = 1;
41 ts[1].tv_nsec = UTIME_NOW;
42 if (utimensat (AT_FDCWD, f, ts, 0))
43 result |= 4;
44 }
45 sleep (1);
46 {
47 struct stat st;
48 struct timespec ts[2];
49 ts[0].tv_sec = 1;
50 ts[0].tv_nsec = UTIME_NOW;
51 ts[1].tv_sec = 1;
52 ts[1].tv_nsec = UTIME_OMIT;
53 if (utimensat (AT_FDCWD, f, ts, 0))
54 result |= 8;
55 if (stat (f, &st))
56 result |= 16;
57 else if (st.st_ctime < st.st_atime)
58 result |= 32;
59 }
60 return result;
61 ]])],
62 [gl_cv_func_utimensat_works=yes],
63 [gl_cv_func_utimensat_works=no],
64 [gl_cv_func_utimensat_works="guessing yes"])])
65 if test "$gl_cv_func_utimensat_works" = no; then
66 REPLACE_UTIMENSAT=1
67 fi
68 fi
69])