mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-14 09:39:42 +00:00
9d626dffc6
This avoids some race conditions (Bug#39683). E.g., if some other program changes a file to a symlink between the time Emacs creates the file and the time it changes the file’s permissions, using the new flag prevents Emacs from inadvertently changing the permissions of a victim in some completely unrelated directory. * admin/merge-gnulib (GNULIB_MODULES): Add fchmodat. * doc/lispref/files.texi (Testing Accessibility, Changing Files): * doc/lispref/os.texi (File Notifications): * etc/NEWS: Adjust documentation accordingly. * lib/chmodat.c, lib/fchmodat.c, lib/lchmod.c, m4/fchmodat.m4: * m4/lchmod.m4: New files, copied from Gnulib. * lib/gnulib.mk.in: Regenerate. * lisp/dired-aux.el (dired-do-chmod): * lisp/doc-view.el (doc-view-make-safe-dir): * lisp/emacs-lisp/autoload.el (autoload--save-buffer): * lisp/emacs-lisp/bytecomp.el (byte-compile-file): * lisp/eshell/em-pred.el (eshell-pred-file-mode): * lisp/files.el (backup-buffer-copy, copy-directory): * lisp/gnus/mail-source.el (mail-source-movemail): * lisp/gnus/mm-decode.el (mm-display-external): * lisp/gnus/nnmail.el (nnmail-write-region): * lisp/net/tramp-adb.el (tramp-adb-handle-file-local-copy) (tramp-adb-handle-write-region): * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-write-region): * lisp/net/tramp.el (tramp-handle-write-region) (tramp-make-tramp-temp-file): * lisp/server.el (server-ensure-safe-dir): * lisp/url/url-util.el (url-make-private-file): When getting or setting file modes, avoid following symbolic links when the file is not supposed to be a symbolic link. * lisp/doc-view.el (doc-view-make-safe-dir): Omit no-longer-needed separate symlink test. * lisp/gnus/gnus-util.el (gnus-set-file-modes): * lisp/net/tramp.el (tramp-handle-file-modes): * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-modes): * src/fileio.c (symlink_nofollow_flag): New function. (Ffile_modes, Fset_file_modes): Support an optional FLAG arg. All C callers changed. * lisp/net/ange-ftp.el (ange-ftp-set-file-modes): * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-modes): * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-modes): * lisp/net/tramp-smb.el (tramp-smb-handle-set-file-modes): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-modes): Accept an optional FLAG arg that is currently ignored, and add a FIXME comment for it. * m4/gnulib-comp.m4: Regenerate.
83 lines
2.7 KiB
Plaintext
83 lines
2.7 KiB
Plaintext
# fchmodat.m4 serial 4
|
|
dnl Copyright (C) 2004-2020 Free Software Foundation, Inc.
|
|
dnl This file is free software; the Free Software Foundation
|
|
dnl gives unlimited permission to copy and/or distribute it,
|
|
dnl with or without modifications, as long as this notice is preserved.
|
|
|
|
# Written by Jim Meyering.
|
|
|
|
AC_DEFUN([gl_FUNC_FCHMODAT],
|
|
[
|
|
AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
|
|
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
|
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
|
AC_CHECK_FUNCS_ONCE([fchmodat lchmod])
|
|
if test $ac_cv_func_fchmodat != yes; then
|
|
HAVE_FCHMODAT=0
|
|
else
|
|
AC_CACHE_CHECK(
|
|
[whether fchmodat+AT_SYMLINK_NOFOLLOW works on non-symlinks],
|
|
[gl_cv_func_fchmodat_works],
|
|
[dnl This test fails on GNU/Linux with glibc 2.31 (but not on
|
|
dnl GNU/kFreeBSD nor GNU/Hurd) and Cygwin 2.9.
|
|
AC_RUN_IFELSE(
|
|
[AC_LANG_PROGRAM(
|
|
[
|
|
AC_INCLUDES_DEFAULT[
|
|
#include <fcntl.h>
|
|
#ifndef S_IRUSR
|
|
#define S_IRUSR 0400
|
|
#endif
|
|
#ifndef S_IWUSR
|
|
#define S_IWUSR 0200
|
|
#endif
|
|
#ifndef S_IRWXU
|
|
#define S_IRWXU 0700
|
|
#endif
|
|
#ifndef S_IRWXG
|
|
#define S_IRWXG 0070
|
|
#endif
|
|
#ifndef S_IRWXO
|
|
#define S_IRWXO 0007
|
|
#endif
|
|
]],
|
|
[[
|
|
int permissive = S_IRWXU | S_IRWXG | S_IRWXO;
|
|
int desired = S_IRUSR | S_IWUSR;
|
|
static char const f[] = "conftest.fchmodat";
|
|
struct stat st;
|
|
if (creat (f, permissive) < 0)
|
|
return 1;
|
|
if (fchmodat (AT_FDCWD, f, desired, AT_SYMLINK_NOFOLLOW) != 0)
|
|
return 1;
|
|
if (stat (f, &st) != 0)
|
|
return 1;
|
|
return ! ((st.st_mode & permissive) == desired);
|
|
]])],
|
|
[gl_cv_func_fchmodat_works=yes],
|
|
[gl_cv_func_fchmodat_works=no],
|
|
[case "$host_os" in
|
|
dnl Guess no on Linux with glibc and Cygwin, yes otherwise.
|
|
linux-gnu* | cygwin*) gl_cv_func_fchmodat_works="guessing no" ;;
|
|
*) gl_cv_func_fchmodat_works="$gl_cross_guess_normal" ;;
|
|
esac
|
|
])
|
|
rm -f conftest.fchmodat])
|
|
case $gl_cv_func_fchmodat_works in
|
|
*yes) ;;
|
|
*)
|
|
AC_DEFINE([NEED_FCHMODAT_NONSYMLINK_FIX], [1],
|
|
[Define to 1 if fchmodat+AT_SYMLINK_NOFOLLOW does not work right on non-symlinks.])
|
|
REPLACE_FCHMODAT=1
|
|
;;
|
|
esac
|
|
fi
|
|
])
|
|
|
|
# Prerequisites of lib/fchmodat.c.
|
|
AC_DEFUN([gl_PREREQ_FCHMODAT],
|
|
[
|
|
AC_CHECK_FUNCS_ONCE([lchmod])
|
|
:
|
|
])
|