From e752e0b0a2622d8d0ba518bf81f6fa652d926e67 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 19 Oct 2012 09:52:02 -0700 Subject: [PATCH] Use faccessat, not access, when checking file permissions. * .bzrignore: Add lib/fcntl.h. * configure.ac (euidaccess): Remove check; gnulib does this for us now. (gl_FCNTL_O_FLAGS): Define a dummy version. * lib/at-func.c, lib/euidaccess.c, lib/faccessat.c, lib/fcntl.in.h: * lib/getgroups.c, lib/group-member.c, lib/root-uid.h: * lib/xalloc-oversized.h, m4/euidaccess.m4, m4/faccessat.m4: * m4/fcntl_h.m4, m4/getgroups.m4, m4/group-member.m4: New files, from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * admin/merge-gnulib (GNULIB_MODULES): Add faccessat. (GNULIB_TOOL_FLAGS): Avoid at-internal, fchdir, malloc-posix, openat-die, openat-h, save-cwd. Do not avoid fcntl-h. Omit gnulib's m4/fcntl-o.m4. * nt/inc/ms-w32.h (AT_FDCWD, AT_EACCESS): New symbols. (access): Remove. (faccessat): New macro. * src/Makefile.in (LIB_EACCESS): New macro. (LIBES): Use it. * src/callproc.c (init_callproc): * src/charset.c (init_charset): * src/fileio.c (check_existing, check_executable): * src/lread.c (openp, load_path_check): * src/process.c (allocate_pty): * src/xrdb.c (file_p): Use faccessat, not access or euidaccess. Use symbolic names instead of integers for the flags, as they're portable now. * src/charset.c, src/xrdb.c: Include , for the new flags used. * src/fileio.c (Ffile_readable_p): Use faccessat, not stat + open + close. (file_directory_p): New function, which uses 'stat' on most places but 'access' (for efficiency) if WINDOWSNT. * src/fileio.c (Ffile_directory_p, Fset_file_times): * src/xrdb.c (file_p): Use file_directory_p. * src/lisp.h (file_directory_p): New decl. * src/lread.c (openp): When opening a file, use fstat rather than stat, as that avoids a permissions race. When not opening a file, use file_directory_p rather than stat. * src/process.c, src/sysdep.c, src/term.c: All uses of '#ifdef O_NONBLOCK' changed to '#if O_NONBLOCK', to accommodate gnulib O_* tyle. * src/w32.c (sys_faccessat): Rename from sys_access and switch to faccessat's API. All uses changed. Fixes: debbugs:12632 --- ChangeLog | 13 ++++++ admin/ChangeLog | 8 ++++ admin/merge-gnulib | 13 +++--- configure.ac | 4 +- lib/gnulib.mk | 97 ++++++++++++++++++++++++++++++++++++++++- m4/gnulib-comp.m4 | 105 +++++++++++++++++++++++++++++++++++++++++++++ nt/ChangeLog | 7 +++ nt/inc/ms-w32.h | 7 ++- src/ChangeLog | 29 +++++++++++++ src/Makefile.in | 3 +- src/callproc.c | 4 +- src/charset.c | 3 +- src/conf_post.h | 4 ++ src/fileio.c | 97 +++++++++++------------------------------ src/lisp.h | 1 + src/lread.c | 56 ++++++++++++------------ src/process.c | 36 ++++++++-------- src/sysdep.c | 6 +-- src/term.c | 4 +- src/w32.c | 18 +++++--- src/xrdb.c | 8 ++-- 21 files changed, 377 insertions(+), 146 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81eddade0a0..c7fcd319af2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2012-10-19 Paul Eggert + + Use faccessat, not access, when checking file permissions (Bug#12632). + * .bzrignore: Add lib/fcntl.h. + * configure.ac (euidaccess): Remove check; gnulib does this for us now. + (gl_FCNTL_O_FLAGS): Define a dummy version. + * lib/at-func.c, lib/euidaccess.c, lib/faccessat.c, lib/fcntl.in.h: + * lib/getgroups.c, lib/group-member.c, lib/root-uid.h: + * lib/xalloc-oversized.h, m4/euidaccess.m4, m4/faccessat.m4: + * m4/fcntl_h.m4, m4/getgroups.m4, m4/group-member.m4: + New files, from gnulib. + * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. + 2012-10-18 Stefan Monnier * Makefile.in ($(MAKEFILE_NAME)): Depend on src/lisp.mk as well. diff --git a/admin/ChangeLog b/admin/ChangeLog index e21293d618d..6d08bf7c37e 100644 --- a/admin/ChangeLog +++ b/admin/ChangeLog @@ -1,3 +1,11 @@ +2012-10-19 Paul Eggert + + Use faccessat, not access, when checking file permissions (Bug#12632). + * merge-gnulib (GNULIB_MODULES): Add faccessat. + (GNULIB_TOOL_FLAGS): Avoid at-internal, fchdir, malloc-posix, + openat-die, openat-h, save-cwd. Do not avoid fcntl-h. + Omit gnulib's m4/fcntl-o.m4. + 2012-10-12 Kenichi Handa * charsets/Makefile (JISC6226.map): Add missing mappings. diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 7fc0b5f4844..3c4d8e8058d 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -28,7 +28,7 @@ GNULIB_URL=git://git.savannah.gnu.org/gnulib.git GNULIB_MODULES=' alloca-opt c-ctype c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 - dtoastr dtotimespec dup2 environ execinfo + dtoastr dtotimespec dup2 environ execinfo faccessat filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink @@ -39,9 +39,12 @@ GNULIB_MODULES=' ' GNULIB_TOOL_FLAGS=' - --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat - --avoid=msvc-inval --avoid=msvc-nothrow - --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types + --avoid=at-internal + --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat + --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow + --avoid=openat-die --avoid=openat-h + --avoid=raise + --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --conditional-dependencies --import --no-changelog --no-vc-files --makefile-name=gnulib.mk @@ -85,7 +88,7 @@ test -x "$gnulib_srcdir"/gnulib-tool || { } "$gnulib_srcdir"/gnulib-tool --dir="$src" $GNULIB_TOOL_FLAGS $GNULIB_MODULES && -rm -- "$src"m4/gnulib-cache.m4 "$src"m4/warn-on-use.m4 && +rm -- "$src"m4/fcntl-o.m4 "$src"m4/gnulib-cache.m4 "$src"m4/warn-on-use.m4 && cp -- "$gnulib_srcdir"/build-aux/texinfo.tex "$src"doc/misc && cp -- "$gnulib_srcdir"/build-aux/move-if-change "$src"build-aux && autoreconf -i -I m4 -- ${src:+"$src"} diff --git a/configure.ac b/configure.ac index 5520dd6a903..6b4c757ced5 100644 --- a/configure.ac +++ b/configure.ac @@ -572,6 +572,8 @@ else test "x$NON_GCC_TEST_OPTIONS" != x && CC="$CC $NON_GCC_TEST_OPTIONS" fi +# Avoid gnulib's tests for O_NOATIME and O_NOFOLLOW, as we don't use them. +AC_DEFUN([gl_FCNTL_O_FLAGS]) # Avoid gnulib's threadlib module, as we do threads our own way. AC_DEFUN([gl_THREADLIB]) @@ -2872,7 +2874,7 @@ AC_SUBST(BLESSMAIL_TARGET) AC_CHECK_FUNCS(gethostname \ closedir getrusage get_current_dir_name \ lrand48 setsid \ -fpathconf select euidaccess getpagesize setlocale \ +fpathconf select getpagesize setlocale \ utimes getrlimit setrlimit setpgid getcwd shutdown getaddrinfo \ __fpending strsignal setitimer \ sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \ diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 23749331a83..d2562a4dae1 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings MOSTLYCLEANFILES += core *.stackdump @@ -150,6 +150,17 @@ EXTRA_libgnu_a_SOURCES += dup2.c ## end gnulib module dup2 +## begin gnulib module euidaccess + +if gl_GNULIB_ENABLED_euidaccess + +endif +EXTRA_DIST += euidaccess.c + +EXTRA_libgnu_a_SOURCES += euidaccess.c + +## end gnulib module euidaccess + ## begin gnulib module execinfo BUILT_SOURCES += $(EXECINFO_H) @@ -175,6 +186,50 @@ EXTRA_libgnu_a_SOURCES += execinfo.c ## end gnulib module execinfo +## begin gnulib module faccessat + + +EXTRA_DIST += at-func.c faccessat.c + +EXTRA_libgnu_a_SOURCES += at-func.c faccessat.c + +## end gnulib module faccessat + +## begin gnulib module fcntl-h + +BUILT_SOURCES += fcntl.h + +# We need the following in order to create when the system +# doesn't have one that works with the given compiler. +fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \ + -e 's/@''GNULIB_FCNTL''@/$(GNULIB_FCNTL)/g' \ + -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \ + -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \ + -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \ + -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \ + -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \ + -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \ + -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \ + -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/fcntl.in.h; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += fcntl.h fcntl.h-t + +EXTRA_DIST += fcntl.in.h + +## end gnulib module fcntl-h + ## begin gnulib module filemode libgnu_a_SOURCES += filemode.c @@ -183,6 +238,17 @@ EXTRA_DIST += filemode.h ## end gnulib module filemode +## begin gnulib module getgroups + +if gl_GNULIB_ENABLED_getgroups + +endif +EXTRA_DIST += getgroups.c + +EXTRA_libgnu_a_SOURCES += getgroups.c + +## end gnulib module getgroups + ## begin gnulib module getloadavg @@ -242,6 +308,17 @@ EXTRA_libgnu_a_SOURCES += gettimeofday.c ## end gnulib module gettimeofday +## begin gnulib module group-member + +if gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1 + +endif +EXTRA_DIST += group-member.c + +EXTRA_libgnu_a_SOURCES += group-member.c + +## end gnulib module group-member + ## begin gnulib module ignore-value @@ -354,6 +431,15 @@ EXTRA_libgnu_a_SOURCES += readlink.c ## end gnulib module readlink +## begin gnulib module root-uid + +if gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c + +endif +EXTRA_DIST += root-uid.h + +## end gnulib module root-uid + ## begin gnulib module signal-h BUILT_SOURCES += signal.h @@ -1312,6 +1398,15 @@ EXTRA_DIST += verify.h ## end gnulib module verify +## begin gnulib module xalloc-oversized + +if gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec + +endif +EXTRA_DIST += xalloc-oversized.h + +## end gnulib module xalloc-oversized + mostlyclean-local: mostlyclean-generic @for dir in '' $(MOSTLYCLEANDIRS); do \ diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index de2355d87c3..9b2dcee1cfa 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -53,17 +53,22 @@ AC_DEFUN([gl_EARLY], # Code from module dtotimespec: # Code from module dup2: # Code from module environ: + # Code from module euidaccess: # Code from module execinfo: # Code from module extensions: AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) # Code from module extern-inline: + # Code from module faccessat: + # Code from module fcntl-h: # Code from module filemode: + # Code from module getgroups: # Code from module getloadavg: # Code from module getopt-gnu: # Code from module getopt-posix: # Code from module gettext-h: # Code from module gettime: # Code from module gettimeofday: + # Code from module group-member: # Code from module ignore-value: # Code from module include_next: # Code from module intprops: @@ -79,6 +84,7 @@ AC_DEFUN([gl_EARLY], # Code from module pselect: # Code from module pthread_sigmask: # Code from module readlink: + # Code from module root-uid: # Code from module signal-h: # Code from module snippet/_Noreturn: # Code from module snippet/arg-nonnull: @@ -120,6 +126,7 @@ AC_DEFUN([gl_EARLY], # Code from module utimens: # Code from module verify: # Code from module warnings: + # Code from module xalloc-oversized: ]) # This macro should be invoked from ./configure.ac, in the section @@ -156,6 +163,14 @@ AC_DEFUN([gl_INIT], gl_UNISTD_MODULE_INDICATOR([environ]) gl_EXECINFO_H AC_REQUIRE([gl_EXTERN_INLINE]) + gl_FUNC_FACCESSAT + if test $HAVE_FACCESSAT = 0; then + AC_LIBOBJ([faccessat]) + gl_PREREQ_FACCESSAT + fi + gl_MODULE_INDICATOR([faccessat]) + gl_UNISTD_MODULE_INDICATOR([faccessat]) + gl_FCNTL_H gl_FILEMODE gl_GETLOADAVG if test $HAVE_GETLOADAVG = 0; then @@ -269,18 +284,53 @@ AC_DEFUN([gl_INIT], gl_UNISTD_H gl_UTIMENS gl_gnulib_enabled_dosname=false + gl_gnulib_enabled_euidaccess=false + gl_gnulib_enabled_getgroups=false gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false + gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false gl_gnulib_enabled_pathmax=false + gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false gl_gnulib_enabled_stat=false gl_gnulib_enabled_strtoll=false gl_gnulib_enabled_strtoull=false gl_gnulib_enabled_verify=false + gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false func_gl_gnulib_m4code_dosname () { if ! $gl_gnulib_enabled_dosname; then gl_gnulib_enabled_dosname=true fi } + func_gl_gnulib_m4code_euidaccess () + { + if ! $gl_gnulib_enabled_euidaccess; then + gl_FUNC_EUIDACCESS + if test $HAVE_EUIDACCESS = 0; then + AC_LIBOBJ([euidaccess]) + gl_PREREQ_EUIDACCESS + fi + gl_UNISTD_MODULE_INDICATOR([euidaccess]) + gl_gnulib_enabled_euidaccess=true + if test $HAVE_EUIDACCESS = 0; then + func_gl_gnulib_m4code_a9786850e999ae65a836a6041e8e5ed1 + fi + func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c + if test $HAVE_EUIDACCESS = 0; then + func_gl_gnulib_m4code_stat + fi + fi + } + func_gl_gnulib_m4code_getgroups () + { + if ! $gl_gnulib_enabled_getgroups; then + gl_FUNC_GETGROUPS + if test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1; then + AC_LIBOBJ([getgroups]) + fi + gl_UNISTD_MODULE_INDICATOR([getgroups]) + gl_gnulib_enabled_getgroups=true + fi + } func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 () { if ! $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then @@ -289,6 +339,24 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true fi } + func_gl_gnulib_m4code_a9786850e999ae65a836a6041e8e5ed1 () + { + if ! $gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1; then + gl_FUNC_GROUP_MEMBER + if test $HAVE_GROUP_MEMBER = 0; then + AC_LIBOBJ([group-member]) + gl_PREREQ_GROUP_MEMBER + fi + gl_UNISTD_MODULE_INDICATOR([group-member]) + gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=true + if test $HAVE_GROUP_MEMBER = 0; then + func_gl_gnulib_m4code_getgroups + fi + if test $HAVE_GROUP_MEMBER = 0; then + func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec + fi + fi + } func_gl_gnulib_m4code_pathmax () { if ! $gl_gnulib_enabled_pathmax; then @@ -296,6 +364,12 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_pathmax=true fi } + func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c () + { + if ! $gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c; then + gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=true + fi + } func_gl_gnulib_m4code_stat () { if ! $gl_gnulib_enabled_stat; then @@ -347,6 +421,18 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_verify=true fi } + func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec () + { + if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then + gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=true + fi + } + if test $HAVE_FACCESSAT = 0; then + func_gl_gnulib_m4code_dosname + fi + if test $HAVE_FACCESSAT = 0; then + func_gl_gnulib_m4code_euidaccess + fi if test $REPLACE_GETOPT = 1; then func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 fi @@ -373,12 +459,17 @@ AC_DEFUN([gl_INIT], fi m4_pattern_allow([^gl_GNULIB_ENABLED_]) AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_getgroups], [$gl_gnulib_enabled_getgroups]) AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1]) AM_CONDITIONAL([gl_GNULIB_ENABLED_pathmax], [$gl_gnulib_enabled_pathmax]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat]) AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull]) AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec]) # End of code from modules m4_ifval(gl_LIBSOURCES_LIST, [ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || @@ -527,6 +618,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/alloca.in.h lib/allocator.c lib/allocator.h + lib/at-func.c lib/c-ctype.c lib/c-ctype.h lib/c-strcase.h @@ -538,12 +630,16 @@ AC_DEFUN([gl_FILE_LIST], [ lib/dtoastr.c lib/dtotimespec.c lib/dup2.c + lib/euidaccess.c lib/execinfo.c lib/execinfo.in.h + lib/faccessat.c + lib/fcntl.in.h lib/filemode.c lib/filemode.h lib/ftoastr.c lib/ftoastr.h + lib/getgroups.c lib/getloadavg.c lib/getopt.c lib/getopt.in.h @@ -552,6 +648,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/gettext.h lib/gettime.c lib/gettimeofday.c + lib/group-member.c lib/ignore-value.h lib/intprops.h lib/inttypes.in.h @@ -564,6 +661,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/pselect.c lib/pthread_sigmask.c lib/readlink.c + lib/root-uid.h lib/sha1.c lib/sha1.h lib/sha256.c @@ -605,21 +703,28 @@ AC_DEFUN([gl_FILE_LIST], [ lib/utimens.c lib/utimens.h lib/verify.h + lib/xalloc-oversized.h m4/00gnulib.m4 m4/alloca.m4 m4/c-strtod.m4 m4/clock_time.m4 m4/dup2.m4 m4/environ.m4 + m4/euidaccess.m4 m4/execinfo.m4 m4/extensions.m4 m4/extern-inline.m4 + m4/faccessat.m4 + m4/fcntl-o.m4 + m4/fcntl_h.m4 m4/filemode.m4 + m4/getgroups.m4 m4/getloadavg.m4 m4/getopt.m4 m4/gettime.m4 m4/gettimeofday.m4 m4/gnulib-common.m4 + m4/group-member.m4 m4/include_next.m4 m4/inttypes.m4 m4/largefile.m4 diff --git a/nt/ChangeLog b/nt/ChangeLog index 94d2ce18551..f64cafe2e16 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog @@ -1,3 +1,10 @@ +2012-10-19 Paul Eggert + + Use faccessat, not access, when checking file permissions (Bug#12632). + * inc/ms-w32.h (AT_FDCWD, AT_EACCESS): New symbols. + (access): Remove. + (faccessat): New macro. + 2012-10-17 Eli Zaretskii * inc/pwd.h (getuid, geteuid): Add prototypes. diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index dd2ae781cb8..0f6b51d3915 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -124,6 +124,10 @@ extern char *getenv (); #define MAXPATHLEN _MAX_PATH #endif +/* Use values compatible with gnulib, as there's no reason to differ. */ +#define AT_FDCWD (-3041965) +#define AT_EACCESS 4 + #ifdef HAVE_NTGUI #define HAVE_WINDOW_SYSTEM 1 #define HAVE_MENUS 1 @@ -145,8 +149,6 @@ extern char *getenv (); #endif /* Calls that are emulated or shadowed. */ -#undef access -#define access sys_access #undef chdir #define chdir sys_chdir #undef chmod @@ -161,6 +163,7 @@ extern char *getenv (); #define dup sys_dup #undef dup2 #define dup2 sys_dup2 +#define faccessat sys_faccessat #define fopen sys_fopen #define link sys_link #define localtime sys_localtime diff --git a/src/ChangeLog b/src/ChangeLog index 5a1b4a5d8ee..ee18650e992 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +2012-10-19 Paul Eggert + + Use faccessat, not access, when checking file permissions (Bug#12632). + * Makefile.in (LIB_EACCESS): New macro. + (LIBES): Use it. + * callproc.c (init_callproc): + * charset.c (init_charset): + * fileio.c (check_existing, check_executable): + * lread.c (openp, load_path_check): + * process.c (allocate_pty): + * xrdb.c (file_p): + Use faccessat, not access or euidaccess. Use symbolic names + instead of integers for the flags, as they're portable now. + * charset.c, xrdb.c: Include , for the new flags used. + * fileio.c (Ffile_readable_p): + Use faccessat, not stat + open + close. + (file_directory_p): New function, which uses 'stat' on most places + but 'access' (for efficiency) if WINDOWSNT. + * fileio.c (Ffile_directory_p, Fset_file_times): + * xrdb.c (file_p): Use file_directory_p. + * lisp.h (file_directory_p): New decl. + * lread.c (openp): When opening a file, use fstat rather than + stat, as that avoids a permissions race. When not opening a file, + use file_directory_p rather than stat. + * process.c, sysdep.c, term.c: All uses of '#ifdef O_NONBLOCK' + changed to '#if O_NONBLOCK', to accommodate gnulib O_* style. + * w32.c (sys_faccessat): Rename from sys_access and switch to + faccessat's API. All uses changed. + 2012-10-19 Kazuhiro Ito (tiny change) * font.c (Ffont_at): Fix previous change. diff --git a/src/Makefile.in b/src/Makefile.in index c24e421bbbc..d034ad04796 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -150,6 +150,7 @@ M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@ M17N_FLT_LIBS = @M17N_FLT_LIBS@ LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@ +LIB_EACCESS=@LIB_EACCESS@ LIB_TIMER_TIME=@LIB_TIMER_TIME@ DBUS_CFLAGS = @DBUS_CFLAGS@ @@ -392,7 +393,7 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \ LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \ $(LIBX_OTHER) $(LIBSOUND) \ $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \ - $(LIB_TIMER_TIME) $(DBUS_LIBS) \ + $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \ $(LIB_EXECINFO) \ $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ diff --git a/src/callproc.c b/src/callproc.c index b33882e54c2..5a9b32f08c3 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1597,13 +1597,13 @@ init_callproc (void) #endif { tempdir = Fdirectory_file_name (Vexec_directory); - if (access (SSDATA (tempdir), 0) < 0) + if (faccessat (AT_FDCWD, SSDATA (tempdir), F_OK, AT_EACCESS) != 0) dir_warning ("Warning: arch-dependent data dir (%s) does not exist.\n", Vexec_directory); } tempdir = Fdirectory_file_name (Vdata_directory); - if (access (SSDATA (tempdir), 0) < 0) + if (faccessat (AT_FDCWD, SSDATA (tempdir), F_OK, AT_EACCESS) != 0) dir_warning ("Warning: arch-independent data dir (%s) does not exist.\n", Vdata_directory); diff --git a/src/charset.c b/src/charset.c index 6b999824dab..fe068e1d3bc 100644 --- a/src/charset.c +++ b/src/charset.c @@ -28,6 +28,7 @@ along with GNU Emacs. If not, see . */ #define CHARSET_INLINE EXTERN_INLINE +#include #include #include #include @@ -2293,7 +2294,7 @@ init_charset (void) { Lisp_Object tempdir; tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); - if (access (SSDATA (tempdir), 0) < 0) + if (faccessat (AT_FDCWD, SSDATA (tempdir), F_OK, AT_EACCESS) != 0) { /* This used to be non-fatal (dir_warning), but it should not happen, and if it does sooner or later it will cause some diff --git a/src/conf_post.h b/src/conf_post.h index aa008107ba6..eade536e6e1 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -169,6 +169,10 @@ extern void _DebPrint (const char *fmt, ...); #endif #endif +/* Tell gnulib to omit support for openat-related functions having a + first argument other than AT_FDCWD. */ +#define GNULIB_SUPPORT_ONLY_AT_FDCWD + #include #include diff --git a/src/fileio.c b/src/fileio.c index d47d7dd9e0b..3accb58a3eb 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2425,15 +2425,7 @@ On Unix, this is a name starting with a `/' or a `~'. */) bool check_existing (const char *filename) { -#ifdef DOS_NT - /* The full emulation of Posix 'stat' is too expensive on - DOS/Windows, when all we want to know is whether the file exists. - So we use 'access' instead, which is much more lightweight. */ - return (access (filename, F_OK) >= 0); -#else - struct stat st; - return (stat (filename, &st) >= 0); -#endif + return faccessat (AT_FDCWD, filename, F_OK, AT_EACCESS) == 0; } /* Return true if file FILENAME exists and can be executed. */ @@ -2441,21 +2433,7 @@ check_existing (const char *filename) static bool check_executable (char *filename) { -#ifdef DOS_NT - struct stat st; - if (stat (filename, &st) < 0) - return 0; - return ((st.st_mode & S_IEXEC) != 0); -#else /* not DOS_NT */ -#ifdef HAVE_EUIDACCESS - return (euidaccess (filename, 1) >= 0); -#else - /* Access isn't quite right because it uses the real uid - and we really want to test with the effective uid. - But Unix doesn't give us a right way to do it. */ - return (access (filename, 1) >= 0); -#endif -#endif /* not DOS_NT */ + return faccessat (AT_FDCWD, filename, X_OK, AT_EACCESS) == 0; } /* Return true if file FILENAME exists and can be written. */ @@ -2464,15 +2442,16 @@ static bool check_writable (const char *filename) { #ifdef MSDOS + /* FIXME: an faccessat implementation should be added to the + DOS/Windows ports and this #ifdef branch should be removed. */ struct stat st; if (stat (filename, &st) < 0) return 0; return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode)); #else /* not MSDOS */ -#ifdef HAVE_EUIDACCESS - bool res = (euidaccess (filename, 2) >= 0); + bool res = faccessat (AT_FDCWD, filename, W_OK, AT_EACCESS) == 0; #ifdef CYGWIN - /* euidaccess may have returned failure because Cygwin couldn't + /* faccessat may have returned failure because Cygwin couldn't determine the file's UID or GID; if so, we return success. */ if (!res) { @@ -2483,14 +2462,6 @@ check_writable (const char *filename) } #endif /* CYGWIN */ return res; -#else /* not HAVE_EUIDACCESS */ - /* Access isn't quite right because it uses the real uid - and we really want to test with the effective uid. - But Unix doesn't give us a right way to do it. - Opening with O_WRONLY could work for an ordinary file, - but would lose for directories. */ - return (access (filename, 2) >= 0); -#endif /* not HAVE_EUIDACCESS */ #endif /* not MSDOS */ } @@ -2547,9 +2518,6 @@ See also `file-exists-p' and `file-attributes'. */) { Lisp_Object absname; Lisp_Object handler; - int desc; - int flags; - struct stat statbuf; CHECK_STRING (filename); absname = Fexpand_file_name (filename, Qnil); @@ -2561,31 +2529,8 @@ See also `file-exists-p' and `file-attributes'. */) return call2 (handler, Qfile_readable_p, absname); absname = ENCODE_FILE (absname); - -#if defined (DOS_NT) || defined (macintosh) - /* Under MS-DOS, Windows, and Macintosh, open does not work for - directories. */ - if (access (SDATA (absname), 0) == 0) - return Qt; - return Qnil; -#else /* not DOS_NT and not macintosh */ - flags = O_RDONLY; -#ifdef O_NONBLOCK - /* Opening a fifo without O_NONBLOCK can wait. - We don't want to wait. But we don't want to mess wth O_NONBLOCK - except in the case of a fifo, on a system which handles it. */ - desc = stat (SSDATA (absname), &statbuf); - if (desc < 0) - return Qnil; - if (S_ISFIFO (statbuf.st_mode)) - flags |= O_NONBLOCK; -#endif - desc = emacs_open (SSDATA (absname), flags, 0); - if (desc < 0) - return Qnil; - emacs_close (desc); - return Qt; -#endif /* not DOS_NT and not macintosh */ + return (faccessat (AT_FDCWD, SSDATA (absname), R_OK, AT_EACCESS) == 0 + ? Qt : Qnil); } /* Having this before file-symlink-p mysteriously caused it to be forgotten @@ -2622,7 +2567,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, /* The read-only attribute of the parent directory doesn't affect whether a file or directory can be created within it. Some day we should check ACLs though, which do affect this. */ - return (access (SDATA (dir), D_OK) < 0) ? Qnil : Qt; + return file_directory_p (SDATA (dir)) ? Qt : Qnil; #else return (check_writable (!NILP (dir) ? SSDATA (dir) : "") ? Qt : Qnil); @@ -2703,8 +2648,7 @@ Symbolic links to directories count as directories. See `file-symlink-p' to distinguish symlinks. */) (Lisp_Object filename) { - register Lisp_Object absname; - struct stat st; + Lisp_Object absname; Lisp_Object handler; absname = expand_and_dir_to_file (filename, BVAR (current_buffer, directory)); @@ -2717,9 +2661,20 @@ See `file-symlink-p' to distinguish symlinks. */) absname = ENCODE_FILE (absname); - if (stat (SSDATA (absname), &st) < 0) - return Qnil; - return S_ISDIR (st.st_mode) ? Qt : Qnil; + return file_directory_p (SSDATA (absname)) ? Qt : Qnil; +} + +/* Return true if FILE is a directory or a symlink to a directory. */ +bool +file_directory_p (char const *file) +{ +#ifdef WINDOWSNT + /* This is cheaper than 'stat'. */ + return faccessat (AT_FDCWD, file, D_OK, AT_EACCESS) == 0; +#else + struct stat st; + return stat (file, &st) == 0 && S_ISDIR (st.st_mode); +#endif } DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, @@ -3044,10 +2999,8 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of if (set_file_times (-1, SSDATA (encoded_absname), t, t)) { #ifdef MSDOS - struct stat st; - /* Setting times on a directory always fails. */ - if (stat (SSDATA (encoded_absname), &st) == 0 && S_ISDIR (st.st_mode)) + if (file_directory_p (SSDATA (encoded_absname))) return Qnil; #endif report_file_error ("Setting file times", Fcons (absname, Qnil)); diff --git a/src/lisp.h b/src/lisp.h index 01f6ca5e57c..897757cf462 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3178,6 +3178,7 @@ extern Lisp_Object close_file_unwind (Lisp_Object); extern Lisp_Object restore_point_unwind (Lisp_Object); extern _Noreturn void report_file_error (const char *, Lisp_Object); extern void internal_delete_file (Lisp_Object); +extern bool file_directory_p (const char *); extern void syms_of_fileio (void); extern Lisp_Object make_temp_name (Lisp_Object, bool); extern Lisp_Object Qdelete_file; diff --git a/src/lread.c b/src/lread.c index 6d4c0d990af..dedce50de2a 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1404,7 +1404,7 @@ Returns the file's name in absolute form, or nil if not found. If SUFFIXES is non-nil, it should be a list of suffixes to append to file name when searching. If non-nil, PREDICATE is used instead of `file-readable-p'. -PREDICATE can also be an integer to pass to the access(2) function, +PREDICATE can also be an integer to pass to the faccessat(2) function, in which case file-name-handlers are ignored. This function will normally skip directories, so if you want it to find directories, make sure the PREDICATE function returns `dir-ok' for them. */) @@ -1442,7 +1442,6 @@ static Lisp_Object Qdir_ok; int openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) { - int fd; ptrdiff_t fn_size = 100; char buf[100]; char *fn = buf; @@ -1497,7 +1496,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto { ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); Lisp_Object handler; - bool exists; /* Concatenate path element/specified name with the suffix. If the directory starts with /:, remove that. */ @@ -1521,6 +1519,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto handler = Ffind_file_name_handler (string, Qfile_exists_p); if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) { + bool exists; if (NILP (predicate)) exists = !NILP (Ffile_readable_p (string)); else @@ -1542,37 +1541,40 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto } else { -#ifndef WINDOWSNT - struct stat st; -#endif + int fd; const char *pfn; encoded_fn = ENCODE_FILE (string); pfn = SSDATA (encoded_fn); -#ifdef WINDOWSNT - exists = access (pfn, F_OK) == 0 && access (pfn, D_OK) < 0; -#else - exists = (stat (pfn, &st) == 0 && ! S_ISDIR (st.st_mode)); -#endif - if (exists) - { - /* Check that we can access or open it. */ - if (NATNUMP (predicate)) - fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 - && access (pfn, XFASTINT (predicate)) == 0) - ? 1 : -1); - else - fd = emacs_open (pfn, O_RDONLY, 0); - if (fd >= 0) + /* Check that we can access or open it. */ + if (NATNUMP (predicate)) + fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 + && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate), + AT_EACCESS) + == 0) + && ! file_directory_p (pfn)) + ? 1 : -1); + else + { + struct stat st; + fd = emacs_open (pfn, O_RDONLY, 0); + if (0 <= fd + && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode))) { - /* We succeeded; return this descriptor and filename. */ - if (storeptr) - *storeptr = string; - UNGCPRO; - return fd; + emacs_close (fd); + fd = -1; } } + + if (fd >= 0) + { + /* We succeeded; return this descriptor and filename. */ + if (storeptr) + *storeptr = string; + UNGCPRO; + return fd; + } } } if (absolute) @@ -4088,7 +4090,7 @@ load_path_check (void) if (STRINGP (dirfile)) { dirfile = Fdirectory_file_name (dirfile); - if (access (SSDATA (dirfile), 0) < 0) + if (faccessat (AT_FDCWD, SSDATA (dirfile), F_OK, AT_EACCESS) != 0) dir_warning ("Warning: Lisp directory `%s' does not exist.\n", XCAR (path_tail)); } diff --git a/src/process.c b/src/process.c index 307e82819d6..572ab83de09 100644 --- a/src/process.c +++ b/src/process.c @@ -204,7 +204,7 @@ static EMACS_INT update_tick; #ifndef NON_BLOCKING_CONNECT #ifdef HAVE_SELECT #if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX) -#if defined (O_NONBLOCK) || defined (O_NDELAY) +#if O_NONBLOCK || O_NDELAY #if defined (EWOULDBLOCK) || defined (EINPROGRESS) #define NON_BLOCKING_CONNECT #endif /* EWOULDBLOCK || EINPROGRESS */ @@ -651,7 +651,7 @@ allocate_pty (void) PTY_OPEN; #else /* no PTY_OPEN */ { -# ifdef O_NONBLOCK +# if O_NONBLOCK fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0); # else fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0); @@ -668,7 +668,7 @@ allocate_pty (void) #else sprintf (pty_name, "/dev/tty%c%x", c, i); #endif /* no PTY_TTY_NAME_SPRINTF */ - if (access (pty_name, 6) != 0) + if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0) { emacs_close (fd); # ifndef __sgi @@ -1621,7 +1621,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ -#ifdef O_NOCTTY +#if O_NOCTTY /* Don't let this terminal become our controlling terminal (in case we don't have one). */ forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); @@ -1675,11 +1675,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) } #endif -#ifdef O_NONBLOCK +#if O_NONBLOCK fcntl (inchannel, F_SETFL, O_NONBLOCK); fcntl (outchannel, F_SETFL, O_NONBLOCK); #else -#ifdef O_NDELAY +#if O_NDELAY fcntl (inchannel, F_SETFL, O_NDELAY); fcntl (outchannel, F_SETFL, O_NDELAY); #endif @@ -1967,7 +1967,7 @@ create_pty (Lisp_Object process) #if ! defined (USG) || defined (USG_SUBTTY_WORKS) /* On most USG systems it does not work to open the pty's tty here, then close it and reopen it in the child. */ -#ifdef O_NOCTTY +#if O_NOCTTY /* Don't let this terminal become our controlling terminal (in case we don't have one). */ int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); @@ -1987,11 +1987,11 @@ create_pty (Lisp_Object process) } #endif /* HAVE_PTYS */ -#ifdef O_NONBLOCK +#if O_NONBLOCK fcntl (inchannel, F_SETFL, O_NONBLOCK); fcntl (outchannel, F_SETFL, O_NONBLOCK); #else -#ifdef O_NDELAY +#if O_NDELAY fcntl (inchannel, F_SETFL, O_NDELAY); fcntl (outchannel, F_SETFL, O_NDELAY); #endif @@ -2951,7 +2951,7 @@ usage: (make-network-process &rest ARGS) */) { /* Don't support network sockets when non-blocking mode is not available, since a blocked Emacs is not useful. */ -#if !defined (O_NONBLOCK) && !defined (O_NDELAY) +#if !O_NONBLOCK && !O_NDELAY error ("Network servers not supported"); #else is_server = 1; @@ -3217,7 +3217,7 @@ usage: (make-network-process &rest ARGS) */) #ifdef NON_BLOCKING_CONNECT if (is_non_blocking_client) { -#ifdef O_NONBLOCK +#if O_NONBLOCK ret = fcntl (s, F_SETFL, O_NONBLOCK); #else ret = fcntl (s, F_SETFL, O_NDELAY); @@ -3434,10 +3434,10 @@ usage: (make-network-process &rest ARGS) */) chan_process[inch] = proc; -#ifdef O_NONBLOCK +#if O_NONBLOCK fcntl (inch, F_SETFL, O_NONBLOCK); #else -#ifdef O_NDELAY +#if O_NDELAY fcntl (inch, F_SETFL, O_NDELAY); #endif #endif @@ -4169,10 +4169,10 @@ server_accept_connection (Lisp_Object server, int channel) chan_process[s] = proc; -#ifdef O_NONBLOCK +#if O_NONBLOCK fcntl (s, F_SETFL, O_NONBLOCK); #else -#ifdef O_NDELAY +#if O_NDELAY fcntl (s, F_SETFL, O_NDELAY); #endif #endif @@ -4873,11 +4873,11 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, #endif /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK, and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */ -#ifdef O_NONBLOCK +#if O_NONBLOCK else if (nread == -1 && errno == EAGAIN) ; #else -#ifdef O_NDELAY +#if O_NDELAY else if (nread == -1 && errno == EAGAIN) ; /* Note that we cannot distinguish between no input @@ -7363,7 +7363,7 @@ init_process_emacs (void) #ifdef HAVE_GETSOCKNAME ADD_SUBFEATURE (QCservice, Qt); #endif -#if defined (O_NONBLOCK) || defined (O_NDELAY) +#if O_NONBLOCK || O_NDELAY ADD_SUBFEATURE (QCserver, Qt); #endif diff --git a/src/sysdep.c b/src/sysdep.c index 35beeaa7202..8a31957d182 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1216,7 +1216,7 @@ reset_sys_modes (struct tty_display_info *tty_out) old_fcntl_owner[fileno (tty_out->input)]); } #endif /* F_SETOWN */ -#ifdef O_NDELAY +#if O_NDELAY fcntl (fileno (tty_out->input), F_SETFL, fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY); #endif @@ -2312,12 +2312,12 @@ serial_open (char *port) fd = emacs_open ((char*) port, O_RDWR -#ifdef O_NONBLOCK +#if O_NONBLOCK | O_NONBLOCK #else | O_NDELAY #endif -#ifdef O_NOCTTY +#if O_NOCTTY | O_NOCTTY #endif , 0); diff --git a/src/term.c b/src/term.c index f7c87b7608d..87ce5447b76 100644 --- a/src/term.c +++ b/src/term.c @@ -3023,7 +3023,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) int fd; FILE *file; -#ifdef O_IGNORE_CTTY +#if O_IGNORE_CTTY if (!ctty) /* Open the terminal device. Don't recognize it as our controlling terminal, and don't make it the controlling tty @@ -3054,7 +3054,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) name); } -#ifndef O_IGNORE_CTTY +#if !O_IGNORE_CTTY if (!ctty) dissociate_if_controlling_tty (fd); #endif diff --git a/src/w32.c b/src/w32.c index 5ac1bc3eb7c..341f4d3fef3 100644 --- a/src/w32.c +++ b/src/w32.c @@ -1597,7 +1597,7 @@ init_environment (char ** argv) see if it succeeds. But I think that's too much to ask. */ /* MSVCRT's _access crashes with D_OK. */ - if (tmp && sys_access (tmp, D_OK) == 0) + if (tmp && sys_faccessat (AT_FDCWD, tmp, D_OK, AT_EACCESS) == 0) { char * var = alloca (strlen (tmp) + 8); sprintf (var, "TMPDIR=%s", tmp); @@ -2714,10 +2714,16 @@ logon_network_drive (const char *path) long file names. */ int -sys_access (const char * path, int mode) +sys_faccessat (int dirfd, const char * path, int mode, int flags) { DWORD attributes; + if (dirfd != AT_FDCWD) + { + errno = EINVAL; + return -1; + } + /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its newer versions blow up when passed D_OK. */ path = map_w32_filename (path, NULL); @@ -2960,7 +2966,7 @@ sys_mktemp (char * template) { int save_errno = errno; p[0] = first_char[i]; - if (sys_access (template, 0) < 0) + if (sys_faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0) { errno = save_errno; return template; @@ -4011,7 +4017,7 @@ symlink (char const *filename, char const *linkname) { /* Non-absolute FILENAME is understood as being relative to LINKNAME's directory. We need to prepend that directory to - FILENAME to get correct results from sys_access below, since + FILENAME to get correct results from sys_faccessat below, since otherwise it will interpret FILENAME relative to the directory where the Emacs process runs. Note that make-symbolic-link always makes sure LINKNAME is a fully @@ -4025,10 +4031,10 @@ symlink (char const *filename, char const *linkname) strncpy (tem, linkfn, p - linkfn); tem[p - linkfn] = '\0'; strcat (tem, filename); - dir_access = sys_access (tem, D_OK); + dir_access = sys_faccessat (AT_FDCWD, tem, D_OK, AT_EACCESS); } else - dir_access = sys_access (filename, D_OK); + dir_access = sys_faccessat (AT_FDCWD, filename, D_OK, AT_EACCESS); /* Since Windows distinguishes between symlinks to directories and to files, we provide a kludgy feature: if FILENAME doesn't diff --git a/src/xrdb.c b/src/xrdb.c index 9d056a607e4..982a6e46a13 100644 --- a/src/xrdb.c +++ b/src/xrdb.c @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see . */ #include +#include #include #include #include @@ -261,11 +262,8 @@ gethomedir (void) static int file_p (const char *filename) { - struct stat status; - - return (access (filename, 4) == 0 /* exists and is readable */ - && stat (filename, &status) == 0 /* get the status */ - && (S_ISDIR (status.st_mode)) == 0); /* not a directory */ + return (faccessat (AT_FDCWD, filename, R_OK, AT_EACCESS) == 0 + && ! file_directory_p (filename)); } -- 2.39.2