aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2012-11-14 22:39:49 +0900
committerKenichi Handa2012-11-14 22:39:49 +0900
commit9ba02fc3046a5aeaca7e4d3e207a365f6ce33a93 (patch)
treed648c55dca0513838634254617723954c50567d2
parent0cdbf84521791935fdfeabf2e84f585cc64db325 (diff)
parentc62792e7dfa403db8c36cb92f32fb69258a199ef (diff)
downloademacs-9ba02fc3046a5aeaca7e4d3e207a365f6ce33a93.tar.gz
emacs-9ba02fc3046a5aeaca7e4d3e207a365f6ce33a93.zip
merge trunk
-rw-r--r--ChangeLog13
-rw-r--r--admin/ChangeLog8
-rwxr-xr-xadmin/merge-gnulib13
-rw-r--r--autogen/Makefile.in91
-rw-r--r--autogen/aclocal.m45
-rw-r--r--autogen/config.in27
-rwxr-xr-xautogen/configure1098
-rw-r--r--configure.ac4
-rw-r--r--doc/lispref/windows.texi4
-rw-r--r--doc/misc/ses.texi14
-rw-r--r--doc/misc/url.texi2
-rw-r--r--etc/NEWS3
-rw-r--r--lib/at-func.c146
-rw-r--r--lib/euidaccess.c221
-rw-r--r--lib/faccessat.c45
-rw-r--r--lib/fcntl.in.h347
-rw-r--r--lib/getgroups.c116
-rw-r--r--lib/gnulib.mk97
-rw-r--r--lib/group-member.c119
-rw-r--r--lib/root-uid.h30
-rw-r--r--lib/xalloc-oversized.h38
-rw-r--r--lisp/ChangeLog57
-rw-r--r--lisp/emacs-lisp/advice.el730
-rw-r--r--lisp/emacs-lisp/gv.el2
-rw-r--r--lisp/emacs-lisp/nadvice.el4
-rw-r--r--lisp/gnus/pop3.el2
-rw-r--r--lisp/progmodes/ruby-mode.el122
-rw-r--r--lisp/woman.el12
-rw-r--r--m4/euidaccess.m452
-rw-r--r--m4/faccessat.m428
-rw-r--r--m4/fcntl_h.m450
-rw-r--r--m4/getgroups.m4107
-rw-r--r--m4/gnulib-comp.m4105
-rw-r--r--m4/group-member.m429
-rw-r--r--nt/ChangeLog7
-rw-r--r--nt/inc/ms-w32.h7
-rw-r--r--src/ChangeLog74
-rw-r--r--src/Makefile.in3
-rw-r--r--src/callproc.c12
-rw-r--r--src/charset.c2
-rw-r--r--src/conf_post.h4
-rw-r--r--src/fileio.c184
-rw-r--r--src/lisp.h2
-rw-r--r--src/lread.c92
-rw-r--r--src/nsterm.m2
-rw-r--r--src/process.c36
-rw-r--r--src/sysdep.c6
-rw-r--r--src/term.c4
-rw-r--r--src/w32.c18
-rw-r--r--src/xdisp.c12
-rw-r--r--src/xrdb.c101
-rw-r--r--test/ChangeLog12
-rw-r--r--test/automated/advice-tests.el23
-rw-r--r--test/automated/ruby-mode-tests.el93
54 files changed, 3466 insertions, 969 deletions
diff --git a/ChangeLog b/ChangeLog
index e8bff20d56d..f5f649aae6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
12012-11-14 Paul Eggert <eggert@cs.ucla.edu>
2
3 Use faccessat, not access, when checking file permissions (Bug#12632).
4 * .bzrignore: Add lib/fcntl.h.
5 * configure.ac (euidaccess): Remove check; gnulib does this for us now.
6 (gl_FCNTL_O_FLAGS): Define a dummy version.
7 * lib/at-func.c, lib/euidaccess.c, lib/faccessat.c, lib/fcntl.in.h:
8 * lib/getgroups.c, lib/group-member.c, lib/root-uid.h:
9 * lib/xalloc-oversized.h, m4/euidaccess.m4, m4/faccessat.m4:
10 * m4/fcntl_h.m4, m4/getgroups.m4, m4/group-member.m4:
11 New files, from gnulib.
12 * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
13
12012-11-05 Paul Eggert <eggert@cs.ucla.edu> 142012-11-05 Paul Eggert <eggert@cs.ucla.edu>
2 15
3 Assume at least POSIX.1-1988 for getpgrp, setpgid, setsid (Bug#12800). 16 Assume at least POSIX.1-1988 for getpgrp, setpgid, setsid (Bug#12800).
diff --git a/admin/ChangeLog b/admin/ChangeLog
index 496e1c1bb6a..fd28bf1228f 100644
--- a/admin/ChangeLog
+++ b/admin/ChangeLog
@@ -1,3 +1,11 @@
12012-11-14 Paul Eggert <eggert@cs.ucla.edu>
2
3 Use faccessat, not access, when checking file permissions (Bug#12632).
4 * merge-gnulib (GNULIB_MODULES): Add faccessat.
5 (GNULIB_TOOL_FLAGS): Avoid at-internal, fchdir, malloc-posix,
6 openat-die, openat-h, save-cwd. Do not avoid fcntl-h.
7 Omit gnulib's m4/fcntl-o.m4.
8
12012-11-05 Paul Eggert <eggert@cs.ucla.edu> 92012-11-05 Paul Eggert <eggert@cs.ucla.edu>
2 10
3 Assume at least POSIX.1-1988 for getpgrp, setpgid, setsid (Bug#12800). 11 Assume at least POSIX.1-1988 for getpgrp, setpgid, setsid (Bug#12800).
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 901daf4e442..f7a675e5101 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -28,7 +28,7 @@ GNULIB_URL=git://git.savannah.gnu.org/gnulib.git
28GNULIB_MODULES=' 28GNULIB_MODULES='
29 alloca-opt c-ctype c-strcase 29 alloca-opt c-ctype c-strcase
30 careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 30 careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512
31 dtoastr dtotimespec dup2 environ execinfo 31 dtoastr dtotimespec dup2 environ execinfo faccessat
32 filemode getloadavg getopt-gnu gettime gettimeofday 32 filemode getloadavg getopt-gnu gettime gettimeofday
33 ignore-value intprops largefile lstat 33 ignore-value intprops largefile lstat
34 manywarnings mktime pselect pthread_sigmask readlink 34 manywarnings mktime pselect pthread_sigmask readlink
@@ -39,9 +39,12 @@ GNULIB_MODULES='
39' 39'
40 40
41GNULIB_TOOL_FLAGS=' 41GNULIB_TOOL_FLAGS='
42 --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat 42 --avoid=at-internal
43 --avoid=msvc-inval --avoid=msvc-nothrow 43 --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat
44 --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types 44 --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow
45 --avoid=openat-die --avoid=openat-h
46 --avoid=raise
47 --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types
45 --avoid=threadlib 48 --avoid=threadlib
46 --conditional-dependencies --import --no-changelog --no-vc-files 49 --conditional-dependencies --import --no-changelog --no-vc-files
47 --makefile-name=gnulib.mk 50 --makefile-name=gnulib.mk
@@ -85,7 +88,7 @@ test -x "$gnulib_srcdir"/gnulib-tool || {
85} 88}
86 89
87"$gnulib_srcdir"/gnulib-tool --dir="$src" $GNULIB_TOOL_FLAGS $GNULIB_MODULES && 90"$gnulib_srcdir"/gnulib-tool --dir="$src" $GNULIB_TOOL_FLAGS $GNULIB_MODULES &&
88rm -- "$src"m4/gnulib-cache.m4 "$src"m4/warn-on-use.m4 && 91rm -- "$src"m4/fcntl-o.m4 "$src"m4/gnulib-cache.m4 "$src"m4/warn-on-use.m4 &&
89cp -- "$gnulib_srcdir"/build-aux/texinfo.tex "$src"doc/misc && 92cp -- "$gnulib_srcdir"/build-aux/texinfo.tex "$src"doc/misc &&
90cp -- "$gnulib_srcdir"/build-aux/move-if-change "$src"build-aux && 93cp -- "$gnulib_srcdir"/build-aux/move-if-change "$src"build-aux &&
91autoreconf -i -I m4 -- ${src:+"$src"} 94autoreconf -i -I m4 -- ${src:+"$src"}
diff --git a/autogen/Makefile.in b/autogen/Makefile.in
index d7855ac46ee..cea3da9a81d 100644
--- a/autogen/Makefile.in
+++ b/autogen/Makefile.in
@@ -36,7 +36,7 @@
36# the same distribution terms as the rest of that program. 36# the same distribution terms as the rest of that program.
37# 37#
38# Generated by gnulib-tool. 38# Generated by gnulib-tool.
39# 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 close-stream 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 39# 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 close-stream 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
40 40
41VPATH = @srcdir@ 41VPATH = @srcdir@
42pkgdatadir = $(datadir)/@PACKAGE@ 42pkgdatadir = $(datadir)/@PACKAGE@
@@ -66,14 +66,17 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
66 $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/c-strtod.m4 \ 66 $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/c-strtod.m4 \
67 $(top_srcdir)/m4/clock_time.m4 \ 67 $(top_srcdir)/m4/clock_time.m4 \
68 $(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/dup2.m4 \ 68 $(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/dup2.m4 \
69 $(top_srcdir)/m4/environ.m4 $(top_srcdir)/m4/execinfo.m4 \ 69 $(top_srcdir)/m4/environ.m4 $(top_srcdir)/m4/euidaccess.m4 \
70 $(top_srcdir)/m4/extensions.m4 \ 70 $(top_srcdir)/m4/execinfo.m4 $(top_srcdir)/m4/extensions.m4 \
71 $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/filemode.m4 \ 71 $(top_srcdir)/m4/extern-inline.m4 \
72 $(top_srcdir)/m4/fpending.m4 $(top_srcdir)/m4/getloadavg.m4 \ 72 $(top_srcdir)/m4/faccessat.m4 $(top_srcdir)/m4/fcntl_h.m4 \
73 $(top_srcdir)/m4/filemode.m4 $(top_srcdir)/m4/fpending.m4 \
74 $(top_srcdir)/m4/getgroups.m4 $(top_srcdir)/m4/getloadavg.m4 \
73 $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gettime.m4 \ 75 $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gettime.m4 \
74 $(top_srcdir)/m4/gettimeofday.m4 \ 76 $(top_srcdir)/m4/gettimeofday.m4 \
75 $(top_srcdir)/m4/gnulib-common.m4 \ 77 $(top_srcdir)/m4/gnulib-common.m4 \
76 $(top_srcdir)/m4/gnulib-comp.m4 \ 78 $(top_srcdir)/m4/gnulib-comp.m4 \
79 $(top_srcdir)/m4/group-member.m4 \
77 $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inttypes.m4 \ 80 $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inttypes.m4 \
78 $(top_srcdir)/m4/largefile.m4 $(top_srcdir)/m4/longlong.m4 \ 81 $(top_srcdir)/m4/largefile.m4 $(top_srcdir)/m4/longlong.m4 \
79 $(top_srcdir)/m4/lstat.m4 $(top_srcdir)/m4/manywarnings.m4 \ 82 $(top_srcdir)/m4/lstat.m4 $(top_srcdir)/m4/manywarnings.m4 \
@@ -213,6 +216,7 @@ GNULIB_FCHDIR = @GNULIB_FCHDIR@
213GNULIB_FCHMODAT = @GNULIB_FCHMODAT@ 216GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
214GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@ 217GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
215GNULIB_FCLOSE = @GNULIB_FCLOSE@ 218GNULIB_FCLOSE = @GNULIB_FCLOSE@
219GNULIB_FCNTL = @GNULIB_FCNTL@
216GNULIB_FDATASYNC = @GNULIB_FDATASYNC@ 220GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
217GNULIB_FDOPEN = @GNULIB_FDOPEN@ 221GNULIB_FDOPEN = @GNULIB_FDOPEN@
218GNULIB_FFLUSH = @GNULIB_FFLUSH@ 222GNULIB_FFLUSH = @GNULIB_FFLUSH@
@@ -279,8 +283,11 @@ GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
279GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@ 283GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
280GNULIB_MKTIME = @GNULIB_MKTIME@ 284GNULIB_MKTIME = @GNULIB_MKTIME@
281GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@ 285GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
286GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
282GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@ 287GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
283GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@ 288GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
289GNULIB_OPEN = @GNULIB_OPEN@
290GNULIB_OPENAT = @GNULIB_OPENAT@
284GNULIB_PCLOSE = @GNULIB_PCLOSE@ 291GNULIB_PCLOSE = @GNULIB_PCLOSE@
285GNULIB_PERROR = @GNULIB_PERROR@ 292GNULIB_PERROR = @GNULIB_PERROR@
286GNULIB_PIPE = @GNULIB_PIPE@ 293GNULIB_PIPE = @GNULIB_PIPE@
@@ -408,6 +415,7 @@ HAVE_FACCESSAT = @HAVE_FACCESSAT@
408HAVE_FCHDIR = @HAVE_FCHDIR@ 415HAVE_FCHDIR = @HAVE_FCHDIR@
409HAVE_FCHMODAT = @HAVE_FCHMODAT@ 416HAVE_FCHMODAT = @HAVE_FCHMODAT@
410HAVE_FCHOWNAT = @HAVE_FCHOWNAT@ 417HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
418HAVE_FCNTL = @HAVE_FCNTL@
411HAVE_FDATASYNC = @HAVE_FDATASYNC@ 419HAVE_FDATASYNC = @HAVE_FDATASYNC@
412HAVE_FSEEKO = @HAVE_FSEEKO@ 420HAVE_FSEEKO = @HAVE_FSEEKO@
413HAVE_FSTATAT = @HAVE_FSTATAT@ 421HAVE_FSTATAT = @HAVE_FSTATAT@
@@ -444,6 +452,7 @@ HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
444HAVE_MKSTEMP = @HAVE_MKSTEMP@ 452HAVE_MKSTEMP = @HAVE_MKSTEMP@
445HAVE_MKSTEMPS = @HAVE_MKSTEMPS@ 453HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
446HAVE_NANOSLEEP = @HAVE_NANOSLEEP@ 454HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
455HAVE_OPENAT = @HAVE_OPENAT@
447HAVE_OS_H = @HAVE_OS_H@ 456HAVE_OS_H = @HAVE_OS_H@
448HAVE_PCLOSE = @HAVE_PCLOSE@ 457HAVE_PCLOSE = @HAVE_PCLOSE@
449HAVE_PIPE = @HAVE_PIPE@ 458HAVE_PIPE = @HAVE_PIPE@
@@ -563,6 +572,7 @@ LIBXTR6 = @LIBXTR6@
563LIBXT_OTHER = @LIBXT_OTHER@ 572LIBXT_OTHER = @LIBXT_OTHER@
564LIBX_OTHER = @LIBX_OTHER@ 573LIBX_OTHER = @LIBX_OTHER@
565LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ 574LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
575LIB_EACCESS = @LIB_EACCESS@
566LIB_EXECINFO = @LIB_EXECINFO@ 576LIB_EXECINFO = @LIB_EXECINFO@
567LIB_GCC = @LIB_GCC@ 577LIB_GCC = @LIB_GCC@
568LIB_MATH = @LIB_MATH@ 578LIB_MATH = @LIB_MATH@
@@ -578,6 +588,7 @@ M17N_FLT_LIBS = @M17N_FLT_LIBS@
578MAKEINFO = @MAKEINFO@ 588MAKEINFO = @MAKEINFO@
579MKDEPDIR = @MKDEPDIR@ 589MKDEPDIR = @MKDEPDIR@
580MKDIR_P = @MKDIR_P@ 590MKDIR_P = @MKDIR_P@
591NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
581NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@ 592NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
582NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ 593NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
583NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@ 594NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
@@ -591,6 +602,7 @@ NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
591NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@ 602NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@
592NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@ 603NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
593NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@ 604NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
605NEXT_FCNTL_H = @NEXT_FCNTL_H@
594NEXT_GETOPT_H = @NEXT_GETOPT_H@ 606NEXT_GETOPT_H = @NEXT_GETOPT_H@
595NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ 607NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
596NEXT_SIGNAL_H = @NEXT_SIGNAL_H@ 608NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
@@ -641,6 +653,7 @@ REPLACE_DUP = @REPLACE_DUP@
641REPLACE_DUP2 = @REPLACE_DUP2@ 653REPLACE_DUP2 = @REPLACE_DUP2@
642REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@ 654REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
643REPLACE_FCLOSE = @REPLACE_FCLOSE@ 655REPLACE_FCLOSE = @REPLACE_FCLOSE@
656REPLACE_FCNTL = @REPLACE_FCNTL@
644REPLACE_FDOPEN = @REPLACE_FDOPEN@ 657REPLACE_FDOPEN = @REPLACE_FDOPEN@
645REPLACE_FFLUSH = @REPLACE_FFLUSH@ 658REPLACE_FFLUSH = @REPLACE_FFLUSH@
646REPLACE_FOPEN = @REPLACE_FOPEN@ 659REPLACE_FOPEN = @REPLACE_FOPEN@
@@ -680,6 +693,8 @@ REPLACE_MKTIME = @REPLACE_MKTIME@
680REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ 693REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
681REPLACE_NULL = @REPLACE_NULL@ 694REPLACE_NULL = @REPLACE_NULL@
682REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@ 695REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
696REPLACE_OPEN = @REPLACE_OPEN@
697REPLACE_OPENAT = @REPLACE_OPENAT@
683REPLACE_PERROR = @REPLACE_PERROR@ 698REPLACE_PERROR = @REPLACE_PERROR@
684REPLACE_POPEN = @REPLACE_POPEN@ 699REPLACE_POPEN = @REPLACE_POPEN@
685REPLACE_PREAD = @REPLACE_PREAD@ 700REPLACE_PREAD = @REPLACE_PREAD@
@@ -859,18 +874,20 @@ x_default_search_path = @x_default_search_path@
859# statements but through direct file reference. Therefore this snippet must be 874# statements but through direct file reference. Therefore this snippet must be
860# present in all Makefile.am that need it. This is ensured by the applicability 875# present in all Makefile.am that need it. This is ensured by the applicability
861# 'all' defined above. 876# 'all' defined above.
862BUILT_SOURCES = $(ALLOCA_H) $(EXECINFO_H) $(GETOPT_H) inttypes.h \ 877BUILT_SOURCES = $(ALLOCA_H) $(EXECINFO_H) fcntl.h $(GETOPT_H) \
863 signal.h arg-nonnull.h c++defs.h warn-on-use.h $(STDALIGN_H) \ 878 inttypes.h signal.h arg-nonnull.h c++defs.h warn-on-use.h \
864 $(STDARG_H) $(STDBOOL_H) $(STDDEF_H) $(STDINT_H) stdio.h \ 879 $(STDALIGN_H) $(STDARG_H) $(STDBOOL_H) $(STDDEF_H) $(STDINT_H) \
865 stdlib.h sys/select.h sys/stat.h sys/time.h time.h unistd.h 880 stdio.h stdlib.h sys/select.h sys/stat.h sys/time.h time.h \
881 unistd.h
866EXTRA_DIST = alloca.in.h allocator.h careadlinkat.h close-stream.h \ 882EXTRA_DIST = alloca.in.h allocator.h careadlinkat.h close-stream.h \
867 md5.h sha1.h sha256.h sha512.h dosname.h ftoastr.c ftoastr.h \ 883 md5.h sha1.h sha256.h sha512.h dosname.h ftoastr.c ftoastr.h \
868 dup2.c execinfo.c execinfo.in.h filemode.h fpending.c \ 884 dup2.c euidaccess.c execinfo.c execinfo.in.h at-func.c \
869 fpending.h getloadavg.c getopt.c getopt.in.h getopt1.c \ 885 faccessat.c fcntl.in.h filemode.h fpending.c fpending.h \
870 getopt_int.h gettimeofday.c ignore-value.h intprops.h \ 886 getgroups.c getloadavg.c getopt.c getopt.in.h getopt1.c \
871 inttypes.in.h lstat.c mktime-internal.h mktime.c pathmax.h \ 887 getopt_int.h gettimeofday.c group-member.c ignore-value.h \
872 pselect.c pthread_sigmask.c readlink.c signal.in.h \ 888 intprops.h inttypes.in.h lstat.c mktime-internal.h mktime.c \
873 $(top_srcdir)/build-aux/snippet/_Noreturn.h \ 889 pathmax.h pselect.c pthread_sigmask.c readlink.c root-uid.h \
890 signal.in.h $(top_srcdir)/build-aux/snippet/_Noreturn.h \
874 $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ 891 $(top_srcdir)/build-aux/snippet/arg-nonnull.h \
875 $(top_srcdir)/build-aux/snippet/c++defs.h \ 892 $(top_srcdir)/build-aux/snippet/c++defs.h \
876 $(top_srcdir)/build-aux/snippet/warn-on-use.h stat.c \ 893 $(top_srcdir)/build-aux/snippet/warn-on-use.h stat.c \
@@ -879,12 +896,12 @@ EXTRA_DIST = alloca.in.h allocator.h careadlinkat.h close-stream.h \
879 strtol.c strtoll.c strtol.c strtoul.c strtoull.c strtoimax.c \ 896 strtol.c strtoll.c strtol.c strtoul.c strtoull.c strtoimax.c \
880 strtoumax.c symlink.c sys_select.in.h sys_stat.in.h \ 897 strtoumax.c symlink.c sys_select.in.h sys_stat.in.h \
881 sys_time.in.h time.in.h time_r.c timespec.h u64.h unistd.in.h \ 898 sys_time.in.h time.in.h time_r.c timespec.h u64.h unistd.in.h \
882 utimens.h verify.h 899 utimens.h verify.h xalloc-oversized.h
883MOSTLYCLEANDIRS = sys sys 900MOSTLYCLEANDIRS = sys sys
884MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t execinfo.h \ 901MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t execinfo.h \
885 execinfo.h-t getopt.h getopt.h-t inttypes.h inttypes.h-t \ 902 execinfo.h-t fcntl.h fcntl.h-t getopt.h getopt.h-t inttypes.h \
886 signal.h signal.h-t arg-nonnull.h arg-nonnull.h-t c++defs.h \ 903 inttypes.h-t signal.h signal.h-t arg-nonnull.h arg-nonnull.h-t \
887 c++defs.h-t warn-on-use.h warn-on-use.h-t stdalign.h \ 904 c++defs.h c++defs.h-t warn-on-use.h warn-on-use.h-t stdalign.h \
888 stdalign.h-t stdarg.h stdarg.h-t stdbool.h stdbool.h-t \ 905 stdalign.h-t stdarg.h stdarg.h-t stdbool.h stdbool.h-t \
889 stddef.h stddef.h-t stdint.h stdint.h-t stdio.h stdio.h-t \ 906 stddef.h stddef.h-t stdint.h stdint.h-t stdio.h stdio.h-t \
890 stdlib.h stdlib.h-t sys/select.h sys/select.h-t sys/stat.h \ 907 stdlib.h stdlib.h-t sys/select.h sys/select.h-t sys/stat.h \
@@ -900,8 +917,9 @@ libgnu_a_SOURCES = allocator.c c-ctype.h c-ctype.c c-strcase.h \
900 timespec.c timespec-add.c timespec-sub.c u64.c utimens.c 917 timespec.c timespec-add.c timespec-sub.c u64.c utimens.c
901libgnu_a_LIBADD = $(gl_LIBOBJS) 918libgnu_a_LIBADD = $(gl_LIBOBJS)
902libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) 919libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
903EXTRA_libgnu_a_SOURCES = ftoastr.c dup2.c execinfo.c fpending.c \ 920EXTRA_libgnu_a_SOURCES = ftoastr.c dup2.c euidaccess.c execinfo.c \
904 getloadavg.c getopt.c getopt1.c gettimeofday.c lstat.c \ 921 at-func.c faccessat.c fpending.c getgroups.c getloadavg.c \
922 getopt.c getopt1.c gettimeofday.c group-member.c lstat.c \
905 mktime.c pselect.c pthread_sigmask.c readlink.c stat.c \ 923 mktime.c pselect.c pthread_sigmask.c readlink.c stat.c \
906 strtoimax.c strtol.c strtoll.c strtol.c strtoul.c strtoull.c \ 924 strtoimax.c strtol.c strtoll.c strtol.c strtoul.c strtoull.c \
907 strtoimax.c strtoumax.c symlink.c time_r.c 925 strtoimax.c strtoumax.c symlink.c time_r.c
@@ -963,6 +981,7 @@ distclean-compile:
963 -rm -f *.tab.c 981 -rm -f *.tab.c
964 982
965@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allocator.Po@am__quote@ 983@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allocator.Po@am__quote@
984@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/at-func.Po@am__quote@
966@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-ctype.Po@am__quote@ 985@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-ctype.Po@am__quote@
967@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strcasecmp.Po@am__quote@ 986@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strcasecmp.Po@am__quote@
968@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strncasecmp.Po@am__quote@ 987@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c-strncasecmp.Po@am__quote@
@@ -971,15 +990,19 @@ distclean-compile:
971@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtoastr.Po@am__quote@ 990@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtoastr.Po@am__quote@
972@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtotimespec.Po@am__quote@ 991@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtotimespec.Po@am__quote@
973@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup2.Po@am__quote@ 992@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup2.Po@am__quote@
993@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/euidaccess.Po@am__quote@
974@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execinfo.Po@am__quote@ 994@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execinfo.Po@am__quote@
995@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/faccessat.Po@am__quote@
975@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filemode.Po@am__quote@ 996@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filemode.Po@am__quote@
976@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpending.Po@am__quote@ 997@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpending.Po@am__quote@
977@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftoastr.Po@am__quote@ 998@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftoastr.Po@am__quote@
999@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getgroups.Po@am__quote@
978@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getloadavg.Po@am__quote@ 1000@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getloadavg.Po@am__quote@
979@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ 1001@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
980@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ 1002@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
981@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettime.Po@am__quote@ 1003@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettime.Po@am__quote@
982@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@ 1004@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@
1005@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/group-member.Po@am__quote@
983@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@ 1006@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@
984@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ 1007@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
985@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@ 1008@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@
@@ -1243,6 +1266,32 @@ uninstall-am:
1243@GL_GENERATE_EXECINFO_H_FALSE@execinfo.h: $(top_builddir)/config.status 1266@GL_GENERATE_EXECINFO_H_FALSE@execinfo.h: $(top_builddir)/config.status
1244@GL_GENERATE_EXECINFO_H_FALSE@ rm -f $@ 1267@GL_GENERATE_EXECINFO_H_FALSE@ rm -f $@
1245 1268
1269# We need the following in order to create <fcntl.h> when the system
1270# doesn't have one that works with the given compiler.
1271fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
1272 $(AM_V_GEN)rm -f $@-t $@ && \
1273 { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
1274 sed -e 's|@''GUARD_PREFIX''@|GL|g' \
1275 -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
1276 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1277 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1278 -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \
1279 -e 's/@''GNULIB_FCNTL''@/$(GNULIB_FCNTL)/g' \
1280 -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
1281 -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
1282 -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
1283 -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
1284 -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
1285 -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \
1286 -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \
1287 -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \
1288 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
1289 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
1290 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
1291 < $(srcdir)/fcntl.in.h; \
1292 } > $@-t && \
1293 mv $@-t $@
1294
1246# We need the following in order to create <getopt.h> when the system 1295# We need the following in order to create <getopt.h> when the system
1247# doesn't have one that works with the given compiler. 1296# doesn't have one that works with the given compiler.
1248getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) 1297getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H)
diff --git a/autogen/aclocal.m4 b/autogen/aclocal.m4
index 37d734c2c7f..f423953b3c8 100644
--- a/autogen/aclocal.m4
+++ b/autogen/aclocal.m4
@@ -991,17 +991,22 @@ m4_include([m4/clock_time.m4])
991m4_include([m4/close-stream.m4]) 991m4_include([m4/close-stream.m4])
992m4_include([m4/dup2.m4]) 992m4_include([m4/dup2.m4])
993m4_include([m4/environ.m4]) 993m4_include([m4/environ.m4])
994m4_include([m4/euidaccess.m4])
994m4_include([m4/execinfo.m4]) 995m4_include([m4/execinfo.m4])
995m4_include([m4/extensions.m4]) 996m4_include([m4/extensions.m4])
996m4_include([m4/extern-inline.m4]) 997m4_include([m4/extern-inline.m4])
998m4_include([m4/faccessat.m4])
999m4_include([m4/fcntl_h.m4])
997m4_include([m4/filemode.m4]) 1000m4_include([m4/filemode.m4])
998m4_include([m4/fpending.m4]) 1001m4_include([m4/fpending.m4])
1002m4_include([m4/getgroups.m4])
999m4_include([m4/getloadavg.m4]) 1003m4_include([m4/getloadavg.m4])
1000m4_include([m4/getopt.m4]) 1004m4_include([m4/getopt.m4])
1001m4_include([m4/gettime.m4]) 1005m4_include([m4/gettime.m4])
1002m4_include([m4/gettimeofday.m4]) 1006m4_include([m4/gettimeofday.m4])
1003m4_include([m4/gnulib-common.m4]) 1007m4_include([m4/gnulib-common.m4])
1004m4_include([m4/gnulib-comp.m4]) 1008m4_include([m4/gnulib-comp.m4])
1009m4_include([m4/group-member.m4])
1005m4_include([m4/include_next.m4]) 1010m4_include([m4/include_next.m4])
1006m4_include([m4/inttypes.m4]) 1011m4_include([m4/inttypes.m4])
1007m4_include([m4/largefile.m4]) 1012m4_include([m4/largefile.m4])
diff --git a/autogen/config.in b/autogen/config.in
index 05418e64623..5388b8dc046 100644
--- a/autogen/config.in
+++ b/autogen/config.in
@@ -174,6 +174,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
174 garbage collection in the jmp_buf. */ 174 garbage collection in the jmp_buf. */
175#undef GC_SETJMP_WORKS 175#undef GC_SETJMP_WORKS
176 176
177/* Define to the type of elements in the array set by `getgroups'. Usually
178 this is either `int' or `gid_t'. */
179#undef GETGROUPS_T
180
181/* Define this to 1 if getgroups(0,NULL) does not return the number of groups.
182 */
183#undef GETGROUPS_ZERO_BUG
184
177/* Define if gettimeofday clobbers the localtime buffer. */ 185/* Define if gettimeofday clobbers the localtime buffer. */
178#undef GETTIMEOFDAY_CLOBBERS_LOCALTIME 186#undef GETTIMEOFDAY_CLOBBERS_LOCALTIME
179 187
@@ -189,6 +197,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
189#undef GNULIB_CLOSE_STREAM 197#undef GNULIB_CLOSE_STREAM
190 198
191/* Define to a C preprocessor expression that evaluates to 1 or 0, depending 199/* Define to a C preprocessor expression that evaluates to 1 or 0, depending
200 whether the gnulib module faccessat shall be considered present. */
201#undef GNULIB_FACCESSAT
202
203/* Define to a C preprocessor expression that evaluates to 1 or 0, depending
192 whether the gnulib module fscanf shall be considered present. */ 204 whether the gnulib module fscanf shall be considered present. */
193#undef GNULIB_FSCANF 205#undef GNULIB_FSCANF
194 206
@@ -209,6 +221,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
209 startup, if using GTK. */ 221 startup, if using GTK. */
210#undef G_SLICE_ALWAYS_MALLOC 222#undef G_SLICE_ALWAYS_MALLOC
211 223
224/* Define to 1 if you have the `access' function. */
225#undef HAVE_ACCESS
226
212/* Define to 1 if the file /usr/lpp/X11/bin/smt.exp exists. */ 227/* Define to 1 if the file /usr/lpp/X11/bin/smt.exp exists. */
213#undef HAVE_AIX_SMT_EXP 228#undef HAVE_AIX_SMT_EXP
214 229
@@ -333,6 +348,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
333/* Define to 1 if you have the 'dup2' function. */ 348/* Define to 1 if you have the 'dup2' function. */
334#undef HAVE_DUP2 349#undef HAVE_DUP2
335 350
351/* Define to 1 if you have the `eaccess' function. */
352#undef HAVE_EACCESS
353
336/* Define to 1 if you have the `endgrent' function. */ 354/* Define to 1 if you have the `endgrent' function. */
337#undef HAVE_ENDGRENT 355#undef HAVE_ENDGRENT
338 356
@@ -348,6 +366,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
348/* Define to 1 if you have the <execinfo.h> header file. */ 366/* Define to 1 if you have the <execinfo.h> header file. */
349#undef HAVE_EXECINFO_H 367#undef HAVE_EXECINFO_H
350 368
369/* Define to 1 if you have the `faccessat' function. */
370#undef HAVE_FACCESSAT
371
351/* Define to 1 if you have the <fcntl.h> header file. */ 372/* Define to 1 if you have the <fcntl.h> header file. */
352#undef HAVE_FCNTL_H 373#undef HAVE_FCNTL_H
353 374
@@ -396,6 +417,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
396/* Define to 1 if you have the `getgrent' function. */ 417/* Define to 1 if you have the `getgrent' function. */
397#undef HAVE_GETGRENT 418#undef HAVE_GETGRENT
398 419
420/* Define to 1 if your system has a working `getgroups' function. */
421#undef HAVE_GETGROUPS
422
399/* Define to 1 if you have the `gethostname' function. */ 423/* Define to 1 if you have the `gethostname' function. */
400#undef HAVE_GETHOSTNAME 424#undef HAVE_GETHOSTNAME
401 425
@@ -562,6 +586,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
562/* Define to 1 if you have the `dnet' library (-ldnet). */ 586/* Define to 1 if you have the `dnet' library (-ldnet). */
563#undef HAVE_LIBDNET 587#undef HAVE_LIBDNET
564 588
589/* Define to 1 if you have the <libgen.h> header file. */
590#undef HAVE_LIBGEN_H
591
565/* Define to 1 if you have the hesiod library (-lhesiod). */ 592/* Define to 1 if you have the hesiod library (-lhesiod). */
566#undef HAVE_LIBHESIOD 593#undef HAVE_LIBHESIOD
567 594
diff --git a/autogen/configure b/autogen/configure
index 159a91bb48c..e44b44a0a00 100755
--- a/autogen/configure
+++ b/autogen/configure
@@ -611,6 +611,8 @@ LD_SWITCH_SYSTEM_TEMACS
611LIBGNU_LTLIBDEPS 611LIBGNU_LTLIBDEPS
612LIBGNU_LIBDEPS 612LIBGNU_LIBDEPS
613gltests_WITNESS 613gltests_WITNESS
614gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE
615gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE
614gl_GNULIB_ENABLED_verify_FALSE 616gl_GNULIB_ENABLED_verify_FALSE
615gl_GNULIB_ENABLED_verify_TRUE 617gl_GNULIB_ENABLED_verify_TRUE
616gl_GNULIB_ENABLED_strtoull_FALSE 618gl_GNULIB_ENABLED_strtoull_FALSE
@@ -619,14 +621,23 @@ gl_GNULIB_ENABLED_strtoll_FALSE
619gl_GNULIB_ENABLED_strtoll_TRUE 621gl_GNULIB_ENABLED_strtoll_TRUE
620gl_GNULIB_ENABLED_stat_FALSE 622gl_GNULIB_ENABLED_stat_FALSE
621gl_GNULIB_ENABLED_stat_TRUE 623gl_GNULIB_ENABLED_stat_TRUE
624gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_FALSE
625gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_TRUE
622gl_GNULIB_ENABLED_pathmax_FALSE 626gl_GNULIB_ENABLED_pathmax_FALSE
623gl_GNULIB_ENABLED_pathmax_TRUE 627gl_GNULIB_ENABLED_pathmax_TRUE
628gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_FALSE
629gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_TRUE
624gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE 630gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE
625gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE 631gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE
632gl_GNULIB_ENABLED_getgroups_FALSE
633gl_GNULIB_ENABLED_getgroups_TRUE
634gl_GNULIB_ENABLED_euidaccess_FALSE
635gl_GNULIB_ENABLED_euidaccess_TRUE
626gl_GNULIB_ENABLED_dosname_FALSE 636gl_GNULIB_ENABLED_dosname_FALSE
627gl_GNULIB_ENABLED_dosname_TRUE 637gl_GNULIB_ENABLED_dosname_TRUE
628LTLIBINTL 638LTLIBINTL
629LIBINTL 639LIBINTL
640LIB_EACCESS
630WINDOWS_64_BIT_OFF_T 641WINDOWS_64_BIT_OFF_T
631HAVE_UNISTD_H 642HAVE_UNISTD_H
632NEXT_AS_FIRST_DIRECTIVE_UNISTD_H 643NEXT_AS_FIRST_DIRECTIVE_UNISTD_H
@@ -895,10 +906,6 @@ GETOPT_H
895HAVE_GETOPT_H 906HAVE_GETOPT_H
896NEXT_AS_FIRST_DIRECTIVE_GETOPT_H 907NEXT_AS_FIRST_DIRECTIVE_GETOPT_H
897NEXT_GETOPT_H 908NEXT_GETOPT_H
898PRAGMA_COLUMNS
899PRAGMA_SYSTEM_HEADER
900INCLUDE_NEXT_AS_FIRST_DIRECTIVE
901INCLUDE_NEXT
902GETLOADAVG_LIBS 909GETLOADAVG_LIBS
903REPLACE_WCTOMB 910REPLACE_WCTOMB
904REPLACE_UNSETENV 911REPLACE_UNSETENV
@@ -974,6 +981,21 @@ GNULIB_CANONICALIZE_FILE_NAME
974GNULIB_CALLOC_POSIX 981GNULIB_CALLOC_POSIX
975GNULIB_ATOLL 982GNULIB_ATOLL
976GNULIB__EXIT 983GNULIB__EXIT
984NEXT_AS_FIRST_DIRECTIVE_FCNTL_H
985NEXT_FCNTL_H
986PRAGMA_COLUMNS
987PRAGMA_SYSTEM_HEADER
988INCLUDE_NEXT_AS_FIRST_DIRECTIVE
989INCLUDE_NEXT
990REPLACE_OPENAT
991REPLACE_OPEN
992REPLACE_FCNTL
993HAVE_OPENAT
994HAVE_FCNTL
995GNULIB_OPENAT
996GNULIB_OPEN
997GNULIB_NONBLOCKING
998GNULIB_FCNTL
977GL_GENERATE_EXECINFO_H_FALSE 999GL_GENERATE_EXECINFO_H_FALSE
978GL_GENERATE_EXECINFO_H_TRUE 1000GL_GENERATE_EXECINFO_H_TRUE
979LIB_EXECINFO 1001LIB_EXECINFO
@@ -3205,6 +3227,7 @@ as_fn_append ac_header_list " sys/un.h"
3205as_fn_append ac_func_list " tzset" 3227as_fn_append ac_func_list " tzset"
3206as_fn_append ac_func_list " readlinkat" 3228as_fn_append ac_func_list " readlinkat"
3207as_fn_append ac_header_list " execinfo.h" 3229as_fn_append ac_header_list " execinfo.h"
3230as_fn_append ac_func_list " faccessat"
3208as_fn_append ac_header_list " stdio_ext.h" 3231as_fn_append ac_header_list " stdio_ext.h"
3209as_fn_append ac_func_list " __fpending" 3232as_fn_append ac_func_list " __fpending"
3210gl_getopt_required=GNU 3233gl_getopt_required=GNU
@@ -5738,6 +5761,8 @@ else
5738 test "x$NON_GCC_TEST_OPTIONS" != x && CC="$CC $NON_GCC_TEST_OPTIONS" 5761 test "x$NON_GCC_TEST_OPTIONS" != x && CC="$CC $NON_GCC_TEST_OPTIONS"
5739fi 5762fi
5740 5763
5764# Avoid gnulib's tests for O_NOATIME and O_NOFOLLOW, as we don't use them.
5765
5741# Avoid gnulib's threadlib module, as we do threads our own way. 5766# Avoid gnulib's threadlib module, as we do threads our own way.
5742 5767
5743 5768
@@ -6969,18 +6994,23 @@ esac
6969 # Code from module dtotimespec: 6994 # Code from module dtotimespec:
6970 # Code from module dup2: 6995 # Code from module dup2:
6971 # Code from module environ: 6996 # Code from module environ:
6997 # Code from module euidaccess:
6972 # Code from module execinfo: 6998 # Code from module execinfo:
6973 # Code from module extensions: 6999 # Code from module extensions:
6974 7000
6975 # Code from module extern-inline: 7001 # Code from module extern-inline:
7002 # Code from module faccessat:
7003 # Code from module fcntl-h:
6976 # Code from module filemode: 7004 # Code from module filemode:
6977 # Code from module fpending: 7005 # Code from module fpending:
7006 # Code from module getgroups:
6978 # Code from module getloadavg: 7007 # Code from module getloadavg:
6979 # Code from module getopt-gnu: 7008 # Code from module getopt-gnu:
6980 # Code from module getopt-posix: 7009 # Code from module getopt-posix:
6981 # Code from module gettext-h: 7010 # Code from module gettext-h:
6982 # Code from module gettime: 7011 # Code from module gettime:
6983 # Code from module gettimeofday: 7012 # Code from module gettimeofday:
7013 # Code from module group-member:
6984 # Code from module ignore-value: 7014 # Code from module ignore-value:
6985 # Code from module include_next: 7015 # Code from module include_next:
6986 # Code from module intprops: 7016 # Code from module intprops:
@@ -6996,6 +7026,7 @@ esac
6996 # Code from module pselect: 7026 # Code from module pselect:
6997 # Code from module pthread_sigmask: 7027 # Code from module pthread_sigmask:
6998 # Code from module readlink: 7028 # Code from module readlink:
7029 # Code from module root-uid:
6999 # Code from module signal-h: 7030 # Code from module signal-h:
7000 # Code from module snippet/_Noreturn: 7031 # Code from module snippet/_Noreturn:
7001 # Code from module snippet/arg-nonnull: 7032 # Code from module snippet/arg-nonnull:
@@ -7035,6 +7066,7 @@ esac
7035 # Code from module utimens: 7066 # Code from module utimens:
7036 # Code from module verify: 7067 # Code from module verify:
7037 # Code from module warnings: 7068 # Code from module warnings:
7069 # Code from module xalloc-oversized:
7038 7070
7039 7071
7040# It's helpful to have C macros available to GDB, so prefer -g3 to -g 7072# It's helpful to have C macros available to GDB, so prefer -g3 to -g
@@ -13417,7 +13449,7 @@ esac
13417for ac_func in gethostname \ 13449for ac_func in gethostname \
13418closedir getrusage get_current_dir_name \ 13450closedir getrusage get_current_dir_name \
13419lrand48 \ 13451lrand48 \
13420fpathconf select euidaccess getpagesize setlocale \ 13452fpathconf select getpagesize setlocale \
13421utimes getrlimit setrlimit getcwd shutdown getaddrinfo \ 13453utimes getrlimit setrlimit getcwd shutdown getaddrinfo \
13422strsignal setitimer \ 13454strsignal setitimer \
13423sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \ 13455sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \
@@ -16777,6 +16809,145 @@ $as_echo "#define HAVE_ENVIRON_DECL 1" >>confdefs.h
16777 16809
16778 16810
16779 16811
16812
16813
16814
16815 GNULIB_FCNTL=0;
16816 GNULIB_NONBLOCKING=0;
16817 GNULIB_OPEN=0;
16818 GNULIB_OPENAT=0;
16819 HAVE_FCNTL=1;
16820 HAVE_OPENAT=1;
16821 REPLACE_FCNTL=0;
16822 REPLACE_OPEN=0;
16823 REPLACE_OPENAT=0;
16824
16825
16826
16827
16828 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the preprocessor supports include_next" >&5
16829$as_echo_n "checking whether the preprocessor supports include_next... " >&6; }
16830if test "${gl_cv_have_include_next+set}" = set; then :
16831 $as_echo_n "(cached) " >&6
16832else
16833 rm -rf conftestd1a conftestd1b conftestd2
16834 mkdir conftestd1a conftestd1b conftestd2
16835 cat <<EOF > conftestd1a/conftest.h
16836#define DEFINED_IN_CONFTESTD1
16837#include_next <conftest.h>
16838#ifdef DEFINED_IN_CONFTESTD2
16839int foo;
16840#else
16841#error "include_next doesn't work"
16842#endif
16843EOF
16844 cat <<EOF > conftestd1b/conftest.h
16845#define DEFINED_IN_CONFTESTD1
16846#include <stdio.h>
16847#include_next <conftest.h>
16848#ifdef DEFINED_IN_CONFTESTD2
16849int foo;
16850#else
16851#error "include_next doesn't work"
16852#endif
16853EOF
16854 cat <<EOF > conftestd2/conftest.h
16855#ifndef DEFINED_IN_CONFTESTD1
16856#error "include_next test doesn't work"
16857#endif
16858#define DEFINED_IN_CONFTESTD2
16859EOF
16860 gl_save_CPPFLAGS="$CPPFLAGS"
16861 CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2"
16862 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16863/* end confdefs.h. */
16864#include <conftest.h>
16865_ACEOF
16866if ac_fn_c_try_compile "$LINENO"; then :
16867 gl_cv_have_include_next=yes
16868else
16869 CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2"
16870 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16871/* end confdefs.h. */
16872#include <conftest.h>
16873_ACEOF
16874if ac_fn_c_try_compile "$LINENO"; then :
16875 gl_cv_have_include_next=buggy
16876else
16877 gl_cv_have_include_next=no
16878fi
16879rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
16880
16881fi
16882rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
16883 CPPFLAGS="$gl_save_CPPFLAGS"
16884 rm -rf conftestd1a conftestd1b conftestd2
16885
16886fi
16887{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_have_include_next" >&5
16888$as_echo "$gl_cv_have_include_next" >&6; }
16889 PRAGMA_SYSTEM_HEADER=
16890 if test $gl_cv_have_include_next = yes; then
16891 INCLUDE_NEXT=include_next
16892 INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
16893 if test -n "$GCC"; then
16894 PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'
16895 fi
16896 else
16897 if test $gl_cv_have_include_next = buggy; then
16898 INCLUDE_NEXT=include
16899 INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
16900 else
16901 INCLUDE_NEXT=include
16902 INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include
16903 fi
16904 fi
16905
16906
16907
16908 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system header files limit the line length" >&5
16909$as_echo_n "checking whether system header files limit the line length... " >&6; }
16910if test "${gl_cv_pragma_columns+set}" = set; then :
16911 $as_echo_n "(cached) " >&6
16912else
16913 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16914/* end confdefs.h. */
16915
16916#ifdef __TANDEM
16917choke me
16918#endif
16919
16920_ACEOF
16921if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
16922 $EGREP "choke me" >/dev/null 2>&1; then :
16923 gl_cv_pragma_columns=yes
16924else
16925 gl_cv_pragma_columns=no
16926fi
16927rm -f conftest*
16928
16929
16930fi
16931{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_pragma_columns" >&5
16932$as_echo "$gl_cv_pragma_columns" >&6; }
16933 if test $gl_cv_pragma_columns = yes; then
16934 PRAGMA_COLUMNS="#pragma COLUMNS 10000"
16935 else
16936 PRAGMA_COLUMNS=
16937 fi
16938
16939
16940ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
16941if test "x$ac_cv_type_mode_t" = x""yes; then :
16942
16943else
16944
16945cat >>confdefs.h <<_ACEOF
16946#define mode_t int
16947_ACEOF
16948
16949fi
16950
16780{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_dm_mode in struct stat" >&5 16951{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_dm_mode in struct stat" >&5
16781$as_echo_n "checking for st_dm_mode in struct stat... " >&6; } 16952$as_echo_n "checking for st_dm_mode in struct stat... " >&6; }
16782if test "${ac_cv_struct_st_dm_mode+set}" = set; then : 16953if test "${ac_cv_struct_st_dm_mode+set}" = set; then :
@@ -16905,120 +17076,6 @@ _ACEOF
16905 17076
16906 17077
16907 17078
16908 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the preprocessor supports include_next" >&5
16909$as_echo_n "checking whether the preprocessor supports include_next... " >&6; }
16910if test "${gl_cv_have_include_next+set}" = set; then :
16911 $as_echo_n "(cached) " >&6
16912else
16913 rm -rf conftestd1a conftestd1b conftestd2
16914 mkdir conftestd1a conftestd1b conftestd2
16915 cat <<EOF > conftestd1a/conftest.h
16916#define DEFINED_IN_CONFTESTD1
16917#include_next <conftest.h>
16918#ifdef DEFINED_IN_CONFTESTD2
16919int foo;
16920#else
16921#error "include_next doesn't work"
16922#endif
16923EOF
16924 cat <<EOF > conftestd1b/conftest.h
16925#define DEFINED_IN_CONFTESTD1
16926#include <stdio.h>
16927#include_next <conftest.h>
16928#ifdef DEFINED_IN_CONFTESTD2
16929int foo;
16930#else
16931#error "include_next doesn't work"
16932#endif
16933EOF
16934 cat <<EOF > conftestd2/conftest.h
16935#ifndef DEFINED_IN_CONFTESTD1
16936#error "include_next test doesn't work"
16937#endif
16938#define DEFINED_IN_CONFTESTD2
16939EOF
16940 gl_save_CPPFLAGS="$CPPFLAGS"
16941 CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2"
16942 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16943/* end confdefs.h. */
16944#include <conftest.h>
16945_ACEOF
16946if ac_fn_c_try_compile "$LINENO"; then :
16947 gl_cv_have_include_next=yes
16948else
16949 CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2"
16950 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16951/* end confdefs.h. */
16952#include <conftest.h>
16953_ACEOF
16954if ac_fn_c_try_compile "$LINENO"; then :
16955 gl_cv_have_include_next=buggy
16956else
16957 gl_cv_have_include_next=no
16958fi
16959rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
16960
16961fi
16962rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
16963 CPPFLAGS="$gl_save_CPPFLAGS"
16964 rm -rf conftestd1a conftestd1b conftestd2
16965
16966fi
16967{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_have_include_next" >&5
16968$as_echo "$gl_cv_have_include_next" >&6; }
16969 PRAGMA_SYSTEM_HEADER=
16970 if test $gl_cv_have_include_next = yes; then
16971 INCLUDE_NEXT=include_next
16972 INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
16973 if test -n "$GCC"; then
16974 PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'
16975 fi
16976 else
16977 if test $gl_cv_have_include_next = buggy; then
16978 INCLUDE_NEXT=include
16979 INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
16980 else
16981 INCLUDE_NEXT=include
16982 INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include
16983 fi
16984 fi
16985
16986
16987
16988 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system header files limit the line length" >&5
16989$as_echo_n "checking whether system header files limit the line length... " >&6; }
16990if test "${gl_cv_pragma_columns+set}" = set; then :
16991 $as_echo_n "(cached) " >&6
16992else
16993 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
16994/* end confdefs.h. */
16995
16996#ifdef __TANDEM
16997choke me
16998#endif
16999
17000_ACEOF
17001if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
17002 $EGREP "choke me" >/dev/null 2>&1; then :
17003 gl_cv_pragma_columns=yes
17004else
17005 gl_cv_pragma_columns=no
17006fi
17007rm -f conftest*
17008
17009
17010fi
17011{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_pragma_columns" >&5
17012$as_echo "$gl_cv_pragma_columns" >&6; }
17013 if test $gl_cv_pragma_columns = yes; then
17014 PRAGMA_COLUMNS="#pragma COLUMNS 10000"
17015 else
17016 PRAGMA_COLUMNS=
17017 fi
17018
17019
17020
17021
17022 17079
17023 17080
17024 17081
@@ -19735,17 +19792,6 @@ fi
19735 19792
19736 19793
19737 19794
19738ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
19739if test "x$ac_cv_type_mode_t" = x""yes; then :
19740
19741else
19742
19743cat >>confdefs.h <<_ACEOF
19744#define mode_t int
19745_ACEOF
19746
19747fi
19748
19749 19795
19750 19796
19751 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timespec in <time.h>" >&5 19797 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timespec in <time.h>" >&5
@@ -20113,6 +20159,74 @@ $as_echo "#define HAVE_STRUCT_UTIMBUF 1" >>confdefs.h
20113 20159
20114 20160
20115 20161
20162{ $as_echo "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5
20163$as_echo_n "checking type of array argument to getgroups... " >&6; }
20164if test "${ac_cv_type_getgroups+set}" = set; then :
20165 $as_echo_n "(cached) " >&6
20166else
20167 if test "$cross_compiling" = yes; then :
20168 ac_cv_type_getgroups=cross
20169else
20170 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
20171/* end confdefs.h. */
20172/* Thanks to Mike Rendell for this test. */
20173$ac_includes_default
20174#define NGID 256
20175#undef MAX
20176#define MAX(x, y) ((x) > (y) ? (x) : (y))
20177
20178int
20179main ()
20180{
20181 gid_t gidset[NGID];
20182 int i, n;
20183 union { gid_t gval; long int lval; } val;
20184
20185 val.lval = -1;
20186 for (i = 0; i < NGID; i++)
20187 gidset[i] = val.gval;
20188 n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
20189 gidset);
20190 /* Exit non-zero if getgroups seems to require an array of ints. This
20191 happens when gid_t is short int but getgroups modifies an array
20192 of ints. */
20193 return n > 0 && gidset[n] != val.gval;
20194}
20195_ACEOF
20196if ac_fn_c_try_run "$LINENO"; then :
20197 ac_cv_type_getgroups=gid_t
20198else
20199 ac_cv_type_getgroups=int
20200fi
20201rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
20202 conftest.$ac_objext conftest.beam conftest.$ac_ext
20203fi
20204
20205if test $ac_cv_type_getgroups = cross; then
20206 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
20207/* end confdefs.h. */
20208#include <unistd.h>
20209
20210_ACEOF
20211if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
20212 $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then :
20213 ac_cv_type_getgroups=gid_t
20214else
20215 ac_cv_type_getgroups=int
20216fi
20217rm -f conftest*
20218
20219fi
20220fi
20221{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5
20222$as_echo "$ac_cv_type_getgroups" >&6; }
20223
20224cat >>confdefs.h <<_ACEOF
20225#define GETGROUPS_T $ac_cv_type_getgroups
20226_ACEOF
20227
20228
20229
20116 20230
20117 if false; then 20231 if false; then
20118 GL_COND_LIBTOOL_TRUE= 20232 GL_COND_LIBTOOL_TRUE=
@@ -20526,6 +20640,136 @@ fi
20526 20640
20527 20641
20528 20642
20643 if test $ac_cv_func_faccessat = no; then
20644 HAVE_FACCESSAT=0
20645 fi
20646
20647 if test $HAVE_FACCESSAT = 0; then
20648
20649
20650
20651
20652
20653
20654
20655
20656 gl_LIBOBJS="$gl_LIBOBJS faccessat.$ac_objext"
20657
20658
20659 for ac_func in access
20660do :
20661 ac_fn_c_check_func "$LINENO" "access" "ac_cv_func_access"
20662if test "x$ac_cv_func_access" = x""yes; then :
20663 cat >>confdefs.h <<_ACEOF
20664#define HAVE_ACCESS 1
20665_ACEOF
20666
20667fi
20668done
20669
20670
20671 fi
20672
20673
20674cat >>confdefs.h <<_ACEOF
20675#define GNULIB_FACCESSAT 1
20676_ACEOF
20677
20678
20679
20680
20681
20682
20683
20684 GNULIB_FACCESSAT=1
20685
20686
20687
20688
20689
20690
20691
20692
20693
20694
20695
20696
20697
20698
20699
20700
20701 if test $gl_cv_have_include_next = yes; then
20702 gl_cv_next_fcntl_h='<'fcntl.h'>'
20703 else
20704 { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <fcntl.h>" >&5
20705$as_echo_n "checking absolute name of <fcntl.h>... " >&6; }
20706if test "${gl_cv_next_fcntl_h+set}" = set; then :
20707 $as_echo_n "(cached) " >&6
20708else
20709
20710 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
20711/* end confdefs.h. */
20712#include <fcntl.h>
20713
20714_ACEOF
20715 case "$host_os" in
20716 aix*) gl_absname_cpp="$ac_cpp -C" ;;
20717 *) gl_absname_cpp="$ac_cpp" ;;
20718 esac
20719
20720 case "$host_os" in
20721 mingw*)
20722 gl_dirsep_regex='[/\\]'
20723 ;;
20724 *)
20725 gl_dirsep_regex='\/'
20726 ;;
20727 esac
20728 gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g'
20729
20730 gl_header_literal_regex=`echo 'fcntl.h' \
20731 | sed -e "$gl_make_literal_regex_sed"`
20732 gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{
20733 s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/
20734 s|^/[^/]|//&|
20735 p
20736 q
20737 }'
20738 gl_cv_next_fcntl_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
20739 sed -n "$gl_absolute_header_sed"`'"'
20740
20741
20742fi
20743{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_fcntl_h" >&5
20744$as_echo "$gl_cv_next_fcntl_h" >&6; }
20745 fi
20746 NEXT_FCNTL_H=$gl_cv_next_fcntl_h
20747
20748 if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
20749 # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
20750 gl_next_as_first_directive='<'fcntl.h'>'
20751 else
20752 # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
20753 gl_next_as_first_directive=$gl_cv_next_fcntl_h
20754 fi
20755 NEXT_AS_FIRST_DIRECTIVE_FCNTL_H=$gl_next_as_first_directive
20756
20757
20758
20759
20760
20761
20762
20763
20764
20765
20766
20767
20768
20769
20770
20771
20772
20529 20773
20530 fp_headers=' 20774 fp_headers='
20531# include <stdio.h> 20775# include <stdio.h>
@@ -24124,18 +24368,481 @@ $as_echo "#define FUTIMESAT_NULL_BUG 1" >>confdefs.h
24124 fi 24368 fi
24125 24369
24126 gl_gnulib_enabled_dosname=false 24370 gl_gnulib_enabled_dosname=false
24371 gl_gnulib_enabled_euidaccess=false
24372 gl_gnulib_enabled_getgroups=false
24127 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false 24373 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
24374 gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
24128 gl_gnulib_enabled_pathmax=false 24375 gl_gnulib_enabled_pathmax=false
24376 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
24129 gl_gnulib_enabled_stat=false 24377 gl_gnulib_enabled_stat=false
24130 gl_gnulib_enabled_strtoll=false 24378 gl_gnulib_enabled_strtoll=false
24131 gl_gnulib_enabled_strtoull=false 24379 gl_gnulib_enabled_strtoull=false
24132 gl_gnulib_enabled_verify=false 24380 gl_gnulib_enabled_verify=false
24381 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
24133 func_gl_gnulib_m4code_dosname () 24382 func_gl_gnulib_m4code_dosname ()
24134 { 24383 {
24135 if ! $gl_gnulib_enabled_dosname; then 24384 if ! $gl_gnulib_enabled_dosname; then
24136 gl_gnulib_enabled_dosname=true 24385 gl_gnulib_enabled_dosname=true
24137 fi 24386 fi
24138 } 24387 }
24388 func_gl_gnulib_m4code_euidaccess ()
24389 {
24390 if ! $gl_gnulib_enabled_euidaccess; then
24391
24392
24393
24394
24395
24396 for ac_func in euidaccess
24397do :
24398 ac_fn_c_check_func "$LINENO" "euidaccess" "ac_cv_func_euidaccess"
24399if test "x$ac_cv_func_euidaccess" = x""yes; then :
24400 cat >>confdefs.h <<_ACEOF
24401#define HAVE_EUIDACCESS 1
24402_ACEOF
24403
24404fi
24405done
24406
24407 if test $ac_cv_func_euidaccess = no; then
24408 HAVE_EUIDACCESS=0
24409 fi
24410
24411 if test $HAVE_EUIDACCESS = 0; then
24412
24413
24414
24415
24416
24417
24418
24419
24420 gl_LIBOBJS="$gl_LIBOBJS euidaccess.$ac_objext"
24421
24422
24423
24424 for ac_header in libgen.h
24425do :
24426 ac_fn_c_check_header_mongrel "$LINENO" "libgen.h" "ac_cv_header_libgen_h" "$ac_includes_default"
24427if test "x$ac_cv_header_libgen_h" = x""yes; then :
24428 cat >>confdefs.h <<_ACEOF
24429#define HAVE_LIBGEN_H 1
24430_ACEOF
24431
24432fi
24433
24434done
24435
24436
24437 ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups"
24438if test "x$ac_cv_func_getgroups" = x""yes; then :
24439
24440fi
24441
24442
24443 # If we don't yet have getgroups, see if it's in -lbsd.
24444 # This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
24445 ac_save_LIBS=$LIBS
24446 if test $ac_cv_func_getgroups = no; then
24447 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgroups in -lbsd" >&5
24448$as_echo_n "checking for getgroups in -lbsd... " >&6; }
24449if test "${ac_cv_lib_bsd_getgroups+set}" = set; then :
24450 $as_echo_n "(cached) " >&6
24451else
24452 ac_check_lib_save_LIBS=$LIBS
24453LIBS="-lbsd $LIBS"
24454cat confdefs.h - <<_ACEOF >conftest.$ac_ext
24455/* end confdefs.h. */
24456
24457/* Override any GCC internal prototype to avoid an error.
24458 Use char because int might match the return type of a GCC
24459 builtin and then its argument prototype would still apply. */
24460#ifdef __cplusplus
24461extern "C"
24462#endif
24463char getgroups ();
24464int
24465main ()
24466{
24467return getgroups ();
24468 ;
24469 return 0;
24470}
24471_ACEOF
24472if ac_fn_c_try_link "$LINENO"; then :
24473 ac_cv_lib_bsd_getgroups=yes
24474else
24475 ac_cv_lib_bsd_getgroups=no
24476fi
24477rm -f core conftest.err conftest.$ac_objext \
24478 conftest$ac_exeext conftest.$ac_ext
24479LIBS=$ac_check_lib_save_LIBS
24480fi
24481{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_getgroups" >&5
24482$as_echo "$ac_cv_lib_bsd_getgroups" >&6; }
24483if test "x$ac_cv_lib_bsd_getgroups" = x""yes; then :
24484 GETGROUPS_LIB=-lbsd
24485fi
24486
24487 fi
24488
24489 # Run the program to test the functionality of the system-supplied
24490 # getgroups function only if there is such a function.
24491 if test $ac_cv_func_getgroups = yes; then
24492 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working getgroups" >&5
24493$as_echo_n "checking for working getgroups... " >&6; }
24494if test "${ac_cv_func_getgroups_works+set}" = set; then :
24495 $as_echo_n "(cached) " >&6
24496else
24497 if test "$cross_compiling" = yes; then :
24498 case "$host_os" in # ((
24499 # Guess yes on glibc systems.
24500 *-gnu*) ac_cv_func_getgroups_works="guessing yes" ;;
24501 # If we don't know, assume the worst.
24502 *) ac_cv_func_getgroups_works="guessing no" ;;
24503 esac
24504
24505else
24506 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
24507/* end confdefs.h. */
24508$ac_includes_default
24509int
24510main ()
24511{
24512/* On Ultrix 4.3, getgroups (0, 0) always fails. */
24513 return getgroups (0, 0) == -1;
24514 ;
24515 return 0;
24516}
24517
24518_ACEOF
24519if ac_fn_c_try_run "$LINENO"; then :
24520 ac_cv_func_getgroups_works=yes
24521else
24522 ac_cv_func_getgroups_works=no
24523fi
24524rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
24525 conftest.$ac_objext conftest.beam conftest.$ac_ext
24526fi
24527
24528
24529fi
24530{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getgroups_works" >&5
24531$as_echo "$ac_cv_func_getgroups_works" >&6; }
24532 else
24533 ac_cv_func_getgroups_works=no
24534 fi
24535 case "$ac_cv_func_getgroups_works" in
24536 *yes)
24537
24538$as_echo "#define HAVE_GETGROUPS 1" >>confdefs.h
24539
24540 ;;
24541 esac
24542 LIBS=$ac_save_LIBS
24543
24544
24545 # Solaris 9 and 10 need -lgen to get the eaccess function.
24546 # Save and restore LIBS so -lgen isn't added to it. Otherwise, *all*
24547 # programs in the package would end up linked with that potentially-shared
24548 # library, inducing unnecessary run-time overhead.
24549 LIB_EACCESS=
24550
24551 gl_saved_libs=$LIBS
24552 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing eaccess" >&5
24553$as_echo_n "checking for library containing eaccess... " >&6; }
24554if test "${ac_cv_search_eaccess+set}" = set; then :
24555 $as_echo_n "(cached) " >&6
24556else
24557 ac_func_search_save_LIBS=$LIBS
24558cat confdefs.h - <<_ACEOF >conftest.$ac_ext
24559/* end confdefs.h. */
24560
24561/* Override any GCC internal prototype to avoid an error.
24562 Use char because int might match the return type of a GCC
24563 builtin and then its argument prototype would still apply. */
24564#ifdef __cplusplus
24565extern "C"
24566#endif
24567char eaccess ();
24568int
24569main ()
24570{
24571return eaccess ();
24572 ;
24573 return 0;
24574}
24575_ACEOF
24576for ac_lib in '' gen; do
24577 if test -z "$ac_lib"; then
24578 ac_res="none required"
24579 else
24580 ac_res=-l$ac_lib
24581 LIBS="-l$ac_lib $ac_func_search_save_LIBS"
24582 fi
24583 if ac_fn_c_try_link "$LINENO"; then :
24584 ac_cv_search_eaccess=$ac_res
24585fi
24586rm -f core conftest.err conftest.$ac_objext \
24587 conftest$ac_exeext
24588 if test "${ac_cv_search_eaccess+set}" = set; then :
24589 break
24590fi
24591done
24592if test "${ac_cv_search_eaccess+set}" = set; then :
24593
24594else
24595 ac_cv_search_eaccess=no
24596fi
24597rm conftest.$ac_ext
24598LIBS=$ac_func_search_save_LIBS
24599fi
24600{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_eaccess" >&5
24601$as_echo "$ac_cv_search_eaccess" >&6; }
24602ac_res=$ac_cv_search_eaccess
24603if test "$ac_res" != no; then :
24604 test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
24605 test "$ac_cv_search_eaccess" = "none required" ||
24606 LIB_EACCESS=$ac_cv_search_eaccess
24607fi
24608
24609 for ac_func in eaccess
24610do :
24611 ac_fn_c_check_func "$LINENO" "eaccess" "ac_cv_func_eaccess"
24612if test "x$ac_cv_func_eaccess" = x""yes; then :
24613 cat >>confdefs.h <<_ACEOF
24614#define HAVE_EACCESS 1
24615_ACEOF
24616
24617fi
24618done
24619
24620 LIBS=$gl_saved_libs
24621
24622 fi
24623
24624
24625
24626
24627
24628 GNULIB_EUIDACCESS=1
24629
24630
24631
24632
24633
24634 gl_gnulib_enabled_euidaccess=true
24635 if test $HAVE_EUIDACCESS = 0; then
24636 func_gl_gnulib_m4code_a9786850e999ae65a836a6041e8e5ed1
24637 fi
24638 func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c
24639 if test $HAVE_EUIDACCESS = 0; then
24640 func_gl_gnulib_m4code_stat
24641 fi
24642 fi
24643 }
24644 func_gl_gnulib_m4code_getgroups ()
24645 {
24646 if ! $gl_gnulib_enabled_getgroups; then
24647
24648
24649
24650
24651
24652 ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups"
24653if test "x$ac_cv_func_getgroups" = x""yes; then :
24654
24655fi
24656
24657
24658 # If we don't yet have getgroups, see if it's in -lbsd.
24659 # This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
24660 ac_save_LIBS=$LIBS
24661 if test $ac_cv_func_getgroups = no; then
24662 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgroups in -lbsd" >&5
24663$as_echo_n "checking for getgroups in -lbsd... " >&6; }
24664if test "${ac_cv_lib_bsd_getgroups+set}" = set; then :
24665 $as_echo_n "(cached) " >&6
24666else
24667 ac_check_lib_save_LIBS=$LIBS
24668LIBS="-lbsd $LIBS"
24669cat confdefs.h - <<_ACEOF >conftest.$ac_ext
24670/* end confdefs.h. */
24671
24672/* Override any GCC internal prototype to avoid an error.
24673 Use char because int might match the return type of a GCC
24674 builtin and then its argument prototype would still apply. */
24675#ifdef __cplusplus
24676extern "C"
24677#endif
24678char getgroups ();
24679int
24680main ()
24681{
24682return getgroups ();
24683 ;
24684 return 0;
24685}
24686_ACEOF
24687if ac_fn_c_try_link "$LINENO"; then :
24688 ac_cv_lib_bsd_getgroups=yes
24689else
24690 ac_cv_lib_bsd_getgroups=no
24691fi
24692rm -f core conftest.err conftest.$ac_objext \
24693 conftest$ac_exeext conftest.$ac_ext
24694LIBS=$ac_check_lib_save_LIBS
24695fi
24696{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_getgroups" >&5
24697$as_echo "$ac_cv_lib_bsd_getgroups" >&6; }
24698if test "x$ac_cv_lib_bsd_getgroups" = x""yes; then :
24699 GETGROUPS_LIB=-lbsd
24700fi
24701
24702 fi
24703
24704 # Run the program to test the functionality of the system-supplied
24705 # getgroups function only if there is such a function.
24706 if test $ac_cv_func_getgroups = yes; then
24707 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working getgroups" >&5
24708$as_echo_n "checking for working getgroups... " >&6; }
24709if test "${ac_cv_func_getgroups_works+set}" = set; then :
24710 $as_echo_n "(cached) " >&6
24711else
24712 if test "$cross_compiling" = yes; then :
24713 case "$host_os" in # ((
24714 # Guess yes on glibc systems.
24715 *-gnu*) ac_cv_func_getgroups_works="guessing yes" ;;
24716 # If we don't know, assume the worst.
24717 *) ac_cv_func_getgroups_works="guessing no" ;;
24718 esac
24719
24720else
24721 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
24722/* end confdefs.h. */
24723$ac_includes_default
24724int
24725main ()
24726{
24727/* On Ultrix 4.3, getgroups (0, 0) always fails. */
24728 return getgroups (0, 0) == -1;
24729 ;
24730 return 0;
24731}
24732
24733_ACEOF
24734if ac_fn_c_try_run "$LINENO"; then :
24735 ac_cv_func_getgroups_works=yes
24736else
24737 ac_cv_func_getgroups_works=no
24738fi
24739rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
24740 conftest.$ac_objext conftest.beam conftest.$ac_ext
24741fi
24742
24743
24744fi
24745{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getgroups_works" >&5
24746$as_echo "$ac_cv_func_getgroups_works" >&6; }
24747 else
24748 ac_cv_func_getgroups_works=no
24749 fi
24750 case "$ac_cv_func_getgroups_works" in
24751 *yes)
24752
24753$as_echo "#define HAVE_GETGROUPS 1" >>confdefs.h
24754
24755 ;;
24756 esac
24757 LIBS=$ac_save_LIBS
24758
24759 if test $ac_cv_func_getgroups != yes; then
24760 HAVE_GETGROUPS=0
24761 else
24762 if test "$ac_cv_type_getgroups" != gid_t \
24763 || { case "$ac_cv_func_getgroups_works" in
24764 *yes) false;;
24765 *) true;;
24766 esac
24767 }; then
24768 REPLACE_GETGROUPS=1
24769
24770$as_echo "#define GETGROUPS_ZERO_BUG 1" >>confdefs.h
24771
24772 else
24773 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getgroups handles negative values" >&5
24774$as_echo_n "checking whether getgroups handles negative values... " >&6; }
24775if test "${gl_cv_func_getgroups_works+set}" = set; then :
24776 $as_echo_n "(cached) " >&6
24777else
24778 if test "$cross_compiling" = yes; then :
24779 case "$host_os" in
24780 # Guess yes on glibc systems.
24781 *-gnu*) gl_cv_func_getgroups_works="guessing yes" ;;
24782 # If we don't know, assume the worst.
24783 *) gl_cv_func_getgroups_works="guessing no" ;;
24784 esac
24785
24786else
24787 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
24788/* end confdefs.h. */
24789$ac_includes_default
24790int
24791main ()
24792{
24793int size = getgroups (0, 0);
24794 gid_t *list = malloc (size * sizeof *list);
24795 return getgroups (-1, list) != -1;
24796 ;
24797 return 0;
24798}
24799_ACEOF
24800if ac_fn_c_try_run "$LINENO"; then :
24801 gl_cv_func_getgroups_works=yes
24802else
24803 gl_cv_func_getgroups_works=no
24804fi
24805rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
24806 conftest.$ac_objext conftest.beam conftest.$ac_ext
24807fi
24808
24809fi
24810{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_getgroups_works" >&5
24811$as_echo "$gl_cv_func_getgroups_works" >&6; }
24812 case "$gl_cv_func_getgroups_works" in
24813 *yes) ;;
24814 *) REPLACE_GETGROUPS=1 ;;
24815 esac
24816 fi
24817 fi
24818 test -n "$GETGROUPS_LIB" && LIBS="$GETGROUPS_LIB $LIBS"
24819
24820 if test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1; then
24821
24822
24823
24824
24825
24826
24827
24828
24829 gl_LIBOBJS="$gl_LIBOBJS getgroups.$ac_objext"
24830
24831 fi
24832
24833
24834
24835
24836
24837 GNULIB_GETGROUPS=1
24838
24839
24840
24841
24842
24843 gl_gnulib_enabled_getgroups=true
24844 fi
24845 }
24139 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 () 24846 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 ()
24140 { 24847 {
24141 if ! $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then 24848 if ! $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then
@@ -24144,6 +24851,59 @@ $as_echo "#define FUTIMESAT_NULL_BUG 1" >>confdefs.h
24144 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true 24851 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true
24145 fi 24852 fi
24146 } 24853 }
24854 func_gl_gnulib_m4code_a9786850e999ae65a836a6041e8e5ed1 ()
24855 {
24856 if ! $gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1; then
24857
24858
24859
24860
24861
24862 ac_fn_c_check_func "$LINENO" "group_member" "ac_cv_func_group_member"
24863if test "x$ac_cv_func_group_member" = x""yes; then :
24864
24865else
24866
24867 HAVE_GROUP_MEMBER=0
24868
24869fi
24870
24871
24872 if test $HAVE_GROUP_MEMBER = 0; then
24873
24874
24875
24876
24877
24878
24879
24880
24881 gl_LIBOBJS="$gl_LIBOBJS group-member.$ac_objext"
24882
24883
24884
24885
24886 fi
24887
24888
24889
24890
24891
24892 GNULIB_GROUP_MEMBER=1
24893
24894
24895
24896
24897
24898 gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=true
24899 if test $HAVE_GROUP_MEMBER = 0; then
24900 func_gl_gnulib_m4code_getgroups
24901 fi
24902 if test $HAVE_GROUP_MEMBER = 0; then
24903 func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec
24904 fi
24905 fi
24906 }
24147 func_gl_gnulib_m4code_pathmax () 24907 func_gl_gnulib_m4code_pathmax ()
24148 { 24908 {
24149 if ! $gl_gnulib_enabled_pathmax; then 24909 if ! $gl_gnulib_enabled_pathmax; then
@@ -24153,6 +24913,12 @@ $as_echo "#define FUTIMESAT_NULL_BUG 1" >>confdefs.h
24153 gl_gnulib_enabled_pathmax=true 24913 gl_gnulib_enabled_pathmax=true
24154 fi 24914 fi
24155 } 24915 }
24916 func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c ()
24917 {
24918 if ! $gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c; then
24919 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=true
24920 fi
24921 }
24156 func_gl_gnulib_m4code_stat () 24922 func_gl_gnulib_m4code_stat ()
24157 { 24923 {
24158 if ! $gl_gnulib_enabled_stat; then 24924 if ! $gl_gnulib_enabled_stat; then
@@ -24409,6 +25175,18 @@ done
24409 gl_gnulib_enabled_verify=true 25175 gl_gnulib_enabled_verify=true
24410 fi 25176 fi
24411 } 25177 }
25178 func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec ()
25179 {
25180 if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then
25181 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=true
25182 fi
25183 }
25184 if test $HAVE_FACCESSAT = 0; then
25185 func_gl_gnulib_m4code_dosname
25186 fi
25187 if test $HAVE_FACCESSAT = 0; then
25188 func_gl_gnulib_m4code_euidaccess
25189 fi
24412 if test $REPLACE_GETOPT = 1; then 25190 if test $REPLACE_GETOPT = 1; then
24413 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 25191 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36
24414 fi 25192 fi
@@ -24442,6 +25220,22 @@ else
24442 gl_GNULIB_ENABLED_dosname_FALSE= 25220 gl_GNULIB_ENABLED_dosname_FALSE=
24443fi 25221fi
24444 25222
25223 if $gl_gnulib_enabled_euidaccess; then
25224 gl_GNULIB_ENABLED_euidaccess_TRUE=
25225 gl_GNULIB_ENABLED_euidaccess_FALSE='#'
25226else
25227 gl_GNULIB_ENABLED_euidaccess_TRUE='#'
25228 gl_GNULIB_ENABLED_euidaccess_FALSE=
25229fi
25230
25231 if $gl_gnulib_enabled_getgroups; then
25232 gl_GNULIB_ENABLED_getgroups_TRUE=
25233 gl_GNULIB_ENABLED_getgroups_FALSE='#'
25234else
25235 gl_GNULIB_ENABLED_getgroups_TRUE='#'
25236 gl_GNULIB_ENABLED_getgroups_FALSE=
25237fi
25238
24445 if $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then 25239 if $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then
24446 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE= 25240 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE=
24447 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE='#' 25241 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE='#'
@@ -24450,6 +25244,14 @@ else
24450 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE= 25244 gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE=
24451fi 25245fi
24452 25246
25247 if $gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1; then
25248 gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_TRUE=
25249 gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_FALSE='#'
25250else
25251 gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_TRUE='#'
25252 gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_FALSE=
25253fi
25254
24453 if $gl_gnulib_enabled_pathmax; then 25255 if $gl_gnulib_enabled_pathmax; then
24454 gl_GNULIB_ENABLED_pathmax_TRUE= 25256 gl_GNULIB_ENABLED_pathmax_TRUE=
24455 gl_GNULIB_ENABLED_pathmax_FALSE='#' 25257 gl_GNULIB_ENABLED_pathmax_FALSE='#'
@@ -24458,6 +25260,14 @@ else
24458 gl_GNULIB_ENABLED_pathmax_FALSE= 25260 gl_GNULIB_ENABLED_pathmax_FALSE=
24459fi 25261fi
24460 25262
25263 if $gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c; then
25264 gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_TRUE=
25265 gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_FALSE='#'
25266else
25267 gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_TRUE='#'
25268 gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_FALSE=
25269fi
25270
24461 if $gl_gnulib_enabled_stat; then 25271 if $gl_gnulib_enabled_stat; then
24462 gl_GNULIB_ENABLED_stat_TRUE= 25272 gl_GNULIB_ENABLED_stat_TRUE=
24463 gl_GNULIB_ENABLED_stat_FALSE='#' 25273 gl_GNULIB_ENABLED_stat_FALSE='#'
@@ -24490,6 +25300,14 @@ else
24490 gl_GNULIB_ENABLED_verify_FALSE= 25300 gl_GNULIB_ENABLED_verify_FALSE=
24491fi 25301fi
24492 25302
25303 if $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then
25304 gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE=
25305 gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE='#'
25306else
25307 gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE='#'
25308 gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE=
25309fi
25310
24493 # End of code from modules 25311 # End of code from modules
24494 25312
24495 25313
@@ -24970,14 +25788,30 @@ if test -z "${gl_GNULIB_ENABLED_dosname_TRUE}" && test -z "${gl_GNULIB_ENABLED_d
24970 as_fn_error "conditional \"gl_GNULIB_ENABLED_dosname\" was never defined. 25788 as_fn_error "conditional \"gl_GNULIB_ENABLED_dosname\" was never defined.
24971Usually this means the macro was only invoked conditionally." "$LINENO" 5 25789Usually this means the macro was only invoked conditionally." "$LINENO" 5
24972fi 25790fi
25791if test -z "${gl_GNULIB_ENABLED_euidaccess_TRUE}" && test -z "${gl_GNULIB_ENABLED_euidaccess_FALSE}"; then
25792 as_fn_error "conditional \"gl_GNULIB_ENABLED_euidaccess\" was never defined.
25793Usually this means the macro was only invoked conditionally." "$LINENO" 5
25794fi
25795if test -z "${gl_GNULIB_ENABLED_getgroups_TRUE}" && test -z "${gl_GNULIB_ENABLED_getgroups_FALSE}"; then
25796 as_fn_error "conditional \"gl_GNULIB_ENABLED_getgroups\" was never defined.
25797Usually this means the macro was only invoked conditionally." "$LINENO" 5
25798fi
24973if test -z "${gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE}" && test -z "${gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE}"; then 25799if test -z "${gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE}" && test -z "${gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_FALSE}"; then
24974 as_fn_error "conditional \"gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36\" was never defined. 25800 as_fn_error "conditional \"gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36\" was never defined.
24975Usually this means the macro was only invoked conditionally." "$LINENO" 5 25801Usually this means the macro was only invoked conditionally." "$LINENO" 5
24976fi 25802fi
25803if test -z "${gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_TRUE}" && test -z "${gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1_FALSE}"; then
25804 as_fn_error "conditional \"gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1\" was never defined.
25805Usually this means the macro was only invoked conditionally." "$LINENO" 5
25806fi
24977if test -z "${gl_GNULIB_ENABLED_pathmax_TRUE}" && test -z "${gl_GNULIB_ENABLED_pathmax_FALSE}"; then 25807if test -z "${gl_GNULIB_ENABLED_pathmax_TRUE}" && test -z "${gl_GNULIB_ENABLED_pathmax_FALSE}"; then
24978 as_fn_error "conditional \"gl_GNULIB_ENABLED_pathmax\" was never defined. 25808 as_fn_error "conditional \"gl_GNULIB_ENABLED_pathmax\" was never defined.
24979Usually this means the macro was only invoked conditionally." "$LINENO" 5 25809Usually this means the macro was only invoked conditionally." "$LINENO" 5
24980fi 25810fi
25811if test -z "${gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_TRUE}" && test -z "${gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_FALSE}"; then
25812 as_fn_error "conditional \"gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c\" was never defined.
25813Usually this means the macro was only invoked conditionally." "$LINENO" 5
25814fi
24981if test -z "${gl_GNULIB_ENABLED_stat_TRUE}" && test -z "${gl_GNULIB_ENABLED_stat_FALSE}"; then 25815if test -z "${gl_GNULIB_ENABLED_stat_TRUE}" && test -z "${gl_GNULIB_ENABLED_stat_FALSE}"; then
24982 as_fn_error "conditional \"gl_GNULIB_ENABLED_stat\" was never defined. 25816 as_fn_error "conditional \"gl_GNULIB_ENABLED_stat\" was never defined.
24983Usually this means the macro was only invoked conditionally." "$LINENO" 5 25817Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24994,6 +25828,10 @@ if test -z "${gl_GNULIB_ENABLED_verify_TRUE}" && test -z "${gl_GNULIB_ENABLED_ve
24994 as_fn_error "conditional \"gl_GNULIB_ENABLED_verify\" was never defined. 25828 as_fn_error "conditional \"gl_GNULIB_ENABLED_verify\" was never defined.
24995Usually this means the macro was only invoked conditionally." "$LINENO" 5 25829Usually this means the macro was only invoked conditionally." "$LINENO" 5
24996fi 25830fi
25831if test -z "${gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE}" && test -z "${gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE}"; then
25832 as_fn_error "conditional \"gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec\" was never defined.
25833Usually this means the macro was only invoked conditionally." "$LINENO" 5
25834fi
24997 25835
24998 gl_libobjs= 25836 gl_libobjs=
24999 gl_ltlibobjs= 25837 gl_ltlibobjs=
diff --git a/configure.ac b/configure.ac
index 9146c669096..b0c81a23f8a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -572,6 +572,8 @@ else
572 test "x$NON_GCC_TEST_OPTIONS" != x && CC="$CC $NON_GCC_TEST_OPTIONS" 572 test "x$NON_GCC_TEST_OPTIONS" != x && CC="$CC $NON_GCC_TEST_OPTIONS"
573fi 573fi
574 574
575# Avoid gnulib's tests for O_NOATIME and O_NOFOLLOW, as we don't use them.
576AC_DEFUN([gl_FCNTL_O_FLAGS])
575# Avoid gnulib's threadlib module, as we do threads our own way. 577# Avoid gnulib's threadlib module, as we do threads our own way.
576AC_DEFUN([gl_THREADLIB]) 578AC_DEFUN([gl_THREADLIB])
577 579
@@ -2872,7 +2874,7 @@ AC_SUBST(BLESSMAIL_TARGET)
2872AC_CHECK_FUNCS(gethostname \ 2874AC_CHECK_FUNCS(gethostname \
2873closedir getrusage get_current_dir_name \ 2875closedir getrusage get_current_dir_name \
2874lrand48 \ 2876lrand48 \
2875fpathconf select euidaccess getpagesize setlocale \ 2877fpathconf select getpagesize setlocale \
2876utimes getrlimit setrlimit getcwd shutdown getaddrinfo \ 2878utimes getrlimit setrlimit getcwd shutdown getaddrinfo \
2877strsignal setitimer \ 2879strsignal setitimer \
2878sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \ 2880sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index bb02b1d54fd..a284fc09045 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -1055,7 +1055,7 @@ including the space earlier stolen from @code{W3}.
1055@end smallexample 1055@end smallexample
1056 1056
1057@noindent 1057@noindent
1058This can be counterintutive, in particular if @code{W4} were used for 1058This can be counterintuitive, in particular if @code{W4} were used for
1059displaying a buffer only temporarily (@pxref{Temporary Displays}), and 1059displaying a buffer only temporarily (@pxref{Temporary Displays}), and
1060you want to continue working with the initial layout. 1060you want to continue working with the initial layout.
1061 1061
@@ -2343,7 +2343,7 @@ buffer previously shown no longer exists, this function calls
2343@code{switch-to-prev-buffer} (@pxref{Window History}) to show some other 2343@code{switch-to-prev-buffer} (@pxref{Window History}) to show some other
2344buffer instead. 2344buffer instead.
2345 2345
2346The optional argument @var{bury-or-kill} specifes how to deal with 2346The optional argument @var{bury-or-kill} specifies how to deal with
2347@var{window}'s buffer. The following values are handled: 2347@var{window}'s buffer. The following values are handled:
2348 2348
2349@table @code 2349@table @code
diff --git a/doc/misc/ses.texi b/doc/misc/ses.texi
index 5de87a2f1c7..cccd74dec0f 100644
--- a/doc/misc/ses.texi
+++ b/doc/misc/ses.texi
@@ -482,9 +482,9 @@ show column letters again.
482Pops up a menu to set the current row as the header, or revert to 482Pops up a menu to set the current row as the header, or revert to
483column letters. 483column letters.
484@item M-x ses-rename-cell 484@item M-x ses-rename-cell
485@findex ses-rename-cell 485@findex ses-rename-cell
486Rename a cell from a standard A1-like name to any 486Rename a cell from a standard A1-like name to any
487string. 487string.
488@item M-x ses-repair-cell-reference-all 488@item M-x ses-repair-cell-reference-all
489@findex ses-repair-cell-reference-all 489@findex ses-repair-cell-reference-all
490When you interrupt a cell formula update by clicking @kbd{C-g}, then 490When you interrupt a cell formula update by clicking @kbd{C-g}, then
@@ -606,15 +606,15 @@ instance @code{(ses-range A1 A4 _ "empty")} will do the same as
606are empty. Similarly, @code{(ses-range A1 A4 _ )} will do the same as 606are empty. Similarly, @code{(ses-range A1 A4 _ )} will do the same as
607@code{(list A1 0 A3 0)}. 607@code{(list A1 0 A3 0)}.
608@item >v 608@item >v
609When order matters, list cells by reading cells rowwise from top left 609When order matters, list cells by reading cells row-wise from top left
610to bottom right. This flag is provided for completeness only as it is 610to bottom right. This flag is provided for completeness only as it is
611the default reading order. 611the default reading order.
612@item <v 612@item <v
613List cells by reading cells rowwise from top right to bottom left. 613List cells by reading cells row-wise from top right to bottom left.
614@item v> 614@item v>
615List cells by reading cells columnwise from top left to bottom right. 615List cells by reading cells column-wise from top left to bottom right.
616@item v< 616@item v<
617List cells by reading cells columnwise from top right to bottom left. 617List cells by reading cells column-wise from top right to bottom left.
618@item v 618@item v
619A short hand for @code{v>}. 619A short hand for @code{v>}.
620@item ^ 620@item ^
diff --git a/doc/misc/url.texi b/doc/misc/url.texi
index fdb3ab452f2..90ab7f5554f 100644
--- a/doc/misc/url.texi
+++ b/doc/misc/url.texi
@@ -346,7 +346,7 @@ To use this function, you must @code{(require 'url-queue)}.
346The value of this option is an integer specifying the maximum number 346The value of this option is an integer specifying the maximum number
347of concurrent @code{url-queue-retrieve} network processes. If the 347of concurrent @code{url-queue-retrieve} network processes. If the
348number of @code{url-queue-retrieve} calls is larger than this number, 348number of @code{url-queue-retrieve} calls is larger than this number,
349later ones are queued until ealier ones are finished. 349later ones are queued until earlier ones are finished.
350@end defopt 350@end defopt
351 351
352@vindex url-queue-timeout 352@vindex url-queue-timeout
diff --git a/etc/NEWS b/etc/NEWS
index fbe24c8345f..58acf81897c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -43,7 +43,8 @@ It is layered as:
43 43
44* Incompatible Lisp Changes in Emacs 24.4 44* Incompatible Lisp Changes in Emacs 24.4
45 45
46** `defadvice' does not honor the `freeze' flag any more. 46** `defadvice' does not honor the `freeze' flag and cannot advise
47special-forms any more.
47 48
48** `dolist' in lexical-binding mode does not bind VAR in RESULT any more. 49** `dolist' in lexical-binding mode does not bind VAR in RESULT any more.
49VAR was bound to nil which was not tremendously useful and just lead to 50VAR was bound to nil which was not tremendously useful and just lead to
diff --git a/lib/at-func.c b/lib/at-func.c
new file mode 100644
index 00000000000..481eea475a1
--- /dev/null
+++ b/lib/at-func.c
@@ -0,0 +1,146 @@
1/* Define at-style functions like fstatat, unlinkat, fchownat, etc.
2 Copyright (C) 2006, 2009-2012 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17/* written by Jim Meyering */
18
19#include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
20
21#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
22# include <errno.h>
23# ifndef ENOTSUP
24# define ENOTSUP EINVAL
25# endif
26#else
27# include "openat.h"
28# include "openat-priv.h"
29# include "save-cwd.h"
30#endif
31
32#ifdef AT_FUNC_USE_F1_COND
33# define CALL_FUNC(F) \
34 (flag == AT_FUNC_USE_F1_COND \
35 ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \
36 : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS))
37# define VALIDATE_FLAG(F) \
38 if (flag & ~AT_FUNC_USE_F1_COND) \
39 { \
40 errno = EINVAL; \
41 return FUNC_FAIL; \
42 }
43#else
44# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS))
45# define VALIDATE_FLAG(F) /* empty */
46#endif
47
48#ifdef AT_FUNC_RESULT
49# define FUNC_RESULT AT_FUNC_RESULT
50#else
51# define FUNC_RESULT int
52#endif
53
54#ifdef AT_FUNC_FAIL
55# define FUNC_FAIL AT_FUNC_FAIL
56#else
57# define FUNC_FAIL -1
58#endif
59
60/* Call AT_FUNC_F1 to operate on FILE, which is in the directory
61 open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value,
62 AT_FUNC_POST_FILE_PARAM_DECLS must include a parameter named flag;
63 call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than
64 AT_FUNC_USE_F1_COND. Return int and fail with -1 unless AT_FUNC_RESULT
65 or AT_FUNC_FAIL are defined. If possible, do it without changing the
66 working directory. Otherwise, resort to using save_cwd/fchdir,
67 then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd
68 fails, then give a diagnostic and exit nonzero. */
69FUNC_RESULT
70AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS)
71{
72 VALIDATE_FLAG (flag);
73
74 if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
75 return CALL_FUNC (file);
76
77#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
78 errno = ENOTSUP;
79 return FUNC_FAIL;
80#else
81 {
82 /* Be careful to choose names unlikely to conflict with
83 AT_FUNC_POST_FILE_PARAM_DECLS. */
84 struct saved_cwd saved_cwd;
85 int saved_errno;
86 FUNC_RESULT err;
87
88 {
89 char proc_buf[OPENAT_BUFFER_SIZE];
90 char *proc_file = openat_proc_name (proc_buf, fd, file);
91 if (proc_file)
92 {
93 FUNC_RESULT proc_result = CALL_FUNC (proc_file);
94 int proc_errno = errno;
95 if (proc_file != proc_buf)
96 free (proc_file);
97 /* If the syscall succeeds, or if it fails with an unexpected
98 errno value, then return right away. Otherwise, fall through
99 and resort to using save_cwd/restore_cwd. */
100 if (FUNC_FAIL != proc_result)
101 return proc_result;
102 if (! EXPECTED_ERRNO (proc_errno))
103 {
104 errno = proc_errno;
105 return proc_result;
106 }
107 }
108 }
109
110 if (save_cwd (&saved_cwd) != 0)
111 openat_save_fail (errno);
112 if (0 <= fd && fd == saved_cwd.desc)
113 {
114 /* If saving the working directory collides with the user's
115 requested fd, then the user's fd must have been closed to
116 begin with. */
117 free_cwd (&saved_cwd);
118 errno = EBADF;
119 return FUNC_FAIL;
120 }
121
122 if (fchdir (fd) != 0)
123 {
124 saved_errno = errno;
125 free_cwd (&saved_cwd);
126 errno = saved_errno;
127 return FUNC_FAIL;
128 }
129
130 err = CALL_FUNC (file);
131 saved_errno = (err == FUNC_FAIL ? errno : 0);
132
133 if (restore_cwd (&saved_cwd) != 0)
134 openat_restore_fail (errno);
135
136 free_cwd (&saved_cwd);
137
138 if (saved_errno)
139 errno = saved_errno;
140 return err;
141 }
142#endif
143}
144#undef CALL_FUNC
145#undef FUNC_RESULT
146#undef FUNC_FAIL
diff --git a/lib/euidaccess.c b/lib/euidaccess.c
new file mode 100644
index 00000000000..ca2ceca5d22
--- /dev/null
+++ b/lib/euidaccess.c
@@ -0,0 +1,221 @@
1/* euidaccess -- check if effective user id can access file
2
3 Copyright (C) 1990-1991, 1995, 1998, 2000, 2003-2006, 2008-2012 Free
4 Software Foundation, Inc.
5
6 This file is part of the GNU C Library.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21/* Written by David MacKenzie and Torbjorn Granlund.
22 Adapted for GNU C library by Roland McGrath. */
23
24#ifndef _LIBC
25# include <config.h>
26#endif
27
28#include <fcntl.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <unistd.h>
32
33#include "root-uid.h"
34
35#if HAVE_LIBGEN_H
36# include <libgen.h>
37#endif
38
39#include <errno.h>
40#ifndef __set_errno
41# define __set_errno(val) errno = (val)
42#endif
43
44#if defined EACCES && !defined EACCESS
45# define EACCESS EACCES
46#endif
47
48#ifndef F_OK
49# define F_OK 0
50# define X_OK 1
51# define W_OK 2
52# define R_OK 4
53#endif
54
55
56#ifdef _LIBC
57
58# define access __access
59# define getuid __getuid
60# define getgid __getgid
61# define geteuid __geteuid
62# define getegid __getegid
63# define group_member __group_member
64# define euidaccess __euidaccess
65# undef stat
66# define stat stat64
67
68#endif
69
70/* Return 0 if the user has permission of type MODE on FILE;
71 otherwise, return -1 and set 'errno'.
72 Like access, except that it uses the effective user and group
73 id's instead of the real ones, and it does not always check for read-only
74 file system, text busy, etc. */
75
76int
77euidaccess (const char *file, int mode)
78{
79#if HAVE_FACCESSAT /* glibc, AIX 7, Solaris 11, Cygwin 1.7 */
80 return faccessat (AT_FDCWD, file, mode, AT_EACCESS);
81#elif defined EFF_ONLY_OK /* IRIX, OSF/1, Interix */
82 return access (file, mode | EFF_ONLY_OK);
83#elif defined ACC_SELF /* AIX */
84 return accessx (file, mode, ACC_SELF);
85#elif HAVE_EACCESS /* FreeBSD */
86 return eaccess (file, mode);
87#else /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, mingw, BeOS */
88
89 uid_t uid = getuid ();
90 gid_t gid = getgid ();
91 uid_t euid = geteuid ();
92 gid_t egid = getegid ();
93 struct stat stats;
94
95# if HAVE_DECL_SETREGID && PREFER_NONREENTRANT_EUIDACCESS
96
97 /* Define PREFER_NONREENTRANT_EUIDACCESS if you prefer euidaccess to
98 return the correct result even if this would make it
99 nonreentrant. Define this only if your entire application is
100 safe even if the uid or gid might temporarily change. If your
101 application uses signal handlers or threads it is probably not
102 safe. */
103
104 if (mode == F_OK)
105 return stat (file, &stats);
106 else
107 {
108 int result;
109 int saved_errno;
110
111 if (uid != euid)
112 setreuid (euid, uid);
113 if (gid != egid)
114 setregid (egid, gid);
115
116 result = access (file, mode);
117 saved_errno = errno;
118
119 /* Restore them. */
120 if (uid != euid)
121 setreuid (uid, euid);
122 if (gid != egid)
123 setregid (gid, egid);
124
125 errno = saved_errno;
126 return result;
127 }
128
129# else
130
131 /* The following code assumes the traditional Unix model, and is not
132 correct on systems that have ACLs or the like. However, it's
133 better than nothing, and it is reentrant. */
134
135 unsigned int granted;
136 if (uid == euid && gid == egid)
137 /* If we are not set-uid or set-gid, access does the same. */
138 return access (file, mode);
139
140 if (stat (file, &stats) != 0)
141 return -1;
142
143 /* The super-user can read and write any file, and execute any file
144 that anyone can execute. */
145 if (euid == ROOT_UID
146 && ((mode & X_OK) == 0
147 || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
148 return 0;
149
150 /* Convert the mode to traditional form, clearing any bogus bits. */
151 if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
152 mode &= 7;
153 else
154 mode = ((mode & R_OK ? 4 : 0)
155 + (mode & W_OK ? 2 : 0)
156 + (mode & X_OK ? 1 : 0));
157
158 if (mode == 0)
159 return 0; /* The file exists. */
160
161 /* Convert the file's permission bits to traditional form. */
162 if (S_IRUSR == (4 << 6) && S_IWUSR == (2 << 6) && S_IXUSR == (1 << 6)
163 && S_IRGRP == (4 << 3) && S_IWGRP == (2 << 3) && S_IXGRP == (1 << 3)
164 && S_IROTH == (4 << 0) && S_IWOTH == (2 << 0) && S_IXOTH == (1 << 0))
165 granted = stats.st_mode;
166 else
167 granted = ((stats.st_mode & S_IRUSR ? 4 << 6 : 0)
168 + (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
169 + (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
170 + (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
171 + (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
172 + (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
173 + (stats.st_mode & S_IROTH ? 4 << 0 : 0)
174 + (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
175 + (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
176
177 if (euid == stats.st_uid)
178 granted >>= 6;
179 else if (egid == stats.st_gid || group_member (stats.st_gid))
180 granted >>= 3;
181
182 if ((mode & ~granted) == 0)
183 return 0;
184 __set_errno (EACCESS);
185 return -1;
186
187# endif
188#endif
189}
190#undef euidaccess
191#ifdef weak_alias
192weak_alias (__euidaccess, euidaccess)
193#endif
194
195#ifdef TEST
196# include <error.h>
197# include <stdio.h>
198# include <stdlib.h>
199
200char *program_name;
201
202int
203main (int argc, char **argv)
204{
205 char *file;
206 int mode;
207 int err;
208
209 program_name = argv[0];
210 if (argc < 3)
211 abort ();
212 file = argv[1];
213 mode = atoi (argv[2]);
214
215 err = euidaccess (file, mode);
216 printf ("%d\n", err);
217 if (err != 0)
218 error (0, errno, "%s", file);
219 exit (0);
220}
221#endif
diff --git a/lib/faccessat.c b/lib/faccessat.c
new file mode 100644
index 00000000000..d11a3efaad6
--- /dev/null
+++ b/lib/faccessat.c
@@ -0,0 +1,45 @@
1/* Check the access rights of a file relative to an open directory.
2 Copyright (C) 2009-2012 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17/* written by Eric Blake */
18
19#include <config.h>
20
21#include <unistd.h>
22#include <fcntl.h>
23
24#ifndef HAVE_ACCESS
25/* Mingw lacks access, but it also lacks real vs. effective ids, so
26 the gnulib euidaccess module is good enough. */
27# undef access
28# define access euidaccess
29#endif
30
31/* Invoke access or euidaccess on file, FILE, using mode MODE, in the directory
32 open on descriptor FD. If possible, do it without changing the
33 working directory. Otherwise, resort to using save_cwd/fchdir, then
34 (access|euidaccess)/restore_cwd. If either the save_cwd or the
35 restore_cwd fails, then give a diagnostic and exit nonzero.
36 Note that this implementation only supports AT_EACCESS, although some
37 native versions also support AT_SYMLINK_NOFOLLOW. */
38
39#define AT_FUNC_NAME faccessat
40#define AT_FUNC_F1 euidaccess
41#define AT_FUNC_F2 access
42#define AT_FUNC_USE_F1_COND AT_EACCESS
43#define AT_FUNC_POST_FILE_PARAM_DECLS , int mode, int flag
44#define AT_FUNC_POST_FILE_ARGS , mode
45#include "at-func.c"
diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h
new file mode 100644
index 00000000000..604c31b7984
--- /dev/null
+++ b/lib/fcntl.in.h
@@ -0,0 +1,347 @@
1/* Like <fcntl.h>, but with non-working flags defined to 0.
2
3 Copyright (C) 2006-2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* written by Paul Eggert */
19
20#if __GNUC__ >= 3
21@PRAGMA_SYSTEM_HEADER@
22#endif
23@PRAGMA_COLUMNS@
24
25#if defined __need_system_fcntl_h
26/* Special invocation convention. */
27
28/* Needed before <sys/stat.h>.
29 May also define off_t to a 64-bit type on native Windows. */
30#include <sys/types.h>
31/* On some systems other than glibc, <sys/stat.h> is a prerequisite of
32 <fcntl.h>. On glibc systems, we would like to avoid namespace pollution.
33 But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an
34 extern "C" { ... } block, which leads to errors in C++ mode with the
35 overridden <sys/stat.h> from gnulib. These errors are known to be gone
36 with g++ version >= 4.3. */
37#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
38# include <sys/stat.h>
39#endif
40#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
41
42#else
43/* Normal invocation convention. */
44
45#ifndef _@GUARD_PREFIX@_FCNTL_H
46
47/* Needed before <sys/stat.h>.
48 May also define off_t to a 64-bit type on native Windows. */
49#include <sys/types.h>
50/* On some systems other than glibc, <sys/stat.h> is a prerequisite of
51 <fcntl.h>. On glibc systems, we would like to avoid namespace pollution.
52 But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an
53 extern "C" { ... } block, which leads to errors in C++ mode with the
54 overridden <sys/stat.h> from gnulib. These errors are known to be gone
55 with g++ version >= 4.3. */
56#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
57# include <sys/stat.h>
58#endif
59/* The include_next requires a split double-inclusion guard. */
60#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
61
62#ifndef _@GUARD_PREFIX@_FCNTL_H
63#define _@GUARD_PREFIX@_FCNTL_H
64
65#ifndef __GLIBC__ /* Avoid namespace pollution on glibc systems. */
66# include <unistd.h>
67#endif
68
69/* Native Windows platforms declare open(), creat() in <io.h>. */
70#if (@GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \
71 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
72# include <io.h>
73#endif
74
75
76/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
77
78/* The definition of _GL_ARG_NONNULL is copied here. */
79
80/* The definition of _GL_WARN_ON_USE is copied here. */
81
82
83/* Declare overridden functions. */
84
85#if @GNULIB_FCNTL@
86# if @REPLACE_FCNTL@
87# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
88# undef fcntl
89# define fcntl rpl_fcntl
90# endif
91_GL_FUNCDECL_RPL (fcntl, int, (int fd, int action, ...));
92_GL_CXXALIAS_RPL (fcntl, int, (int fd, int action, ...));
93# else
94# if !@HAVE_FCNTL@
95_GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...));
96# endif
97_GL_CXXALIAS_SYS (fcntl, int, (int fd, int action, ...));
98# endif
99_GL_CXXALIASWARN (fcntl);
100#elif defined GNULIB_POSIXCHECK
101# undef fcntl
102# if HAVE_RAW_DECL_FCNTL
103_GL_WARN_ON_USE (fcntl, "fcntl is not always POSIX compliant - "
104 "use gnulib module fcntl for portability");
105# endif
106#endif
107
108#if @GNULIB_OPEN@
109# if @REPLACE_OPEN@
110# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
111# undef open
112# define open rpl_open
113# endif
114_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
115 _GL_ARG_NONNULL ((1)));
116_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
117# else
118_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
119# endif
120/* On HP-UX 11, in C++ mode, open() is defined as an inline function with a
121 default argument. _GL_CXXALIASWARN does not work in this case. */
122# if !defined __hpux
123_GL_CXXALIASWARN (open);
124# endif
125#elif defined GNULIB_POSIXCHECK
126# undef open
127/* Assume open is always declared. */
128_GL_WARN_ON_USE (open, "open is not always POSIX compliant - "
129 "use gnulib module open for portability");
130#endif
131
132#if @GNULIB_OPENAT@
133# if @REPLACE_OPENAT@
134# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
135# undef openat
136# define openat rpl_openat
137# endif
138_GL_FUNCDECL_RPL (openat, int,
139 (int fd, char const *file, int flags, /* mode_t mode */ ...)
140 _GL_ARG_NONNULL ((2)));
141_GL_CXXALIAS_RPL (openat, int,
142 (int fd, char const *file, int flags, /* mode_t mode */ ...));
143# else
144# if !@HAVE_OPENAT@
145_GL_FUNCDECL_SYS (openat, int,
146 (int fd, char const *file, int flags, /* mode_t mode */ ...)
147 _GL_ARG_NONNULL ((2)));
148# endif
149_GL_CXXALIAS_SYS (openat, int,
150 (int fd, char const *file, int flags, /* mode_t mode */ ...));
151# endif
152_GL_CXXALIASWARN (openat);
153#elif defined GNULIB_POSIXCHECK
154# undef openat
155# if HAVE_RAW_DECL_OPENAT
156_GL_WARN_ON_USE (openat, "openat is not portable - "
157 "use gnulib module openat for portability");
158# endif
159#endif
160
161
162/* Fix up the FD_* macros, only known to be missing on mingw. */
163
164#ifndef FD_CLOEXEC
165# define FD_CLOEXEC 1
166#endif
167
168/* Fix up the supported F_* macros. Intentionally leave other F_*
169 macros undefined. Only known to be missing on mingw. */
170
171#ifndef F_DUPFD_CLOEXEC
172# define F_DUPFD_CLOEXEC 0x40000000
173/* Witness variable: 1 if gnulib defined F_DUPFD_CLOEXEC, 0 otherwise. */
174# define GNULIB_defined_F_DUPFD_CLOEXEC 1
175#else
176# define GNULIB_defined_F_DUPFD_CLOEXEC 0
177#endif
178
179#ifndef F_DUPFD
180# define F_DUPFD 1
181#endif
182
183#ifndef F_GETFD
184# define F_GETFD 2
185#endif
186
187/* Fix up the O_* macros. */
188
189#if !defined O_DIRECT && defined O_DIRECTIO
190/* Tru64 spells it 'O_DIRECTIO'. */
191# define O_DIRECT O_DIRECTIO
192#endif
193
194#if !defined O_CLOEXEC && defined O_NOINHERIT
195/* Mingw spells it 'O_NOINHERIT'. */
196# define O_CLOEXEC O_NOINHERIT
197#endif
198
199#ifndef O_CLOEXEC
200# define O_CLOEXEC 0
201#endif
202
203#ifndef O_DIRECT
204# define O_DIRECT 0
205#endif
206
207#ifndef O_DIRECTORY
208# define O_DIRECTORY 0
209#endif
210
211#ifndef O_DSYNC
212# define O_DSYNC 0
213#endif
214
215#ifndef O_EXEC
216# define O_EXEC O_RDONLY /* This is often close enough in older systems. */
217#endif
218
219#ifndef O_IGNORE_CTTY
220# define O_IGNORE_CTTY 0
221#endif
222
223#ifndef O_NDELAY
224# define O_NDELAY 0
225#endif
226
227#ifndef O_NOATIME
228# define O_NOATIME 0
229#endif
230
231#ifndef O_NONBLOCK
232# define O_NONBLOCK O_NDELAY
233#endif
234
235/* If the gnulib module 'nonblocking' is in use, guarantee a working non-zero
236 value of O_NONBLOCK. Otherwise, O_NONBLOCK is defined (above) to O_NDELAY
237 or to 0 as fallback. */
238#if @GNULIB_NONBLOCKING@
239# if O_NONBLOCK
240# define GNULIB_defined_O_NONBLOCK 0
241# else
242# define GNULIB_defined_O_NONBLOCK 1
243# undef O_NONBLOCK
244# define O_NONBLOCK 0x40000000
245# endif
246#endif
247
248#ifndef O_NOCTTY
249# define O_NOCTTY 0
250#endif
251
252#ifndef O_NOFOLLOW
253# define O_NOFOLLOW 0
254#endif
255
256#ifndef O_NOLINK
257# define O_NOLINK 0
258#endif
259
260#ifndef O_NOLINKS
261# define O_NOLINKS 0
262#endif
263
264#ifndef O_NOTRANS
265# define O_NOTRANS 0
266#endif
267
268#ifndef O_RSYNC
269# define O_RSYNC 0
270#endif
271
272#ifndef O_SEARCH
273# define O_SEARCH O_RDONLY /* This is often close enough in older systems. */
274#endif
275
276#ifndef O_SYNC
277# define O_SYNC 0
278#endif
279
280#ifndef O_TTY_INIT
281# define O_TTY_INIT 0
282#endif
283
284#if ~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
285# undef O_ACCMODE
286# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
287#endif
288
289/* For systems that distinguish between text and binary I/O.
290 O_BINARY is usually declared in fcntl.h */
291#if !defined O_BINARY && defined _O_BINARY
292 /* For MSC-compatible compilers. */
293# define O_BINARY _O_BINARY
294# define O_TEXT _O_TEXT
295#endif
296
297#if defined __BEOS__ || defined __HAIKU__
298 /* BeOS 5 and Haiku have O_BINARY and O_TEXT, but they have no effect. */
299# undef O_BINARY
300# undef O_TEXT
301#endif
302
303#ifndef O_BINARY
304# define O_BINARY 0
305# define O_TEXT 0
306#endif
307
308/* Fix up the AT_* macros. */
309
310/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its
311 value exceeds INT_MAX, so its use as an int doesn't conform to the
312 C standard, and GCC and Sun C complain in some cases. If the bug
313 is present, undef AT_FDCWD here, so it can be redefined below. */
314#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553
315# undef AT_FDCWD
316#endif
317
318/* Use the same bit pattern as Solaris 9, but with the proper
319 signedness. The bit pattern is important, in case this actually is
320 Solaris with the above workaround. */
321#ifndef AT_FDCWD
322# define AT_FDCWD (-3041965)
323#endif
324
325/* Use the same values as Solaris 9. This shouldn't matter, but
326 there's no real reason to differ. */
327#ifndef AT_SYMLINK_NOFOLLOW
328# define AT_SYMLINK_NOFOLLOW 4096
329#endif
330
331#ifndef AT_REMOVEDIR
332# define AT_REMOVEDIR 1
333#endif
334
335/* Solaris 9 lacks these two, so just pick unique values. */
336#ifndef AT_SYMLINK_FOLLOW
337# define AT_SYMLINK_FOLLOW 2
338#endif
339
340#ifndef AT_EACCESS
341# define AT_EACCESS 4
342#endif
343
344
345#endif /* _@GUARD_PREFIX@_FCNTL_H */
346#endif /* _@GUARD_PREFIX@_FCNTL_H */
347#endif
diff --git a/lib/getgroups.c b/lib/getgroups.c
new file mode 100644
index 00000000000..f9d36236afe
--- /dev/null
+++ b/lib/getgroups.c
@@ -0,0 +1,116 @@
1/* provide consistent interface to getgroups for systems that don't allow N==0
2
3 Copyright (C) 1996, 1999, 2003, 2006-2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* written by Jim Meyering */
19
20#include <config.h>
21
22#include <unistd.h>
23
24#include <errno.h>
25#include <stdlib.h>
26#include <stdint.h>
27
28#if !HAVE_GETGROUPS
29
30/* Provide a stub that fails with ENOSYS, since there is no group
31 information available on mingw. */
32int
33getgroups (int n _GL_UNUSED, GETGROUPS_T *groups _GL_UNUSED)
34{
35 errno = ENOSYS;
36 return -1;
37}
38
39#else /* HAVE_GETGROUPS */
40
41# undef getgroups
42# ifndef GETGROUPS_ZERO_BUG
43# define GETGROUPS_ZERO_BUG 0
44# endif
45
46/* On at least Ultrix 4.3 and NextStep 3.2, getgroups (0, NULL) always
47 fails. On other systems, it returns the number of supplemental
48 groups for the process. This function handles that special case
49 and lets the system-provided function handle all others. However,
50 it can fail with ENOMEM if memory is tight. It is unspecified
51 whether the effective group id is included in the list. */
52
53int
54rpl_getgroups (int n, gid_t *group)
55{
56 int n_groups;
57 GETGROUPS_T *gbuf;
58 int saved_errno;
59
60 if (n < 0)
61 {
62 errno = EINVAL;
63 return -1;
64 }
65
66 if (n != 0 || !GETGROUPS_ZERO_BUG)
67 {
68 int result;
69 if (sizeof *group == sizeof *gbuf)
70 return getgroups (n, (GETGROUPS_T *) group);
71
72 if (SIZE_MAX / sizeof *gbuf <= n)
73 {
74 errno = ENOMEM;
75 return -1;
76 }
77 gbuf = malloc (n * sizeof *gbuf);
78 if (!gbuf)
79 return -1;
80 result = getgroups (n, gbuf);
81 if (0 <= result)
82 {
83 n = result;
84 while (n--)
85 group[n] = gbuf[n];
86 }
87 saved_errno = errno;
88 free (gbuf);
89 errno == saved_errno;
90 return result;
91 }
92
93 n = 20;
94 while (1)
95 {
96 /* No need to worry about address arithmetic overflow here,
97 since the ancient systems that we're running on have low
98 limits on the number of secondary groups. */
99 gbuf = malloc (n * sizeof *gbuf);
100 if (!gbuf)
101 return -1;
102 n_groups = getgroups (n, gbuf);
103 if (n_groups == -1 ? errno != EINVAL : n_groups < n)
104 break;
105 free (gbuf);
106 n *= 2;
107 }
108
109 saved_errno = errno;
110 free (gbuf);
111 errno = saved_errno;
112
113 return n_groups;
114}
115
116#endif /* HAVE_GETGROUPS */
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 324e5cb78fd..f74c46ae9c8 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# 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 close-stream 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 24# 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 close-stream 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
25 25
26 26
27MOSTLYCLEANFILES += core *.stackdump 27MOSTLYCLEANFILES += core *.stackdump
@@ -158,6 +158,17 @@ EXTRA_libgnu_a_SOURCES += dup2.c
158 158
159## end gnulib module dup2 159## end gnulib module dup2
160 160
161## begin gnulib module euidaccess
162
163if gl_GNULIB_ENABLED_euidaccess
164
165endif
166EXTRA_DIST += euidaccess.c
167
168EXTRA_libgnu_a_SOURCES += euidaccess.c
169
170## end gnulib module euidaccess
171
161## begin gnulib module execinfo 172## begin gnulib module execinfo
162 173
163BUILT_SOURCES += $(EXECINFO_H) 174BUILT_SOURCES += $(EXECINFO_H)
@@ -183,6 +194,50 @@ EXTRA_libgnu_a_SOURCES += execinfo.c
183 194
184## end gnulib module execinfo 195## end gnulib module execinfo
185 196
197## begin gnulib module faccessat
198
199
200EXTRA_DIST += at-func.c faccessat.c
201
202EXTRA_libgnu_a_SOURCES += at-func.c faccessat.c
203
204## end gnulib module faccessat
205
206## begin gnulib module fcntl-h
207
208BUILT_SOURCES += fcntl.h
209
210# We need the following in order to create <fcntl.h> when the system
211# doesn't have one that works with the given compiler.
212fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
213 $(AM_V_GEN)rm -f $@-t $@ && \
214 { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
215 sed -e 's|@''GUARD_PREFIX''@|GL|g' \
216 -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
217 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
218 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
219 -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \
220 -e 's/@''GNULIB_FCNTL''@/$(GNULIB_FCNTL)/g' \
221 -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
222 -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
223 -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
224 -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
225 -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
226 -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \
227 -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \
228 -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \
229 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
230 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
231 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
232 < $(srcdir)/fcntl.in.h; \
233 } > $@-t && \
234 mv $@-t $@
235MOSTLYCLEANFILES += fcntl.h fcntl.h-t
236
237EXTRA_DIST += fcntl.in.h
238
239## end gnulib module fcntl-h
240
186## begin gnulib module filemode 241## begin gnulib module filemode
187 242
188libgnu_a_SOURCES += filemode.c 243libgnu_a_SOURCES += filemode.c
@@ -200,6 +255,17 @@ EXTRA_libgnu_a_SOURCES += fpending.c
200 255
201## end gnulib module fpending 256## end gnulib module fpending
202 257
258## begin gnulib module getgroups
259
260if gl_GNULIB_ENABLED_getgroups
261
262endif
263EXTRA_DIST += getgroups.c
264
265EXTRA_libgnu_a_SOURCES += getgroups.c
266
267## end gnulib module getgroups
268
203## begin gnulib module getloadavg 269## begin gnulib module getloadavg
204 270
205 271
@@ -259,6 +325,17 @@ EXTRA_libgnu_a_SOURCES += gettimeofday.c
259 325
260## end gnulib module gettimeofday 326## end gnulib module gettimeofday
261 327
328## begin gnulib module group-member
329
330if gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1
331
332endif
333EXTRA_DIST += group-member.c
334
335EXTRA_libgnu_a_SOURCES += group-member.c
336
337## end gnulib module group-member
338
262## begin gnulib module ignore-value 339## begin gnulib module ignore-value
263 340
264 341
@@ -371,6 +448,15 @@ EXTRA_libgnu_a_SOURCES += readlink.c
371 448
372## end gnulib module readlink 449## end gnulib module readlink
373 450
451## begin gnulib module root-uid
452
453if gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c
454
455endif
456EXTRA_DIST += root-uid.h
457
458## end gnulib module root-uid
459
374## begin gnulib module signal-h 460## begin gnulib module signal-h
375 461
376BUILT_SOURCES += signal.h 462BUILT_SOURCES += signal.h
@@ -1329,6 +1415,15 @@ EXTRA_DIST += verify.h
1329 1415
1330## end gnulib module verify 1416## end gnulib module verify
1331 1417
1418## begin gnulib module xalloc-oversized
1419
1420if gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec
1421
1422endif
1423EXTRA_DIST += xalloc-oversized.h
1424
1425## end gnulib module xalloc-oversized
1426
1332 1427
1333mostlyclean-local: mostlyclean-generic 1428mostlyclean-local: mostlyclean-generic
1334 @for dir in '' $(MOSTLYCLEANDIRS); do \ 1429 @for dir in '' $(MOSTLYCLEANDIRS); do \
diff --git a/lib/group-member.c b/lib/group-member.c
new file mode 100644
index 00000000000..5fcc7e01d0c
--- /dev/null
+++ b/lib/group-member.c
@@ -0,0 +1,119 @@
1/* group-member.c -- determine whether group id is in calling user's group list
2
3 Copyright (C) 1994, 1997-1998, 2003, 2005-2006, 2009-2012 Free Software
4 Foundation, Inc.
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include <config.h>
20
21/* Specification. */
22#include <unistd.h>
23
24#include <stdio.h>
25#include <sys/types.h>
26#include <stdlib.h>
27
28#include "xalloc-oversized.h"
29
30/* Most processes have no more than this many groups, and for these
31 processes we can avoid using malloc. */
32enum { GROUPBUF_SIZE = 100 };
33
34struct group_info
35 {
36 gid_t *group;
37 gid_t groupbuf[GROUPBUF_SIZE];
38 };
39
40static void
41free_group_info (struct group_info const *g)
42{
43 if (g->group != g->groupbuf)
44 free (g->group);
45}
46
47static int
48get_group_info (struct group_info *gi)
49{
50 int n_groups = getgroups (GROUPBUF_SIZE, gi->groupbuf);
51 gi->group = gi->groupbuf;
52
53 if (n_groups < 0)
54 {
55 int n_group_slots = getgroups (0, NULL);
56 if (0 <= n_group_slots
57 && ! xalloc_oversized (n_group_slots, sizeof *gi->group))
58 {
59 gi->group = malloc (n_group_slots * sizeof *gi->group);
60 if (gi->group)
61 n_groups = getgroups (n_group_slots, gi->group);
62 }
63 }
64
65 /* In case of error, the user loses. */
66 return n_groups;
67}
68
69/* Return non-zero if GID is one that we have in our groups list.
70 Note that the groups list is not guaranteed to contain the current
71 or effective group ID, so they should generally be checked
72 separately. */
73
74int
75group_member (gid_t gid)
76{
77 int i;
78 int found;
79 struct group_info gi;
80 int n_groups = get_group_info (&gi);
81
82 /* Search through the list looking for GID. */
83 found = 0;
84 for (i = 0; i < n_groups; i++)
85 {
86 if (gid == gi.group[i])
87 {
88 found = 1;
89 break;
90 }
91 }
92
93 free_group_info (&gi);
94
95 return found;
96}
97
98#ifdef TEST
99
100char *program_name;
101
102int
103main (int argc, char **argv)
104{
105 int i;
106
107 program_name = argv[0];
108
109 for (i = 1; i < argc; i++)
110 {
111 gid_t gid;
112
113 gid = atoi (argv[i]);
114 printf ("%d: %s\n", gid, group_member (gid) ? "yes" : "no");
115 }
116 exit (0);
117}
118
119#endif /* TEST */
diff --git a/lib/root-uid.h b/lib/root-uid.h
new file mode 100644
index 00000000000..2379773c291
--- /dev/null
+++ b/lib/root-uid.h
@@ -0,0 +1,30 @@
1/* The user ID that always has appropriate privileges in the POSIX sense.
2
3 Copyright 2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 Written by Paul Eggert. */
19
20#ifndef ROOT_UID_H_
21#define ROOT_UID_H_
22
23/* The user ID that always has appropriate privileges in the POSIX sense. */
24#ifdef __TANDEM
25# define ROOT_UID 65535
26#else
27# define ROOT_UID 0
28#endif
29
30#endif
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
new file mode 100644
index 00000000000..ad777d8dd79
--- /dev/null
+++ b/lib/xalloc-oversized.h
@@ -0,0 +1,38 @@
1/* xalloc-oversized.h -- memory allocation size checking
2
3 Copyright (C) 1990-2000, 2003-2004, 2006-2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#ifndef XALLOC_OVERSIZED_H_
19# define XALLOC_OVERSIZED_H_
20
21# include <stddef.h>
22
23/* Return 1 if an array of N objects, each of size S, cannot exist due
24 to size arithmetic overflow. S must be positive and N must be
25 nonnegative. This is a macro, not a function, so that it
26 works correctly even when SIZE_MAX < N.
27
28 By gnulib convention, SIZE_MAX represents overflow in size
29 calculations, so the conservative dividend to use here is
30 SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
31 However, malloc (SIZE_MAX) fails on all known hosts where
32 sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
33 exactly-SIZE_MAX allocations on such hosts; this avoids a test and
34 branch when S is known to be 1. */
35# define xalloc_oversized(n, s) \
36 ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
37
38#endif /* !XALLOC_OVERSIZED_H_ */
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index fc69b8643b6..99bfabb8115 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,60 @@
12012-11-14 Dmitry Gutov <dgutov@yandex.ru>
2
3 * progmodes/ruby-mode.el (ruby-expr-beg): Make heredoc detection
4 more strict. Add docstring.
5 (ruby-expression-expansion-re): Extract from
6 `ruby-match-expression-expansion'.
7 (ruby-syntax-propertize-function): After everything else, search
8 for expansions in string literals, mark their insides as
9 whitespace syntax and save match data for font-lock.
10 (ruby-font-lock-keywords): Use the 2nd group from expression
11 expansion matches.
12 (ruby-match-expression-expansion): Use the match data saved to the
13 text property in ruby-syntax-propertize-function.
14
152012-11-14 Stefan Monnier <monnier@iro.umontreal.ca>
16
17 * emacs-lisp/gv.el (setf): Fix debug spec for multiple assignments
18 (bug#12879).
19
202012-11-13 Dmitry Gutov <dgutov@yandex.ru>
21
22 * progmodes/ruby-mode.el (ruby-move-to-block): Looks for a block
23 start/end keyword a bit harder. Works with different values of N.
24 Add more comments.
25 (ruby-end-of-block): Update accordingly.
26
272012-11-13 Stefan Monnier <monnier@iro.umontreal.ca>
28
29 * woman.el (woman-file-name): Don't mess with unread-command-events
30 (bug#12861).
31
32 * emacs-lisp/advice.el: Layer on top of nadvice.el.
33 Remove out of date self-require hack.
34 (ad-do-advised-functions): Use simple `dolist'.
35 (ad-advice-name, ad-advice-protected, ad-advice-enabled)
36 (ad-advice-definition): Redefine as functions.
37 (ad-advice-classes): Move before first use.
38 (ad-make-origname, ad-set-orig-definition, ad-clear-orig-definition)
39 (ad-make-mapped-call, ad-make-advised-docstring,ad-make-plain-docstring)
40 (ad--defalias-fset): Remove functions.
41 (ad-make-advicefunname, ad-clear-advicefunname-definition): New funs.
42 (ad-get-orig-definition): Rewrite.
43 (ad-make-advised-definition-docstring): Change base docstring.
44 (ad-real-orig-definition): Rewrite.
45 (ad-map-arglists): Change name of called function.
46 (ad--make-advised-docstring): Redirect `function' from ad-Advice-...
47 (ad-make-advised-definition): Simplify.
48 (ad-assemble-advised-definition): Tweak for new calling context.
49 (ad-activate-advised-definition): Setup ad-Advice-* i.s.o ad-Orig-*.
50 (ad--defalias-fset): Rename from ad-handle-definition. Make it set the
51 function and call ad-activate if needed.
52 (ad-activate, ad-deactivate): Don't call ad-handle-definition any more.
53 (ad-recover): Clear ad-Advice-* instead of ad-Orig-*.
54 (ad-compile-function): Compile ad-Advice-*.
55 (ad-activate-on-top-level, ad-with-auto-activation-disabled): Remove.
56 (ad-start-advice, ad-stop-advice): Remove.
57
12012-11-13 Dmitry Gutov <dgutov@yandex.ru> 582012-11-13 Dmitry Gutov <dgutov@yandex.ru>
2 59
3 * progmodes/ruby-mode.el (ruby-add-log-current-method): Print the 60 * progmodes/ruby-mode.el (ruby-add-log-current-method): Print the
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index ecaf6861a6c..f9b4491e6e0 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -47,14 +47,12 @@
47;; @ Highlights: 47;; @ Highlights:
48;; ============= 48;; =============
49;; - Clean definition of multiple, named before/around/after advices 49;; - Clean definition of multiple, named before/around/after advices
50;; for functions, macros, subrs and special forms 50;; for functions and macros.
51;; - Full control over the arguments an advised function will receive, 51;; - Full control over the arguments an advised function will receive,
52;; the binding environment in which it will be executed, as well as the 52;; the binding environment in which it will be executed, as well as the
53;; value it will return. 53;; value it will return.
54;; - Allows re/definition of interactive behavior for functions and subrs 54;; - Allows re/definition of interactive behavior for commands.
55;; - Every piece of advice can have its documentation string which will be 55;; - Every piece of advice can have its documentation string.
56;; combined with the original documentation of the advised function at
57;; call-time of `documentation' for proper command-key substitution.
58;; - The execution of every piece of advice can be protected against error 56;; - The execution of every piece of advice can be protected against error
59;; and non-local exits in preceding code or advices. 57;; and non-local exits in preceding code or advices.
60;; - Simple argument access either by name, or, more portable but as 58;; - Simple argument access either by name, or, more portable but as
@@ -63,7 +61,7 @@
63;; version of a function. 61;; version of a function.
64;; - Advised functions can be byte-compiled either at file-compile time 62;; - Advised functions can be byte-compiled either at file-compile time
65;; (see preactivation) or activation time. 63;; (see preactivation) or activation time.
66;; - Separation of advice definition and activation 64;; - Separation of advice definition and activation.
67;; - Forward advice is possible, that is 65;; - Forward advice is possible, that is
68;; as yet undefined or autoload functions can be advised without having to 66;; as yet undefined or autoload functions can be advised without having to
69;; preload the file in which they are defined. 67;; preload the file in which they are defined.
@@ -77,7 +75,7 @@
77;; - En/disablement mechanism allows the use of different "views" of advised 75;; - En/disablement mechanism allows the use of different "views" of advised
78;; functions depending on what pieces of advice are currently en/disabled 76;; functions depending on what pieces of advice are currently en/disabled
79;; - Provides manipulation mechanisms for sets of advised functions via 77;; - Provides manipulation mechanisms for sets of advised functions via
80;; regular expressions that match advice names 78;; regular expressions that match advice names.
81 79
82;; @ Overview, or how to read this file: 80;; @ Overview, or how to read this file:
83;; ===================================== 81;; =====================================
@@ -113,23 +111,12 @@
113;; others come from the various Lisp advice mechanisms I've come across 111;; others come from the various Lisp advice mechanisms I've come across
114;; so far, and a few are simply mine. 112;; so far, and a few are simply mine.
115 113
116;; @ Comments, suggestions, bug reports:
117;; =====================================
118;; If you find any bugs, have suggestions for new advice features, find the
119;; documentation wrong, confusing, incomplete, or otherwise unsatisfactory,
120;; have any questions about Advice, or have otherwise enlightening
121;; comments feel free to send me email at <hans@cs.buffalo.edu>.
122
123;; @ Safety Rules and Emergency Exits: 114;; @ Safety Rules and Emergency Exits:
124;; =================================== 115;; ===================================
125;; Before we begin: CAUTION!! 116;; Before we begin: CAUTION!!
126;; Advice provides you with a lot of rope to hang yourself on very 117;; Advice provides you with a lot of rope to hang yourself on very
127;; easily accessible trees, so, here are a few important things you 118;; easily accessible trees, so, here are a few important things you
128;; should know: Once Advice has been started with `ad-start-advice' 119;; should know:
129;; (which happens automatically when you load this file), it
130;; generates an advised definition of the `documentation' function, and
131;; it will enable automatic advice activation when functions get defined.
132;; All of this can be undone at any time with `M-x ad-stop-advice'.
133;; 120;;
134;; If you experience any strange behavior/errors etc. that you attribute to 121;; If you experience any strange behavior/errors etc. that you attribute to
135;; Advice or to some ill-advised function do one of the following: 122;; Advice or to some ill-advised function do one of the following:
@@ -137,45 +124,37 @@
137;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what 124;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what
138;; function gives you problems) 125;; function gives you problems)
139;; - M-x ad-deactivate-all (if you don't have a clue what's going wrong) 126;; - M-x ad-deactivate-all (if you don't have a clue what's going wrong)
140;; - M-x ad-stop-advice (if you think the problem is related to the
141;; advised functions used by Advice itself)
142;; - M-x ad-recover-normality (for real emergencies) 127;; - M-x ad-recover-normality (for real emergencies)
143;; - If none of the above solves your Advice-related problem go to another 128;; - If none of the above solves your Advice-related problem go to another
144;; terminal, kill your Emacs process and send me some hate mail. 129;; terminal, kill your Emacs process and send me some hate mail.
145 130
146;; The first three measures have restarts, i.e., once you've figured out 131;; The first two measures have restarts, i.e., once you've figured out
147;; the problem you can reactivate advised functions with either `ad-activate', 132;; the problem you can reactivate advised functions with either `ad-activate',
148;; `ad-activate-all', or `ad-start-advice'. `ad-recover-normality' unadvises 133;; or `ad-activate-all'. `ad-recover-normality' unadvises
149;; everything so you won't be able to reactivate any advised functions, you'll 134;; everything so you won't be able to reactivate any advised functions, you'll
150;; have to stick with their standard incarnations for the rest of the session. 135;; have to stick with their standard incarnations for the rest of the session.
151 136
152;; IMPORTANT: With Advice loaded always do `M-x ad-deactivate-all' before
153;; you byte-compile a file, because advised special forms and macros can lead
154;; to unwanted compilation results. When you are done compiling use
155;; `M-x ad-activate-all' to go back to the advised state of all your
156;; advised functions.
157
158;; RELAX: Advice is pretty safe even if you are oblivious to the above. 137;; RELAX: Advice is pretty safe even if you are oblivious to the above.
159;; I use it extensively and haven't run into any serious trouble in a long 138;; I use it extensively and haven't run into any serious trouble in a long
160;; time. Just wanted you to be warned. 139;; time. Just wanted you to be warned.
161 140
162;; @ Customization: 141;; @ Customization:
163;; ================ 142;; ================
164 143
165;; Look at the documentation of `ad-redefinition-action' for possible values 144;; Look at the documentation of `ad-redefinition-action' for possible values
166;; of this variable. Its default value is `warn' which will print a warning 145;; of this variable. Its default value is `warn' which will print a warning
167;; message when an already defined advised function gets redefined with a 146;; message when an already defined advised function gets redefined with a
168;; new original definition and de/activated. 147;; new original definition and de/activated.
169 148
170;; Look at the documentation of `ad-default-compilation-action' for possible 149;; Look at the documentation of `ad-default-compilation-action' for possible
171;; values of this variable. Its default value is `maybe' which will compile 150;; values of this variable. Its default value is `maybe' which will compile
172;; advised definitions during activation in case the byte-compiler is already 151;; advised definitions during activation in case the byte-compiler is already
173;; loaded. Otherwise, it will leave them uncompiled. 152;; loaded. Otherwise, it will leave them uncompiled.
174 153
175;; @ Motivation: 154;; @ Motivation:
176;; ============= 155;; =============
177;; Before I go on explaining how advice works, here are four simple examples 156;; Before I go on explaining how advice works, here are four simple examples
178;; how this package can be used. The first three are very useful, the last one 157;; how this package can be used. The first three are very useful, the last one
179;; is just a joke: 158;; is just a joke:
180 159
181;;(defadvice switch-to-buffer (before existing-buffers-only activate) 160;;(defadvice switch-to-buffer (before existing-buffers-only activate)
@@ -206,13 +185,12 @@
206 185
207;; @ Advice documentation: 186;; @ Advice documentation:
208;; ======================= 187;; =======================
209;; Below is general documentation of the various features of advice. For more 188;; Below is general documentation of the various features of advice. For more
210;; concrete examples check the corresponding sections in the tutorial part. 189;; concrete examples check the corresponding sections in the tutorial part.
211 190
212;; @@ Terminology: 191;; @@ Terminology:
213;; =============== 192;; ===============
214;; - Emacs: Emacs as released by the GNU Project 193;; - Emacs: Emacs as released by the GNU Project
215;; - jwz: Jamie Zawinski - creator of the byte-compiler used in v19s.
216;; - Advice: The name of this package. 194;; - Advice: The name of this package.
217;; - advices: Short for "pieces of advice". 195;; - advices: Short for "pieces of advice".
218 196
@@ -236,22 +214,22 @@
236;; <name> is the name of the advice which has to be a non-nil symbol. 214;; <name> is the name of the advice which has to be a non-nil symbol.
237;; Names uniquely identify a piece of advice in a certain advice class, 215;; Names uniquely identify a piece of advice in a certain advice class,
238;; hence, advices can be redefined by defining an advice with the same class 216;; hence, advices can be redefined by defining an advice with the same class
239;; and name. Advice names are global symbols, hence, the same name space 217;; and name. Advice names are global symbols, hence, the same name space
240;; conventions used for function names should be applied. 218;; conventions used for function names should be applied.
241 219
242;; An optional <position> specifies where in the current list of advices of 220;; An optional <position> specifies where in the current list of advices of
243;; the specified <class> this new advice will be placed. <position> has to 221;; the specified <class> this new advice will be placed. <position> has to
244;; be either `first', `last' or a number that specifies a zero-based 222;; be either `first', `last' or a number that specifies a zero-based
245;; position (`first' is equivalent to 0). If no position is specified 223;; position (`first' is equivalent to 0). If no position is specified
246;; `first' will be used as a default. If this call to `defadvice' redefines 224;; `first' will be used as a default. If this call to `defadvice' redefines
247;; an already existing advice (see above) then the position argument will 225;; an already existing advice (see above) then the position argument will
248;; be ignored and the position of the already existing advice will be used. 226;; be ignored and the position of the already existing advice will be used.
249 227
250;; An optional <arglist> which has to be a list can be used to define the 228;; An optional <arglist> which has to be a list can be used to define the
251;; argument list of the advised function. This argument list should of 229;; argument list of the advised function. This argument list should of
252;; course be compatible with the argument list of the original function, 230;; course be compatible with the argument list of the original function,
253;; otherwise functions that call the advised function with the original 231;; otherwise functions that call the advised function with the original
254;; argument list in mind will break. If more than one advice specify an 232;; argument list in mind will break. If more than one advice specify an
255;; argument list then the first one (the one with the smallest position) 233;; argument list then the first one (the one with the smallest position)
256;; found in the list of before/around/after advices will be used. 234;; found in the list of before/around/after advices will be used.
257 235
@@ -267,10 +245,10 @@
267;; `disable': Specifies that the defined advice should be disabled, hence, 245;; `disable': Specifies that the defined advice should be disabled, hence,
268;; it will not be used in an activation until somebody enables it. 246;; it will not be used in an activation until somebody enables it.
269;; `preactivate': Specifies that the advised function should get preactivated 247;; `preactivate': Specifies that the advised function should get preactivated
270;; at macro-expansion/compile time of this `defadvice'. This 248;; at macro-expansion/compile time of this `defadvice'. This
271;; generates a compiled advised definition according to the 249;; generates a compiled advised definition according to the
272;; current advice state which will be used during activation 250;; current advice state which will be used during activation
273;; if appropriate. Only use this if the `defadvice' gets 251;; if appropriate. Only use this if the `defadvice' gets
274;; actually compiled. 252;; actually compiled.
275 253
276;; An optional <documentation-string> can be supplied to document the advice. 254;; An optional <documentation-string> can be supplied to document the advice.
@@ -278,20 +256,20 @@
278;; documentation strings of the original function and other advices. 256;; documentation strings of the original function and other advices.
279 257
280;; An optional <interactive-form> form can be supplied to change/add 258;; An optional <interactive-form> form can be supplied to change/add
281;; interactive behavior of the original function. If more than one advice 259;; interactive behavior of the original function. If more than one advice
282;; has an `(interactive ...)' specification then the first one (the one 260;; has an `(interactive ...)' specification then the first one (the one
283;; with the smallest position) found in the list of before/around/after 261;; with the smallest position) found in the list of before/around/after
284;; advices will be used. 262;; advices will be used.
285 263
286;; A possibly empty list of <body-forms> specifies the body of the advice in 264;; A possibly empty list of <body-forms> specifies the body of the advice in
287;; an implicit progn. The body of an advice can access/change arguments, 265;; an implicit progn. The body of an advice can access/change arguments,
288;; the return value, the binding environment, and can have all sorts of 266;; the return value, the binding environment, and can have all sorts of
289;; other side effects. 267;; other side effects.
290 268
291;; @@ Assembling advised definitions: 269;; @@ Assembling advised definitions:
292;; ================================== 270;; ==================================
293;; Suppose a function/macro/subr/special-form has N pieces of before advice, 271;; Suppose a function/macro/subr/special-form has N pieces of before advice,
294;; M pieces of around advice and K pieces of after advice. Assuming none of 272;; M pieces of around advice and K pieces of after advice. Assuming none of
295;; the advices is protected, its advised definition will look like this 273;; the advices is protected, its advised definition will look like this
296;; (body-form indices correspond to the position of the respective advice in 274;; (body-form indices correspond to the position of the respective advice in
297;; that advice class): 275;; that advice class):
@@ -330,11 +308,11 @@
330;; be expanded into a proper documentation string upon call of `documentation'. 308;; be expanded into a proper documentation string upon call of `documentation'.
331 309
332;; (interactive ...) is an optional interactive form either taken from the 310;; (interactive ...) is an optional interactive form either taken from the
333;; original function or from a before/around/after advice. For advised 311;; original function or from a before/around/after advice. For advised
334;; interactive subrs that do not have an interactive form specified in any 312;; interactive subrs that do not have an interactive form specified in any
335;; advice we have to use (interactive) and then call the subr interactively 313;; advice we have to use (interactive) and then call the subr interactively
336;; if the advised function was called interactively, because the 314;; if the advised function was called interactively, because the
337;; interactive specification of subrs is not accessible. This is the only 315;; interactive specification of subrs is not accessible. This is the only
338;; case where changing the values of arguments will not have an affect 316;; case where changing the values of arguments will not have an affect
339;; because they will be reset by the interactive specification of the subr. 317;; because they will be reset by the interactive specification of the subr.
340;; If this is a problem one can always specify an interactive form in a 318;; If this is a problem one can always specify an interactive form in a
@@ -343,45 +321,44 @@
343;; 321;;
344;; Then the body forms of the various advices in the various classes of advice 322;; Then the body forms of the various advices in the various classes of advice
345;; are assembled in order. The forms of around advice L are normally part of 323;; are assembled in order. The forms of around advice L are normally part of
346;; one of the forms of around advice L-1. An around advice can specify where 324;; one of the forms of around advice L-1. An around advice can specify where
347;; the forms of the wrapped or surrounded forms should go with the special 325;; the forms of the wrapped or surrounded forms should go with the special
348;; keyword `ad-do-it', which will be substituted with a `progn' containing the 326;; keyword `ad-do-it', which will run the forms of the surrounded code.
349;; forms of the surrounded code.
350 327
351;; The innermost part of the around advice onion is 328;; The innermost part of the around advice onion is
352;; <apply original definition to <arglist>> 329;; <apply original definition to <arglist>>
353;; whose form depends on the type of the original function. The variable 330;; whose form depends on the type of the original function. The variable
354;; `ad-return-value' will be set to its result. This variable is visible to 331;; `ad-return-value' will be set to its result. This variable is visible to
355;; all pieces of advice which can access and modify it before it gets returned. 332;; all pieces of advice which can access and modify it before it gets returned.
356;; 333;;
357;; The semantic structure of advised functions that contain protected pieces 334;; The semantic structure of advised functions that contain protected pieces
358;; of advice is the same. The only difference is that `unwind-protect' forms 335;; of advice is the same. The only difference is that `unwind-protect' forms
359;; make sure that the protected advice gets executed even if some previous 336;; make sure that the protected advice gets executed even if some previous
360;; piece of advice had an error or a non-local exit. If any around advice is 337;; piece of advice had an error or a non-local exit. If any around advice is
361;; protected then the whole around advice onion will be protected. 338;; protected then the whole around advice onion will be protected.
362 339
363;; @@ Argument access in advised functions: 340;; @@ Argument access in advised functions:
364;; ======================================== 341;; ========================================
365;; As already mentioned, the simplest way to access the arguments of an 342;; As already mentioned, the simplest way to access the arguments of an
366;; advised function in the body of an advice is to refer to them by name. To 343;; advised function in the body of an advice is to refer to them by name.
367;; do that, the advice programmer needs to know either the names of the 344;; To do that, the advice programmer needs to know either the names of the
368;; argument variables of the original function, or the names used in the 345;; argument variables of the original function, or the names used in the
369;; argument list redefinition given in a piece of advice. While this simple 346;; argument list redefinition given in a piece of advice. While this simple
370;; method might be sufficient in many cases, it has the disadvantage that it 347;; method might be sufficient in many cases, it has the disadvantage that it
371;; is not very portable because it hardcodes the argument names into the 348;; is not very portable because it hardcodes the argument names into the
372;; advice. If the definition of the original function changes the advice 349;; advice. If the definition of the original function changes the advice
373;; might break even though the code might still be correct. Situations like 350;; might break even though the code might still be correct. Situations like
374;; that arise, for example, if one advises a subr like `eval-region' which 351;; that arise, for example, if one advises a subr like `eval-region' which
375;; gets redefined in a non-advice style into a function by the edebug 352;; gets redefined in a non-advice style into a function by the edebug
376;; package. If the advice assumes `eval-region' to be a subr it might break 353;; package. If the advice assumes `eval-region' to be a subr it might break
377;; once edebug is loaded. Similar situations arise when one wants to use the 354;; once edebug is loaded. Similar situations arise when one wants to use the
378;; same piece of advice across different versions of Emacs. 355;; same piece of advice across different versions of Emacs.
379 356
380;; As a solution to that advice provides argument list access macros that get 357;; As a solution to that advice provides argument list access macros that get
381;; translated into the proper access forms at activation time, i.e., when the 358;; translated into the proper access forms at activation time, i.e., when the
382;; advised definition gets constructed. Access macros access actual arguments 359;; advised definition gets constructed. Access macros access actual arguments
383;; by position regardless of how these actual argument get distributed onto 360;; by position regardless of how these actual argument get distributed onto
384;; the argument variables of a function. The rational behind this is that in 361;; the argument variables of a function. The rational behind this is that in
385;; Emacs Lisp the semantics of an argument is strictly determined by its 362;; Emacs Lisp the semantics of an argument is strictly determined by its
386;; position (there are no keyword arguments). 363;; position (there are no keyword arguments).
387 364
@@ -393,9 +370,9 @@
393;; 370;;
394;; (foo 0 1 2 3 4 5 6) 371;; (foo 0 1 2 3 4 5 6)
395 372
396;; which means that X=0, Y=1, Z=2 and R=(3 4 5 6). The assumption is that 373;; which means that X=0, Y=1, Z=2 and R=(3 4 5 6). The assumption is that
397;; the semantics of an actual argument is determined by its position. It is 374;; the semantics of an actual argument is determined by its position. It is
398;; this semantics that has to be known by the advice programmer. Then s/he 375;; this semantics that has to be known by the advice programmer. Then s/he
399;; can access these arguments in a piece of advice with some of the 376;; can access these arguments in a piece of advice with some of the
400;; following macros (the arrows indicate what value they will return): 377;; following macros (the arrows indicate what value they will return):
401 378
@@ -408,17 +385,17 @@
408 385
409;; `(ad-get-arg <position>)' will return the actual argument that was supplied 386;; `(ad-get-arg <position>)' will return the actual argument that was supplied
410;; at <position>, `(ad-get-args <position>)' will return the list of actual 387;; at <position>, `(ad-get-args <position>)' will return the list of actual
411;; arguments supplied starting at <position>. Note that these macros can be 388;; arguments supplied starting at <position>. Note that these macros can be
412;; used without any knowledge about the form of the actual argument list of 389;; used without any knowledge about the form of the actual argument list of
413;; the original function. 390;; the original function.
414 391
415;; Similarly, `(ad-set-arg <position> <value-form>)' can be used to set the 392;; Similarly, `(ad-set-arg <position> <value-form>)' can be used to set the
416;; value of the actual argument at <position> to <value-form>. For example, 393;; value of the actual argument at <position> to <value-form>. For example,
417;; 394;;
418;; (ad-set-arg 5 "five") 395;; (ad-set-arg 5 "five")
419;; 396;;
420;; will have the effect that R=(3 4 "five" 6) once the original function is 397;; will have the effect that R=(3 4 "five" 6) once the original function is
421;; called. `(ad-set-args <position> <value-list-form>)' can be used to set 398;; called. `(ad-set-args <position> <value-list-form>)' can be used to set
422;; the list of actual arguments starting at <position> to <value-list-form>. 399;; the list of actual arguments starting at <position> to <value-list-form>.
423;; For example, 400;; For example,
424;; 401;;
@@ -427,7 +404,7 @@
427;; will have the effect that X=5, Y=4, Z=3 and R=(2 1 0) once the original 404;; will have the effect that X=5, Y=4, Z=3 and R=(2 1 0) once the original
428;; function is called. 405;; function is called.
429 406
430;; All these access macros are text macros rather than real Lisp macros. When 407;; All these access macros are text macros rather than real Lisp macros. When
431;; the advised definition gets constructed they get replaced with actual access 408;; the advised definition gets constructed they get replaced with actual access
432;; forms depending on the argument list of the advised function, i.e., after 409;; forms depending on the argument list of the advised function, i.e., after
433;; that argument access is in most cases as efficient as using the argument 410;; that argument access is in most cases as efficient as using the argument
@@ -437,7 +414,7 @@
437;; ======================================================= 414;; =======================================================
438;; Some functions (such as `trace-function' defined in trace.el) need a 415;; Some functions (such as `trace-function' defined in trace.el) need a
439;; method of accessing the names and bindings of the arguments of an 416;; method of accessing the names and bindings of the arguments of an
440;; arbitrary advised function. To do that within an advice one can use the 417;; arbitrary advised function. To do that within an advice one can use the
441;; special keyword `ad-arg-bindings' which is a text macro that will be 418;; special keyword `ad-arg-bindings' which is a text macro that will be
442;; substituted with a form that will evaluate to a list of binding 419;; substituted with a form that will evaluate to a list of binding
443;; specifications, one for every argument variable. These binding 420;; specifications, one for every argument variable. These binding
@@ -463,7 +440,7 @@
463;; ========================== 440;; ==========================
464;; Because `defadvice' allows the specification of the argument list 441;; Because `defadvice' allows the specification of the argument list
465;; of the advised function we need a mapping mechanism that maps this 442;; of the advised function we need a mapping mechanism that maps this
466;; argument list onto that of the original function. Hence SYM and 443;; argument list onto that of the original function. Hence SYM and
467;; NEWDEF have to be properly mapped onto the &rest variable when the 444;; NEWDEF have to be properly mapped onto the &rest variable when the
468;; original definition is called. Advice automatically takes care of 445;; original definition is called. Advice automatically takes care of
469;; that mapping, hence, the advice programmer can specify an argument 446;; that mapping, hence, the advice programmer can specify an argument
@@ -474,11 +451,10 @@
474;; @@ Activation and deactivation: 451;; @@ Activation and deactivation:
475;; =============================== 452;; ===============================
476;; The definition of an advised function does not change until all its advice 453;; The definition of an advised function does not change until all its advice
477;; gets actually activated. Activation can either happen with the `activate' 454;; gets actually activated. Activation can either happen with the `activate'
478;; flag specified in the `defadvice', with an explicit call or interactive 455;; flag specified in the `defadvice', with an explicit call or interactive
479;; invocation of `ad-activate', or if forward advice is enabled (i.e., the 456;; invocation of `ad-activate', or at the time an already advised function
480;; value of `ad-activate-on-definition' is t) at the time an already advised 457;; gets defined.
481;; function gets defined.
482 458
483;; When a function gets first activated its original definition gets saved, 459;; When a function gets first activated its original definition gets saved,
484;; all defined and enabled pieces of advice will get combined with the 460;; all defined and enabled pieces of advice will get combined with the
@@ -496,7 +472,7 @@
496;; the file that contained the `defadvice' with the `preactivate' flag. 472;; the file that contained the `defadvice' with the `preactivate' flag.
497 473
498;; `ad-deactivate' can be used to back-define an advised function to its 474;; `ad-deactivate' can be used to back-define an advised function to its
499;; original definition. It can be called interactively or directly. Because 475;; original definition. It can be called interactively or directly. Because
500;; `ad-activate' caches the advised definition the function can be 476;; `ad-activate' caches the advised definition the function can be
501;; reactivated via `ad-activate' with only minor overhead (it is checked 477;; reactivated via `ad-activate' with only minor overhead (it is checked
502;; whether the current advice state is consistent with the cached 478;; whether the current advice state is consistent with the cached
@@ -504,12 +480,12 @@
504 480
505;; `ad-activate-regexp' and `ad-deactivate-regexp' can be used to de/activate 481;; `ad-activate-regexp' and `ad-deactivate-regexp' can be used to de/activate
506;; all currently advised function that have a piece of advice with a name that 482;; all currently advised function that have a piece of advice with a name that
507;; contains a match for a regular expression. These functions can be used to 483;; contains a match for a regular expression. These functions can be used to
508;; de/activate sets of functions depending on certain advice naming 484;; de/activate sets of functions depending on certain advice naming
509;; conventions. 485;; conventions.
510 486
511;; Finally, `ad-activate-all' and `ad-deactivate-all' can be used to 487;; Finally, `ad-activate-all' and `ad-deactivate-all' can be used to
512;; de/activate all currently advised functions. These are useful to 488;; de/activate all currently advised functions. These are useful to
513;; (temporarily) return to an un/advised state. 489;; (temporarily) return to an un/advised state.
514 490
515;; @@@ Reasons for the separation of advice definition and activation: 491;; @@@ Reasons for the separation of advice definition and activation:
@@ -521,26 +497,26 @@
521 497
522;; The advantage of this is that various pieces of advice can be defined 498;; The advantage of this is that various pieces of advice can be defined
523;; before they get combined into an advised definition which avoids 499;; before they get combined into an advised definition which avoids
524;; unnecessary constructions of intermediate advised definitions. The more 500;; unnecessary constructions of intermediate advised definitions. The more
525;; important advantage is that it allows the implementation of forward advice. 501;; important advantage is that it allows the implementation of forward advice.
526;; Advice information for a certain function accumulates as the value of the 502;; Advice information for a certain function accumulates as the value of the
527;; `advice-info' property of the function symbol. This accumulation is 503;; `advice-info' property of the function symbol. This accumulation is
528;; completely independent of the fact that that function might not yet be 504;; completely independent of the fact that that function might not yet be
529;; defined. The special forms `defun' and `defmacro' have been advised to 505;; defined. The macros `defun' and `defmacro' check whether the
530;; check whether the function/macro they defined had advice information 506;; function/macro they defined had advice information
531;; associated with it. If so and forward advice is enabled, the original 507;; associated with it. If so and forward advice is enabled, the original
532;; definition will be saved, and then the advice will be activated. 508;; definition will be saved, and then the advice will be activated.
533 509
534;; @@ Enabling/disabling pieces or sets of advice: 510;; @@ Enabling/disabling pieces or sets of advice:
535;; =============================================== 511;; ===============================================
536;; A major motivation for the development of this advice package was to bring 512;; A major motivation for the development of this advice package was to bring
537;; a little bit more structure into the function overloading chaos in Emacs 513;; a little bit more structure into the function overloading chaos in Emacs
538;; Lisp. Many packages achieve some of their functionality by adding a little 514;; Lisp. Many packages achieve some of their functionality by adding a little
539;; bit (or a lot) to the standard functionality of some Emacs Lisp function. 515;; bit (or a lot) to the standard functionality of some Emacs Lisp function.
540;; ange-ftp is a very popular package that achieves its magic by overloading 516;; ange-ftp is a very popular package that used to achieve its magic by
541;; most Emacs Lisp functions that deal with files. A popular function that's 517;; overloading most Emacs Lisp functions that deal with files. A popular
542;; overloaded by many packages is `expand-file-name'. The situation that one 518;; function that's overloaded by many packages is `expand-file-name'.
543;; function is multiply overloaded can arise easily. 519;; The situation that one function is multiply overloaded can arise easily.
544 520
545;; Once in a while it would be desirable to be able to disable some/all 521;; Once in a while it would be desirable to be able to disable some/all
546;; overloads of a particular package while keeping all the rest. Ideally - 522;; overloads of a particular package while keeping all the rest. Ideally -
@@ -548,7 +524,7 @@
548;; I know I am dreaming right now... In that ideal case the enable/disable 524;; I know I am dreaming right now... In that ideal case the enable/disable
549;; mechanism of advice could be used to achieve just that. 525;; mechanism of advice could be used to achieve just that.
550 526
551;; Every piece of advice is associated with an enablement flag. When the 527;; Every piece of advice is associated with an enablement flag. When the
552;; advised definition of a particular function gets constructed (e.g., during 528;; advised definition of a particular function gets constructed (e.g., during
553;; activation) only the currently enabled pieces of advice will be considered. 529;; activation) only the currently enabled pieces of advice will be considered.
554;; This mechanism allows one to have different "views" of an advised function 530;; This mechanism allows one to have different "views" of an advised function
@@ -556,17 +532,15 @@
556 532
557;; Another motivation for this mechanism is that it allows one to define a 533;; Another motivation for this mechanism is that it allows one to define a
558;; piece of advice for some function yet keep it dormant until a certain 534;; piece of advice for some function yet keep it dormant until a certain
559;; condition is met. Until then activation of the function will not make use 535;; condition is met. Until then activation of the function will not make use
560;; of that piece of advice. Once the condition is met the advice can be 536;; of that piece of advice. Once the condition is met the advice can be
561;; enabled and a reactivation of the function will add its functionality as 537;; enabled and a reactivation of the function will add its functionality as
562;; part of the new advised definition. For example, the advices of `defun' 538;; part of the new advised definition. Hence, if somebody
563;; etc. used by advice itself will stay disabled until `ad-start-advice' is
564;; called and some variables have the proper values. Hence, if somebody
565;; else advised these functions too and activates them the advices defined 539;; else advised these functions too and activates them the advices defined
566;; by advice will get used only if they are intended to be used. 540;; by advice will get used only if they are intended to be used.
567 541
568;; The main interface to this mechanism are the interactive functions 542;; The main interface to this mechanism are the interactive functions
569;; `ad-enable-advice' and `ad-disable-advice'. For example, the following 543;; `ad-enable-advice' and `ad-disable-advice'. For example, the following
570;; would disable a particular advice of the function `foo': 544;; would disable a particular advice of the function `foo':
571;; 545;;
572;; (ad-disable-advice 'foo 'before 'my-advice) 546;; (ad-disable-advice 'foo 'before 'my-advice)
@@ -576,28 +550,28 @@
576;; 550;;
577;; (ad-activate 'foo) 551;; (ad-activate 'foo)
578;; 552;;
579;; or interactively. To disable whole sets of advices one can use a regular 553;; or interactively. To disable whole sets of advices one can use a regular
580;; expression mechanism. For example, let us assume that ange-ftp actually 554;; expression mechanism. For example, let us assume that ange-ftp actually
581;; used advice to overload all its functions, and that it used the 555;; used advice to overload all its functions, and that it used the
582;; "ange-ftp-" prefix for all its advice names, then we could temporarily 556;; "ange-ftp-" prefix for all its advice names, then we could temporarily
583;; disable all its advices with 557;; disable all its advices with
584;; 558;;
585;; (ad-disable-regexp "^ange-ftp-") 559;; (ad-disable-regexp "\\`ange-ftp-")
586;; 560;;
587;; and the following call would put that actually into effect: 561;; and the following call would put that actually into effect:
588;; 562;;
589;; (ad-activate-regexp "^ange-ftp-") 563;; (ad-activate-regexp "\\`ange-ftp-")
590;; 564;;
591;; A safer way would have been to use 565;; A safer way would have been to use
592;; 566;;
593;; (ad-update-regexp "^ange-ftp-") 567;; (ad-update-regexp "\\`ange-ftp-")
594;; 568;;
595;; instead which would have only reactivated currently actively advised 569;; instead which would have only reactivated currently actively advised
596;; functions, but not functions that were currently inactive. All these 570;; functions, but not functions that were currently inactive. All these
597;; functions can also be called interactively. 571;; functions can also be called interactively.
598 572
599;; A certain piece of advice is considered a match if its name contains a 573;; A certain piece of advice is considered a match if its name contains a
600;; match for the regular expression. To enable ange-ftp again we would use 574;; match for the regular expression. To enable ange-ftp again we would use
601;; `ad-enable-regexp' and then activate or update again. 575;; `ad-enable-regexp' and then activate or update again.
602 576
603;; @@ Forward advice, automatic advice activation: 577;; @@ Forward advice, automatic advice activation:
@@ -616,7 +590,7 @@
616;; of advice definition and activation that makes it possible to accumulate 590;; of advice definition and activation that makes it possible to accumulate
617;; advice information without having the original function already defined, 591;; advice information without having the original function already defined,
618;; 2) special versions of the built-in functions `fset/defalias' which check 592;; 2) special versions of the built-in functions `fset/defalias' which check
619;; for advice information whenever they define a function. If advice 593;; for advice information whenever they define a function. If advice
620;; information was found then the advice will immediately get activated when 594;; information was found then the advice will immediately get activated when
621;; the function gets defined. 595;; the function gets defined.
622 596
@@ -625,16 +599,11 @@
625;; file, and the function has some advice-info stored with it then that 599;; file, and the function has some advice-info stored with it then that
626;; advice will get activated right away. 600;; advice will get activated right away.
627 601
628;; @@@ Enabling automatic advice activation:
629;; =========================================
630;; Automatic advice activation is enabled by default. It can be disabled with
631;; `M-x ad-stop-advice' and enabled again with `M-x ad-start-advice'.
632
633;; @@ Caching of advised definitions: 602;; @@ Caching of advised definitions:
634;; ================================== 603;; ==================================
635;; After an advised definition got constructed it gets cached as part of the 604;; After an advised definition got constructed it gets cached as part of the
636;; advised function's advice-info so it can be reused, for example, after an 605;; advised function's advice-info so it can be reused, for example, after an
637;; intermediate deactivation. Because the advice-info of a function might 606;; intermediate deactivation. Because the advice-info of a function might
638;; change between the time of caching and reuse a cached definition gets 607;; change between the time of caching and reuse a cached definition gets
639;; a cache-id associated with it so it can be verified whether the cached 608;; a cache-id associated with it so it can be verified whether the cached
640;; definition is still valid (the main application of this is preactivation 609;; definition is still valid (the main application of this is preactivation
@@ -642,19 +611,19 @@
642 611
643;; When an advised function gets activated and a verifiable cached definition 612;; When an advised function gets activated and a verifiable cached definition
644;; is available, then that definition will be used instead of creating a new 613;; is available, then that definition will be used instead of creating a new
645;; advised definition from scratch. If you want to make sure that a new 614;; advised definition from scratch. If you want to make sure that a new
646;; definition gets constructed then you should use `ad-clear-cache' before you 615;; definition gets constructed then you should use `ad-clear-cache' before you
647;; activate the advised function. 616;; activate the advised function.
648 617
649;; @@ Preactivation: 618;; @@ Preactivation:
650;; ================= 619;; =================
651;; Constructing an advised definition is moderately expensive. In a situation 620;; Constructing an advised definition is moderately expensive. In a situation
652;; where one package defines a lot of advised functions it might be 621;; where one package defines a lot of advised functions it might be
653;; prohibitively expensive to do all the advised definition construction at 622;; prohibitively expensive to do all the advised definition construction at
654;; runtime. Preactivation is a mechanism that allows compile-time construction 623;; runtime. Preactivation is a mechanism that allows compile-time construction
655;; of compiled advised definitions that can be activated cheaply during 624;; of compiled advised definitions that can be activated cheaply during
656;; runtime. Preactivation uses the caching mechanism to do that. Here's how it 625;; runtime. Preactivation uses the caching mechanism to do that. Here's how
657;; works: 626;; it works:
658 627
659;; When the byte-compiler compiles a `defadvice' that has the `preactivate' 628;; When the byte-compiler compiles a `defadvice' that has the `preactivate'
660;; flag specified, it uses the current original definition of the advised 629;; flag specified, it uses the current original definition of the advised
@@ -665,27 +634,27 @@
665;; byte-compiler. 634;; byte-compiler.
666;; When the file with the compiled, preactivating `defadvice' gets loaded the 635;; When the file with the compiled, preactivating `defadvice' gets loaded the
667;; precompiled advised definition will be cached on the advised function's 636;; precompiled advised definition will be cached on the advised function's
668;; advice-info. When it gets activated (can be immediately on execution of the 637;; advice-info. When it gets activated (can be immediately on execution of the
669;; `defadvice' or any time later) the cache-id gets checked against the 638;; `defadvice' or any time later) the cache-id gets checked against the
670;; current state of advice and if it is verified the precompiled definition 639;; current state of advice and if it is verified the precompiled definition
671;; will be used directly (the verification is pretty cheap). If it couldn't get 640;; will be used directly (the verification is pretty cheap). If it couldn't
672;; verified a new advised definition for that function will be built from 641;; get verified a new advised definition for that function will be built from
673;; scratch, hence, the efficiency added by the preactivation mechanism does 642;; scratch, hence, the efficiency added by the preactivation mechanism does not
674;; not at all impair the flexibility of the advice mechanism. 643;; at all impair the flexibility of the advice mechanism.
675 644
676;; MORAL: In order get all the efficiency out of preactivation the advice 645;; MORAL: In order get all the efficiency out of preactivation the advice
677;; state of an advised function at the time the file with the 646;; state of an advised function at the time the file with the
678;; preactivating `defadvice' gets byte-compiled should be exactly 647;; preactivating `defadvice' gets byte-compiled should be exactly
679;; the same as it will be when the advice of that function gets 648;; the same as it will be when the advice of that function gets
680;; actually activated. If it is not there is a high chance that the 649;; actually activated. If it is not there is a high chance that the
681;; cache-id will not match and hence a new advised definition will 650;; cache-id will not match and hence a new advised definition will
682;; have to be constructed at runtime. 651;; have to be constructed at runtime.
683 652
684;; Preactivation and forward advice do not contradict each other. It is 653;; Preactivation and forward advice do not contradict each other. It is
685;; perfectly ok to load a file with a preactivating `defadvice' before the 654;; perfectly ok to load a file with a preactivating `defadvice' before the
686;; original definition of the advised function is available. The constructed 655;; original definition of the advised function is available. The constructed
687;; advised definition will be used once the original function gets defined and 656;; advised definition will be used once the original function gets defined and
688;; its advice gets activated. The only constraint is that at the time the 657;; its advice gets activated. The only constraint is that at the time the
689;; file with the preactivating `defadvice' got compiled the original function 658;; file with the preactivating `defadvice' got compiled the original function
690;; definition was available. 659;; definition was available.
691 660
@@ -697,18 +666,18 @@
697;; - `byte-compile' is part of the `features' variable even though you 666;; - `byte-compile' is part of the `features' variable even though you
698;; did not use the byte-compiler 667;; did not use the byte-compiler
699;; Right now advice does not provide an elegant way to find out whether 668;; Right now advice does not provide an elegant way to find out whether
700;; and why a preactivation failed. What you can do is to trace the 669;; and why a preactivation failed. What you can do is to trace the
701;; function `ad-cache-id-verification-code' (with the function 670;; function `ad-cache-id-verification-code' (with the function
702;; `trace-function-background' defined in my trace.el package) before 671;; `trace-function-background' defined in my trace.el package) before
703;; any of your advised functions get activated. After they got 672;; any of your advised functions get activated. After they got
704;; activated check whether all calls to `ad-cache-id-verification-code' 673;; activated check whether all calls to `ad-cache-id-verification-code'
705;; returned `verified' as a result. Other values indicate why the 674;; returned `verified' as a result. Other values indicate why the
706;; verification failed which should give you enough information to 675;; verification failed which should give you enough information to
707;; fix your preactivation/compile/load/activation sequence. 676;; fix your preactivation/compile/load/activation sequence.
708 677
709;; IMPORTANT: There is one case (that I am aware of) that can make 678;; IMPORTANT: There is one case (that I am aware of) that can make
710;; preactivation fail, i.e., a preconstructed advised definition that does 679;; preactivation fail, i.e., a preconstructed advised definition that does
711;; NOT match the current state of advice gets used nevertheless. That case 680;; NOT match the current state of advice gets used nevertheless. That case
712;; arises if one package defines a certain piece of advice which gets used 681;; arises if one package defines a certain piece of advice which gets used
713;; during preactivation, and another package incompatibly redefines that 682;; during preactivation, and another package incompatibly redefines that
714;; very advice (i.e., same function/class/name), and it is the second advice 683;; very advice (i.e., same function/class/name), and it is the second advice
@@ -720,30 +689,20 @@
720;; MORAL-II: Redefining somebody else's advice is BAAAAD (to speak with 689;; MORAL-II: Redefining somebody else's advice is BAAAAD (to speak with
721;; George Walker Bush), and why would you redefine your own advice anyway? 690;; George Walker Bush), and why would you redefine your own advice anyway?
722;; Advice is a mechanism to facilitate function redefinition, not advice 691;; Advice is a mechanism to facilitate function redefinition, not advice
723;; redefinition (wait until I write Meta-Advice :-). If you really have 692;; redefinition (wait until I write Meta-Advice :-). If you really have
724;; to undo somebody else's advice try to write a "neutralizing" advice. 693;; to undo somebody else's advice, try to write a "neutralizing" advice.
725 694
726;; @@ Advising macros and special forms and other dangerous things: 695;; @@ Advising macros and other dangerous things:
727;; ================================================================ 696;; ==============================================
728;; Look at the corresponding tutorial sections for more information on 697;; Look at the corresponding tutorial sections for more information on
729;; these topics. Here it suffices to point out that the special treatment 698;; these topics. Here it suffices to point out that the special treatment
730;; of macros and special forms by the byte-compiler can lead to problems 699;; of macros can lead to problems when they get advised. Macros can create
731;; when they get advised. Macros can create problems because they get 700;; problems because they get expanded at compile or load time, hence, they
732;; expanded at compile time, hence, they might not have all the necessary 701;; might not have all the necessary runtime support and such advice cannot be
733;; runtime support and such advice cannot be de/activated or changed as 702;; de/activated or changed as it is possible for functions.
734;; it is possible for functions. Special forms create problems because they 703;; Special forms cannot be advised.
735;; have to be advised "into" macros, i.e., an advised special form is a 704;;
736;; implemented as a macro, hence, in most cases the byte-compiler will 705;; MORAL: - Only advise macros when you are absolutely sure what you are doing.
737;; not recognize it as a special form anymore which can lead to very strange
738;; results.
739;;
740;; MORAL: - Only advise macros or special forms when you are absolutely sure
741;; what you are doing.
742;; - As a safety measure, always do `ad-deactivate-all' before you
743;; byte-compile a file to make sure that even if some inconsiderate
744;; person advised some special forms you'll get proper compilation
745;; results. After compilation do `ad-activate-all' to get back to
746;; the previous state.
747 706
748;; @@ Adding a piece of advice with `ad-add-advice': 707;; @@ Adding a piece of advice with `ad-add-advice':
749;; ================================================= 708;; =================================================
@@ -754,10 +713,10 @@
754;; @@ Activation/deactivation advices, file load hooks: 713;; @@ Activation/deactivation advices, file load hooks:
755;; ==================================================== 714;; ====================================================
756;; There are two special classes of advice called `activation' and 715;; There are two special classes of advice called `activation' and
757;; `deactivation'. The body forms of these advices are not included into the 716;; `deactivation'. The body forms of these advices are not included into the
758;; advised definition of a function, rather they are assembled into a hook 717;; advised definition of a function, rather they are assembled into a hook
759;; form which will be evaluated whenever the advice-info of the advised 718;; form which will be evaluated whenever the advice-info of the advised
760;; function gets activated or deactivated. One application of this mechanism 719;; function gets activated or deactivated. One application of this mechanism
761;; is to define file load hooks for files that do not provide such hooks. 720;; is to define file load hooks for files that do not provide such hooks.
762;; For example, suppose you want to print a message whenever `file-x' gets 721;; For example, suppose you want to print a message whenever `file-x' gets
763;; loaded, and suppose the last function defined in `file-x' is 722;; loaded, and suppose the last function defined in `file-x' is
@@ -769,7 +728,7 @@
769;; 728;;
770;; This will constitute a forward advice for function `file-x-last-fn' which 729;; This will constitute a forward advice for function `file-x-last-fn' which
771;; will get activated when `file-x' is loaded (only if forward advice is 730;; will get activated when `file-x' is loaded (only if forward advice is
772;; enabled of course). Because there are no "real" pieces of advice 731;; enabled of course). Because there are no "real" pieces of advice
773;; available for it, its definition will not be changed, but the activation 732;; available for it, its definition will not be changed, but the activation
774;; advice will be run during its activation which is equivalent to having a 733;; advice will be run during its activation which is equivalent to having a
775;; file load hook for `file-x'. 734;; file load hook for `file-x'.
@@ -784,14 +743,14 @@
784;; enabled advices are considered during construction of an advised 743;; enabled advices are considered during construction of an advised
785;; definition. 744;; definition.
786;; - Activation: 745;; - Activation:
787;; Redefine an advised function with its advised definition. Constructs 746;; Redefine an advised function with its advised definition. Constructs
788;; an advised definition from scratch if no verifiable cached advised 747;; an advised definition from scratch if no verifiable cached advised
789;; definition is available and caches it. 748;; definition is available and caches it.
790;; - Deactivation: 749;; - Deactivation:
791;; Back-define an advised function to its original definition. 750;; Back-define an advised function to its original definition.
792;; - Update: 751;; - Update:
793;; Reactivate an advised function but only if its advice is currently 752;; Reactivate an advised function but only if its advice is currently
794;; active. This can be used to bring all currently advised function up 753;; active. This can be used to bring all currently advised function up
795;; to date with the current state of advice without also activating 754;; to date with the current state of advice without also activating
796;; currently inactive functions. 755;; currently inactive functions.
797;; - Caching: 756;; - Caching:
@@ -800,7 +759,7 @@
800;; - Preactivation: 759;; - Preactivation:
801;; Is the construction of an advised definition according to the current 760;; Is the construction of an advised definition according to the current
802;; state of advice during byte-compilation of a file with a preactivating 761;; state of advice during byte-compilation of a file with a preactivating
803;; `defadvice'. That advised definition can then rather cheaply be used 762;; `defadvice'. That advised definition can then rather cheaply be used
804;; during activation without having to construct an advised definition 763;; during activation without having to construct an advised definition
805;; from scratch at runtime. 764;; from scratch at runtime.
806 765
@@ -860,12 +819,8 @@
860 819
861;; @ Foo games: An advice tutorial 820;; @ Foo games: An advice tutorial
862;; =============================== 821;; ===============================
863;; The following tutorial was created in Emacs 18.59. Left-justified 822;; The following tutorial was created in Emacs 18.59. Left-justified
864;; s-expressions are input forms followed by one or more result forms. 823;; s-expressions are input forms followed by one or more result forms.
865;; First we have to start the advice magic:
866;;
867;; (ad-start-advice)
868;; nil
869;; 824;;
870;; We start by defining an innocent looking function `foo' that simply 825;; We start by defining an innocent looking function `foo' that simply
871;; adds 1 to its argument X: 826;; adds 1 to its argument X:
@@ -988,19 +943,6 @@
988;; (call-interactively 'foo) 943;; (call-interactively 'foo)
989;; 6 944;; 6
990;; 945;;
991;; Let's have a look at what the definition of `foo' looks like now
992;; (indentation added by hand for legibility):
993;;
994;; (symbol-function 'foo)
995;; (lambda (x)
996;; "$ad-doc: foo$"
997;; (interactive (list 5))
998;; (let (ad-return-value)
999;; (setq x (1- x))
1000;; (setq x (1+ x))
1001;; (setq ad-return-value (ad-Orig-foo x))
1002;; ad-return-value))
1003;;
1004;; @@ Around advices: 946;; @@ Around advices:
1005;; ================== 947;; ==================
1006;; Now we'll try some `around' advices. An around advice is a wrapper around 948;; Now we'll try some `around' advices. An around advice is a wrapper around
@@ -1038,20 +980,6 @@
1038;; (foo 3) 980;; (foo 3)
1039;; 8 981;; 8
1040;; 982;;
1041;; Again, let's see what the definition of `foo' looks like so far:
1042;;
1043;; (symbol-function 'foo)
1044;; (lambda (x)
1045;; "$ad-doc: foo$"
1046;; (interactive (list 5))
1047;; (let (ad-return-value)
1048;; (setq x (1- x))
1049;; (setq x (1+ x))
1050;; (let ((x (* x 2)))
1051;; (let ((x (1+ x)))
1052;; (setq ad-return-value (ad-Orig-foo x))))
1053;; ad-return-value))
1054;;
1055;; @@ Controlling advice activation: 983;; @@ Controlling advice activation:
1056;; ================================= 984;; =================================
1057;; In every `defadvice' so far we have used the flag `activate' to activate 985;; In every `defadvice' so far we have used the flag `activate' to activate
@@ -1071,9 +999,9 @@
1071;; 8 999;; 8
1072;; 1000;;
1073;; Now we define another advice and activate which will also activate the 1001;; Now we define another advice and activate which will also activate the
1074;; previous advice `fg-times-x'. Note the use of the special variable 1002;; previous advice `fg-times-x'. Note the use of the special variable
1075;; `ad-return-value' in the body of the advice which is set to the result of 1003;; `ad-return-value' in the body of the advice which is set to the result of
1076;; the original function. If we change its value then the value returned by 1004;; the original function. If we change its value then the value returned by
1077;; the advised function will be changed accordingly: 1005;; the advised function will be changed accordingly:
1078;; 1006;;
1079;; (defadvice foo (after fg-times-x-again act) 1007;; (defadvice foo (after fg-times-x-again act)
@@ -1121,24 +1049,6 @@
1121;; "Let's clean up now!" 1049;; "Let's clean up now!"
1122;; error-in-foo 1050;; error-in-foo
1123;; 1051;;
1124;; Again, let's see what `foo' looks like:
1125;;
1126;; (symbol-function 'foo)
1127;; (lambda (x)
1128;; "$ad-doc: foo$"
1129;; (interactive (list 5))
1130;; (let (ad-return-value)
1131;; (unwind-protect
1132;; (progn (setq x (1- x))
1133;; (setq x (1+ x))
1134;; (let ((x (* x 2)))
1135;; (let ((x (1+ x)))
1136;; (setq ad-return-value (ad-Orig-foo x))))
1137;; (setq ad-return-value (* ad-return-value x))
1138;; (setq ad-return-value (* ad-return-value x)))
1139;; (print "Let's clean up now!"))
1140;; ad-return-value))
1141;;
1142;; @@ Compilation of advised definitions: 1052;; @@ Compilation of advised definitions:
1143;; ====================================== 1053;; ======================================
1144;; Finally, we can specify the `compile' keyword in a `defadvice' to say 1054;; Finally, we can specify the `compile' keyword in a `defadvice' to say
@@ -1150,13 +1060,10 @@
1150;; (print "Let's clean up now!")) 1060;; (print "Let's clean up now!"))
1151;; foo 1061;; foo
1152;; 1062;;
1153;; Now `foo' is byte-compiled: 1063;; Now `foo's advice is byte-compiled:
1154;; 1064;;
1155;; (symbol-function 'foo) 1065;; (byte-code-function-p 'ad-Advice-foo)
1156;; (lambda (x) 1066;; t
1157;; "$ad-doc: foo$"
1158;; (interactive (byte-code "....." [5] 1))
1159;; (byte-code "....." [ad-return-value x nil ((byte-code "....." [print "Let's clean up now!"] 2)) * 2 ad-Orig-foo] 6))
1160;; 1067;;
1161;; (foo 3) 1068;; (foo 3)
1162;; "Let's clean up now!" 1069;; "Let's clean up now!"
@@ -1262,7 +1169,7 @@
1262;; deactivate functions that have a piece of advice defined by a certain 1169;; deactivate functions that have a piece of advice defined by a certain
1263;; package (we save the old definition to check out caching): 1170;; package (we save the old definition to check out caching):
1264;; 1171;;
1265;; (setq old-definition (symbol-function 'foo)) 1172;; (setq old-definition (symbol-function 'ad-Advice-foo))
1266;; (lambda (x) ....) 1173;; (lambda (x) ....)
1267;; 1174;;
1268;; (ad-deactivate-regexp "^fg-") 1175;; (ad-deactivate-regexp "^fg-")
@@ -1274,7 +1181,7 @@
1274;; (ad-activate-regexp "^fg-") 1181;; (ad-activate-regexp "^fg-")
1275;; nil 1182;; nil
1276;; 1183;;
1277;; (eq old-definition (symbol-function 'foo)) 1184;; (eq old-definition (symbol-function 'ad-Advice-foo))
1278;; t 1185;; t
1279;; 1186;;
1280;; (foo 3) 1187;; (foo 3)
@@ -1283,14 +1190,6 @@
1283;; 1190;;
1284;; @@ Forward advice: 1191;; @@ Forward advice:
1285;; ================== 1192;; ==================
1286;; To enable automatic activation of forward advice we first have to set
1287;; `ad-activate-on-definition' to t and restart advice:
1288;;
1289;; (setq ad-activate-on-definition t)
1290;; t
1291;;
1292;; (ad-start-advice)
1293;; (ad-activate-defined-function)
1294;; 1193;;
1295;; Let's define a piece of advice for an undefined function: 1194;; Let's define a piece of advice for an undefined function:
1296;; 1195;;
@@ -1303,9 +1202,7 @@
1303;; (fboundp 'bar) 1202;; (fboundp 'bar)
1304;; nil 1203;; nil
1305;; 1204;;
1306;; Now we define it and the forward advice will get activated (only because 1205;; Now we define it and the forward advice will get activated:
1307;; `ad-activate-on-definition' was t when we started advice above with
1308;; `ad-start-advice'):
1309;; 1206;;
1310;; (defun bar (x) 1207;; (defun bar (x)
1311;; "Subtract 1 from X." 1208;; "Subtract 1 from X."
@@ -1357,7 +1254,7 @@
1357;; (ad-activate 'fie) 1254;; (ad-activate 'fie)
1358;; fie 1255;; fie
1359;; 1256;;
1360;; (eq cached-definition (symbol-function 'fie)) 1257;; (eq cached-definition (symbol-function 'ad-Advice-fie))
1361;; t 1258;; t
1362;; 1259;;
1363;; (fie 2) 1260;; (fie 2)
@@ -1365,7 +1262,7 @@
1365;; 1262;;
1366;; If you put a preactivating `defadvice' into a Lisp file that gets byte- 1263;; If you put a preactivating `defadvice' into a Lisp file that gets byte-
1367;; compiled then the constructed advised definition will get compiled by 1264;; compiled then the constructed advised definition will get compiled by
1368;; the byte-compiler. For that to occur in a v18 Emacs you had to put the 1265;; the byte-compiler. For that to occur in a v18 Emacs you had to put the
1369;; `defadvice' inside a `defun' because the v18 compiler did not compile 1266;; `defadvice' inside a `defun' because the v18 compiler did not compile
1370;; top-level forms other than `defun' or `defmacro', for example, 1267;; top-level forms other than `defun' or `defmacro', for example,
1371;; 1268;;
@@ -1407,18 +1304,16 @@
1407;; constructed during preactivation was used, even though we did not specify 1304;; constructed during preactivation was used, even though we did not specify
1408;; the `compile' flag: 1305;; the `compile' flag:
1409;; 1306;;
1410;; (symbol-function 'fum) 1307;; (byte-code-function-p 'ad-Advice-fum)
1411;; (lambda (x) 1308;; t
1412;; "$ad-doc: fum$"
1413;; (byte-code "....." [ad-return-value x nil * 2 ad-Orig-fum] 4))
1414;; 1309;;
1415;; (fum 2) 1310;; (fum 2)
1416;; 8 1311;; 8
1417;; 1312;;
1418;; A preactivated definition will only be used if it matches the current 1313;; A preactivated definition will only be used if it matches the current
1419;; function definition and advice information. If it does not match it 1314;; function definition and advice information. If it does not match it
1420;; will simply be discarded and a new advised definition will be constructed 1315;; will simply be discarded and a new advised definition will be constructed
1421;; from scratch. For example, let's first remove all advice-info for `fum': 1316;; from scratch. For example, let's first remove all advice-info for `fum':
1422;; 1317;;
1423;; (ad-unadvise 'fum) 1318;; (ad-unadvise 'fum)
1424;; (("fie") ("bar") ("foo") ...) 1319;; (("fie") ("bar") ("foo") ...)
@@ -1431,7 +1326,7 @@
1431;; fum 1326;; fum
1432;; 1327;;
1433;; When we now try to use a preactivation it will not be used because the 1328;; When we now try to use a preactivation it will not be used because the
1434;; current advice state is different from the one at preactivation time. This 1329;; current advice state is different from the one at preactivation time. This
1435;; is no tragedy, everything will work as expected just not as efficient, 1330;; is no tragedy, everything will work as expected just not as efficient,
1436;; because a new advised definition has to be constructed from scratch: 1331;; because a new advised definition has to be constructed from scratch:
1437;; 1332;;
@@ -1440,7 +1335,7 @@
1440;; 1335;;
1441;; A new uncompiled advised definition got constructed: 1336;; A new uncompiled advised definition got constructed:
1442;; 1337;;
1443;; (ad-compiled-p (symbol-function 'fum)) 1338;; (byte-code-function-p 'ad-Advice-fum)
1444;; nil 1339;; nil
1445;; 1340;;
1446;; (fum 2) 1341;; (fum 2)
@@ -1448,7 +1343,7 @@
1448;; 1343;;
1449;; MORAL: To get all the efficiency out of preactivation the function 1344;; MORAL: To get all the efficiency out of preactivation the function
1450;; definition and advice state at preactivation time must be the same as the 1345;; definition and advice state at preactivation time must be the same as the
1451;; state at activation time. Preactivation does work with forward advice, all 1346;; state at activation time. Preactivation does work with forward advice, all
1452;; that's necessary is that the definition of the forward advised function is 1347;; that's necessary is that the definition of the forward advised function is
1453;; available when the `defadvice' with the preactivation gets compiled. 1348;; available when the `defadvice' with the preactivation gets compiled.
1454;; 1349;;
@@ -1702,15 +1597,9 @@
1702;; @@ Compilation idiosyncrasies: 1597;; @@ Compilation idiosyncrasies:
1703;; ============================== 1598;; ==============================
1704 1599
1705;; `defadvice' expansion needs quite a few advice functions and variables,
1706;; hence, I need to preload the file before it can be compiled. To avoid
1707;; interference of bogus compiled files I always preload the source file:
1708(provide 'advice-preload)
1709;; During a normal load this is a noop:
1710(require 'advice-preload "advice.el")
1711(require 'macroexp) 1600(require 'macroexp)
1712;; At run-time also, since ad-do-advised-functions returns code that uses it. 1601;; At run-time also, since ad-do-advised-functions returns code that uses it.
1713(require 'cl-lib) 1602(eval-when-compile (require 'cl-lib))
1714 1603
1715;; @@ Variable definitions: 1604;; @@ Variable definitions:
1716;; ======================== 1605;; ========================
@@ -1789,7 +1678,7 @@ generates a copy of TREE."
1789;; (after adv1 adv2 ...) 1678;; (after adv1 adv2 ...)
1790;; (activation adv1 adv2 ...) 1679;; (activation adv1 adv2 ...)
1791;; (deactivation adv1 adv2 ...) 1680;; (deactivation adv1 adv2 ...)
1792;; (origname . <symbol fbound to origdef>) 1681;; (advicefunname . <symbol fbound to assembled advice function>)
1793;; (cache . (<advised-definition> . <id>))) 1682;; (cache . (<advised-definition> . <id>)))
1794 1683
1795;; List of currently advised though not necessarily activated functions 1684;; List of currently advised though not necessarily activated functions
@@ -1816,7 +1705,7 @@ generates a copy of TREE."
1816On each iteration VAR will be bound to the name of an advised function 1705On each iteration VAR will be bound to the name of an advised function
1817\(a symbol)." 1706\(a symbol)."
1818 (declare (indent 1)) 1707 (declare (indent 1))
1819 `(cl-dolist (,(car varform) ad-advised-functions) 1708 `(dolist (,(car varform) ad-advised-functions)
1820 (setq ,(car varform) (intern (car ,(car varform)))) 1709 (setq ,(car varform) (intern (car ,(car varform))))
1821 ,@body)) 1710 ,@body))
1822 1711
@@ -1882,18 +1771,17 @@ either t or nil, and DEFINITION should be a list of the form
1882 1771
1883;; ad-find-advice uses the alist structure directly -> 1772;; ad-find-advice uses the alist structure directly ->
1884;; change if this data structure changes!! 1773;; change if this data structure changes!!
1885(defmacro ad-advice-name (advice) 1774(defsubst ad-advice-name (advice) (car advice))
1886 (list 'car advice)) 1775(defsubst ad-advice-protected (advice) (nth 1 advice))
1887(defmacro ad-advice-protected (advice) 1776(defsubst ad-advice-enabled (advice) (nth 2 advice))
1888 (list 'nth 1 advice)) 1777(defsubst ad-advice-definition (advice) (nth 3 advice))
1889(defmacro ad-advice-enabled (advice)
1890 (list 'nth 2 advice))
1891(defmacro ad-advice-definition (advice)
1892 (list 'nth 3 advice))
1893 1778
1894(defun ad-advice-set-enabled (advice flag) 1779(defun ad-advice-set-enabled (advice flag)
1895 (rplaca (cdr (cdr advice)) flag)) 1780 (rplaca (cdr (cdr advice)) flag))
1896 1781
1782(defvar ad-advice-classes '(before around after activation deactivation)
1783 "List of defined advice classes.")
1784
1897(defun ad-class-p (thing) 1785(defun ad-class-p (thing)
1898 (memq thing ad-advice-classes)) 1786 (memq thing ad-advice-classes))
1899(defun ad-name-p (thing) 1787(defun ad-name-p (thing)
@@ -1906,9 +1794,6 @@ either t or nil, and DEFINITION should be a list of the form
1906;; @@ Advice access functions: 1794;; @@ Advice access functions:
1907;; =========================== 1795;; ===========================
1908 1796
1909;; List of defined advice classes:
1910(defvar ad-advice-classes '(before around after activation deactivation))
1911
1912(defun ad-has-enabled-advice (function class) 1797(defun ad-has-enabled-advice (function class)
1913 "True if at least one of FUNCTION's advices in CLASS is enabled." 1798 "True if at least one of FUNCTION's advices in CLASS is enabled."
1914 (cl-dolist (advice (ad-get-advice-info-field function class)) 1799 (cl-dolist (advice (ad-get-advice-info-field function class))
@@ -1948,58 +1833,23 @@ Redefining advices affect the construction of an advised definition."
1948;; Whether advised definitions created by automatic activations will be 1833;; Whether advised definitions created by automatic activations will be
1949;; compiled depends on the value of `ad-default-compilation-action'. 1834;; compiled depends on the value of `ad-default-compilation-action'.
1950 1835
1951;; Since calling `ad-activate-internal' in the built-in definition of `fset' can 1836(defalias 'ad-activate-internal 'ad-activate)
1952;; create major disasters we have to be a bit careful. One precaution is
1953;; to provide a dummy definition for `ad-activate-internal' which can be used to
1954;; turn off automatic advice activation (e.g., when `ad-stop-advice' or
1955;; `ad-recover-normality' are called). Another is to avoid recursive calls
1956;; to `ad-activate' by using `ad-with-auto-activation-disabled' where
1957;; appropriate, especially in a safe version of `fset'.
1958
1959(defun ad--defalias-fset (fsetfun function definition)
1960 (funcall (or fsetfun #'fset) function definition)
1961 (ad-activate-internal function nil))
1962
1963;; For now define `ad-activate-internal' to the dummy definition:
1964(defun ad-activate-internal (_function &optional _compile)
1965 "Automatic advice activation is disabled. `ad-start-advice' enables it."
1966 nil)
1967
1968;; This is just a copy of the above:
1969(defun ad-activate-internal-off (_function &optional _compile)
1970 "Automatic advice activation is disabled. `ad-start-advice' enables it."
1971 nil)
1972
1973;; This will be t for top-level calls to `ad-activate-internal-on':
1974(defvar ad-activate-on-top-level t)
1975
1976(defmacro ad-with-auto-activation-disabled (&rest body)
1977 `(let ((ad-activate-on-top-level nil))
1978 ,@body))
1979
1980;; @@ Access functions for original definitions:
1981;; ============================================
1982;; The advice-info of an advised function contains its `origname' which is
1983;; a symbol that is fbound to the original definition available at the first
1984;; proper activation of the function after a valid re/definition. If the
1985;; original was defined via fcell indirection then `origname' will be defined
1986;; just so. Hence, to get hold of the actual original definition of a function
1987;; we need to use `ad-real-orig-definition'.
1988
1989(defun ad-make-origname (function)
1990 "Make name to be used to call the original FUNCTION."
1991 (intern (format "ad-Orig-%s" function)))
1992 1837
1993(defmacro ad-get-orig-definition (function) 1838(defun ad-make-advicefunname (function)
1994 `(let ((origname (ad-get-advice-info-field ,function 'origname))) 1839 "Make name to be used to call the assembled advice function."
1995 (if (fboundp origname) 1840 (intern (format "ad-Advice-%s" function)))
1996 (symbol-function origname))))
1997 1841
1998(defmacro ad-set-orig-definition (function definition) 1842(defun ad-get-orig-definition (function) ;FIXME: Rename to "-unadvised-".
1999 `(fset (ad-get-advice-info-field ,function 'origname) ,definition)) 1843 (if (symbolp function)
1844 (setq function (if (fboundp function)
1845 (advice--strip-macro (symbol-function function)))))
1846 (while (advice--p function) (setq function (advice--cdr function)))
1847 function)
2000 1848
2001(defmacro ad-clear-orig-definition (function) 1849(defun ad-clear-advicefunname-definition (function)
2002 `(fmakunbound (ad-get-advice-info-field ,function 'origname))) 1850 (let ((advicefunname (ad-get-advice-info-field function 'advicefunname)))
1851 (advice-remove function advicefunname)
1852 (fmakunbound advicefunname)))
2003 1853
2004 1854
2005;; @@ Interactive input functions: 1855;; @@ Interactive input functions:
@@ -2259,7 +2109,7 @@ See Info node `(elisp)Computed Advice' for detailed documentation."
2259 (cond ((not (ad-is-advised function)) 2109 (cond ((not (ad-is-advised function))
2260 (ad-initialize-advice-info function) 2110 (ad-initialize-advice-info function)
2261 (ad-set-advice-info-field 2111 (ad-set-advice-info-field
2262 function 'origname (ad-make-origname function)))) 2112 function 'advicefunname (ad-make-advicefunname function))))
2263 (let* ((previous-position 2113 (let* ((previous-position
2264 (ad-advice-position function class (ad-advice-name advice))) 2114 (ad-advice-position function class (ad-advice-name advice)))
2265 (advices (ad-get-advice-info-field function class)) 2115 (advices (ad-get-advice-info-field function class))
@@ -2374,7 +2224,8 @@ the name of the advised function from the docstring. This is needed
2374to generate a proper advised docstring even if we are just given a 2224to generate a proper advised docstring even if we are just given a
2375definition (see the code for `documentation')." 2225definition (see the code for `documentation')."
2376 (eval-when-compile 2226 (eval-when-compile
2377 (propertize "Advice doc string" 'dynamic-docstring-function 2227 (propertize "Advice function assembled by advice.el."
2228 'dynamic-docstring-function
2378 #'ad--make-advised-docstring))) 2229 #'ad--make-advised-docstring)))
2379 2230
2380(defun ad-advised-definition-p (definition) 2231(defun ad-advised-definition-p (definition)
@@ -2417,9 +2268,9 @@ For that it has to be fbound with a non-autoload definition."
2417 definition)))) 2268 definition))))
2418 2269
2419(defun ad-real-orig-definition (function) 2270(defun ad-real-orig-definition (function)
2420 "Find FUNCTION's real original definition starting from its `origname'." 2271 (let* ((fun1 (ad-get-orig-definition function))
2421 (if (ad-is-advised function) 2272 (fun2 (indirect-function fun1)))
2422 (ad-real-definition (ad-get-advice-info-field function 'origname)))) 2273 (unless (autoloadp fun2) fun2)))
2423 2274
2424(defun ad-is-compilable (function) 2275(defun ad-is-compilable (function)
2425 "True if FUNCTION has an interpreted definition that can be compiled." 2276 "True if FUNCTION has an interpreted definition that can be compiled."
@@ -2430,24 +2281,15 @@ For that it has to be fbound with a non-autoload definition."
2430 2281
2431(defvar warning-suppress-types) ;From warnings.el. 2282(defvar warning-suppress-types) ;From warnings.el.
2432(defun ad-compile-function (function) 2283(defun ad-compile-function (function)
2433 "Byte-compiles FUNCTION (or macro) if it is not yet compiled." 2284 "Byte-compile the assembled advice function."
2434 (interactive "aByte-compile function: ") 2285 (require 'bytecomp)
2435 (if (ad-is-compilable function) 2286 (require 'warnings) ;To define warning-suppress-types before we let-bind it.
2436 ;; Need to turn off auto-activation 2287 (let ((byte-compile-warnings byte-compile-warnings)
2437 ;; because `byte-compile' uses `fset': 2288 ;; Don't pop up windows showing byte-compiler warnings.
2438 (ad-with-auto-activation-disabled 2289 (warning-suppress-types '((bytecomp))))
2439 (require 'bytecomp) 2290 (if (featurep 'cl)
2440 (require 'warnings) ;To define warning-suppress-types 2291 (byte-compile-disable-warning 'cl-functions))
2441 ;before we let-bind it. 2292 (byte-compile (ad-get-advice-info-field function 'advicefunname))))
2442 (let ((symbol (make-symbol "advice-compilation"))
2443 (byte-compile-warnings byte-compile-warnings)
2444 ;; Don't pop up windows showing byte-compiler warnings.
2445 (warning-suppress-types '((bytecomp))))
2446 (if (featurep 'cl)
2447 (byte-compile-disable-warning 'cl-functions))
2448 (fset symbol (symbol-function function))
2449 (byte-compile symbol)
2450 (fset function (symbol-function symbol))))))
2451 2293
2452;; @@@ Accessing argument lists: 2294;; @@@ Accessing argument lists:
2453;; ============================= 2295;; =============================
@@ -2634,7 +2476,7 @@ Excess source arguments will be neglected, missing source arguments will be
2634supplied as nil. Returns a `funcall' or `apply' form with the second element 2476supplied as nil. Returns a `funcall' or `apply' form with the second element
2635being `function' which has to be replaced by an actual function argument. 2477being `function' which has to be replaced by an actual function argument.
2636Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return 2478Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2637 `(funcall function a (car args) (car (cdr args)) (nth 2 args))'." 2479 `(funcall ad--addoit-function a (car args) (car (cdr args)) (nth 2 args))'."
2638 (let* ((parsed-source-arglist (ad-parse-arglist source-arglist)) 2480 (let* ((parsed-source-arglist (ad-parse-arglist source-arglist))
2639 (source-reqopt-args (append (nth 0 parsed-source-arglist) 2481 (source-reqopt-args (append (nth 0 parsed-source-arglist)
2640 (nth 1 parsed-source-arglist))) 2482 (nth 1 parsed-source-arglist)))
@@ -2648,7 +2490,7 @@ Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2648 ;; This produces ``error-proof'' target function calls with the exception 2490 ;; This produces ``error-proof'' target function calls with the exception
2649 ;; of a case like (&rest a) mapped onto (x &rest y) where the actual args 2491 ;; of a case like (&rest a) mapped onto (x &rest y) where the actual args
2650 ;; supplied to A might not be enough to supply the required target arg X 2492 ;; supplied to A might not be enough to supply the required target arg X
2651 (append (list (if need-apply 'apply 'funcall) 'function) 2493 (append (list (if need-apply 'apply 'funcall) 'ad--addoit-function)
2652 (cond (need-apply 2494 (cond (need-apply
2653 ;; `apply' can take care of that directly: 2495 ;; `apply' can take care of that directly:
2654 (append source-reqopt-args (list source-rest-arg))) 2496 (append source-reqopt-args (list source-rest-arg)))
@@ -2663,13 +2505,6 @@ Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2663 (nthcdr (length target-reqopt-args) 2505 (nthcdr (length target-reqopt-args)
2664 source-reqopt-args))))))))) 2506 source-reqopt-args)))))))))
2665 2507
2666(defun ad-make-mapped-call (source-arglist target-arglist target-function)
2667 "Make form to call TARGET-FUNCTION with args from SOURCE-ARGLIST."
2668 (let ((mapped-form (ad-map-arglists source-arglist target-arglist)))
2669 (if (eq (car mapped-form) 'funcall)
2670 (cons target-function (cdr (cdr mapped-form)))
2671 (prog1 mapped-form
2672 (setcar (cdr mapped-form) (list 'quote target-function))))))
2673 2508
2674;; @@@ Making an advised documentation string: 2509;; @@@ Making an advised documentation string:
2675;; =========================================== 2510;; ===========================================
@@ -2697,13 +2532,6 @@ Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2697 2532
2698(require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage. 2533(require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage.
2699 2534
2700(defun ad-make-advised-docstring (function &optional style)
2701 (let* ((origdef (ad-real-orig-definition function))
2702 (origdoc
2703 ;; Retrieve raw doc, key substitution will be taken care of later:
2704 (documentation origdef t)))
2705 (ad--make-advised-docstring origdoc function style)))
2706
2707(defun ad--make-advised-docstring (origdoc function &optional style) 2535(defun ad--make-advised-docstring (origdoc function &optional style)
2708 "Construct a documentation string for the advised FUNCTION. 2536 "Construct a documentation string for the advised FUNCTION.
2709It concatenates the original documentation with the documentation 2537It concatenates the original documentation with the documentation
@@ -2712,14 +2540,14 @@ according to STYLE. STYLE can be `plain', everything else
2712will be interpreted as `default'. The order of the advice documentation 2540will be interpreted as `default'. The order of the advice documentation
2713strings corresponds to before/around/after and the individual ordering 2541strings corresponds to before/around/after and the individual ordering
2714in any of these classes." 2542in any of these classes."
2715 (let* ((origdef (ad-real-orig-definition function)) 2543 (if (and (symbolp function)
2716 (origtype (symbol-name (ad-definition-type origdef))) 2544 (string-match "\\`ad-+Advice-" (symbol-name function)))
2717 (usage (help-split-fundoc origdoc function)) 2545 (setq function
2546 (intern (substring (symbol-name function) (match-end 0)))))
2547 (let* ((usage (help-split-fundoc origdoc function))
2718 paragraphs advice-docstring) 2548 paragraphs advice-docstring)
2719 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage))) 2549 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage)))
2720 (if origdoc (setq paragraphs (list origdoc))) 2550 (if origdoc (setq paragraphs (list origdoc)))
2721 (unless (eq style 'plain)
2722 (push (concat "This " origtype " is advised.") paragraphs))
2723 (dolist (class ad-advice-classes) 2551 (dolist (class ad-advice-classes)
2724 (dolist (advice (ad-get-enabled-advices function class)) 2552 (dolist (advice (ad-get-enabled-advices function class))
2725 (setq advice-docstring 2553 (setq advice-docstring
@@ -2735,8 +2563,6 @@ in any of these classes."
2735 #'ad--make-advised-docstring))) 2563 #'ad--make-advised-docstring)))
2736 (help-add-fundoc-usage origdoc usage))) 2564 (help-add-fundoc-usage origdoc usage)))
2737 2565
2738(defun ad-make-plain-docstring (function)
2739 (ad-make-advised-docstring function 'plain))
2740 2566
2741;; @@@ Accessing overriding arglists and interactive forms: 2567;; @@@ Accessing overriding arglists and interactive forms:
2742;; ======================================================== 2568;; ========================================================
@@ -2770,64 +2596,16 @@ in any of these classes."
2770 (if (and (ad-is-advised function) 2596 (if (and (ad-is-advised function)
2771 (ad-has-redefining-advice function)) 2597 (ad-has-redefining-advice function))
2772 (let* ((origdef (ad-real-orig-definition function)) 2598 (let* ((origdef (ad-real-orig-definition function))
2773 (origname (ad-get-advice-info-field function 'origname))
2774 (orig-interactive-p (commandp origdef))
2775 (orig-subr-p (ad-subr-p origdef))
2776 (orig-special-form-p (special-form-p origdef))
2777 (orig-macro-p (ad-macro-p origdef))
2778 ;; Construct the individual pieces that we need for assembly: 2599 ;; Construct the individual pieces that we need for assembly:
2779 (orig-arglist (ad-arglist origdef)) 2600 (orig-arglist (ad-arglist origdef))
2780 (advised-arglist (or (ad-advised-arglist function) 2601 (advised-arglist (or (ad-advised-arglist function)
2781 orig-arglist)) 2602 orig-arglist))
2782 (advised-interactive-form (ad-advised-interactive-form function)) 2603 (interactive-form (ad-advised-interactive-form function))
2783 (interactive-form
2784 (cond (orig-macro-p nil)
2785 (advised-interactive-form)
2786 ((interactive-form origdef)
2787 (interactive-form
2788 (if (and (symbolp function) (get function 'elp-info))
2789 (aref (get function 'elp-info) 2)
2790 origdef)))))
2791 (orig-form 2604 (orig-form
2792 (cond ((or orig-special-form-p orig-macro-p) 2605 (ad-map-arglists advised-arglist orig-arglist)))
2793 ;; Special forms and macros will be advised into macros.
2794 ;; The trick is to construct an expansion for the advised
2795 ;; macro that does the correct thing when it gets eval'ed.
2796 ;; For macros we'll just use the expansion of the original
2797 ;; macro and return that. This way compiled advised macros
2798 ;; will be expanded into something useful. Note that after
2799 ;; advices have full control over whether they want to
2800 ;; evaluate the expansion (the value of `ad-return-value')
2801 ;; at macro expansion time or not. For special forms there
2802 ;; is no solution that interacts reasonably with the
2803 ;; compiler, hence we just evaluate the original at macro
2804 ;; expansion time and return the result. The moral of that
2805 ;; is that one should always deactivate advised special
2806 ;; forms before one byte-compiles a file.
2807 `(,(if orig-macro-p 'macroexpand 'eval)
2808 (cons ',origname
2809 ,(ad-get-arguments advised-arglist 0))))
2810 ((and orig-subr-p
2811 orig-interactive-p
2812 (not interactive-form)
2813 (not advised-interactive-form))
2814 ;; Check whether we were called interactively
2815 ;; in order to do proper prompting:
2816 `(if (called-interactively-p 'any)
2817 (call-interactively ',origname)
2818 ,(ad-make-mapped-call advised-arglist
2819 orig-arglist
2820 origname)))
2821 ;; And now for normal functions and non-interactive subrs
2822 ;; (or subrs whose interactive behavior was advised):
2823 (t (ad-make-mapped-call
2824 advised-arglist orig-arglist origname)))))
2825 2606
2826 ;; Finally, build the sucker: 2607 ;; Finally, build the sucker:
2827 (ad-assemble-advised-definition 2608 (ad-assemble-advised-definition
2828 (cond (orig-macro-p 'macro)
2829 (orig-special-form-p 'special-form)
2830 (t 'function))
2831 advised-arglist 2609 advised-arglist
2832 (ad-make-advised-definition-docstring function) 2610 (ad-make-advised-definition-docstring function)
2833 interactive-form 2611 interactive-form
@@ -2837,13 +2615,11 @@ in any of these classes."
2837 (ad-get-enabled-advices function 'after))))) 2615 (ad-get-enabled-advices function 'after)))))
2838 2616
2839(defun ad-assemble-advised-definition 2617(defun ad-assemble-advised-definition
2840 (type args docstring interactive orig &optional befores arounds afters) 2618 (args docstring interactive orig &optional befores arounds afters)
2841 2619 "Assemble the advices into an overall advice function.
2842 "Assembles an original and its advices into an advised function. 2620ARGS is the argument list that has to be used,
2843It constructs a function or macro definition according to TYPE which has to 2621DOCSTRING if non-nil defines the documentation of the definition,
2844be either `macro', `function' or `special-form'. ARGS is the argument list 2622INTERACTIVE if non-nil is the interactive form to be used,
2845that has to be used, DOCSTRING if non-nil defines the documentation of the
2846definition, INTERACTIVE if non-nil is the interactive form to be used,
2847ORIG is a form that calls the body of the original unadvised function, 2623ORIG is a form that calls the body of the original unadvised function,
2848and BEFORES, AROUNDS and AFTERS are the lists of advices with which ORIG 2624and BEFORES, AROUNDS and AFTERS are the lists of advices with which ORIG
2849should be modified. The assembled function will be returned." 2625should be modified. The assembled function will be returned."
@@ -2894,16 +2670,12 @@ should be modified. The assembled function will be returned."
2894 (ad-body-forms (ad-advice-definition advice))))))) 2670 (ad-body-forms (ad-advice-definition advice)))))))
2895 2671
2896 (setq definition 2672 (setq definition
2897 `(,@(if (memq type '(macro special-form)) '(macro)) 2673 `(lambda (ad--addoit-function ,@args)
2898 lambda
2899 ,args
2900 ,@(if docstring (list docstring)) 2674 ,@(if docstring (list docstring))
2901 ,@(if interactive (list interactive)) 2675 ,@(if interactive (list interactive))
2902 (let (ad-return-value) 2676 (let (ad-return-value)
2903 ,@after-forms 2677 ,@after-forms
2904 ,(if (eq type 'special-form) 2678 ad-return-value)))
2905 '(list 'quote ad-return-value)
2906 'ad-return-value))))
2907 2679
2908 (ad-insert-argument-access-forms definition args))) 2680 (ad-insert-argument-access-forms definition args)))
2909 2681
@@ -3000,11 +2772,11 @@ advised definition from scratch."
3000 "Generate an identifying image of the current advices of FUNCTION." 2772 "Generate an identifying image of the current advices of FUNCTION."
3001 (let ((original-definition (ad-real-orig-definition function)) 2773 (let ((original-definition (ad-real-orig-definition function))
3002 (cached-definition (ad-get-cache-definition function))) 2774 (cached-definition (ad-get-cache-definition function)))
3003 (list (mapcar (function (lambda (advice) (ad-advice-name advice))) 2775 (list (mapcar #'ad-advice-name
3004 (ad-get-enabled-advices function 'before)) 2776 (ad-get-enabled-advices function 'before))
3005 (mapcar (function (lambda (advice) (ad-advice-name advice))) 2777 (mapcar #'ad-advice-name
3006 (ad-get-enabled-advices function 'around)) 2778 (ad-get-enabled-advices function 'around))
3007 (mapcar (function (lambda (advice) (ad-advice-name advice))) 2779 (mapcar #'ad-advice-name
3008 (ad-get-enabled-advices function 'after)) 2780 (ad-get-enabled-advices function 'after))
3009 (ad-definition-type original-definition) 2781 (ad-definition-type original-definition)
3010 (if (equal (ad-arglist original-definition) 2782 (if (equal (ad-arglist original-definition)
@@ -3147,25 +2919,32 @@ The resulting FUNCTION will be compiled if `ad-should-compile' returns t.
3147The current definition and its cache-id will be put into the cache." 2919The current definition and its cache-id will be put into the cache."
3148 (let ((verified-cached-definition 2920 (let ((verified-cached-definition
3149 (if (ad-verify-cache-id function) 2921 (if (ad-verify-cache-id function)
3150 (ad-get-cache-definition function)))) 2922 (ad-get-cache-definition function)))
3151 (fset function 2923 (advicefunname (ad-get-advice-info-field function 'advicefunname)))
3152 (or verified-cached-definition 2924 (fset advicefunname
3153 (ad-make-advised-definition function))) 2925 (or verified-cached-definition
2926 (ad-make-advised-definition function)))
2927 (advice-add function :around advicefunname)
3154 (if (ad-should-compile function compile) 2928 (if (ad-should-compile function compile)
3155 (ad-compile-function function)) 2929 (byte-compile advicefunname))
3156 (if verified-cached-definition 2930 (if verified-cached-definition
3157 (if (not (eq verified-cached-definition (symbol-function function))) 2931 (if (not (eq verified-cached-definition
2932 (symbol-function advicefunname)))
3158 ;; we must have compiled, cache the compiled definition: 2933 ;; we must have compiled, cache the compiled definition:
3159 (ad-set-cache 2934 (ad-set-cache function (symbol-function advicefunname)
3160 function (symbol-function function) (ad-get-cache-id function))) 2935 (ad-get-cache-id function)))
3161 ;; We created a new advised definition, cache it with a proper id: 2936 ;; We created a new advised definition, cache it with a proper id:
3162 (ad-clear-cache function) 2937 (ad-clear-cache function)
3163 ;; ad-make-cache-id needs the new cached definition: 2938 ;; ad-make-cache-id needs the new cached definition:
3164 (ad-set-cache function (symbol-function function) nil) 2939 (ad-set-cache function (symbol-function advicefunname) nil)
3165 (ad-set-cache 2940 (ad-set-cache
3166 function (symbol-function function) (ad-make-cache-id function))))) 2941 function (symbol-function advicefunname) (ad-make-cache-id function)))))
3167 2942
3168(defun ad-handle-definition (function) 2943(defun ad--defalias-fset (fsetfun function newdef)
2944 ;; Besides ad-redefinition-action we use this defalias-fset-function hook
2945 ;; for two other reasons:
2946 ;; - for `activation/deactivation' advices.
2947 ;; - to rebuild the ad-Advice-* function with the right argument names.
3169 "Handle re/definition of an advised FUNCTION during de/activation. 2948 "Handle re/definition of an advised FUNCTION during de/activation.
3170If FUNCTION does not have an original definition associated with it and 2949If FUNCTION does not have an original definition associated with it and
3171the current definition is usable, then it will be stored as FUNCTION's 2950the current definition is usable, then it will be stored as FUNCTION's
@@ -3177,33 +2956,27 @@ associated with it but got redefined with a new definition and then
3177de/activated. If you do not like the current redefinition action change 2956de/activated. If you do not like the current redefinition action change
3178the value of `ad-redefinition-action' and de/activate again." 2957the value of `ad-redefinition-action' and de/activate again."
3179 (let ((original-definition (ad-get-orig-definition function)) 2958 (let ((original-definition (ad-get-orig-definition function))
3180 (current-definition (if (ad-real-definition function) 2959 (current-definition (ad-get-orig-definition newdef)))
3181 (symbol-function function))))
3182 (if original-definition 2960 (if original-definition
3183 (if current-definition 2961 (if current-definition
3184 (if (and (not (eq current-definition original-definition)) 2962 (if (not (eq current-definition original-definition))
3185 ;; Redefinition with an advised definition from a 2963 ;; We have a redefinition:
3186 ;; different function won't count as such:
3187 (not (ad-advised-definition-p current-definition)))
3188 ;; we have a redefinition:
3189 (if (not (memq ad-redefinition-action '(accept discard warn))) 2964 (if (not (memq ad-redefinition-action '(accept discard warn)))
3190 (error "ad-handle-definition (see its doc): `%s' %s" 2965 (error "ad-redefinition-action: `%s' %s"
3191 function "invalidly redefined") 2966 function "invalidly redefined")
3192 (if (eq ad-redefinition-action 'discard) 2967 (if (eq ad-redefinition-action 'discard)
3193 (fset function original-definition) 2968 nil ;; Just drop it!
3194 (ad-set-orig-definition function current-definition) 2969 (funcall (or fsetfun #'fset) function newdef)
2970 (ad-activate-internal function)
3195 (if (eq ad-redefinition-action 'warn) 2971 (if (eq ad-redefinition-action 'warn)
3196 (message "ad-handle-definition: `%s' got redefined" 2972 (message "ad-handle-definition: `%s' got redefined"
3197 function)))) 2973 function))))
3198 ;; either advised def or correct original is in place: 2974 ;; either advised def or correct original is in place:
3199 nil) 2975 nil)
3200 ;; we have an undefinition, ignore it: 2976 ;; We have an undefinition, ignore it:
3201 nil) 2977 (funcall (or fsetfun #'fset) function newdef))
3202 (if current-definition 2978 (funcall (or fsetfun #'fset) function newdef)
3203 ;; we have a first definition, save it as original: 2979 (when current-definition (ad-activate-internal function)))))
3204 (ad-set-orig-definition function current-definition)
3205 ;; we don't have anything noteworthy:
3206 nil))))
3207 2980
3208 2981
3209;; @@ The top-level advice interface: 2982;; @@ The top-level advice interface:
@@ -3229,24 +3002,20 @@ definition will always be cached for later usage."
3229 (interactive 3002 (interactive
3230 (list (ad-read-advised-function "Activate advice of") 3003 (list (ad-read-advised-function "Activate advice of")
3231 current-prefix-arg)) 3004 current-prefix-arg))
3232 (if ad-activate-on-top-level 3005 (if (not (ad-is-advised function))
3233 ;; avoid recursive calls to `ad-activate': 3006 (error "ad-activate: `%s' is not advised" function)
3234 (ad-with-auto-activation-disabled 3007 ;; Just return for forward advised and not yet defined functions:
3235 (if (not (ad-is-advised function)) 3008 (if (ad-get-orig-definition function)
3236 (error "ad-activate: `%s' is not advised" function) 3009 (if (not (ad-has-any-advice function))
3237 (ad-handle-definition function) 3010 (ad-unadvise function)
3238 ;; Just return for forward advised and not yet defined functions: 3011 ;; Otherwise activate the advice:
3239 (if (ad-get-orig-definition function) 3012 (cond ((ad-has-redefining-advice function)
3240 (if (not (ad-has-any-advice function)) 3013 (ad-activate-advised-definition function compile)
3241 (ad-unadvise function) 3014 (ad-set-advice-info-field function 'active t)
3242 ;; Otherwise activate the advice: 3015 (eval (ad-make-hook-form function 'activation))
3243 (cond ((ad-has-redefining-advice function) 3016 function)
3244 (ad-activate-advised-definition function compile) 3017 ;; Here we are if we have all disabled advices:
3245 (ad-set-advice-info-field function 'active t) 3018 (t (ad-deactivate function)))))))
3246 (eval (ad-make-hook-form function 'activation))
3247 function)
3248 ;; Here we are if we have all disabled advices:
3249 (t (ad-deactivate function)))))))))
3250 3019
3251(defalias 'ad-activate-on 'ad-activate) 3020(defalias 'ad-activate-on 'ad-activate)
3252 3021
@@ -3261,11 +3030,10 @@ a call to `ad-activate'."
3261 (if (not (ad-is-advised function)) 3030 (if (not (ad-is-advised function))
3262 (error "ad-deactivate: `%s' is not advised" function) 3031 (error "ad-deactivate: `%s' is not advised" function)
3263 (cond ((ad-is-active function) 3032 (cond ((ad-is-active function)
3264 (ad-handle-definition function)
3265 (if (not (ad-get-orig-definition function)) 3033 (if (not (ad-get-orig-definition function))
3266 (error "ad-deactivate: `%s' has no original definition" 3034 (error "ad-deactivate: `%s' has no original definition"
3267 function) 3035 function)
3268 (fset function (ad-get-orig-definition function)) 3036 (ad-clear-advicefunname-definition function)
3269 (ad-set-advice-info-field function 'active nil) 3037 (ad-set-advice-info-field function 'active nil)
3270 (eval (ad-make-hook-form function 'deactivation)) 3038 (eval (ad-make-hook-form function 'deactivation))
3271 function))))) 3039 function)))))
@@ -3287,7 +3055,7 @@ If FUNCTION was not advised this will be a noop."
3287 (cond ((ad-is-advised function) 3055 (cond ((ad-is-advised function)
3288 (if (ad-is-active function) 3056 (if (ad-is-active function)
3289 (ad-deactivate function)) 3057 (ad-deactivate function))
3290 (ad-clear-orig-definition function) 3058 (ad-clear-advicefunname-definition function)
3291 (ad-set-advice-info function nil) 3059 (ad-set-advice-info function nil)
3292 (ad-pop-advised-function function)))) 3060 (ad-pop-advised-function function))))
3293 3061
@@ -3302,9 +3070,7 @@ Use in emergencies."
3302 (list (intern 3070 (list (intern
3303 (completing-read "Recover advised function: " obarray nil t)))) 3071 (completing-read "Recover advised function: " obarray nil t))))
3304 (cond ((ad-is-advised function) 3072 (cond ((ad-is-advised function)
3305 (cond ((ad-get-orig-definition function) 3073 (ad-clear-advicefunname-definition function)
3306 (fset function (ad-get-orig-definition function))
3307 (ad-clear-orig-definition function)))
3308 (ad-set-advice-info function nil) 3074 (ad-set-advice-info function nil)
3309 (ad-pop-advised-function function)))) 3075 (ad-pop-advised-function function))))
3310 3076
@@ -3544,35 +3310,15 @@ undone on exit of this macro."
3544;; @@ Starting, stopping and recovering from the advice package magic: 3310;; @@ Starting, stopping and recovering from the advice package magic:
3545;; =================================================================== 3311;; ===================================================================
3546 3312
3547(defun ad-start-advice ()
3548 "Start the automatic advice handling magic."
3549 (interactive)
3550 ;; Advising `ad-activate-internal' means death!!
3551 (ad-set-advice-info 'ad-activate-internal nil)
3552 (fset 'ad-activate-internal 'ad-activate))
3553
3554(defun ad-stop-advice ()
3555 "Stop the automatic advice handling magic.
3556You should only need this in case of Advice-related emergencies."
3557 (interactive)
3558 ;; Advising `ad-activate-internal' means death!!
3559 (ad-set-advice-info 'ad-activate-internal nil)
3560 (fset 'ad-activate-internal 'ad-activate-internal-off))
3561
3562(defun ad-recover-normality () 3313(defun ad-recover-normality ()
3563 "Undo all advice related redefinitions and unadvises everything. 3314 "Undo all advice related redefinitions and unadvises everything.
3564Use only in REAL emergencies." 3315Use only in REAL emergencies."
3565 (interactive) 3316 (interactive)
3566 ;; Advising `ad-activate-internal' means death!!
3567 (ad-set-advice-info 'ad-activate-internal nil)
3568 (fset 'ad-activate-internal 'ad-activate-internal-off)
3569 (ad-recover-all) 3317 (ad-recover-all)
3570 (ad-do-advised-functions (function) 3318 (ad-do-advised-functions (function)
3571 (message "Oops! Left over advised function %S" function) 3319 (message "Oops! Left over advised function %S" function)
3572 (ad-pop-advised-function function))) 3320 (ad-pop-advised-function function)))
3573 3321
3574(ad-start-advice)
3575
3576(provide 'advice) 3322(provide 'advice)
3577 3323
3578;;; advice.el ends here 3324;;; advice.el ends here
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index 02eec08f96b..5488330a1a4 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -236,7 +236,7 @@ For example, (setf (cadr x) y) is equivalent to (setcar (cdr x) y).
236The return value is the last VAL in the list. 236The return value is the last VAL in the list.
237 237
238\(fn PLACE VAL PLACE VAL ...)" 238\(fn PLACE VAL PLACE VAL ...)"
239 (declare (debug (gv-place form))) 239 (declare (debug (&rest [gv-place form])))
240 (if (and args (null (cddr args))) 240 (if (and args (null (cddr args)))
241 (let ((place (pop args)) 241 (let ((place (pop args))
242 (val (car args))) 242 (val (car args)))
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index ca1ebf3cad2..ff30d9e7fa4 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -30,7 +30,7 @@
30;; holds a function. 30;; holds a function.
31;; This part provides mainly 2 macros: `add-function' and `remove-function'. 31;; This part provides mainly 2 macros: `add-function' and `remove-function'.
32;; 32;;
33;; - The second part provides `add-advice' and `remove-advice' which are 33;; - The second part provides `advice-add' and `advice-remove' which are
34;; refined version of the previous macros specially tailored for the case 34;; refined version of the previous macros specially tailored for the case
35;; where the place that we want to modify is a `symbol-function'. 35;; where the place that we want to modify is a `symbol-function'.
36 36
@@ -234,7 +234,7 @@ of the piece of advice."
234 (cond 234 (cond
235 ((special-form-p def) 235 ((special-form-p def)
236 ;; Not worth the trouble trying to handle this, I think. 236 ;; Not worth the trouble trying to handle this, I think.
237 (error "add-advice failure: %S is a special form" symbol)) 237 (error "advice-add failure: %S is a special form" symbol))
238 ((and (symbolp def) 238 ((and (symbolp def)
239 (eq 'macro (car-safe (ignore-errors (indirect-function def))))) 239 (eq 'macro (car-safe (ignore-errors (indirect-function def)))))
240 (let ((newval (cons 'macro (cdr (indirect-function def))))) 240 (let ((newval (cons 'macro (cdr (indirect-function def)))))
diff --git a/lisp/gnus/pop3.el b/lisp/gnus/pop3.el
index f95bf26ad1d..801ed66ec2b 100644
--- a/lisp/gnus/pop3.el
+++ b/lisp/gnus/pop3.el
@@ -178,7 +178,7 @@ Shorter values mean quicker response, but are more CPU intensive.")
178 1000)))))) 178 1000))))))
179 179
180(defvar pop3-uidl) 180(defvar pop3-uidl)
181;; List of UIDLs of existing messages at pesent in the server: 181;; List of UIDLs of existing messages at present in the server:
182;; ("UIDL1" "UIDL2" "UIDL3"...) 182;; ("UIDL1" "UIDL2" "UIDL3"...)
183 183
184(defvar pop3-uidl-saved) 184(defvar pop3-uidl-saved)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 7c72b73a879..9d78b20ba4c 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -105,7 +105,10 @@
105(eval-and-compile 105(eval-and-compile
106 (defconst ruby-here-doc-beg-re 106 (defconst ruby-here-doc-beg-re
107 "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)" 107 "\\(<\\)<\\(-\\)?\\(\\([a-zA-Z0-9_]+\\)\\|[\"]\\([^\"]+\\)[\"]\\|[']\\([^']+\\)[']\\)"
108 "Regexp to match the beginning of a heredoc.")) 108 "Regexp to match the beginning of a heredoc.")
109
110 (defconst ruby-expression-expansion-re
111 "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)"))
109 112
110(defun ruby-here-doc-end-match () 113(defun ruby-here-doc-end-match ()
111 "Return a regexp to find the end of a heredoc. 114 "Return a regexp to find the end of a heredoc.
@@ -384,7 +387,9 @@ and `\\' when preceded by `?'."
384 (looking-at "class\\s *<<")))) 387 (looking-at "class\\s *<<"))))
385 388
386(defun ruby-expr-beg (&optional option) 389(defun ruby-expr-beg (&optional option)
387 "TODO: document." 390 "Check if point is possibly at the beginning of an expression.
391OPTION specifies the type of the expression.
392Can be one of `heredoc', `modifier', `expr-qstr', `expr-re'."
388 (save-excursion 393 (save-excursion
389 (store-match-data nil) 394 (store-match-data nil)
390 (let ((space (skip-chars-backward " \t")) 395 (let ((space (skip-chars-backward " \t"))
@@ -397,10 +402,10 @@ and `\\' when preceded by `?'."
397 (or (eq (char-syntax (char-before (point))) ?w) 402 (or (eq (char-syntax (char-before (point))) ?w)
398 (ruby-special-char-p)))) 403 (ruby-special-char-p))))
399 nil) 404 nil)
400 ((and (eq option 'heredoc) (< space 0)) 405 ((looking-at ruby-operator-re))
401 (not (progn (goto-char start) (ruby-singleton-class-p)))) 406 ((eq option 'heredoc)
402 ((or (looking-at ruby-operator-re) 407 (and (< space 0) (not (ruby-singleton-class-p start))))
403 (looking-at "[\\[({,;]") 408 ((or (looking-at "[\\[({,;]")
404 (and (looking-at "[!?]") 409 (and (looking-at "[!?]")
405 (or (not (eq option 'modifier)) 410 (or (not (eq option 'modifier))
406 (bolp) 411 (bolp)
@@ -865,39 +870,54 @@ calculating indentation on the lines after it."
865 (beginning-of-line))))) 870 (beginning-of-line)))))
866 871
867(defun ruby-move-to-block (n) 872(defun ruby-move-to-block (n)
868 "Move to the beginning (N < 0) or the end (N > 0) of the current block 873 "Move to the beginning (N < 0) or the end (N > 0) of the
869or blocks containing the current block." 874current block, a sibling block, or an outer block. Do that (abs N) times."
870 ;; TODO: Make this work for n > 1,
871 ;; make it not loop for n = 0,
872 ;; document body
873 (let ((orig (point)) 875 (let ((orig (point))
874 (start (ruby-calculate-indent)) 876 (start (ruby-calculate-indent))
875 (down (looking-at (if (< n 0) ruby-block-end-re 877 (signum (if (> n 0) 1 -1))
876 (concat "\\<\\(" ruby-block-beg-re "\\)\\>")))) 878 (backward (< n 0))
877 pos done) 879 down pos done)
878 (while (and (not done) (not (if (< n 0) (bobp) (eobp)))) 880 (dotimes (_ (abs n))
879 (forward-line n) 881 (setq done nil)
880 (cond 882 (setq down (save-excursion
881 ((looking-at "^\\s *$")) 883 (back-to-indentation)
882 ((looking-at "^\\s *#")) 884 ;; There is a block start or block end keyword on this
883 ((and (> n 0) (looking-at "^=begin\\>")) 885 ;; line, don't need to look for another block.
884 (re-search-forward "^=end\\>")) 886 (and (re-search-forward
885 ((and (< n 0) (looking-at "^=end\\>")) 887 (if backward ruby-block-end-re
886 (re-search-backward "^=begin\\>")) 888 (concat "\\_<\\(" ruby-block-beg-re "\\)\\_>"))
887 (t 889 (line-end-position) t)
888 (setq pos (current-indentation)) 890 (not (nth 8 (syntax-ppss))))))
891 (while (and (not done) (not (if backward (bobp) (eobp))))
892 (forward-line signum)
889 (cond 893 (cond
890 ((< start pos) 894 ;; Skip empty and commented out lines.
891 (setq down t)) 895 ((looking-at "^\\s *$"))
892 ((and down (= pos start)) 896 ((looking-at "^\\s *#"))
893 (setq done t)) 897 ;; Skip block comments;
894 ((> start pos) 898 ((and (not backward) (looking-at "^=begin\\>"))
895 (setq done t))))) 899 (re-search-forward "^=end\\>"))
896 (if done 900 ((and backward (looking-at "^=end\\>"))
897 (save-excursion 901 (re-search-backward "^=begin\\>"))
898 (back-to-indentation) 902 (t
899 (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>")) 903 (setq pos (current-indentation))
900 (setq done nil))))) 904 (cond
905 ;; Deeper indentation, we found a block.
906 ;; FIXME: We can't recognize empty blocks this way.
907 ((< start pos)
908 (setq down t))
909 ;; Block found, and same indentation as when started, stop.
910 ((and down (= pos start))
911 (setq done t))
912 ;; Shallower indentation, means outer block, can stop now.
913 ((> start pos)
914 (setq done t)))))
915 (if done
916 (save-excursion
917 (back-to-indentation)
918 ;; Not really at the first or last line of the block, move on.
919 (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>"))
920 (setq done nil))))))
901 (back-to-indentation))) 921 (back-to-indentation)))
902 922
903(defun ruby-beginning-of-block (&optional arg) 923(defun ruby-beginning-of-block (&optional arg)
@@ -909,8 +929,7 @@ With ARG, move up multiple blocks."
909(defun ruby-end-of-block (&optional arg) 929(defun ruby-end-of-block (&optional arg)
910 "Move forward to the end of the current block. 930 "Move forward to the end of the current block.
911With ARG, move out of multiple blocks." 931With ARG, move out of multiple blocks."
912 ;; Passing a value > 1 to ruby-move-to-block currently doesn't work. 932 (interactive "p")
913 (interactive)
914 (ruby-move-to-block (or arg 1))) 933 (ruby-move-to-block (or arg 1)))
915 934
916(defun ruby-forward-sexp (&optional arg) 935(defun ruby-forward-sexp (&optional arg)
@@ -1233,7 +1252,19 @@ It will be properly highlighted even when the call omits parens."))
1233 ;; Handle percent literals: %w(), %q{}, etc. 1252 ;; Handle percent literals: %w(), %q{}, etc.
1234 ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re) 1253 ((concat "\\(?:^\\|[[ \t\n<+(,=]\\)" ruby-percent-literal-beg-re)
1235 (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end))))) 1254 (1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
1236 (point) end)) 1255 (point) end)
1256 (remove-text-properties start end '(ruby-expansion-match-data))
1257 (goto-char start)
1258 ;; Find all expression expansions and
1259 ;; - set the syntax of all text inside to whitespace,
1260 ;; - save the match data to a text property, for font-locking later.
1261 (while (re-search-forward ruby-expression-expansion-re end 'move)
1262 (when (ruby-in-ppss-context-p 'string)
1263 (put-text-property (match-beginning 2) (match-end 2)
1264 'syntax-table (string-to-syntax "-"))
1265 (put-text-property (match-beginning 2) (1+ (match-beginning 2))
1266 'ruby-expansion-match-data
1267 (match-data)))))
1237 1268
1238 (defun ruby-syntax-propertize-heredoc (limit) 1269 (defun ruby-syntax-propertize-heredoc (limit)
1239 (let ((ppss (syntax-ppss)) 1270 (let ((ppss (syntax-ppss))
@@ -1566,7 +1597,7 @@ See `font-lock-syntax-table'.")
1566 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face) 1597 '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face)
1567 ;; expression expansion 1598 ;; expression expansion
1568 '(ruby-match-expression-expansion 1599 '(ruby-match-expression-expansion
1569 0 font-lock-variable-name-face t) 1600 2 font-lock-variable-name-face t)
1570 ;; warn lower camel case 1601 ;; warn lower camel case
1571 ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)" 1602 ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)"
1572 ; 0 font-lock-warning-face) 1603 ; 0 font-lock-warning-face)
@@ -1574,9 +1605,14 @@ See `font-lock-syntax-table'.")
1574 "Additional expressions to highlight in Ruby mode.") 1605 "Additional expressions to highlight in Ruby mode.")
1575 1606
1576(defun ruby-match-expression-expansion (limit) 1607(defun ruby-match-expression-expansion (limit)
1577 (when (re-search-forward "[^\\]\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\)\\)" limit 'move) 1608 (let ((prop 'ruby-expansion-match-data) pos value)
1578 (or (ruby-in-ppss-context-p 'string) 1609 (when (and (setq pos (next-single-char-property-change (point) prop
1579 (ruby-match-expression-expansion limit)))) 1610 nil limit))
1611 (> pos (point)))
1612 (goto-char pos)
1613 (or (and (setq value (get-text-property pos prop))
1614 (progn (set-match-data value) t))
1615 (ruby-match-expression-expansion limit)))))
1580 1616
1581;;;###autoload 1617;;;###autoload
1582(define-derived-mode ruby-mode prog-mode "Ruby" 1618(define-derived-mode ruby-mode prog-mode "Ruby"
diff --git a/lisp/woman.el b/lisp/woman.el
index 974a7d72465..46b6b680440 100644
--- a/lisp/woman.el
+++ b/lisp/woman.el
@@ -1303,12 +1303,12 @@ cache to be re-read."
1303 ((null (cdr files)) (car (car files))) ; only 1 file for topic. 1303 ((null (cdr files)) (car (car files))) ; only 1 file for topic.
1304 (t 1304 (t
1305 ;; Multiple files for topic, so must select 1. 1305 ;; Multiple files for topic, so must select 1.
1306 ;; Unread the command event (TAB = ?\t = 9) that runs the command 1306 ;; Run the command `minibuffer-complete' in order to automatically
1307 ;; `minibuffer-complete' in order to automatically complete the 1307 ;; complete the minibuffer contents as far as possible.
1308 ;; minibuffer contents as far as possible. 1308 (minibuffer-with-setup-hook
1309 (setq unread-command-events '(9)) ; and delete any type-ahead! 1309 (lambda () (let ((this-command this-command)) (minibuffer-complete)))
1310 (completing-read "Manual file: " files nil 1 1310 (completing-read "Manual file: " files nil 1
1311 (try-completion "" files) 'woman-file-history)))))) 1311 (try-completion "" files) 'woman-file-history)))))))
1312 1312
1313(defun woman-select (predicate list) 1313(defun woman-select (predicate list)
1314 "Select unique elements for which PREDICATE is true in LIST. 1314 "Select unique elements for which PREDICATE is true in LIST.
diff --git a/m4/euidaccess.m4 b/m4/euidaccess.m4
new file mode 100644
index 00000000000..2de95b88ba8
--- /dev/null
+++ b/m4/euidaccess.m4
@@ -0,0 +1,52 @@
1# euidaccess.m4 serial 15
2dnl Copyright (C) 2002-2012 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_FUNC_NONREENTRANT_EUIDACCESS],
8[
9 AC_REQUIRE([gl_FUNC_EUIDACCESS])
10 AC_CHECK_DECLS([setregid])
11 AC_DEFINE([PREFER_NONREENTRANT_EUIDACCESS], [1],
12 [Define this if you prefer euidaccess to return the correct result
13 even if this would make it nonreentrant. Define this only if your
14 entire application is safe even if the uid or gid might temporarily
15 change. If your application uses signal handlers or threads it
16 is probably not safe.])
17])
18
19AC_DEFUN([gl_FUNC_EUIDACCESS],
20[
21 AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
22
23 dnl Persuade glibc <unistd.h> to declare euidaccess().
24 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
25
26 AC_CHECK_FUNCS([euidaccess])
27 if test $ac_cv_func_euidaccess = no; then
28 HAVE_EUIDACCESS=0
29 fi
30])
31
32# Prerequisites of lib/euidaccess.c.
33AC_DEFUN([gl_PREREQ_EUIDACCESS], [
34 dnl Prefer POSIX faccessat over non-standard euidaccess.
35 AC_CHECK_FUNCS_ONCE([faccessat])
36 dnl Try various other non-standard fallbacks.
37 AC_CHECK_HEADERS([libgen.h])
38 AC_FUNC_GETGROUPS
39
40 # Solaris 9 and 10 need -lgen to get the eaccess function.
41 # Save and restore LIBS so -lgen isn't added to it. Otherwise, *all*
42 # programs in the package would end up linked with that potentially-shared
43 # library, inducing unnecessary run-time overhead.
44 LIB_EACCESS=
45 AC_SUBST([LIB_EACCESS])
46 gl_saved_libs=$LIBS
47 AC_SEARCH_LIBS([eaccess], [gen],
48 [test "$ac_cv_search_eaccess" = "none required" ||
49 LIB_EACCESS=$ac_cv_search_eaccess])
50 AC_CHECK_FUNCS([eaccess])
51 LIBS=$gl_saved_libs
52])
diff --git a/m4/faccessat.m4 b/m4/faccessat.m4
new file mode 100644
index 00000000000..82f3b1f8dde
--- /dev/null
+++ b/m4/faccessat.m4
@@ -0,0 +1,28 @@
1# serial 6
2# See if we need to provide faccessat replacement.
3
4dnl Copyright (C) 2009-2012 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_FACCESSAT],
12[
13 AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
14
15 dnl Persuade glibc <unistd.h> to declare faccessat().
16 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
17
18 AC_CHECK_FUNCS_ONCE([faccessat])
19 if test $ac_cv_func_faccessat = no; then
20 HAVE_FACCESSAT=0
21 fi
22])
23
24# Prerequisites of lib/faccessat.m4.
25AC_DEFUN([gl_PREREQ_FACCESSAT],
26[
27 AC_CHECK_FUNCS([access])
28])
diff --git a/m4/fcntl_h.m4 b/m4/fcntl_h.m4
new file mode 100644
index 00000000000..cac28aeb283
--- /dev/null
+++ b/m4/fcntl_h.m4
@@ -0,0 +1,50 @@
1# serial 15
2# Configure fcntl.h.
3dnl Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
4dnl This file is free software; the Free Software Foundation
5dnl gives unlimited permission to copy and/or distribute it,
6dnl with or without modifications, as long as this notice is preserved.
7
8dnl Written by Paul Eggert.
9
10AC_DEFUN([gl_FCNTL_H],
11[
12 AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
13 AC_REQUIRE([gl_FCNTL_O_FLAGS])
14 gl_NEXT_HEADERS([fcntl.h])
15
16 dnl Ensure the type pid_t gets defined.
17 AC_REQUIRE([AC_TYPE_PID_T])
18
19 dnl Ensure the type mode_t gets defined.
20 AC_REQUIRE([AC_TYPE_MODE_T])
21
22 dnl Check for declarations of anything we want to poison if the
23 dnl corresponding gnulib module is not in use, if it is not common
24 dnl enough to be declared everywhere.
25 gl_WARN_ON_USE_PREPARE([[#include <fcntl.h>
26 ]], [fcntl openat])
27])
28
29AC_DEFUN([gl_FCNTL_MODULE_INDICATOR],
30[
31 dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
32 AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
33 gl_MODULE_INDICATOR_SET_VARIABLE([$1])
34 dnl Define it also as a C macro, for the benefit of the unit tests.
35 gl_MODULE_INDICATOR_FOR_TESTS([$1])
36])
37
38AC_DEFUN([gl_FCNTL_H_DEFAULTS],
39[
40 GNULIB_FCNTL=0; AC_SUBST([GNULIB_FCNTL])
41 GNULIB_NONBLOCKING=0; AC_SUBST([GNULIB_NONBLOCKING])
42 GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN])
43 GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT])
44 dnl Assume proper GNU behavior unless another module says otherwise.
45 HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
46 HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])
47 REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL])
48 REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN])
49 REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT])
50])
diff --git a/m4/getgroups.m4 b/m4/getgroups.m4
new file mode 100644
index 00000000000..17473af486b
--- /dev/null
+++ b/m4/getgroups.m4
@@ -0,0 +1,107 @@
1# serial 18
2
3dnl From Jim Meyering.
4dnl A wrapper around AC_FUNC_GETGROUPS.
5
6# Copyright (C) 1996-1997, 1999-2004, 2008-2012 Free Software Foundation, Inc.
7#
8# This file is free software; the Free Software Foundation
9# gives unlimited permission to copy and/or distribute it,
10# with or without modifications, as long as this notice is preserved.
11
12m4_version_prereq([2.70], [] ,[
13
14# This is taken from the following Autoconf patch:
15# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9
16AC_DEFUN([AC_FUNC_GETGROUPS],
17[
18 AC_REQUIRE([AC_TYPE_GETGROUPS])dnl
19 AC_REQUIRE([AC_TYPE_SIZE_T])dnl
20 AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles
21 AC_CHECK_FUNC([getgroups])
22
23 # If we don't yet have getgroups, see if it's in -lbsd.
24 # This is reported to be necessary on an ITOS 3000WS running SEIUX 3.1.
25 ac_save_LIBS=$LIBS
26 if test $ac_cv_func_getgroups = no; then
27 AC_CHECK_LIB(bsd, getgroups, [GETGROUPS_LIB=-lbsd])
28 fi
29
30 # Run the program to test the functionality of the system-supplied
31 # getgroups function only if there is such a function.
32 if test $ac_cv_func_getgroups = yes; then
33 AC_CACHE_CHECK([for working getgroups], [ac_cv_func_getgroups_works],
34 [AC_RUN_IFELSE(
35 [AC_LANG_PROGRAM(
36 [AC_INCLUDES_DEFAULT],
37 [[/* On Ultrix 4.3, getgroups (0, 0) always fails. */
38 return getgroups (0, 0) == -1;]])
39 ],
40 [ac_cv_func_getgroups_works=yes],
41 [ac_cv_func_getgroups_works=no],
42 [case "$host_os" in # ((
43 # Guess yes on glibc systems.
44 *-gnu*) ac_cv_func_getgroups_works="guessing yes" ;;
45 # If we don't know, assume the worst.
46 *) ac_cv_func_getgroups_works="guessing no" ;;
47 esac
48 ])
49 ])
50 else
51 ac_cv_func_getgroups_works=no
52 fi
53 case "$ac_cv_func_getgroups_works" in
54 *yes)
55 AC_DEFINE([HAVE_GETGROUPS], [1],
56 [Define to 1 if your system has a working `getgroups' function.])
57 ;;
58 esac
59 LIBS=$ac_save_LIBS
60])# AC_FUNC_GETGROUPS
61
62])
63
64AC_DEFUN([gl_FUNC_GETGROUPS],
65[
66 AC_REQUIRE([AC_TYPE_GETGROUPS])
67 AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
68 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
69
70 AC_FUNC_GETGROUPS
71 if test $ac_cv_func_getgroups != yes; then
72 HAVE_GETGROUPS=0
73 else
74 if test "$ac_cv_type_getgroups" != gid_t \
75 || { case "$ac_cv_func_getgroups_works" in
76 *yes) false;;
77 *) true;;
78 esac
79 }; then
80 REPLACE_GETGROUPS=1
81 AC_DEFINE([GETGROUPS_ZERO_BUG], [1], [Define this to 1 if
82 getgroups(0,NULL) does not return the number of groups.])
83 else
84 dnl Detect FreeBSD bug; POSIX requires getgroups(-1,ptr) to fail.
85 AC_CACHE_CHECK([whether getgroups handles negative values],
86 [gl_cv_func_getgroups_works],
87 [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
88 [[int size = getgroups (0, 0);
89 gid_t *list = malloc (size * sizeof *list);
90 return getgroups (-1, list) != -1;]])],
91 [gl_cv_func_getgroups_works=yes],
92 [gl_cv_func_getgroups_works=no],
93 [case "$host_os" in
94 # Guess yes on glibc systems.
95 *-gnu*) gl_cv_func_getgroups_works="guessing yes" ;;
96 # If we don't know, assume the worst.
97 *) gl_cv_func_getgroups_works="guessing no" ;;
98 esac
99 ])])
100 case "$gl_cv_func_getgroups_works" in
101 *yes) ;;
102 *) REPLACE_GETGROUPS=1 ;;
103 esac
104 fi
105 fi
106 test -n "$GETGROUPS_LIB" && LIBS="$GETGROUPS_LIB $LIBS"
107])
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 5cd278454e7..30f81b4781f 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -54,18 +54,23 @@ AC_DEFUN([gl_EARLY],
54 # Code from module dtotimespec: 54 # Code from module dtotimespec:
55 # Code from module dup2: 55 # Code from module dup2:
56 # Code from module environ: 56 # Code from module environ:
57 # Code from module euidaccess:
57 # Code from module execinfo: 58 # Code from module execinfo:
58 # Code from module extensions: 59 # Code from module extensions:
59 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) 60 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
60 # Code from module extern-inline: 61 # Code from module extern-inline:
62 # Code from module faccessat:
63 # Code from module fcntl-h:
61 # Code from module filemode: 64 # Code from module filemode:
62 # Code from module fpending: 65 # Code from module fpending:
66 # Code from module getgroups:
63 # Code from module getloadavg: 67 # Code from module getloadavg:
64 # Code from module getopt-gnu: 68 # Code from module getopt-gnu:
65 # Code from module getopt-posix: 69 # Code from module getopt-posix:
66 # Code from module gettext-h: 70 # Code from module gettext-h:
67 # Code from module gettime: 71 # Code from module gettime:
68 # Code from module gettimeofday: 72 # Code from module gettimeofday:
73 # Code from module group-member:
69 # Code from module ignore-value: 74 # Code from module ignore-value:
70 # Code from module include_next: 75 # Code from module include_next:
71 # Code from module intprops: 76 # Code from module intprops:
@@ -81,6 +86,7 @@ AC_DEFUN([gl_EARLY],
81 # Code from module pselect: 86 # Code from module pselect:
82 # Code from module pthread_sigmask: 87 # Code from module pthread_sigmask:
83 # Code from module readlink: 88 # Code from module readlink:
89 # Code from module root-uid:
84 # Code from module signal-h: 90 # Code from module signal-h:
85 # Code from module snippet/_Noreturn: 91 # Code from module snippet/_Noreturn:
86 # Code from module snippet/arg-nonnull: 92 # Code from module snippet/arg-nonnull:
@@ -122,6 +128,7 @@ AC_DEFUN([gl_EARLY],
122 # Code from module utimens: 128 # Code from module utimens:
123 # Code from module verify: 129 # Code from module verify:
124 # Code from module warnings: 130 # Code from module warnings:
131 # Code from module xalloc-oversized:
125]) 132])
126 133
127# This macro should be invoked from ./configure.ac, in the section 134# This macro should be invoked from ./configure.ac, in the section
@@ -160,6 +167,14 @@ AC_DEFUN([gl_INIT],
160 gl_UNISTD_MODULE_INDICATOR([environ]) 167 gl_UNISTD_MODULE_INDICATOR([environ])
161 gl_EXECINFO_H 168 gl_EXECINFO_H
162 AC_REQUIRE([gl_EXTERN_INLINE]) 169 AC_REQUIRE([gl_EXTERN_INLINE])
170 gl_FUNC_FACCESSAT
171 if test $HAVE_FACCESSAT = 0; then
172 AC_LIBOBJ([faccessat])
173 gl_PREREQ_FACCESSAT
174 fi
175 gl_MODULE_INDICATOR([faccessat])
176 gl_UNISTD_MODULE_INDICATOR([faccessat])
177 gl_FCNTL_H
163 gl_FILEMODE 178 gl_FILEMODE
164 gl_FUNC_FPENDING 179 gl_FUNC_FPENDING
165 if test $ac_cv_func___fpending = no; then 180 if test $ac_cv_func___fpending = no; then
@@ -278,18 +293,53 @@ AC_DEFUN([gl_INIT],
278 gl_UNISTD_H 293 gl_UNISTD_H
279 gl_UTIMENS 294 gl_UTIMENS
280 gl_gnulib_enabled_dosname=false 295 gl_gnulib_enabled_dosname=false
296 gl_gnulib_enabled_euidaccess=false
297 gl_gnulib_enabled_getgroups=false
281 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false 298 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
299 gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=false
282 gl_gnulib_enabled_pathmax=false 300 gl_gnulib_enabled_pathmax=false
301 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
283 gl_gnulib_enabled_stat=false 302 gl_gnulib_enabled_stat=false
284 gl_gnulib_enabled_strtoll=false 303 gl_gnulib_enabled_strtoll=false
285 gl_gnulib_enabled_strtoull=false 304 gl_gnulib_enabled_strtoull=false
286 gl_gnulib_enabled_verify=false 305 gl_gnulib_enabled_verify=false
306 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
287 func_gl_gnulib_m4code_dosname () 307 func_gl_gnulib_m4code_dosname ()
288 { 308 {
289 if ! $gl_gnulib_enabled_dosname; then 309 if ! $gl_gnulib_enabled_dosname; then
290 gl_gnulib_enabled_dosname=true 310 gl_gnulib_enabled_dosname=true
291 fi 311 fi
292 } 312 }
313 func_gl_gnulib_m4code_euidaccess ()
314 {
315 if ! $gl_gnulib_enabled_euidaccess; then
316 gl_FUNC_EUIDACCESS
317 if test $HAVE_EUIDACCESS = 0; then
318 AC_LIBOBJ([euidaccess])
319 gl_PREREQ_EUIDACCESS
320 fi
321 gl_UNISTD_MODULE_INDICATOR([euidaccess])
322 gl_gnulib_enabled_euidaccess=true
323 if test $HAVE_EUIDACCESS = 0; then
324 func_gl_gnulib_m4code_a9786850e999ae65a836a6041e8e5ed1
325 fi
326 func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c
327 if test $HAVE_EUIDACCESS = 0; then
328 func_gl_gnulib_m4code_stat
329 fi
330 fi
331 }
332 func_gl_gnulib_m4code_getgroups ()
333 {
334 if ! $gl_gnulib_enabled_getgroups; then
335 gl_FUNC_GETGROUPS
336 if test $HAVE_GETGROUPS = 0 || test $REPLACE_GETGROUPS = 1; then
337 AC_LIBOBJ([getgroups])
338 fi
339 gl_UNISTD_MODULE_INDICATOR([getgroups])
340 gl_gnulib_enabled_getgroups=true
341 fi
342 }
293 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 () 343 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 ()
294 { 344 {
295 if ! $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then 345 if ! $gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36; then
@@ -298,6 +348,24 @@ AC_DEFUN([gl_INIT],
298 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true 348 gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=true
299 fi 349 fi
300 } 350 }
351 func_gl_gnulib_m4code_a9786850e999ae65a836a6041e8e5ed1 ()
352 {
353 if ! $gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1; then
354 gl_FUNC_GROUP_MEMBER
355 if test $HAVE_GROUP_MEMBER = 0; then
356 AC_LIBOBJ([group-member])
357 gl_PREREQ_GROUP_MEMBER
358 fi
359 gl_UNISTD_MODULE_INDICATOR([group-member])
360 gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1=true
361 if test $HAVE_GROUP_MEMBER = 0; then
362 func_gl_gnulib_m4code_getgroups
363 fi
364 if test $HAVE_GROUP_MEMBER = 0; then
365 func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec
366 fi
367 fi
368 }
301 func_gl_gnulib_m4code_pathmax () 369 func_gl_gnulib_m4code_pathmax ()
302 { 370 {
303 if ! $gl_gnulib_enabled_pathmax; then 371 if ! $gl_gnulib_enabled_pathmax; then
@@ -305,6 +373,12 @@ AC_DEFUN([gl_INIT],
305 gl_gnulib_enabled_pathmax=true 373 gl_gnulib_enabled_pathmax=true
306 fi 374 fi
307 } 375 }
376 func_gl_gnulib_m4code_6099e9737f757db36c47fa9d9f02e88c ()
377 {
378 if ! $gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c; then
379 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=true
380 fi
381 }
308 func_gl_gnulib_m4code_stat () 382 func_gl_gnulib_m4code_stat ()
309 { 383 {
310 if ! $gl_gnulib_enabled_stat; then 384 if ! $gl_gnulib_enabled_stat; then
@@ -356,6 +430,18 @@ AC_DEFUN([gl_INIT],
356 gl_gnulib_enabled_verify=true 430 gl_gnulib_enabled_verify=true
357 fi 431 fi
358 } 432 }
433 func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec ()
434 {
435 if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then
436 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=true
437 fi
438 }
439 if test $HAVE_FACCESSAT = 0; then
440 func_gl_gnulib_m4code_dosname
441 fi
442 if test $HAVE_FACCESSAT = 0; then
443 func_gl_gnulib_m4code_euidaccess
444 fi
359 if test $REPLACE_GETOPT = 1; then 445 if test $REPLACE_GETOPT = 1; then
360 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36 446 func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36
361 fi 447 fi
@@ -382,12 +468,17 @@ AC_DEFUN([gl_INIT],
382 fi 468 fi
383 m4_pattern_allow([^gl_GNULIB_ENABLED_]) 469 m4_pattern_allow([^gl_GNULIB_ENABLED_])
384 AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname]) 470 AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname])
471 AM_CONDITIONAL([gl_GNULIB_ENABLED_euidaccess], [$gl_gnulib_enabled_euidaccess])
472 AM_CONDITIONAL([gl_GNULIB_ENABLED_getgroups], [$gl_gnulib_enabled_getgroups])
385 AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36]) 473 AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
474 AM_CONDITIONAL([gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1], [$gl_gnulib_enabled_a9786850e999ae65a836a6041e8e5ed1])
386 AM_CONDITIONAL([gl_GNULIB_ENABLED_pathmax], [$gl_gnulib_enabled_pathmax]) 475 AM_CONDITIONAL([gl_GNULIB_ENABLED_pathmax], [$gl_gnulib_enabled_pathmax])
476 AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c])
387 AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat]) 477 AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat])
388 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) 478 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
389 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull]) 479 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull])
390 AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify]) 480 AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify])
481 AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec])
391 # End of code from modules 482 # End of code from modules
392 m4_ifval(gl_LIBSOURCES_LIST, [ 483 m4_ifval(gl_LIBSOURCES_LIST, [
393 m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || 484 m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||
@@ -536,6 +627,7 @@ AC_DEFUN([gl_FILE_LIST], [
536 lib/alloca.in.h 627 lib/alloca.in.h
537 lib/allocator.c 628 lib/allocator.c
538 lib/allocator.h 629 lib/allocator.h
630 lib/at-func.c
539 lib/c-ctype.c 631 lib/c-ctype.c
540 lib/c-ctype.h 632 lib/c-ctype.h
541 lib/c-strcase.h 633 lib/c-strcase.h
@@ -549,14 +641,18 @@ AC_DEFUN([gl_FILE_LIST], [
549 lib/dtoastr.c 641 lib/dtoastr.c
550 lib/dtotimespec.c 642 lib/dtotimespec.c
551 lib/dup2.c 643 lib/dup2.c
644 lib/euidaccess.c
552 lib/execinfo.c 645 lib/execinfo.c
553 lib/execinfo.in.h 646 lib/execinfo.in.h
647 lib/faccessat.c
648 lib/fcntl.in.h
554 lib/filemode.c 649 lib/filemode.c
555 lib/filemode.h 650 lib/filemode.h
556 lib/fpending.c 651 lib/fpending.c
557 lib/fpending.h 652 lib/fpending.h
558 lib/ftoastr.c 653 lib/ftoastr.c
559 lib/ftoastr.h 654 lib/ftoastr.h
655 lib/getgroups.c
560 lib/getloadavg.c 656 lib/getloadavg.c
561 lib/getopt.c 657 lib/getopt.c
562 lib/getopt.in.h 658 lib/getopt.in.h
@@ -565,6 +661,7 @@ AC_DEFUN([gl_FILE_LIST], [
565 lib/gettext.h 661 lib/gettext.h
566 lib/gettime.c 662 lib/gettime.c
567 lib/gettimeofday.c 663 lib/gettimeofday.c
664 lib/group-member.c
568 lib/ignore-value.h 665 lib/ignore-value.h
569 lib/intprops.h 666 lib/intprops.h
570 lib/inttypes.in.h 667 lib/inttypes.in.h
@@ -577,6 +674,7 @@ AC_DEFUN([gl_FILE_LIST], [
577 lib/pselect.c 674 lib/pselect.c
578 lib/pthread_sigmask.c 675 lib/pthread_sigmask.c
579 lib/readlink.c 676 lib/readlink.c
677 lib/root-uid.h
580 lib/sha1.c 678 lib/sha1.c
581 lib/sha1.h 679 lib/sha1.h
582 lib/sha256.c 680 lib/sha256.c
@@ -618,6 +716,7 @@ AC_DEFUN([gl_FILE_LIST], [
618 lib/utimens.c 716 lib/utimens.c
619 lib/utimens.h 717 lib/utimens.h
620 lib/verify.h 718 lib/verify.h
719 lib/xalloc-oversized.h
621 m4/00gnulib.m4 720 m4/00gnulib.m4
622 m4/alloca.m4 721 m4/alloca.m4
623 m4/c-strtod.m4 722 m4/c-strtod.m4
@@ -625,16 +724,22 @@ AC_DEFUN([gl_FILE_LIST], [
625 m4/close-stream.m4 724 m4/close-stream.m4
626 m4/dup2.m4 725 m4/dup2.m4
627 m4/environ.m4 726 m4/environ.m4
727 m4/euidaccess.m4
628 m4/execinfo.m4 728 m4/execinfo.m4
629 m4/extensions.m4 729 m4/extensions.m4
630 m4/extern-inline.m4 730 m4/extern-inline.m4
731 m4/faccessat.m4
732 m4/fcntl-o.m4
733 m4/fcntl_h.m4
631 m4/filemode.m4 734 m4/filemode.m4
632 m4/fpending.m4 735 m4/fpending.m4
736 m4/getgroups.m4
633 m4/getloadavg.m4 737 m4/getloadavg.m4
634 m4/getopt.m4 738 m4/getopt.m4
635 m4/gettime.m4 739 m4/gettime.m4
636 m4/gettimeofday.m4 740 m4/gettimeofday.m4
637 m4/gnulib-common.m4 741 m4/gnulib-common.m4
742 m4/group-member.m4
638 m4/include_next.m4 743 m4/include_next.m4
639 m4/inttypes.m4 744 m4/inttypes.m4
640 m4/largefile.m4 745 m4/largefile.m4
diff --git a/m4/group-member.m4 b/m4/group-member.m4
new file mode 100644
index 00000000000..c393b5b1303
--- /dev/null
+++ b/m4/group-member.m4
@@ -0,0 +1,29 @@
1# serial 14
2
3# Copyright (C) 1999-2001, 2003-2007, 2009-2012 Free Software Foundation, Inc.
4
5# This file is free software; the Free Software Foundation
6# gives unlimited permission to copy and/or distribute it,
7# with or without modifications, as long as this notice is preserved.
8
9dnl Written by Jim Meyering
10
11AC_DEFUN([gl_FUNC_GROUP_MEMBER],
12[
13 AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
14
15 dnl Persuade glibc <unistd.h> to declare group_member().
16 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
17
18 dnl Do this replacement check manually because I want the hyphen
19 dnl (not the underscore) in the filename.
20 AC_CHECK_FUNC([group_member], , [
21 HAVE_GROUP_MEMBER=0
22 ])
23])
24
25# Prerequisites of lib/group-member.c.
26AC_DEFUN([gl_PREREQ_GROUP_MEMBER],
27[
28 AC_REQUIRE([AC_FUNC_GETGROUPS])
29])
diff --git a/nt/ChangeLog b/nt/ChangeLog
index 931cb745c8b..320c9e6366e 100644
--- a/nt/ChangeLog
+++ b/nt/ChangeLog
@@ -1,3 +1,10 @@
12012-11-14 Paul Eggert <eggert@cs.ucla.edu>
2
3 Use faccessat, not access, when checking file permissions (Bug#12632).
4 * inc/ms-w32.h (AT_FDCWD, AT_EACCESS): New symbols.
5 (access): Remove.
6 (faccessat): New macro.
7
12012-11-05 Eli Zaretskii <eliz@gnu.org> 82012-11-05 Eli Zaretskii <eliz@gnu.org>
2 9
3 * inc/unistd.h (tcgetpgrp, setsid): Provide prototypes. 10 * inc/unistd.h (tcgetpgrp, setsid): Provide 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 ();
124#define MAXPATHLEN _MAX_PATH 124#define MAXPATHLEN _MAX_PATH
125#endif 125#endif
126 126
127/* Use values compatible with gnulib, as there's no reason to differ. */
128#define AT_FDCWD (-3041965)
129#define AT_EACCESS 4
130
127#ifdef HAVE_NTGUI 131#ifdef HAVE_NTGUI
128#define HAVE_WINDOW_SYSTEM 1 132#define HAVE_WINDOW_SYSTEM 1
129#define HAVE_MENUS 1 133#define HAVE_MENUS 1
@@ -145,8 +149,6 @@ extern char *getenv ();
145#endif 149#endif
146 150
147/* Calls that are emulated or shadowed. */ 151/* Calls that are emulated or shadowed. */
148#undef access
149#define access sys_access
150#undef chdir 152#undef chdir
151#define chdir sys_chdir 153#define chdir sys_chdir
152#undef chmod 154#undef chmod
@@ -161,6 +163,7 @@ extern char *getenv ();
161#define dup sys_dup 163#define dup sys_dup
162#undef dup2 164#undef dup2
163#define dup2 sys_dup2 165#define dup2 sys_dup2
166#define faccessat sys_faccessat
164#define fopen sys_fopen 167#define fopen sys_fopen
165#define link sys_link 168#define link sys_link
166#define localtime sys_localtime 169#define localtime sys_localtime
diff --git a/src/ChangeLog b/src/ChangeLog
index e67518d63ba..ba476cdacba 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -3,13 +3,85 @@
3 * font.c (font_unparse_xlfd): Exclude special characters from the 3 * font.c (font_unparse_xlfd): Exclude special characters from the
4 generating XLFD name. 4 generating XLFD name.
5 5
62012-11-14 Dmitry Antipov <dmantipov@yandex.ru>
7
8 * xdisp.c (echo_area_display, redisplay_internal):
9 Omit redundant check whether frame_garbaged is set.
10
112012-11-14 Paul Eggert <eggert@cs.ucla.edu>
12
13 Use faccessat, not access, when checking file permissions (Bug#12632).
14 This fixes a bug that has been present in Emacs since its creation.
15 It was reported by Chris Torek in 1983 even before GNU Emacs existed,
16 which must set some sort of record. (Torek's bug report was against
17 a predecessor of GNU Emacs, but GNU Emacs happened to have the
18 same common flaw.) See Torek's Usenet posting
19 "setuid/setgid programs & Emacs" Article-I.D.: sri-arpa.858
20 Posted: Fri Apr 8 14:18:56 1983.
21 * Makefile.in (LIB_EACCESS): New macro.
22 (LIBES): Use it.
23 * callproc.c (init_callproc):
24 * charset.c (init_charset):
25 * fileio.c (check_existing, check_executable, check_writable)
26 (Ffile_readable_p):
27 * lread.c (openp, load_path_check):
28 * process.c (allocate_pty):
29 * xrdb.c (file_p):
30 Use effective UID when checking permissions, not real UID.
31 * callproc.c (init_callproc):
32 * charset.c (init_charset):
33 * lread.c (load_path_check, init_lread):
34 Test whether directories are accessible, not merely whether they exist.
35 * conf_post.h (GNULIB_SUPPORT_ONLY_AT_FDCWD): New macro.
36 * fileio.c (check_existing, check_executable, check_writable)
37 (Ffile_readable_p):
38 Use symbolic names instead of integers for the flags, as they're
39 portable now.
40 (check_writable): New arg AMODE. All uses changed.
41 Set errno on failure.
42 (Ffile_readable_p): Use faccessat, not stat + open + close.
43 (Ffile_writable_p): No need to call check_existing + check_writable.
44 Just call check_writable and then look at errno. This saves a syscall.
45 dir should never be nil; replace an unnecessary runtime check
46 with an eassert. When checking the parent directory of a nonexistent
47 file, check that the directory is searchable as well as writable, as
48 we can't create files in unsearchable directories.
49 (file_directory_p): New function, which uses 'stat' on most platforms
50 but faccessat with D_OK (for efficiency) if WINDOWSNT.
51 (Ffile_directory_p, Fset_file_times): Use it.
52 (file_accessible_directory_p): New function, which uses a single
53 syscall for efficiency.
54 (Ffile_accessible_directory_p): Use it.
55 * xrdb.c (file_p): Use file_directory_p.
56 * lisp.h (file_directory_p, file_accessible_directory_p): New decls.
57 * lread.c (openp): When opening a file, use fstat rather than
58 stat, as that avoids a permissions race. When not opening a file,
59 use file_directory_p rather than stat.
60 (dir_warning): First arg is now a usage string, not a format.
61 Use errno. All uses changed.
62 * nsterm.m (ns_term_init): Remove unnecessary call to file-readable
63 that merely introduced a race.
64 * process.c, sysdep.c, term.c: All uses of '#ifdef O_NONBLOCK'
65 changed to '#if O_NONBLOCK', to accommodate gnulib O_* style,
66 and similarly for the other O_* flags.
67 * w32.c (sys_faccessat): Rename from sys_access and switch to
68 faccessat's API. All uses changed.
69 * xrdb.c: Do not include <sys/stat.h>; no longer needed.
70 (magic_db): Rename from magic_file_p.
71 (magic_db, search_magic_path): Return an XrmDatabase rather than a
72 char *, so that we don't have to test for file existence
73 separately from opening the file for reading. This removes a race
74 fixes a permission-checking problem, and simplifies the code.
75 All uses changed.
76 (file_p): Remove; no longer needed.
77
62012-11-13 Dmitry Antipov <dmantipov@yandex.ru> 782012-11-13 Dmitry Antipov <dmantipov@yandex.ru>
7 79
8 Omit glyphs initialization at startup. 80 Omit glyphs initialization at startup.
9 * dispnew.c (glyphs_initialized_initially_p): Remove. 81 * dispnew.c (glyphs_initialized_initially_p): Remove.
10 (adjust_frame_glyphs_initially): Likewise. Adjust users. 82 (adjust_frame_glyphs_initially): Likewise. Adjust users.
11 (Fredraw_frame): Move actual code from here... 83 (Fredraw_frame): Move actual code from here...
12 (redraw_here): ...to here. Add eassert. Adjust comment. 84 (redraw_frame): ...to here. Add eassert. Adjust comment.
13 (Fredraw_display): Use redraw_frame. 85 (Fredraw_display): Use redraw_frame.
14 * xdisp.c (clear_garbaged_frames): Likewise. 86 * xdisp.c (clear_garbaged_frames): Likewise.
15 87
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@
150M17N_FLT_LIBS = @M17N_FLT_LIBS@ 150M17N_FLT_LIBS = @M17N_FLT_LIBS@
151 151
152LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@ 152LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@
153LIB_EACCESS=@LIB_EACCESS@
153LIB_TIMER_TIME=@LIB_TIMER_TIME@ 154LIB_TIMER_TIME=@LIB_TIMER_TIME@
154 155
155DBUS_CFLAGS = @DBUS_CFLAGS@ 156DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -392,7 +393,7 @@ otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
392LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \ 393LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \
393 $(LIBX_OTHER) $(LIBSOUND) \ 394 $(LIBX_OTHER) $(LIBSOUND) \
394 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \ 395 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \
395 $(LIB_TIMER_TIME) $(DBUS_LIBS) \ 396 $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
396 $(LIB_EXECINFO) \ 397 $(LIB_EXECINFO) \
397 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 398 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
398 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 399 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
diff --git a/src/callproc.c b/src/callproc.c
index c7bbe36e605..8ecaba2b408 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1576,15 +1576,13 @@ init_callproc (void)
1576#endif 1576#endif
1577 { 1577 {
1578 tempdir = Fdirectory_file_name (Vexec_directory); 1578 tempdir = Fdirectory_file_name (Vexec_directory);
1579 if (access (SSDATA (tempdir), 0) < 0) 1579 if (! file_accessible_directory_p (SSDATA (tempdir)))
1580 dir_warning ("Warning: arch-dependent data dir (%s) does not exist.\n", 1580 dir_warning ("arch-dependent data dir", Vexec_directory);
1581 Vexec_directory);
1582 } 1581 }
1583 1582
1584 tempdir = Fdirectory_file_name (Vdata_directory); 1583 tempdir = Fdirectory_file_name (Vdata_directory);
1585 if (access (SSDATA (tempdir), 0) < 0) 1584 if (! file_accessible_directory_p (SSDATA (tempdir)))
1586 dir_warning ("Warning: arch-independent data dir (%s) does not exist.\n", 1585 dir_warning ("arch-independent data dir", Vdata_directory);
1587 Vdata_directory);
1588 1586
1589 sh = (char *) getenv ("SHELL"); 1587 sh = (char *) getenv ("SHELL");
1590 Vshell_file_name = build_string (sh ? sh : "/bin/sh"); 1588 Vshell_file_name = build_string (sh ? sh : "/bin/sh");
@@ -1593,7 +1591,7 @@ init_callproc (void)
1593 Vshared_game_score_directory = Qnil; 1591 Vshared_game_score_directory = Qnil;
1594#else 1592#else
1595 Vshared_game_score_directory = build_string (PATH_GAME); 1593 Vshared_game_score_directory = build_string (PATH_GAME);
1596 if (NILP (Ffile_directory_p (Vshared_game_score_directory))) 1594 if (NILP (Ffile_accessible_directory_p (Vshared_game_score_directory)))
1597 Vshared_game_score_directory = Qnil; 1595 Vshared_game_score_directory = Qnil;
1598#endif 1596#endif
1599} 1597}
diff --git a/src/charset.c b/src/charset.c
index 6b999824dab..c9133c780e8 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2293,7 +2293,7 @@ init_charset (void)
2293{ 2293{
2294 Lisp_Object tempdir; 2294 Lisp_Object tempdir;
2295 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); 2295 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
2296 if (access (SSDATA (tempdir), 0) < 0) 2296 if (! file_accessible_directory_p (SSDATA (tempdir)))
2297 { 2297 {
2298 /* This used to be non-fatal (dir_warning), but it should not 2298 /* This used to be non-fatal (dir_warning), but it should not
2299 happen, and if it does sooner or later it will cause some 2299 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 66390ddf103..b1997e79081 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -178,6 +178,10 @@ extern void _DebPrint (const char *fmt, ...);
178#endif 178#endif
179#endif 179#endif
180 180
181/* Tell gnulib to omit support for openat-related functions having a
182 first argument other than AT_FDCWD. */
183#define GNULIB_SUPPORT_ONLY_AT_FDCWD
184
181#include <string.h> 185#include <string.h>
182#include <stdlib.h> 186#include <stdlib.h>
183 187
diff --git a/src/fileio.c b/src/fileio.c
index b9541e78838..572f6d8ef83 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2425,15 +2425,7 @@ On Unix, this is a name starting with a `/' or a `~'. */)
2425bool 2425bool
2426check_existing (const char *filename) 2426check_existing (const char *filename)
2427{ 2427{
2428#ifdef DOS_NT 2428 return faccessat (AT_FDCWD, filename, F_OK, AT_EACCESS) == 0;
2429 /* The full emulation of Posix 'stat' is too expensive on
2430 DOS/Windows, when all we want to know is whether the file exists.
2431 So we use 'access' instead, which is much more lightweight. */
2432 return (access (filename, F_OK) >= 0);
2433#else
2434 struct stat st;
2435 return (stat (filename, &st) >= 0);
2436#endif
2437} 2429}
2438 2430
2439/* Return true if file FILENAME exists and can be executed. */ 2431/* Return true if file FILENAME exists and can be executed. */
@@ -2441,56 +2433,40 @@ check_existing (const char *filename)
2441static bool 2433static bool
2442check_executable (char *filename) 2434check_executable (char *filename)
2443{ 2435{
2444#ifdef DOS_NT 2436 return faccessat (AT_FDCWD, filename, X_OK, AT_EACCESS) == 0;
2445 struct stat st;
2446 if (stat (filename, &st) < 0)
2447 return 0;
2448 return ((st.st_mode & S_IEXEC) != 0);
2449#else /* not DOS_NT */
2450#ifdef HAVE_EUIDACCESS
2451 return (euidaccess (filename, 1) >= 0);
2452#else
2453 /* Access isn't quite right because it uses the real uid
2454 and we really want to test with the effective uid.
2455 But Unix doesn't give us a right way to do it. */
2456 return (access (filename, 1) >= 0);
2457#endif
2458#endif /* not DOS_NT */
2459} 2437}
2460 2438
2461/* Return true if file FILENAME exists and can be written. */ 2439/* Return true if file FILENAME exists and can be accessed
2440 according to AMODE, which should include W_OK.
2441 On failure, return false and set errno. */
2462 2442
2463static bool 2443static bool
2464check_writable (const char *filename) 2444check_writable (const char *filename, int amode)
2465{ 2445{
2466#ifdef MSDOS 2446#ifdef MSDOS
2447 /* FIXME: an faccessat implementation should be added to the
2448 DOS/Windows ports and this #ifdef branch should be removed. */
2467 struct stat st; 2449 struct stat st;
2468 if (stat (filename, &st) < 0) 2450 if (stat (filename, &st) < 0)
2469 return 0; 2451 return 0;
2452 errno = EPERM;
2470 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode)); 2453 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode));
2471#else /* not MSDOS */ 2454#else /* not MSDOS */
2472#ifdef HAVE_EUIDACCESS 2455 bool res = faccessat (AT_FDCWD, filename, amode, AT_EACCESS) == 0;
2473 bool res = (euidaccess (filename, 2) >= 0);
2474#ifdef CYGWIN 2456#ifdef CYGWIN
2475 /* euidaccess may have returned failure because Cygwin couldn't 2457 /* faccessat may have returned failure because Cygwin couldn't
2476 determine the file's UID or GID; if so, we return success. */ 2458 determine the file's UID or GID; if so, we return success. */
2477 if (!res) 2459 if (!res)
2478 { 2460 {
2461 int faccessat_errno = errno;
2479 struct stat st; 2462 struct stat st;
2480 if (stat (filename, &st) < 0) 2463 if (stat (filename, &st) < 0)
2481 return 0; 2464 return 0;
2482 res = (st.st_uid == -1 || st.st_gid == -1); 2465 res = (st.st_uid == -1 || st.st_gid == -1);
2466 errno = faccessat_errno;
2483 } 2467 }
2484#endif /* CYGWIN */ 2468#endif /* CYGWIN */
2485 return res; 2469 return res;
2486#else /* not HAVE_EUIDACCESS */
2487 /* Access isn't quite right because it uses the real uid
2488 and we really want to test with the effective uid.
2489 But Unix doesn't give us a right way to do it.
2490 Opening with O_WRONLY could work for an ordinary file,
2491 but would lose for directories. */
2492 return (access (filename, 2) >= 0);
2493#endif /* not HAVE_EUIDACCESS */
2494#endif /* not MSDOS */ 2470#endif /* not MSDOS */
2495} 2471}
2496 2472
@@ -2547,9 +2523,6 @@ See also `file-exists-p' and `file-attributes'. */)
2547{ 2523{
2548 Lisp_Object absname; 2524 Lisp_Object absname;
2549 Lisp_Object handler; 2525 Lisp_Object handler;
2550 int desc;
2551 int flags;
2552 struct stat statbuf;
2553 2526
2554 CHECK_STRING (filename); 2527 CHECK_STRING (filename);
2555 absname = Fexpand_file_name (filename, Qnil); 2528 absname = Fexpand_file_name (filename, Qnil);
@@ -2561,35 +2534,10 @@ See also `file-exists-p' and `file-attributes'. */)
2561 return call2 (handler, Qfile_readable_p, absname); 2534 return call2 (handler, Qfile_readable_p, absname);
2562 2535
2563 absname = ENCODE_FILE (absname); 2536 absname = ENCODE_FILE (absname);
2564 2537 return (faccessat (AT_FDCWD, SSDATA (absname), R_OK, AT_EACCESS) == 0
2565#if defined (DOS_NT) || defined (macintosh) 2538 ? Qt : Qnil);
2566 /* Under MS-DOS, Windows, and Macintosh, open does not work for
2567 directories. */
2568 if (access (SDATA (absname), 0) == 0)
2569 return Qt;
2570 return Qnil;
2571#else /* not DOS_NT and not macintosh */
2572 flags = O_RDONLY;
2573#ifdef O_NONBLOCK
2574 /* Opening a fifo without O_NONBLOCK can wait.
2575 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2576 except in the case of a fifo, on a system which handles it. */
2577 desc = stat (SSDATA (absname), &statbuf);
2578 if (desc < 0)
2579 return Qnil;
2580 if (S_ISFIFO (statbuf.st_mode))
2581 flags |= O_NONBLOCK;
2582#endif
2583 desc = emacs_open (SSDATA (absname), flags, 0);
2584 if (desc < 0)
2585 return Qnil;
2586 emacs_close (desc);
2587 return Qt;
2588#endif /* not DOS_NT and not macintosh */
2589} 2539}
2590 2540
2591/* Having this before file-symlink-p mysteriously caused it to be forgotten
2592 on the RT/PC. */
2593DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, 2541DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2594 doc: /* Return t if file FILENAME can be written or created by you. */) 2542 doc: /* Return t if file FILENAME can be written or created by you. */)
2595 (Lisp_Object filename) 2543 (Lisp_Object filename)
@@ -2607,14 +2555,15 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2607 return call2 (handler, Qfile_writable_p, absname); 2555 return call2 (handler, Qfile_writable_p, absname);
2608 2556
2609 encoded = ENCODE_FILE (absname); 2557 encoded = ENCODE_FILE (absname);
2610 if (check_existing (SSDATA (encoded))) 2558 if (check_writable (SSDATA (encoded), W_OK))
2611 return (check_writable (SSDATA (encoded)) 2559 return Qt;
2612 ? Qt : Qnil); 2560 if (errno != ENOENT)
2561 return Qnil;
2613 2562
2614 dir = Ffile_name_directory (absname); 2563 dir = Ffile_name_directory (absname);
2564 eassert (!NILP (dir));
2615#ifdef MSDOS 2565#ifdef MSDOS
2616 if (!NILP (dir)) 2566 dir = Fdirectory_file_name (dir);
2617 dir = Fdirectory_file_name (dir);
2618#endif /* MSDOS */ 2567#endif /* MSDOS */
2619 2568
2620 dir = ENCODE_FILE (dir); 2569 dir = ENCODE_FILE (dir);
@@ -2622,10 +2571,9 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2622 /* The read-only attribute of the parent directory doesn't affect 2571 /* The read-only attribute of the parent directory doesn't affect
2623 whether a file or directory can be created within it. Some day we 2572 whether a file or directory can be created within it. Some day we
2624 should check ACLs though, which do affect this. */ 2573 should check ACLs though, which do affect this. */
2625 return (access (SDATA (dir), D_OK) < 0) ? Qnil : Qt; 2574 return file_directory_p (SDATA (dir)) ? Qt : Qnil;
2626#else 2575#else
2627 return (check_writable (!NILP (dir) ? SSDATA (dir) : "") 2576 return check_writable (SSDATA (dir), W_OK | X_OK) ? Qt : Qnil;
2628 ? Qt : Qnil);
2629#endif 2577#endif
2630} 2578}
2631 2579
@@ -2703,8 +2651,7 @@ Symbolic links to directories count as directories.
2703See `file-symlink-p' to distinguish symlinks. */) 2651See `file-symlink-p' to distinguish symlinks. */)
2704 (Lisp_Object filename) 2652 (Lisp_Object filename)
2705{ 2653{
2706 register Lisp_Object absname; 2654 Lisp_Object absname;
2707 struct stat st;
2708 Lisp_Object handler; 2655 Lisp_Object handler;
2709 2656
2710 absname = expand_and_dir_to_file (filename, BVAR (current_buffer, directory)); 2657 absname = expand_and_dir_to_file (filename, BVAR (current_buffer, directory));
@@ -2717,9 +2664,20 @@ See `file-symlink-p' to distinguish symlinks. */)
2717 2664
2718 absname = ENCODE_FILE (absname); 2665 absname = ENCODE_FILE (absname);
2719 2666
2720 if (stat (SSDATA (absname), &st) < 0) 2667 return file_directory_p (SSDATA (absname)) ? Qt : Qnil;
2721 return Qnil; 2668}
2722 return S_ISDIR (st.st_mode) ? Qt : Qnil; 2669
2670/* Return true if FILE is a directory or a symlink to a directory. */
2671bool
2672file_directory_p (char const *file)
2673{
2674#ifdef WINDOWSNT
2675 /* This is cheaper than 'stat'. */
2676 return faccessat (AT_FDCWD, file, D_OK, AT_EACCESS) == 0;
2677#else
2678 struct stat st;
2679 return stat (file, &st) == 0 && S_ISDIR (st.st_mode);
2680#endif
2723} 2681}
2724 2682
2725DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, 2683DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p,
@@ -2733,21 +2691,65 @@ if the directory so specified exists and really is a readable and
2733searchable directory. */) 2691searchable directory. */)
2734 (Lisp_Object filename) 2692 (Lisp_Object filename)
2735{ 2693{
2694 Lisp_Object absname;
2736 Lisp_Object handler; 2695 Lisp_Object handler;
2737 bool tem; 2696
2738 struct gcpro gcpro1; 2697 CHECK_STRING (filename);
2698 absname = Fexpand_file_name (filename, Qnil);
2739 2699
2740 /* If the file name has special constructs in it, 2700 /* If the file name has special constructs in it,
2741 call the corresponding file handler. */ 2701 call the corresponding file handler. */
2742 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p); 2702 handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p);
2743 if (!NILP (handler)) 2703 if (!NILP (handler))
2744 return call2 (handler, Qfile_accessible_directory_p, filename); 2704 return call2 (handler, Qfile_accessible_directory_p, absname);
2745 2705
2746 GCPRO1 (filename); 2706 absname = ENCODE_FILE (absname);
2747 tem = (NILP (Ffile_directory_p (filename)) 2707 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil;
2748 || NILP (Ffile_executable_p (filename))); 2708}
2749 UNGCPRO; 2709
2750 return tem ? Qnil : Qt; 2710/* If FILE is a searchable directory or a symlink to a
2711 searchable directory, return true. Otherwise return
2712 false and set errno to an error number. */
2713bool
2714file_accessible_directory_p (char const *file)
2715{
2716#ifdef DOS_NT
2717 /* There's no need to test whether FILE is searchable, as the
2718 searchable/executable bit is invented on DOS_NT platforms. */
2719 return file_directory_p (file);
2720#else
2721 /* On POSIXish platforms, use just one system call; this avoids a
2722 race and is typically faster. */
2723 ptrdiff_t len = strlen (file);
2724 char const *dir;
2725 bool ok;
2726 int saved_errno;
2727 USE_SAFE_ALLOCA;
2728
2729 /* Normally a file "FOO" is an accessible directory if "FOO/." exists.
2730 There are three exceptions: "", "/", and "//". Leave "" alone,
2731 as it's invalid. Append only "." to the other two exceptions as
2732 "/" and "//" are distinct on some platforms, whereas "/", "///",
2733 "////", etc. are all equivalent. */
2734 if (! len)
2735 dir = file;
2736 else
2737 {
2738 /* Just check for trailing '/' when deciding whether to append '/'.
2739 That's simpler than testing the two special cases "/" and "//",
2740 and it's a safe optimization here. */
2741 char *buf = SAFE_ALLOCA (len + 3);
2742 memcpy (buf, file, len);
2743 strcpy (buf + len, "/." + (file[len - 1] == '/'));
2744 dir = buf;
2745 }
2746
2747 ok = check_existing (dir);
2748 saved_errno = errno;
2749 SAFE_FREE ();
2750 errno = saved_errno;
2751 return ok;
2752#endif
2751} 2753}
2752 2754
2753DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0, 2755DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
@@ -3044,10 +3046,8 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3044 if (set_file_times (-1, SSDATA (encoded_absname), t, t)) 3046 if (set_file_times (-1, SSDATA (encoded_absname), t, t))
3045 { 3047 {
3046#ifdef MSDOS 3048#ifdef MSDOS
3047 struct stat st;
3048
3049 /* Setting times on a directory always fails. */ 3049 /* Setting times on a directory always fails. */
3050 if (stat (SSDATA (encoded_absname), &st) == 0 && S_ISDIR (st.st_mode)) 3050 if (file_directory_p (SSDATA (encoded_absname)))
3051 return Qnil; 3051 return Qnil;
3052#endif 3052#endif
3053 report_file_error ("Setting file times", Fcons (absname, Qnil)); 3053 report_file_error ("Setting file times", Fcons (absname, Qnil));
diff --git a/src/lisp.h b/src/lisp.h
index 72e38fa4653..67ae28a488f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3202,6 +3202,8 @@ extern Lisp_Object close_file_unwind (Lisp_Object);
3202extern Lisp_Object restore_point_unwind (Lisp_Object); 3202extern Lisp_Object restore_point_unwind (Lisp_Object);
3203extern _Noreturn void report_file_error (const char *, Lisp_Object); 3203extern _Noreturn void report_file_error (const char *, Lisp_Object);
3204extern void internal_delete_file (Lisp_Object); 3204extern void internal_delete_file (Lisp_Object);
3205extern bool file_directory_p (const char *);
3206extern bool file_accessible_directory_p (const char *);
3205extern void syms_of_fileio (void); 3207extern void syms_of_fileio (void);
3206extern Lisp_Object make_temp_name (Lisp_Object, bool); 3208extern Lisp_Object make_temp_name (Lisp_Object, bool);
3207extern Lisp_Object Qdelete_file; 3209extern Lisp_Object Qdelete_file;
diff --git a/src/lread.c b/src/lread.c
index 3a82e0057e2..5859a2f85a9 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1403,7 +1403,7 @@ Returns the file's name in absolute form, or nil if not found.
1403If SUFFIXES is non-nil, it should be a list of suffixes to append to 1403If SUFFIXES is non-nil, it should be a list of suffixes to append to
1404file name when searching. 1404file name when searching.
1405If non-nil, PREDICATE is used instead of `file-readable-p'. 1405If non-nil, PREDICATE is used instead of `file-readable-p'.
1406PREDICATE can also be an integer to pass to the access(2) function, 1406PREDICATE can also be an integer to pass to the faccessat(2) function,
1407in which case file-name-handlers are ignored. 1407in which case file-name-handlers are ignored.
1408This function will normally skip directories, so if you want it to find 1408This function will normally skip directories, so if you want it to find
1409directories, make sure the PREDICATE function returns `dir-ok' for them. */) 1409directories, make sure the PREDICATE function returns `dir-ok' for them. */)
@@ -1441,7 +1441,6 @@ static Lisp_Object Qdir_ok;
1441int 1441int
1442openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) 1442openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate)
1443{ 1443{
1444 int fd;
1445 ptrdiff_t fn_size = 100; 1444 ptrdiff_t fn_size = 100;
1446 char buf[100]; 1445 char buf[100];
1447 char *fn = buf; 1446 char *fn = buf;
@@ -1496,7 +1495,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1496 { 1495 {
1497 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); 1496 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
1498 Lisp_Object handler; 1497 Lisp_Object handler;
1499 bool exists;
1500 1498
1501 /* Concatenate path element/specified name with the suffix. 1499 /* Concatenate path element/specified name with the suffix.
1502 If the directory starts with /:, remove that. */ 1500 If the directory starts with /:, remove that. */
@@ -1520,6 +1518,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1520 handler = Ffind_file_name_handler (string, Qfile_exists_p); 1518 handler = Ffind_file_name_handler (string, Qfile_exists_p);
1521 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1519 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1522 { 1520 {
1521 bool exists;
1523 if (NILP (predicate)) 1522 if (NILP (predicate))
1524 exists = !NILP (Ffile_readable_p (string)); 1523 exists = !NILP (Ffile_readable_p (string));
1525 else 1524 else
@@ -1541,37 +1540,40 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1541 } 1540 }
1542 else 1541 else
1543 { 1542 {
1544#ifndef WINDOWSNT 1543 int fd;
1545 struct stat st;
1546#endif
1547 const char *pfn; 1544 const char *pfn;
1548 1545
1549 encoded_fn = ENCODE_FILE (string); 1546 encoded_fn = ENCODE_FILE (string);
1550 pfn = SSDATA (encoded_fn); 1547 pfn = SSDATA (encoded_fn);
1551#ifdef WINDOWSNT
1552 exists = access (pfn, F_OK) == 0 && access (pfn, D_OK) < 0;
1553#else
1554 exists = (stat (pfn, &st) == 0 && ! S_ISDIR (st.st_mode));
1555#endif
1556 if (exists)
1557 {
1558 /* Check that we can access or open it. */
1559 if (NATNUMP (predicate))
1560 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
1561 && access (pfn, XFASTINT (predicate)) == 0)
1562 ? 1 : -1);
1563 else
1564 fd = emacs_open (pfn, O_RDONLY, 0);
1565 1548
1566 if (fd >= 0) 1549 /* Check that we can access or open it. */
1550 if (NATNUMP (predicate))
1551 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
1552 && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
1553 AT_EACCESS)
1554 == 0)
1555 && ! file_directory_p (pfn))
1556 ? 1 : -1);
1557 else
1558 {
1559 struct stat st;
1560 fd = emacs_open (pfn, O_RDONLY, 0);
1561 if (0 <= fd
1562 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode)))
1567 { 1563 {
1568 /* We succeeded; return this descriptor and filename. */ 1564 emacs_close (fd);
1569 if (storeptr) 1565 fd = -1;
1570 *storeptr = string;
1571 UNGCPRO;
1572 return fd;
1573 } 1566 }
1574 } 1567 }
1568
1569 if (fd >= 0)
1570 {
1571 /* We succeeded; return this descriptor and filename. */
1572 if (storeptr)
1573 *storeptr = string;
1574 UNGCPRO;
1575 return fd;
1576 }
1575 } 1577 }
1576 } 1578 }
1577 if (absolute) 1579 if (absolute)
@@ -4087,9 +4089,8 @@ load_path_check (void)
4087 if (STRINGP (dirfile)) 4089 if (STRINGP (dirfile))
4088 { 4090 {
4089 dirfile = Fdirectory_file_name (dirfile); 4091 dirfile = Fdirectory_file_name (dirfile);
4090 if (access (SSDATA (dirfile), 0) < 0) 4092 if (! file_accessible_directory_p (SSDATA (dirfile)))
4091 dir_warning ("Warning: Lisp directory `%s' does not exist.\n", 4093 dir_warning ("Lisp directory", XCAR (path_tail));
4092 XCAR (path_tail));
4093 } 4094 }
4094 } 4095 }
4095} 4096}
@@ -4201,11 +4202,11 @@ init_lread (void)
4201 Lisp_Object tem, tem1; 4202 Lisp_Object tem, tem1;
4202 4203
4203 /* Add to the path the lisp subdir of the installation 4204 /* Add to the path the lisp subdir of the installation
4204 dir, if it exists. Note: in out-of-tree builds, 4205 dir, if it is accessible. Note: in out-of-tree builds,
4205 this directory is empty save for Makefile. */ 4206 this directory is empty save for Makefile. */
4206 tem = Fexpand_file_name (build_string ("lisp"), 4207 tem = Fexpand_file_name (build_string ("lisp"),
4207 Vinstallation_directory); 4208 Vinstallation_directory);
4208 tem1 = Ffile_exists_p (tem); 4209 tem1 = Ffile_accessible_directory_p (tem);
4209 if (!NILP (tem1)) 4210 if (!NILP (tem1))
4210 { 4211 {
4211 if (NILP (Fmember (tem, Vload_path))) 4212 if (NILP (Fmember (tem, Vload_path)))
@@ -4222,10 +4223,10 @@ init_lread (void)
4222 Lisp dirs instead. */ 4223 Lisp dirs instead. */
4223 Vload_path = nconc2 (Vload_path, dump_path); 4224 Vload_path = nconc2 (Vload_path, dump_path);
4224 4225
4225 /* Add leim under the installation dir, if it exists. */ 4226 /* Add leim under the installation dir, if it is accessible. */
4226 tem = Fexpand_file_name (build_string ("leim"), 4227 tem = Fexpand_file_name (build_string ("leim"),
4227 Vinstallation_directory); 4228 Vinstallation_directory);
4228 tem1 = Ffile_exists_p (tem); 4229 tem1 = Ffile_accessible_directory_p (tem);
4229 if (!NILP (tem1)) 4230 if (!NILP (tem1))
4230 { 4231 {
4231 if (NILP (Fmember (tem, Vload_path))) 4232 if (NILP (Fmember (tem, Vload_path)))
@@ -4237,7 +4238,7 @@ init_lread (void)
4237 { 4238 {
4238 tem = Fexpand_file_name (build_string ("site-lisp"), 4239 tem = Fexpand_file_name (build_string ("site-lisp"),
4239 Vinstallation_directory); 4240 Vinstallation_directory);
4240 tem1 = Ffile_exists_p (tem); 4241 tem1 = Ffile_accessible_directory_p (tem);
4241 if (!NILP (tem1)) 4242 if (!NILP (tem1))
4242 { 4243 {
4243 if (NILP (Fmember (tem, Vload_path))) 4244 if (NILP (Fmember (tem, Vload_path)))
@@ -4282,7 +4283,7 @@ init_lread (void)
4282 { 4283 {
4283 tem = Fexpand_file_name (build_string ("site-lisp"), 4284 tem = Fexpand_file_name (build_string ("site-lisp"),
4284 Vsource_directory); 4285 Vsource_directory);
4285 tem1 = Ffile_exists_p (tem); 4286 tem1 = Ffile_accessible_directory_p (tem);
4286 if (!NILP (tem1)) 4287 if (!NILP (tem1))
4287 { 4288 {
4288 if (NILP (Fmember (tem, Vload_path))) 4289 if (NILP (Fmember (tem, Vload_path)))
@@ -4338,21 +4339,28 @@ init_lread (void)
4338 Vloads_in_progress = Qnil; 4339 Vloads_in_progress = Qnil;
4339} 4340}
4340 4341
4341/* Print a warning, using format string FORMAT, that directory DIRNAME 4342/* Print a warning that directory intended for use USE and with name
4342 does not exist. Print it on stderr and put it in *Messages*. */ 4343 DIRNAME cannot be accessed. On entry, errno should correspond to
4344 the access failure. Print the warning on stderr and put it in
4345 *Messages*. */
4343 4346
4344void 4347void
4345dir_warning (const char *format, Lisp_Object dirname) 4348dir_warning (char const *use, Lisp_Object dirname)
4346{ 4349{
4347 fprintf (stderr, format, SDATA (dirname)); 4350 static char const format[] = "Warning: %s `%s': %s\n";
4351 int access_errno = errno;
4352 fprintf (stderr, format, use, SSDATA (dirname), strerror (access_errno));
4348 4353
4349 /* Don't log the warning before we've initialized!! */ 4354 /* Don't log the warning before we've initialized!! */
4350 if (initialized) 4355 if (initialized)
4351 { 4356 {
4357 char const *diagnostic = emacs_strerror (access_errno);
4352 USE_SAFE_ALLOCA; 4358 USE_SAFE_ALLOCA;
4353 char *buffer = SAFE_ALLOCA (SBYTES (dirname) 4359 char *buffer = SAFE_ALLOCA (sizeof format - 3 * (sizeof "%s" - 1)
4354 + strlen (format) - (sizeof "%s" - 1) + 1); 4360 + strlen (use) + SBYTES (dirname)
4355 ptrdiff_t message_len = esprintf (buffer, format, SDATA (dirname)); 4361 + strlen (diagnostic));
4362 ptrdiff_t message_len = esprintf (buffer, format, use, SSDATA (dirname),
4363 diagnostic);
4356 message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname)); 4364 message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname));
4357 SAFE_FREE (); 4365 SAFE_FREE ();
4358 } 4366 }
diff --git a/src/nsterm.m b/src/nsterm.m
index 7ba1608268b..804ab825dee 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4112,8 +4112,6 @@ ns_term_init (Lisp_Object display_name)
4112 4112
4113 color_file = Fexpand_file_name (build_string ("rgb.txt"), 4113 color_file = Fexpand_file_name (build_string ("rgb.txt"),
4114 Fsymbol_value (intern ("data-directory"))); 4114 Fsymbol_value (intern ("data-directory")));
4115 if (NILP (Ffile_readable_p (color_file)))
4116 fatal ("Could not find %s.\n", SDATA (color_file));
4117 4115
4118 color_map = Fx_load_color_file (color_file); 4116 color_map = Fx_load_color_file (color_file);
4119 if (NILP (color_map)) 4117 if (NILP (color_map))
diff --git a/src/process.c b/src/process.c
index 43f0239d301..728abebe758 100644
--- a/src/process.c
+++ b/src/process.c
@@ -208,7 +208,7 @@ static EMACS_INT update_tick;
208#ifndef NON_BLOCKING_CONNECT 208#ifndef NON_BLOCKING_CONNECT
209#ifdef HAVE_SELECT 209#ifdef HAVE_SELECT
210#if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX) 210#if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX)
211#if defined (O_NONBLOCK) || defined (O_NDELAY) 211#if O_NONBLOCK || O_NDELAY
212#if defined (EWOULDBLOCK) || defined (EINPROGRESS) 212#if defined (EWOULDBLOCK) || defined (EINPROGRESS)
213#define NON_BLOCKING_CONNECT 213#define NON_BLOCKING_CONNECT
214#endif /* EWOULDBLOCK || EINPROGRESS */ 214#endif /* EWOULDBLOCK || EINPROGRESS */
@@ -655,7 +655,7 @@ allocate_pty (void)
655 PTY_OPEN; 655 PTY_OPEN;
656#else /* no PTY_OPEN */ 656#else /* no PTY_OPEN */
657 { 657 {
658# ifdef O_NONBLOCK 658# if O_NONBLOCK
659 fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0); 659 fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0);
660# else 660# else
661 fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0); 661 fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0);
@@ -672,7 +672,7 @@ allocate_pty (void)
672#else 672#else
673 sprintf (pty_name, "/dev/tty%c%x", c, i); 673 sprintf (pty_name, "/dev/tty%c%x", c, i);
674#endif /* no PTY_TTY_NAME_SPRINTF */ 674#endif /* no PTY_TTY_NAME_SPRINTF */
675 if (access (pty_name, 6) != 0) 675 if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0)
676 { 676 {
677 emacs_close (fd); 677 emacs_close (fd);
678# ifndef __sgi 678# ifndef __sgi
@@ -1624,7 +1624,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1624#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 1624#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
1625 /* On most USG systems it does not work to open the pty's tty here, 1625 /* On most USG systems it does not work to open the pty's tty here,
1626 then close it and reopen it in the child. */ 1626 then close it and reopen it in the child. */
1627#ifdef O_NOCTTY 1627#if O_NOCTTY
1628 /* Don't let this terminal become our controlling terminal 1628 /* Don't let this terminal become our controlling terminal
1629 (in case we don't have one). */ 1629 (in case we don't have one). */
1630 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); 1630 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
@@ -1678,11 +1678,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1678 } 1678 }
1679#endif 1679#endif
1680 1680
1681#ifdef O_NONBLOCK 1681#if O_NONBLOCK
1682 fcntl (inchannel, F_SETFL, O_NONBLOCK); 1682 fcntl (inchannel, F_SETFL, O_NONBLOCK);
1683 fcntl (outchannel, F_SETFL, O_NONBLOCK); 1683 fcntl (outchannel, F_SETFL, O_NONBLOCK);
1684#else 1684#else
1685#ifdef O_NDELAY 1685#if O_NDELAY
1686 fcntl (inchannel, F_SETFL, O_NDELAY); 1686 fcntl (inchannel, F_SETFL, O_NDELAY);
1687 fcntl (outchannel, F_SETFL, O_NDELAY); 1687 fcntl (outchannel, F_SETFL, O_NDELAY);
1688#endif 1688#endif
@@ -1943,7 +1943,7 @@ create_pty (Lisp_Object process)
1943#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 1943#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
1944 /* On most USG systems it does not work to open the pty's tty here, 1944 /* On most USG systems it does not work to open the pty's tty here,
1945 then close it and reopen it in the child. */ 1945 then close it and reopen it in the child. */
1946#ifdef O_NOCTTY 1946#if O_NOCTTY
1947 /* Don't let this terminal become our controlling terminal 1947 /* Don't let this terminal become our controlling terminal
1948 (in case we don't have one). */ 1948 (in case we don't have one). */
1949 int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); 1949 int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
@@ -1963,11 +1963,11 @@ create_pty (Lisp_Object process)
1963 } 1963 }
1964#endif /* HAVE_PTYS */ 1964#endif /* HAVE_PTYS */
1965 1965
1966#ifdef O_NONBLOCK 1966#if O_NONBLOCK
1967 fcntl (inchannel, F_SETFL, O_NONBLOCK); 1967 fcntl (inchannel, F_SETFL, O_NONBLOCK);
1968 fcntl (outchannel, F_SETFL, O_NONBLOCK); 1968 fcntl (outchannel, F_SETFL, O_NONBLOCK);
1969#else 1969#else
1970#ifdef O_NDELAY 1970#if O_NDELAY
1971 fcntl (inchannel, F_SETFL, O_NDELAY); 1971 fcntl (inchannel, F_SETFL, O_NDELAY);
1972 fcntl (outchannel, F_SETFL, O_NDELAY); 1972 fcntl (outchannel, F_SETFL, O_NDELAY);
1973#endif 1973#endif
@@ -2927,7 +2927,7 @@ usage: (make-network-process &rest ARGS) */)
2927 { 2927 {
2928 /* Don't support network sockets when non-blocking mode is 2928 /* Don't support network sockets when non-blocking mode is
2929 not available, since a blocked Emacs is not useful. */ 2929 not available, since a blocked Emacs is not useful. */
2930#if !defined (O_NONBLOCK) && !defined (O_NDELAY) 2930#if !O_NONBLOCK && !O_NDELAY
2931 error ("Network servers not supported"); 2931 error ("Network servers not supported");
2932#else 2932#else
2933 is_server = 1; 2933 is_server = 1;
@@ -3193,7 +3193,7 @@ usage: (make-network-process &rest ARGS) */)
3193#ifdef NON_BLOCKING_CONNECT 3193#ifdef NON_BLOCKING_CONNECT
3194 if (is_non_blocking_client) 3194 if (is_non_blocking_client)
3195 { 3195 {
3196#ifdef O_NONBLOCK 3196#if O_NONBLOCK
3197 ret = fcntl (s, F_SETFL, O_NONBLOCK); 3197 ret = fcntl (s, F_SETFL, O_NONBLOCK);
3198#else 3198#else
3199 ret = fcntl (s, F_SETFL, O_NDELAY); 3199 ret = fcntl (s, F_SETFL, O_NDELAY);
@@ -3410,10 +3410,10 @@ usage: (make-network-process &rest ARGS) */)
3410 3410
3411 chan_process[inch] = proc; 3411 chan_process[inch] = proc;
3412 3412
3413#ifdef O_NONBLOCK 3413#if O_NONBLOCK
3414 fcntl (inch, F_SETFL, O_NONBLOCK); 3414 fcntl (inch, F_SETFL, O_NONBLOCK);
3415#else 3415#else
3416#ifdef O_NDELAY 3416#if O_NDELAY
3417 fcntl (inch, F_SETFL, O_NDELAY); 3417 fcntl (inch, F_SETFL, O_NDELAY);
3418#endif 3418#endif
3419#endif 3419#endif
@@ -4145,10 +4145,10 @@ server_accept_connection (Lisp_Object server, int channel)
4145 4145
4146 chan_process[s] = proc; 4146 chan_process[s] = proc;
4147 4147
4148#ifdef O_NONBLOCK 4148#if O_NONBLOCK
4149 fcntl (s, F_SETFL, O_NONBLOCK); 4149 fcntl (s, F_SETFL, O_NONBLOCK);
4150#else 4150#else
4151#ifdef O_NDELAY 4151#if O_NDELAY
4152 fcntl (s, F_SETFL, O_NDELAY); 4152 fcntl (s, F_SETFL, O_NDELAY);
4153#endif 4153#endif
4154#endif 4154#endif
@@ -4849,11 +4849,11 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4849#endif 4849#endif
4850 /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK, 4850 /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK,
4851 and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */ 4851 and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */
4852#ifdef O_NONBLOCK 4852#if O_NONBLOCK
4853 else if (nread == -1 && errno == EAGAIN) 4853 else if (nread == -1 && errno == EAGAIN)
4854 ; 4854 ;
4855#else 4855#else
4856#ifdef O_NDELAY 4856#if O_NDELAY
4857 else if (nread == -1 && errno == EAGAIN) 4857 else if (nread == -1 && errno == EAGAIN)
4858 ; 4858 ;
4859 /* Note that we cannot distinguish between no input 4859 /* Note that we cannot distinguish between no input
@@ -7348,7 +7348,7 @@ init_process_emacs (void)
7348#ifdef HAVE_GETSOCKNAME 7348#ifdef HAVE_GETSOCKNAME
7349 ADD_SUBFEATURE (QCservice, Qt); 7349 ADD_SUBFEATURE (QCservice, Qt);
7350#endif 7350#endif
7351#if defined (O_NONBLOCK) || defined (O_NDELAY) 7351#if O_NONBLOCK || O_NDELAY
7352 ADD_SUBFEATURE (QCserver, Qt); 7352 ADD_SUBFEATURE (QCserver, Qt);
7353#endif 7353#endif
7354 7354
diff --git a/src/sysdep.c b/src/sysdep.c
index aa9d0f38c3c..a7f3de2f1b1 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1287,7 +1287,7 @@ reset_sys_modes (struct tty_display_info *tty_out)
1287 old_fcntl_owner[fileno (tty_out->input)]); 1287 old_fcntl_owner[fileno (tty_out->input)]);
1288 } 1288 }
1289#endif /* F_SETOWN */ 1289#endif /* F_SETOWN */
1290#ifdef O_NDELAY 1290#if O_NDELAY
1291 fcntl (fileno (tty_out->input), F_SETFL, 1291 fcntl (fileno (tty_out->input), F_SETFL,
1292 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY); 1292 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
1293#endif 1293#endif
@@ -2384,12 +2384,12 @@ serial_open (char *port)
2384 2384
2385 fd = emacs_open ((char*) port, 2385 fd = emacs_open ((char*) port,
2386 O_RDWR 2386 O_RDWR
2387#ifdef O_NONBLOCK 2387#if O_NONBLOCK
2388 | O_NONBLOCK 2388 | O_NONBLOCK
2389#else 2389#else
2390 | O_NDELAY 2390 | O_NDELAY
2391#endif 2391#endif
2392#ifdef O_NOCTTY 2392#if O_NOCTTY
2393 | O_NOCTTY 2393 | O_NOCTTY
2394#endif 2394#endif
2395 , 0); 2395 , 0);
diff --git a/src/term.c b/src/term.c
index 578c701858f..96549290da5 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2992,7 +2992,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
2992 int fd; 2992 int fd;
2993 FILE *file; 2993 FILE *file;
2994 2994
2995#ifdef O_IGNORE_CTTY 2995#if O_IGNORE_CTTY
2996 if (!ctty) 2996 if (!ctty)
2997 /* Open the terminal device. Don't recognize it as our 2997 /* Open the terminal device. Don't recognize it as our
2998 controlling terminal, and don't make it the controlling tty 2998 controlling terminal, and don't make it the controlling tty
@@ -3023,7 +3023,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3023 name); 3023 name);
3024 } 3024 }
3025 3025
3026#ifndef O_IGNORE_CTTY 3026#if !O_IGNORE_CTTY
3027 if (!ctty) 3027 if (!ctty)
3028 dissociate_if_controlling_tty (fd); 3028 dissociate_if_controlling_tty (fd);
3029#endif 3029#endif
diff --git a/src/w32.c b/src/w32.c
index 5ac1bc3eb7c..0e7da449b81 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1597,7 +1597,7 @@ init_environment (char ** argv)
1597 see if it succeeds. But I think that's too much to ask. */ 1597 see if it succeeds. But I think that's too much to ask. */
1598 1598
1599 /* MSVCRT's _access crashes with D_OK. */ 1599 /* MSVCRT's _access crashes with D_OK. */
1600 if (tmp && sys_access (tmp, D_OK) == 0) 1600 if (tmp && sys_faccessat (AT_FDCWD, tmp, D_OK, AT_EACCESS) == 0)
1601 { 1601 {
1602 char * var = alloca (strlen (tmp) + 8); 1602 char * var = alloca (strlen (tmp) + 8);
1603 sprintf (var, "TMPDIR=%s", tmp); 1603 sprintf (var, "TMPDIR=%s", tmp);
@@ -2714,10 +2714,16 @@ logon_network_drive (const char *path)
2714 long file names. */ 2714 long file names. */
2715 2715
2716int 2716int
2717sys_access (const char * path, int mode) 2717sys_faccessat (int dirfd, const char * path, int mode, int flags)
2718{ 2718{
2719 DWORD attributes; 2719 DWORD attributes;
2720 2720
2721 if (dirfd != AT_FDCWD)
2722 {
2723 errno = EBADF;
2724 return -1;
2725 }
2726
2721 /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its 2727 /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its
2722 newer versions blow up when passed D_OK. */ 2728 newer versions blow up when passed D_OK. */
2723 path = map_w32_filename (path, NULL); 2729 path = map_w32_filename (path, NULL);
@@ -2960,7 +2966,7 @@ sys_mktemp (char * template)
2960 { 2966 {
2961 int save_errno = errno; 2967 int save_errno = errno;
2962 p[0] = first_char[i]; 2968 p[0] = first_char[i];
2963 if (sys_access (template, 0) < 0) 2969 if (sys_faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0)
2964 { 2970 {
2965 errno = save_errno; 2971 errno = save_errno;
2966 return template; 2972 return template;
@@ -4011,7 +4017,7 @@ symlink (char const *filename, char const *linkname)
4011 { 4017 {
4012 /* Non-absolute FILENAME is understood as being relative to 4018 /* Non-absolute FILENAME is understood as being relative to
4013 LINKNAME's directory. We need to prepend that directory to 4019 LINKNAME's directory. We need to prepend that directory to
4014 FILENAME to get correct results from sys_access below, since 4020 FILENAME to get correct results from sys_faccessat below, since
4015 otherwise it will interpret FILENAME relative to the 4021 otherwise it will interpret FILENAME relative to the
4016 directory where the Emacs process runs. Note that 4022 directory where the Emacs process runs. Note that
4017 make-symbolic-link always makes sure LINKNAME is a fully 4023 make-symbolic-link always makes sure LINKNAME is a fully
@@ -4025,10 +4031,10 @@ symlink (char const *filename, char const *linkname)
4025 strncpy (tem, linkfn, p - linkfn); 4031 strncpy (tem, linkfn, p - linkfn);
4026 tem[p - linkfn] = '\0'; 4032 tem[p - linkfn] = '\0';
4027 strcat (tem, filename); 4033 strcat (tem, filename);
4028 dir_access = sys_access (tem, D_OK); 4034 dir_access = sys_faccessat (AT_FDCWD, tem, D_OK, AT_EACCESS);
4029 } 4035 }
4030 else 4036 else
4031 dir_access = sys_access (filename, D_OK); 4037 dir_access = sys_faccessat (AT_FDCWD, filename, D_OK, AT_EACCESS);
4032 4038
4033 /* Since Windows distinguishes between symlinks to directories and 4039 /* Since Windows distinguishes between symlinks to directories and
4034 to files, we provide a kludgy feature: if FILENAME doesn't 4040 to files, we provide a kludgy feature: if FILENAME doesn't
diff --git a/src/xdisp.c b/src/xdisp.c
index a74628db392..27d9fff0b7d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10816,8 +10816,7 @@ echo_area_display (int update_frame_p)
10816#endif /* HAVE_WINDOW_SYSTEM */ 10816#endif /* HAVE_WINDOW_SYSTEM */
10817 10817
10818 /* Redraw garbaged frames. */ 10818 /* Redraw garbaged frames. */
10819 if (frame_garbaged) 10819 clear_garbaged_frames ();
10820 clear_garbaged_frames ();
10821 10820
10822 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0) 10821 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10823 { 10822 {
@@ -13104,8 +13103,7 @@ redisplay_internal (void)
13104 } 13103 }
13105 13104
13106 /* Clear frames marked as garbaged. */ 13105 /* Clear frames marked as garbaged. */
13107 if (frame_garbaged) 13106 clear_garbaged_frames ();
13108 clear_garbaged_frames ();
13109 13107
13110 /* Build menubar and tool-bar items. */ 13108 /* Build menubar and tool-bar items. */
13111 if (NILP (Vmemory_full)) 13109 if (NILP (Vmemory_full))
@@ -13189,8 +13187,7 @@ redisplay_internal (void)
13189 /* If window configuration was changed, frames may have been 13187 /* If window configuration was changed, frames may have been
13190 marked garbaged. Clear them or we will experience 13188 marked garbaged. Clear them or we will experience
13191 surprises wrt scrolling. */ 13189 surprises wrt scrolling. */
13192 if (frame_garbaged) 13190 clear_garbaged_frames ();
13193 clear_garbaged_frames ();
13194 } 13191 }
13195 } 13192 }
13196 else if (EQ (selected_window, minibuf_window) 13193 else if (EQ (selected_window, minibuf_window)
@@ -13213,8 +13210,7 @@ redisplay_internal (void)
13213 /* If window configuration was changed, frames may have been 13210 /* If window configuration was changed, frames may have been
13214 marked garbaged. Clear them or we will experience 13211 marked garbaged. Clear them or we will experience
13215 surprises wrt scrolling. */ 13212 surprises wrt scrolling. */
13216 if (frame_garbaged) 13213 clear_garbaged_frames ();
13217 clear_garbaged_frames ();
13218 } 13214 }
13219 13215
13220 13216
diff --git a/src/xrdb.c b/src/xrdb.c
index 9d056a607e4..59b0876ebf8 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -41,7 +41,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#ifdef HAVE_PWD_H 41#ifdef HAVE_PWD_H
42#include <pwd.h> 42#include <pwd.h>
43#endif 43#endif
44#include <sys/stat.h>
45 44
46#ifdef USE_MOTIF 45#ifdef USE_MOTIF
47/* For Vdouble_click_time. */ 46/* For Vdouble_click_time. */
@@ -50,7 +49,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50 49
51char *x_get_string_resource (XrmDatabase rdb, const char *name, 50char *x_get_string_resource (XrmDatabase rdb, const char *name,
52 const char *class); 51 const char *class);
53static int file_p (const char *filename);
54 52
55 53
56/* X file search path processing. */ 54/* X file search path processing. */
@@ -108,7 +106,7 @@ x_get_customization_string (XrmDatabase db, const char *name,
108 database associated with display. 106 database associated with display.
109 (This is x_customization_string.) 107 (This is x_customization_string.)
110 108
111 Return the expanded file name if it exists and is readable, and 109 Return the resource database if its file was read successfully, and
112 refers to %L only when the LANG environment variable is set, or 110 refers to %L only when the LANG environment variable is set, or
113 otherwise provided by X. 111 otherwise provided by X.
114 112
@@ -117,10 +115,11 @@ x_get_customization_string (XrmDatabase db, const char *name,
117 115
118 Return NULL otherwise. */ 116 Return NULL otherwise. */
119 117
120static char * 118static XrmDatabase
121magic_file_p (const char *string, ptrdiff_t string_len, const char *class, 119magic_db (const char *string, ptrdiff_t string_len, const char *class,
122 const char *escaped_suffix) 120 const char *escaped_suffix)
123{ 121{
122 XrmDatabase db;
124 char *lang = getenv ("LANG"); 123 char *lang = getenv ("LANG");
125 124
126 ptrdiff_t path_size = 100; 125 ptrdiff_t path_size = 100;
@@ -217,14 +216,9 @@ magic_file_p (const char *string, ptrdiff_t string_len, const char *class,
217 } 216 }
218 217
219 path[path_len] = '\0'; 218 path[path_len] = '\0';
220 219 db = XrmGetFileDatabase (path);
221 if (! file_p (path)) 220 xfree (path);
222 { 221 return db;
223 xfree (path);
224 return NULL;
225 }
226
227 return path;
228} 222}
229 223
230 224
@@ -258,22 +252,11 @@ gethomedir (void)
258} 252}
259 253
260 254
261static int
262file_p (const char *filename)
263{
264 struct stat status;
265
266 return (access (filename, 4) == 0 /* exists and is readable */
267 && stat (filename, &status) == 0 /* get the status */
268 && (S_ISDIR (status.st_mode)) == 0); /* not a directory */
269}
270
271
272/* Find the first element of SEARCH_PATH which exists and is readable, 255/* Find the first element of SEARCH_PATH which exists and is readable,
273 after expanding the %-escapes. Return 0 if we didn't find any, and 256 after expanding the %-escapes. Return 0 if we didn't find any, and
274 the path name of the one we found otherwise. */ 257 the path name of the one we found otherwise. */
275 258
276static char * 259static XrmDatabase
277search_magic_path (const char *search_path, const char *class, 260search_magic_path (const char *search_path, const char *class,
278 const char *escaped_suffix) 261 const char *escaped_suffix)
279{ 262{
@@ -286,18 +269,16 @@ search_magic_path (const char *search_path, const char *class,
286 269
287 if (p > s) 270 if (p > s)
288 { 271 {
289 char *path = magic_file_p (s, p - s, class, escaped_suffix); 272 XrmDatabase db = magic_db (s, p - s, class, escaped_suffix);
290 if (path) 273 if (db)
291 return path; 274 return db;
292 } 275 }
293 else if (*p == ':') 276 else if (*p == ':')
294 { 277 {
295 char *path; 278 static char const ns[] = "%N%S";
296 279 XrmDatabase db = magic_db (ns, strlen (ns), class, escaped_suffix);
297 s = "%N%S"; 280 if (db)
298 path = magic_file_p (s, strlen (s), class, escaped_suffix); 281 return db;
299 if (path)
300 return path;
301 } 282 }
302 283
303 if (*p == ':') 284 if (*p == ':')
@@ -312,21 +293,12 @@ search_magic_path (const char *search_path, const char *class,
312static XrmDatabase 293static XrmDatabase
313get_system_app (const char *class) 294get_system_app (const char *class)
314{ 295{
315 XrmDatabase db = NULL;
316 const char *path; 296 const char *path;
317 char *p;
318 297
319 path = getenv ("XFILESEARCHPATH"); 298 path = getenv ("XFILESEARCHPATH");
320 if (! path) path = PATH_X_DEFAULTS; 299 if (! path) path = PATH_X_DEFAULTS;
321 300
322 p = search_magic_path (path, class, 0); 301 return search_magic_path (path, class, 0);
323 if (p)
324 {
325 db = XrmGetFileDatabase (p);
326 xfree (p);
327 }
328
329 return db;
330} 302}
331 303
332 304
@@ -340,35 +312,40 @@ get_fallback (Display *display)
340static XrmDatabase 312static XrmDatabase
341get_user_app (const char *class) 313get_user_app (const char *class)
342{ 314{
315 XrmDatabase db = 0;
343 const char *path; 316 const char *path;
344 char *file = 0;
345 char *free_it = 0;
346 317
347 /* Check for XUSERFILESEARCHPATH. It is a path of complete file 318 /* Check for XUSERFILESEARCHPATH. It is a path of complete file
348 names, not directories. */ 319 names, not directories. */
349 if (((path = getenv ("XUSERFILESEARCHPATH")) 320 path = getenv ("XUSERFILESEARCHPATH");
350 && (file = search_magic_path (path, class, 0))) 321 if (path)
322 db = search_magic_path (path, class, 0);
351 323
324 if (! db)
325 {
352 /* Check for APPLRESDIR; it is a path of directories. In each, 326 /* Check for APPLRESDIR; it is a path of directories. In each,
353 we have to search for LANG/CLASS and then CLASS. */ 327 we have to search for LANG/CLASS and then CLASS. */
354 || ((path = getenv ("XAPPLRESDIR")) 328 path = getenv ("XAPPLRESDIR");
355 && ((file = search_magic_path (path, class, "/%L/%N")) 329 if (path)
356 || (file = search_magic_path (path, class, "/%N")))) 330 {
331 db = search_magic_path (path, class, "/%L/%N");
332 if (!db)
333 db = search_magic_path (path, class, "/%N");
334 }
335 }
357 336
337 if (! db)
338 {
358 /* Check in the home directory. This is a bit of a hack; let's 339 /* Check in the home directory. This is a bit of a hack; let's
359 hope one's home directory doesn't contain any %-escapes. */ 340 hope one's home directory doesn't contain any %-escapes. */
360 || (free_it = gethomedir (), 341 char *home = gethomedir ();
361 ((file = search_magic_path (free_it, class, "%L/%N")) 342 db = search_magic_path (home, class, "%L/%N");
362 || (file = search_magic_path (free_it, class, "%N"))))) 343 if (! db)
363 { 344 db = search_magic_path (home, class, "%N");
364 XrmDatabase db = XrmGetFileDatabase (file); 345 xfree (home);
365 xfree (file);
366 xfree (free_it);
367 return db;
368 } 346 }
369 347
370 xfree (free_it); 348 return db;
371 return NULL;
372} 349}
373 350
374 351
diff --git a/test/ChangeLog b/test/ChangeLog
index 44c013e9887..f11325d0318 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,9 +1,21 @@
12012-11-14 Dmitry Gutov <dgutov@yandex.ru>
2
3 * automated/ruby-mode-tests.el (ruby-indent-singleton-class): Pass.
4 (ruby-indent-inside-heredoc-after-operator)
5 (ruby-indent-inside-heredoc-after-space): New tests.
6 Change direct font-lock face references to var references.
7 (ruby-interpolation-suppresses-syntax-inside): New test.
8 (ruby-interpolation-inside-percent-literal-with-paren): New
9 failing test.
10
12012-11-13 Dmitry Gutov <dgutov@yandex.ru> 112012-11-13 Dmitry Gutov <dgutov@yandex.ru>
2 12
3 * automated/ruby-mode-tests.el (ruby-heredoc-font-lock) 13 * automated/ruby-mode-tests.el (ruby-heredoc-font-lock)
4 (ruby-singleton-class-no-heredoc-font-lock) 14 (ruby-singleton-class-no-heredoc-font-lock)
5 (ruby-add-log-current-method-examples): New tests. 15 (ruby-add-log-current-method-examples): New tests.
6 (ruby-test-string): Extract from ruby-should-indent-buffer. 16 (ruby-test-string): Extract from ruby-should-indent-buffer.
17 (ruby-deftest-move-to-block): New macro.
18 Add several move-to-block tests.
7 19
82012-11-12 Stefan Monnier <monnier@iro.umontreal.ca> 202012-11-12 Stefan Monnier <monnier@iro.umontreal.ca>
9 21
diff --git a/test/automated/advice-tests.el b/test/automated/advice-tests.el
index 9f9719fdcfc..8f9bf54114c 100644
--- a/test/automated/advice-tests.el
+++ b/test/automated/advice-tests.el
@@ -57,6 +57,29 @@
57 (defmacro sm-test3 (x) `(call-test3 ,x)) 57 (defmacro sm-test3 (x) `(call-test3 ,x))
58 (macroexpand '(sm-test3 56)) (toto (call-test3 56))) 58 (macroexpand '(sm-test3 56)) (toto (call-test3 56)))
59 59
60 ((defadvice sm-test4 (around wrap-with-toto activate)
61 ad-do-it (setq ad-return-value `(toto ,ad-return-value)))
62 (defmacro sm-test4 (x) `(call-test4 ,x))
63 (macroexpand '(sm-test4 56)) (toto (call-test4 56)))
64 ((defmacro sm-test4 (x) `(call-testq ,x))
65 (macroexpand '(sm-test4 56)) (toto (call-testq 56)))
66
67 ;; Combining old style and new style advices.
68 ((defun sm-test5 (x) (+ x 4))
69 (sm-test5 6) 10)
70 ((advice-add 'sm-test5 :around (lambda (f y) (* (funcall f y) 5)))
71 (sm-test5 6) 50)
72 ((defadvice sm-test5 (around test activate)
73 ad-do-it (setq ad-return-value (+ ad-return-value 0.1)))
74 (sm-test5 5) 45.1)
75 ((ad-deactivate 'sm-test5)
76 (sm-test5 6) 50)
77 ((ad-activate 'sm-test5)
78 (sm-test5 6) 50.1)
79 ((defun sm-test5 (x) (+ x 14))
80 (sm-test5 6) 100.1)
81 ((advice-remove 'sm-test5 (lambda (f y) (* (funcall f y) 5)))
82 (sm-test5 6) 20.1)
60 )) 83 ))
61 84
62(ert-deftest advice-tests () 85(ert-deftest advice-tests ()
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index 0e41b2ba1e2..ad48413b030 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -80,7 +80,7 @@ VALUES-PLIST is a list with alternating index and value elements."
80 80
81(ert-deftest ruby-heredoc-font-lock () 81(ert-deftest ruby-heredoc-font-lock ()
82 (let ((s "foo <<eos.gsub('^ *', '')")) 82 (let ((s "foo <<eos.gsub('^ *', '')"))
83 (ruby-assert-face s 9 'font-lock-string-face) 83 (ruby-assert-face s 9 font-lock-string-face)
84 (ruby-assert-face s 10 nil))) 84 (ruby-assert-face s 10 nil)))
85 85
86(ert-deftest ruby-singleton-class-no-heredoc-font-lock () 86(ert-deftest ruby-singleton-class-no-heredoc-font-lock ()
@@ -154,7 +154,6 @@ VALUES-PLIST is a list with alternating index and value elements."
154 |")) 154 |"))
155 155
156(ert-deftest ruby-indent-singleton-class () 156(ert-deftest ruby-indent-singleton-class ()
157 :expected-result :failed ; Doesn't work yet, when no space before "<<".
158 (ruby-should-indent-buffer 157 (ruby-should-indent-buffer
159 "class<<bar 158 "class<<bar
160 | foo 159 | foo
@@ -165,6 +164,20 @@ VALUES-PLIST is a list with alternating index and value elements."
165 | end 164 | end
166 |")) 165 |"))
167 166
167(ert-deftest ruby-indent-inside-heredoc-after-operator ()
168 (ruby-should-indent-buffer
169 "b=<<eos
170 | 42"
171 "b=<<eos
172 | 42"))
173
174(ert-deftest ruby-indent-inside-heredoc-after-space ()
175 (ruby-should-indent-buffer
176 "foo <<eos.gsub(' ', '*')
177 | 42"
178 "foo <<eos.gsub(' ', '*')
179 | 42"))
180
168(ert-deftest ruby-indent-array-literal () 181(ert-deftest ruby-indent-array-literal ()
169 (let ((ruby-deep-indent-paren nil)) 182 (let ((ruby-deep-indent-paren nil))
170 (ruby-should-indent-buffer 183 (ruby-should-indent-buffer
@@ -249,19 +262,35 @@ VALUES-PLIST is a list with alternating index and value elements."
249 (should (string= "foo do |b|\n b + 1\nend" (buffer-string))))) 262 (should (string= "foo do |b|\n b + 1\nend" (buffer-string)))))
250 263
251(ert-deftest ruby-recognize-symbols-starting-with-at-character () 264(ert-deftest ruby-recognize-symbols-starting-with-at-character ()
252 (ruby-assert-face ":@abc" 3 'font-lock-constant-face)) 265 (ruby-assert-face ":@abc" 3 font-lock-constant-face))
253 266
254(ert-deftest ruby-hash-character-not-interpolation () 267(ert-deftest ruby-hash-character-not-interpolation ()
255 (ruby-assert-face "\"This is #{interpolation}\"" 15 268 (ruby-assert-face "\"This is #{interpolation}\"" 15
256 'font-lock-variable-name-face) 269 font-lock-variable-name-face)
257 (ruby-assert-face "\"This is \\#{no interpolation} despite the #\"" 270 (ruby-assert-face "\"This is \\#{no interpolation} despite the #\""
258 15 'font-lock-string-face) 271 15 font-lock-string-face)
259 (ruby-assert-face "\n#@comment, not ruby code" 5 'font-lock-comment-face) 272 (ruby-assert-face "\n#@comment, not ruby code" 5 font-lock-comment-face)
260 (ruby-assert-state "\n#@comment, not ruby code" 4 t) 273 (ruby-assert-state "\n#@comment, not ruby code" 4 t)
261 (ruby-assert-face "# A comment cannot have #{an interpolation} in it" 274 (ruby-assert-face "# A comment cannot have #{an interpolation} in it"
262 30 'font-lock-comment-face) 275 30 font-lock-comment-face)
263 (ruby-assert-face "# #{comment}\n \"#{interpolation}\"" 16 276 (ruby-assert-face "# #{comment}\n \"#{interpolation}\"" 16
264 'font-lock-variable-name-face)) 277 font-lock-variable-name-face))
278
279(ert-deftest ruby-interpolation-suppresses-syntax-inside ()
280 (let ((s "\"<ul><li>#{@files.join(\"</li><li>\")}</li></ul>\""))
281 (ruby-assert-state s 8 nil)
282 (ruby-assert-face s 9 font-lock-string-face)
283 (ruby-assert-face s 10 font-lock-variable-name-face)
284 (ruby-assert-face s 41 font-lock-string-face)))
285
286(ert-deftest ruby-interpolation-inside-percent-literal-with-paren ()
287 :expected-result :failed
288 (let ((s "%(^#{\")\"}^)"))
289 (ruby-assert-face s 3 font-lock-string-face)
290 (ruby-assert-face s 4 font-lock-variable-name-face)
291 (ruby-assert-face s 10 font-lock-string-face)
292 ;; It's confused by the closing paren in the middle.
293 (ruby-assert-state s 8 nil)))
265 294
266(ert-deftest ruby-add-log-current-method-examples () 295(ert-deftest ruby-add-log-current-method-examples ()
267 (let ((pairs '(("foo" . "#foo") 296 (let ((pairs '(("foo" . "#foo")
@@ -283,6 +312,54 @@ VALUES-PLIST is a list with alternating index and value elements."
283 (should (string= (ruby-add-log-current-method) 312 (should (string= (ruby-add-log-current-method)
284 (format "M::C%s" value))))))) 313 (format "M::C%s" value)))))))
285 314
315(defvar ruby-block-test-example
316 (ruby-test-string
317 "class C
318 | def foo
319 | 1
320 | end
321 |
322 | def bar
323 | 2
324 | end
325 |
326 | def baz
327 | some do
328 | end
329 | end
330 |end"))
331
332(defmacro ruby-deftest-move-to-block (name &rest body)
333 `(ert-deftest ,(intern (format "ruby-move-to-block-%s" name)) ()
334 (with-temp-buffer
335 (insert ruby-block-test-example)
336 (ruby-mode)
337 ,@body)))
338
339(put 'ruby-deftest-move-to-block 'lisp-indent-function 'defun)
340
341(ruby-deftest-move-to-block works-on-do
342 (goto-line 11)
343 (ruby-end-of-block)
344 (should (= 12 (line-number-at-pos)))
345 (ruby-beginning-of-block)
346 (should (= 11 (line-number-at-pos))))
347
348(ruby-deftest-move-to-block zero-is-noop
349 (goto-line 5)
350 (ruby-move-to-block 0)
351 (should (= 5 (line-number-at-pos))))
352
353(ruby-deftest-move-to-block ok-with-three
354 (goto-line 2)
355 (ruby-move-to-block 3)
356 (should (= 13 (line-number-at-pos))))
357
358(ruby-deftest-move-to-block ok-with-minus-two
359 (goto-line 10)
360 (ruby-move-to-block -2)
361 (should (= 2 (line-number-at-pos))))
362
286(provide 'ruby-mode-tests) 363(provide 'ruby-mode-tests)
287 364
288;;; ruby-mode-tests.el ends here 365;;; ruby-mode-tests.el ends here