summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-02-22 11:30:07 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2011-02-22 11:30:07 -0800
commitae0d725005539d9259efac6a81ff8fdd45eb69a6 (patch)
treec721b530409b355281537abc7b058bdb2697ee01
parent8d40723d1e9661840a67ca7be9c5b073526ab421 (diff)
downloademacs-ae0d725005539d9259efac6a81ff8fdd45eb69a6.tar.gz
[ChangeLog]
Work around some portability problems with symlinks. * Makefile.in (GNULIB_MODULES): Add lstat, readlink, symlink. * configure.in (lstat, HAVE_LSTAT): Remove special hack. * lib/lstat.c, lib/readlink.c, lib/stat.c, lib/symlink.c: * m4/dos.m4, m4/lstat.m4, m4/readlink.m4, m4/stat.m4, m4/symlink.m4: New files, automatically generated from gnulib. * aclocal.m4, configure, lib/Makefile.in, lib/gnulib.mk: * lib/stdlib.in.h, m4/gl-comp.m4, m4/stdlib_h.m4: Regenerate. 2011-02-22 Paul Eggert <eggert@cs.ucla.edu> [src/ChangeLog] Work around some portability problems with symlinks. * fileio.c (Frename_file, Fmake_symbolic_link, Ffile_symlink_p): Simplify the code by assuming that the readlink and symlink calls exist, even if they always fail on this host. (Ffile_readable_p): Likewise, for fifos. * config.in: Regenerate.
-rw-r--r--ChangeLog11
-rw-r--r--Makefile.in2
-rw-r--r--aclocal.m45
-rwxr-xr-xconfigure702
-rw-r--r--configure.in9
-rw-r--r--lib/Makefile.in44
-rw-r--r--lib/gnulib.mk42
-rw-r--r--lib/lstat.c91
-rw-r--r--lib/readlink.c74
-rw-r--r--lib/stat.c104
-rw-r--r--lib/stdlib.in.h30
-rw-r--r--lib/symlink.c57
-rw-r--r--m4/dos.m471
-rw-r--r--m4/gl-comp.m425
-rw-r--r--m4/lstat.m469
-rw-r--r--m4/readlink.m462
-rw-r--r--m4/stat.m467
-rw-r--r--m4/stdlib_h.m46
-rw-r--r--m4/symlink.m445
-rw-r--r--src/ChangeLog7
-rw-r--r--src/config.in40
-rw-r--r--src/fileio.c35
22 files changed, 1449 insertions, 149 deletions
diff --git a/ChangeLog b/ChangeLog
index 5aacf77688b..dfde83ba24e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2011-02-22 Paul Eggert <eggert@cs.ucla.edu>
+ Work around some portability problems with symlinks.
+ * Makefile.in (GNULIB_MODULES): Add lstat, readlink, symlink.
+ * configure.in (lstat, HAVE_LSTAT): Remove special hack.
+ * lib/lstat.c, lib/readlink.c, lib/stat.c, lib/symlink.c:
+ * m4/dos.m4, m4/lstat.m4, m4/readlink.m4, m4/stat.m4, m4/symlink.m4:
+ New files, automatically generated from gnulib.
+ * aclocal.m4, configure, lib/Makefile.in, lib/gnulib.mk:
+ * lib/stdlib.in.h, m4/gl-comp.m4, m4/stdlib_h.m4: Regenerate.
+
+2011-02-22 Paul Eggert <eggert@cs.ucla.edu>
+
Assume S_ISLNK etc. work, since gnulib supports this.
* Makefile.in (GNULIB_MODULES): Add sys_stat.
* configure.in: Check for lstat and set HAVE_LSTAT=0 if not.
diff --git a/Makefile.in b/Makefile.in
index 489409afe5b..7bd4318bfba 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -332,7 +332,7 @@ DOS_gnulib_comp.m4 = gl-comp.m4
# as per $(gnulib_srcdir)/DEPENDENCIES.
GNULIB_MODULES = \
crypto/md5 dtoastr filemode getloadavg getopt-gnu \
- ignore-value mktime strftime sys_stat
+ ignore-value lstat mktime readlink strftime symlink sys_stat
GNULIB_TOOL_FLAGS = \
--import --no-changelog --no-vc-files --makefile-name=gnulib.mk
sync-from-gnulib: $(gnulib_srcdir)
diff --git a/aclocal.m4 b/aclocal.m4
index 880166dc34e..7bc72240c80 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -986,6 +986,7 @@ AC_SUBST([am__untar])
m4_include([m4/00gnulib.m4])
m4_include([m4/c-strtod.m4])
+m4_include([m4/dos.m4])
m4_include([m4/extensions.m4])
m4_include([m4/filemode.m4])
m4_include([m4/getloadavg.m4])
@@ -994,15 +995,19 @@ m4_include([m4/gl-comp.m4])
m4_include([m4/gnulib-common.m4])
m4_include([m4/include_next.m4])
m4_include([m4/longlong.m4])
+m4_include([m4/lstat.m4])
m4_include([m4/md5.m4])
m4_include([m4/mktime.m4])
m4_include([m4/multiarch.m4])
+m4_include([m4/readlink.m4])
m4_include([m4/st_dm_mode.m4])
+m4_include([m4/stat.m4])
m4_include([m4/stdbool.m4])
m4_include([m4/stddef_h.m4])
m4_include([m4/stdint.m4])
m4_include([m4/stdlib_h.m4])
m4_include([m4/strftime.m4])
+m4_include([m4/symlink.m4])
m4_include([m4/sys_stat_h.m4])
m4_include([m4/time_h.m4])
m4_include([m4/time_r.m4])
diff --git a/configure b/configure
index 70aa60bb1e7..4083c8386c1 100755
--- a/configure
+++ b/configure
@@ -679,38 +679,6 @@ NEXT_AS_FIRST_DIRECTIVE_TIME_H
NEXT_TIME_H
NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H
NEXT_SYS_STAT_H
-REPLACE_UTIMENSAT
-REPLACE_STAT
-REPLACE_MKNOD
-REPLACE_MKFIFO
-REPLACE_MKDIR
-REPLACE_LSTAT
-REPLACE_FUTIMENS
-REPLACE_FSTATAT
-REPLACE_FSTAT
-HAVE_UTIMENSAT
-HAVE_MKNODAT
-HAVE_MKNOD
-HAVE_MKFIFOAT
-HAVE_MKFIFO
-HAVE_MKDIRAT
-HAVE_LSTAT
-HAVE_LCHMOD
-HAVE_FUTIMENS
-HAVE_FSTATAT
-HAVE_FCHMODAT
-GNULIB_UTIMENSAT
-GNULIB_STAT
-GNULIB_MKNODAT
-GNULIB_MKNOD
-GNULIB_MKFIFOAT
-GNULIB_MKFIFO
-GNULIB_MKDIRAT
-GNULIB_LSTAT
-GNULIB_LCHMOD
-GNULIB_FUTIMENS
-GNULIB_FSTATAT
-GNULIB_FCHMODAT
NEXT_AS_FIRST_DIRECTIVE_STDLIB_H
NEXT_STDLIB_H
STDINT_H
@@ -758,6 +726,38 @@ GNULIB_TIMEGM
GNULIB_STRPTIME
GNULIB_NANOSLEEP
GNULIB_MKTIME
+REPLACE_UTIMENSAT
+REPLACE_STAT
+REPLACE_MKNOD
+REPLACE_MKFIFO
+REPLACE_MKDIR
+REPLACE_LSTAT
+REPLACE_FUTIMENS
+REPLACE_FSTATAT
+REPLACE_FSTAT
+HAVE_UTIMENSAT
+HAVE_MKNODAT
+HAVE_MKNOD
+HAVE_MKFIFOAT
+HAVE_MKFIFO
+HAVE_MKDIRAT
+HAVE_LSTAT
+HAVE_LCHMOD
+HAVE_FUTIMENS
+HAVE_FSTATAT
+HAVE_FCHMODAT
+GNULIB_UTIMENSAT
+GNULIB_STAT
+GNULIB_MKNODAT
+GNULIB_MKNOD
+GNULIB_MKFIFOAT
+GNULIB_MKFIFO
+GNULIB_MKDIRAT
+GNULIB_LSTAT
+GNULIB_LCHMOD
+GNULIB_FUTIMENS
+GNULIB_FSTATAT
+GNULIB_FCHMODAT
LTLIBINTL
LIBINTL
GETOPT_H
@@ -874,6 +874,7 @@ GNULIB_DUP2
GNULIB_CLOSE
GNULIB_CHOWN
GETLOADAVG_LIBS
+REPLACE_WCTOMB
REPLACE_UNSETENV
REPLACE_STRTOD
REPLACE_SETENV
@@ -881,6 +882,7 @@ REPLACE_REALPATH
REPLACE_REALLOC
REPLACE_PUTENV
REPLACE_MKSTEMP
+REPLACE_MBTOWC
REPLACE_MALLOC
REPLACE_CANONICALIZE_FILE_NAME
REPLACE_CALLOC
@@ -909,6 +911,7 @@ HAVE_DECL_GETLOADAVG
HAVE_CANONICALIZE_FILE_NAME
HAVE_ATOLL
HAVE__EXIT
+GNULIB_WCTOMB
GNULIB_UNSETENV
GNULIB_UNLOCKPT
GNULIB_SYSTEM_POSIX
@@ -927,6 +930,7 @@ GNULIB_MKSTEMP
GNULIB_MKOSTEMPS
GNULIB_MKOSTEMP
GNULIB_MKDTEMP
+GNULIB_MBTOWC
GNULIB_MALLOC_POSIX
GNULIB_GRANTPT
GNULIB_GETSUBOPT
@@ -2956,14 +2960,16 @@ as_fn_append ac_header_list " unistd.h"
as_fn_append ac_header_list " sys/param.h"
gl_getopt_required=GNU
as_fn_append ac_header_list " getopt.h"
+as_fn_append ac_func_list " lstat"
as_fn_append ac_func_list " alarm"
+as_fn_append ac_func_list " readlink"
as_fn_append ac_header_list " wchar.h"
as_fn_append ac_header_list " stdint.h"
as_fn_append ac_func_list " tzset"
+as_fn_append ac_func_list " symlink"
as_fn_append ac_header_list " sys/stat.h"
as_fn_append ac_header_list " sys/time.h"
as_fn_append ac_func_list " localtime_r"
-as_fn_append ac_func_list " lstat"
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
@@ -6133,13 +6139,17 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
# Code from module ignore-value:
# Code from module include_next:
# Code from module intprops:
+ # Code from module lstat:
# Code from module mktime:
# Code from module multiarch:
+ # Code from module readlink:
+ # Code from module stat:
# Code from module stdbool:
# Code from module stddef:
# Code from module stdint:
# Code from module stdlib:
# Code from module strftime:
+ # Code from module symlink:
# Code from module sys_stat:
# Code from module time:
# Code from module time_r:
@@ -13780,6 +13790,7 @@ _ACEOF
GNULIB_GETSUBOPT=0;
GNULIB_GRANTPT=0;
GNULIB_MALLOC_POSIX=0;
+ GNULIB_MBTOWC=0;
GNULIB_MKDTEMP=0;
GNULIB_MKOSTEMP=0;
GNULIB_MKOSTEMPS=0;
@@ -13798,6 +13809,7 @@ _ACEOF
GNULIB_SYSTEM_POSIX=0;
GNULIB_UNLOCKPT=0;
GNULIB_UNSETENV=0;
+ GNULIB_WCTOMB=0;
HAVE__EXIT=1;
HAVE_ATOLL=1;
HAVE_CANONICALIZE_FILE_NAME=1;
@@ -13826,6 +13838,7 @@ _ACEOF
REPLACE_CALLOC=0;
REPLACE_CANONICALIZE_FILE_NAME=0;
REPLACE_MALLOC=0;
+ REPLACE_MBTOWC=0;
REPLACE_MKSTEMP=0;
REPLACE_PUTENV=0;
REPLACE_REALLOC=0;
@@ -13833,6 +13846,7 @@ _ACEOF
REPLACE_SETENV=0;
REPLACE_STRTOD=0;
REPLACE_UNSETENV=0;
+ REPLACE_WCTOMB=0;
GNULIB_CHOWN=0;
@@ -14492,19 +14506,38 @@ fi
- GNULIB_MKTIME=0;
- GNULIB_NANOSLEEP=0;
- GNULIB_STRPTIME=0;
- GNULIB_TIMEGM=0;
- GNULIB_TIME_R=0;
- HAVE_DECL_LOCALTIME_R=1;
- HAVE_NANOSLEEP=1;
- HAVE_STRPTIME=1;
- HAVE_TIMEGM=1;
- REPLACE_LOCALTIME_R=GNULIB_PORTCHECK;
- REPLACE_MKTIME=GNULIB_PORTCHECK;
- REPLACE_NANOSLEEP=GNULIB_PORTCHECK;
- REPLACE_TIMEGM=GNULIB_PORTCHECK;
+ GNULIB_FCHMODAT=0;
+ GNULIB_FSTATAT=0;
+ GNULIB_FUTIMENS=0;
+ GNULIB_LCHMOD=0;
+ GNULIB_LSTAT=0;
+ GNULIB_MKDIRAT=0;
+ GNULIB_MKFIFO=0;
+ GNULIB_MKFIFOAT=0;
+ GNULIB_MKNOD=0;
+ GNULIB_MKNODAT=0;
+ GNULIB_STAT=0;
+ GNULIB_UTIMENSAT=0;
+ HAVE_FCHMODAT=1;
+ HAVE_FSTATAT=1;
+ HAVE_FUTIMENS=1;
+ HAVE_LCHMOD=1;
+ HAVE_LSTAT=1;
+ HAVE_MKDIRAT=1;
+ HAVE_MKFIFO=1;
+ HAVE_MKFIFOAT=1;
+ HAVE_MKNOD=1;
+ HAVE_MKNODAT=1;
+ HAVE_UTIMENSAT=1;
+ REPLACE_FSTAT=0;
+ REPLACE_FSTATAT=0;
+ REPLACE_FUTIMENS=0;
+ REPLACE_LSTAT=0;
+ REPLACE_MKDIR=0;
+ REPLACE_MKFIFO=0;
+ REPLACE_MKNOD=0;
+ REPLACE_STAT=0;
+ REPLACE_UTIMENSAT=0;
@@ -14524,6 +14557,93 @@ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5
+$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; }
+if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f conftest.sym conftest.file
+ echo >conftest.file
+ if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
+ if test "$cross_compiling" = yes; then :
+ # When cross-compiling, be pessimistic so we will end up using the
+ # replacement version of lstat that checks for trailing slashes and
+ # calls lstat a second time when necessary.
+ ac_cv_func_lstat_dereferences_slashed_symlink=no
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+struct stat sbuf;
+ /* Linux will dereference the symlink and fail, as required by
+ POSIX. That is better in the sense that it means we will not
+ have to compile and use the lstat wrapper. */
+ return lstat ("conftest.sym/", &sbuf) == 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_lstat_dereferences_slashed_symlink=yes
+else
+ ac_cv_func_lstat_dereferences_slashed_symlink=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ else
+ # If the 'ln -s' command failed, then we probably don't even
+ # have an lstat function.
+ ac_cv_func_lstat_dereferences_slashed_symlink=no
+ fi
+ rm -f conftest.sym conftest.file
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
+$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; }
+ test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
+
+cat >>confdefs.h <<_ACEOF
+#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
+_ACEOF
+
+ if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS lstat.$ac_objext"
+
+ fi
+
+
+ GNULIB_MKTIME=0;
+ GNULIB_NANOSLEEP=0;
+ GNULIB_STRPTIME=0;
+ GNULIB_TIMEGM=0;
+ GNULIB_TIME_R=0;
+ HAVE_DECL_LOCALTIME_R=1;
+ HAVE_NANOSLEEP=1;
+ HAVE_STRPTIME=1;
+ HAVE_TIMEGM=1;
+ REPLACE_LOCALTIME_R=GNULIB_PORTCHECK;
+ REPLACE_MKTIME=GNULIB_PORTCHECK;
+ REPLACE_NANOSLEEP=GNULIB_PORTCHECK;
+ REPLACE_TIMEGM=GNULIB_PORTCHECK;
+
+
+
+
gl_cv_c_multiarch=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -14565,6 +14685,104 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system is Windows or MSDOS" >&5
+$as_echo_n "checking whether system is Windows or MSDOS... " >&6; }
+if ${ac_cv_win_or_dos+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__
+neither MSDOS nor Windows
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_win_or_dos=yes
+else
+ ac_cv_win_or_dos=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win_or_dos" >&5
+$as_echo "$ac_cv_win_or_dos" >&6; }
+
+ if test x"$ac_cv_win_or_dos" = xyes; then
+ ac_fs_accepts_drive_letter_prefix=1
+ ac_fs_backslash_is_file_name_separator=1
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether drive letter can start relative path" >&5
+$as_echo_n "checking whether drive letter can start relative path... " >&6; }
+if ${ac_cv_drive_letter_can_be_relative+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+#if defined __CYGWIN__
+drive letters are always absolute
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_drive_letter_can_be_relative=yes
+else
+ ac_cv_drive_letter_can_be_relative=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_drive_letter_can_be_relative" >&5
+$as_echo "$ac_cv_drive_letter_can_be_relative" >&6; }
+ if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then
+ ac_fs_drive_letter_can_be_relative=1
+ else
+ ac_fs_drive_letter_can_be_relative=0
+ fi
+ else
+ ac_fs_accepts_drive_letter_prefix=0
+ ac_fs_backslash_is_file_name_separator=0
+ ac_fs_drive_letter_can_be_relative=0
+ fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX $ac_fs_accepts_drive_letter_prefix
+_ACEOF
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR $ac_fs_backslash_is_file_name_separator
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE $ac_fs_drive_letter_can_be_relative
+_ACEOF
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
if ${ac_cv_header_stdbool_h+:} false; then :
@@ -14824,38 +15042,6 @@ fi
- GNULIB_FCHMODAT=0;
- GNULIB_FSTATAT=0;
- GNULIB_FUTIMENS=0;
- GNULIB_LCHMOD=0;
- GNULIB_LSTAT=0;
- GNULIB_MKDIRAT=0;
- GNULIB_MKFIFO=0;
- GNULIB_MKFIFOAT=0;
- GNULIB_MKNOD=0;
- GNULIB_MKNODAT=0;
- GNULIB_STAT=0;
- GNULIB_UTIMENSAT=0;
- HAVE_FCHMODAT=1;
- HAVE_FSTATAT=1;
- HAVE_FUTIMENS=1;
- HAVE_LCHMOD=1;
- HAVE_LSTAT=1;
- HAVE_MKDIRAT=1;
- HAVE_MKFIFO=1;
- HAVE_MKFIFOAT=1;
- HAVE_MKNOD=1;
- HAVE_MKNODAT=1;
- HAVE_UTIMENSAT=1;
- REPLACE_FSTAT=0;
- REPLACE_FSTATAT=0;
- REPLACE_FUTIMENS=0;
- REPLACE_LSTAT=0;
- REPLACE_MKDIR=0;
- REPLACE_MKFIFO=0;
- REPLACE_MKNOD=0;
- REPLACE_STAT=0;
- REPLACE_UTIMENSAT=0;
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5
$as_echo_n "checking whether stat file-mode macros are broken... " >&6; }
@@ -15768,6 +15954,28 @@ fi
# Code from module include_next:
# Code from module intprops:
+ # Code from module lstat:
+
+
+
+ if test $ac_cv_func_lstat = yes; then
+
+ if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
+ REPLACE_LSTAT=1
+ fi
+ # Prerequisites of lib/lstat.c.
+
+ else
+ HAVE_LSTAT=0
+ fi
+
+
+
+
+ GNULIB_LSTAT=1
+
+
+
# Code from module mktime:
@@ -16025,6 +16233,247 @@ fi
# Code from module multiarch:
+ # Code from module readlink:
+
+
+
+ if test $ac_cv_func_readlink = no; then
+ HAVE_READLINK=0
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS readlink.$ac_objext"
+
+
+ :
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether readlink signature is correct" >&5
+$as_echo_n "checking whether readlink signature is correct... " >&6; }
+if ${gl_cv_decl_readlink_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+ /* Cause compilation failure if original declaration has wrong type. */
+ ssize_t readlink (const char *, char *, size_t);
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gl_cv_decl_readlink_works=yes
+else
+ gl_cv_decl_readlink_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_decl_readlink_works" >&5
+$as_echo "$gl_cv_decl_readlink_works" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether readlink handles trailing slash correctly" >&5
+$as_echo_n "checking whether readlink handles trailing slash correctly... " >&6; }
+if ${gl_cv_func_readlink_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # We have readlink, so assume ln -s works.
+ ln -s conftest.no-such conftest.link
+ ln -s conftest.link conftest.lnk2
+ if test "$cross_compiling" = yes; then :
+ gl_cv_func_readlink_works="guessing no"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+
+int
+main ()
+{
+char buf[20];
+ return readlink ("conftest.lnk2/", buf, sizeof buf) != -1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gl_cv_func_readlink_works=yes
+else
+ gl_cv_func_readlink_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ rm -f conftest.link conftest.lnk2
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_readlink_works" >&5
+$as_echo "$gl_cv_func_readlink_works" >&6; }
+ if test "$gl_cv_func_readlink_works" != yes; then
+
+$as_echo "#define READLINK_TRAILING_SLASH_BUG 1" >>confdefs.h
+
+ REPLACE_READLINK=1
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS readlink.$ac_objext"
+
+ elif test "$gl_cv_decl_readlink_works" != yes; then
+ REPLACE_READLINK=1
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS readlink.$ac_objext"
+
+ fi
+ fi
+
+
+
+
+ GNULIB_READLINK=1
+
+
+
+ # Code from module stat:
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat handles trailing slashes on directories" >&5
+$as_echo_n "checking whether stat handles trailing slashes on directories... " >&6; }
+if ${gl_cv_func_stat_dir_slash+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ case $host_os in
+ mingw*) gl_cv_func_stat_dir_slash="guessing no";;
+ *) gl_cv_func_stat_dir_slash="guessing yes";;
+ esac
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/stat.h>
+
+int
+main ()
+{
+struct stat st; return stat (".", &st) != stat ("./", &st);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gl_cv_func_stat_dir_slash=yes
+else
+ gl_cv_func_stat_dir_slash=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_stat_dir_slash" >&5
+$as_echo "$gl_cv_func_stat_dir_slash" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat handles trailing slashes on files" >&5
+$as_echo_n "checking whether stat handles trailing slashes on files... " >&6; }
+if ${gl_cv_func_stat_file_slash+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ touch conftest.tmp
+ # Assume that if we have lstat, we can also check symlinks.
+ if test $ac_cv_func_lstat = yes; then
+ ln -s conftest.tmp conftest.lnk
+ fi
+ if test "$cross_compiling" = yes; then :
+ gl_cv_func_stat_file_slash="guessing no"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/stat.h>
+
+int
+main ()
+{
+int result = 0;
+ struct stat st;
+ if (!stat ("conftest.tmp/", &st))
+ result |= 1;
+#if HAVE_LSTAT
+ if (!stat ("conftest.lnk/", &st))
+ result |= 2;
+#endif
+ return result;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gl_cv_func_stat_file_slash=yes
+else
+ gl_cv_func_stat_file_slash=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ rm -f conftest.tmp conftest.lnk
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_stat_file_slash" >&5
+$as_echo "$gl_cv_func_stat_file_slash" >&6; }
+ case $gl_cv_func_stat_dir_slash in
+ *no) REPLACE_STAT=1
+
+$as_echo "#define REPLACE_FUNC_STAT_DIR 1" >>confdefs.h
+;;
+ esac
+ case $gl_cv_func_stat_file_slash in
+ *no) REPLACE_STAT=1
+
+$as_echo "#define REPLACE_FUNC_STAT_FILE 1" >>confdefs.h
+;;
+ esac
+ if test $REPLACE_STAT = 1; then
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS stat.$ac_objext"
+
+
+ fi
+
+
+
+
+ GNULIB_STAT=1
+
+
+
# Code from module stdbool:
@@ -16929,6 +17378,86 @@ $as_echo "#define my_strftime nstrftime" >>confdefs.h
+ # Code from module symlink:
+
+
+
+ if test $ac_cv_func_symlink = no; then
+ HAVE_SYMLINK=0
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS symlink.$ac_objext"
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether symlink handles trailing slash correctly" >&5
+$as_echo_n "checking whether symlink handles trailing slash correctly... " >&6; }
+if ${gl_cv_func_symlink_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ gl_cv_func_symlink_works="guessing no"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+
+int
+main ()
+{
+int result = 0;
+ if (!symlink ("a", "conftest.link/"))
+ result |= 1;
+ if (symlink ("conftest.f", "conftest.lnk2"))
+ result |= 2;
+ else if (!symlink ("a", "conftest.lnk2/"))
+ result |= 4;
+ return result;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gl_cv_func_symlink_works=yes
+else
+ gl_cv_func_symlink_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ rm -f conftest.f conftest.link conftest.lnk2
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_symlink_works" >&5
+$as_echo "$gl_cv_func_symlink_works" >&6; }
+ if test "$gl_cv_func_symlink_works" != yes; then
+ REPLACE_SYMLINK=1
+
+
+
+
+
+
+
+
+ gl_LIBOBJS="$gl_LIBOBJS symlink.$ac_objext"
+
+ fi
+ fi
+
+
+
+
+ GNULIB_SYMLINK=1
+
+
+
# Code from module sys_stat:
@@ -17212,23 +17741,6 @@ $as_echo "$gl_cv_next_unistd_h" >&6; }
-# Emacs does not care about lstat's behavior on files whose names end in
-# trailing slashes, so it does not use the gnulib lstat module.
-# However, Emacs does want the "#define lstat stat" in sys/stat.h
-# when lstat does not exist, so it pretends to use the lstat module
-# even though it implements only the lstat-checking part of that module.
-
-
-
-test $ac_cv_func_lstat = yes || HAVE_LSTAT=0
-
-
-
- GNULIB_LSTAT=1
-
-
-
-
# UNIX98 PTYs.
for ac_func in grantpt
do :
diff --git a/configure.in b/configure.in
index fa5ae960c59..376c82c4ca4 100644
--- a/configure.in
+++ b/configure.in
@@ -2661,15 +2661,6 @@ gl_ASSERT_NO_GNULIB_POSIXCHECK
gl_ASSERT_NO_GNULIB_TESTS
gl_INIT
-# Emacs does not care about lstat's behavior on files whose names end in
-# trailing slashes, so it does not use the gnulib lstat module.
-# However, Emacs does want the "#define lstat stat" in sys/stat.h
-# when lstat does not exist, so it pretends to use the lstat module
-# even though it implements only the lstat-checking part of that module.
-AC_CHECK_FUNCS_ONCE([lstat])
-test $ac_cv_func_lstat = yes || HAVE_LSTAT=0
-gl_SYS_STAT_MODULE_INDICATOR([lstat])
-
# UNIX98 PTYs.
AC_CHECK_FUNCS(grantpt)
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 48e7b1d6507..e9b9f2eb86e 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -24,7 +24,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value mktime strftime sys_stat
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value lstat mktime readlink strftime symlink sys_stat
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
@@ -50,16 +50,18 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
subdir = lib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
- $(top_srcdir)/m4/c-strtod.m4 $(top_srcdir)/m4/extensions.m4 \
- $(top_srcdir)/m4/filemode.m4 $(top_srcdir)/m4/getloadavg.m4 \
- $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gl-comp.m4 \
- $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/c-strtod.m4 $(top_srcdir)/m4/dos.m4 \
+ $(top_srcdir)/m4/extensions.m4 $(top_srcdir)/m4/filemode.m4 \
+ $(top_srcdir)/m4/getloadavg.m4 $(top_srcdir)/m4/getopt.m4 \
+ $(top_srcdir)/m4/gl-comp.m4 $(top_srcdir)/m4/gnulib-common.m4 \
$(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/longlong.m4 \
- $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/mktime.m4 \
- $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/st_dm_mode.m4 \
- $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \
- $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdlib_h.m4 \
- $(top_srcdir)/m4/strftime.m4 $(top_srcdir)/m4/sys_stat_h.m4 \
+ $(top_srcdir)/m4/lstat.m4 $(top_srcdir)/m4/md5.m4 \
+ $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/multiarch.m4 \
+ $(top_srcdir)/m4/readlink.m4 $(top_srcdir)/m4/st_dm_mode.m4 \
+ $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdbool.m4 \
+ $(top_srcdir)/m4/stddef_h.m4 $(top_srcdir)/m4/stdint.m4 \
+ $(top_srcdir)/m4/stdlib_h.m4 $(top_srcdir)/m4/strftime.m4 \
+ $(top_srcdir)/m4/symlink.m4 $(top_srcdir)/m4/sys_stat_h.m4 \
$(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \
$(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/unistd_h.m4 \
$(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/configure.in
@@ -179,6 +181,7 @@ GNULIB_LINKAT = @GNULIB_LINKAT@
GNULIB_LSEEK = @GNULIB_LSEEK@
GNULIB_LSTAT = @GNULIB_LSTAT@
GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBTOWC = @GNULIB_MBTOWC@
GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
GNULIB_MKFIFO = @GNULIB_MKFIFO@
@@ -225,6 +228,7 @@ GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
GNULIB_UNSETENV = @GNULIB_UNSETENV@
GNULIB_USLEEP = @GNULIB_USLEEP@
GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
GNULIB_WRITE = @GNULIB_WRITE@
GNULIB__EXIT = @GNULIB__EXIT@
GNU_OBJC_CFLAGS = @GNU_OBJC_CFLAGS@
@@ -452,6 +456,7 @@ REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
REPLACE_LSEEK = @REPLACE_LSEEK@
REPLACE_LSTAT = @REPLACE_LSTAT@
REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
REPLACE_MKDIR = @REPLACE_MKDIR@
REPLACE_MKFIFO = @REPLACE_MKFIFO@
REPLACE_MKNOD = @REPLACE_MKNOD@
@@ -478,6 +483,7 @@ REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
REPLACE_UNSETENV = @REPLACE_UNSETENV@
REPLACE_USLEEP = @REPLACE_USLEEP@
REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
REPLACE_WRITE = @REPLACE_WRITE@
RSVG_CFLAGS = @RSVG_CFLAGS@
RSVG_LIBS = @RSVG_LIBS@
@@ -600,9 +606,10 @@ BUILT_SOURCES = arg-nonnull.h c++defs.h $(GETOPT_H) $(STDBOOL_H) \
EXTRA_DIST = $(top_srcdir)/./arg-nonnull.h $(top_srcdir)/./c++defs.h \
md5.c md5.h ftoastr.c ftoastr.h filemode.c filemode.h \
getloadavg.c getopt.c getopt.in.h getopt1.c getopt_int.h \
- intprops.h mktime-internal.h mktime.c stdbool.in.h stddef.in.h \
- stdint.in.h stdlib.in.h strftime.c strftime.h sys_stat.in.h \
- time.in.h time_r.c unistd.in.h $(top_srcdir)/./warn-on-use.h
+ intprops.h lstat.c mktime-internal.h mktime.c readlink.c \
+ stat.c stdbool.in.h stddef.in.h stdint.in.h stdlib.in.h \
+ strftime.c strftime.h symlink.c sys_stat.in.h time.in.h \
+ time_r.c unistd.in.h $(top_srcdir)/./warn-on-use.h
MOSTLYCLEANDIRS = sys
MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \
c++defs.h c++defs.h-t getopt.h getopt.h-t stdbool.h \
@@ -615,7 +622,8 @@ libgnu_a_SOURCES = dtoastr.c gettext.h ignore-value.h
libgnu_a_LIBADD = $(gl_LIBOBJS)
libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
EXTRA_libgnu_a_SOURCES = md5.c ftoastr.c filemode.c getloadavg.c \
- getopt.c getopt1.c mktime.c strftime.c time_r.c
+ getopt.c getopt1.c lstat.c mktime.c readlink.c stat.c \
+ strftime.c symlink.c time_r.c
ARG_NONNULL_H = arg-nonnull.h
CXXDEFS_H = c++defs.h
WARN_ON_USE_H = warn-on-use.h
@@ -674,9 +682,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getloadavg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strftime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@
.c.o:
@@ -1001,6 +1013,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
-e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \
-e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
+ -e 's|@''GNULIB_MBTOWC''@|$(GNULIB_MBTOWC)|g' \
-e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
-e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \
-e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \
@@ -1019,6 +1032,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''GNULIB_SYSTEM_POSIX''@|$(GNULIB_SYSTEM_POSIX)|g' \
-e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \
-e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
+ -e 's|@''GNULIB_WCTOMB''@|$(GNULIB_WCTOMB)|g' \
< $(srcdir)/stdlib.in.h | \
sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
-e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
@@ -1047,6 +1061,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \
-e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
-e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
+ -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
-e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
@@ -1054,6 +1069,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
-e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
-e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
+ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 32bf5714d17..1d918ff5fae 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -9,7 +9,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value mktime strftime sys_stat
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value lstat mktime readlink strftime symlink sys_stat
MOSTLYCLEANFILES += core *.stackdump
@@ -151,6 +151,15 @@ EXTRA_DIST += intprops.h
## end gnulib module intprops
+## begin gnulib module lstat
+
+
+EXTRA_DIST += lstat.c
+
+EXTRA_libgnu_a_SOURCES += lstat.c
+
+## end gnulib module lstat
+
## begin gnulib module mktime
@@ -160,6 +169,24 @@ EXTRA_libgnu_a_SOURCES += mktime.c
## end gnulib module mktime
+## begin gnulib module readlink
+
+
+EXTRA_DIST += readlink.c
+
+EXTRA_libgnu_a_SOURCES += readlink.c
+
+## end gnulib module readlink
+
+## begin gnulib module stat
+
+
+EXTRA_DIST += stat.c
+
+EXTRA_libgnu_a_SOURCES += stat.c
+
+## end gnulib module stat
+
## begin gnulib module stdbool
BUILT_SOURCES += $(STDBOOL_H)
@@ -267,6 +294,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
-e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \
-e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
+ -e 's|@''GNULIB_MBTOWC''@|$(GNULIB_MBTOWC)|g' \
-e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
-e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \
-e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \
@@ -285,6 +313,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''GNULIB_SYSTEM_POSIX''@|$(GNULIB_SYSTEM_POSIX)|g' \
-e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \
-e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
+ -e 's|@''GNULIB_WCTOMB''@|$(GNULIB_WCTOMB)|g' \
< $(srcdir)/stdlib.in.h | \
sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
-e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
@@ -313,6 +342,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \
-e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
-e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
+ -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \
-e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
@@ -320,6 +350,7 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
-e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
-e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
-e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
+ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
@@ -340,6 +371,15 @@ EXTRA_libgnu_a_SOURCES += strftime.c
## end gnulib module strftime
+## begin gnulib module symlink
+
+
+EXTRA_DIST += symlink.c
+
+EXTRA_libgnu_a_SOURCES += symlink.c
+
+## end gnulib module symlink
+
## begin gnulib module sys_stat
BUILT_SOURCES += sys/stat.h
diff --git a/lib/lstat.c b/lib/lstat.c
new file mode 100644
index 00000000000..b26065ede28
--- /dev/null
+++ b/lib/lstat.c
@@ -0,0 +1,91 @@
+/* Work around a bug of lstat on some systems
+
+ Copyright (C) 1997-2006, 2008-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+#if !HAVE_LSTAT
+/* On systems that lack symlinks, our replacement <sys/stat.h> already
+ defined lstat as stat, so there is nothing further to do other than
+ avoid an empty file. */
+typedef int dummy;
+#else /* HAVE_LSTAT */
+
+/* Get the original definition of lstat. It might be defined as a macro. */
+# define __need_system_sys_stat_h
+# include <sys/types.h>
+# include <sys/stat.h>
+# undef __need_system_sys_stat_h
+
+static inline int
+orig_lstat (const char *filename, struct stat *buf)
+{
+ return lstat (filename, buf);
+}
+
+/* Specification. */
+# include <sys/stat.h>
+
+# include <string.h>
+# include <errno.h>
+
+/* lstat works differently on Linux and Solaris systems. POSIX (see
+ `pathname resolution' in the glossary) requires that programs like
+ `ls' take into consideration the fact that FILE has a trailing slash
+ when FILE is a symbolic link. On Linux and Solaris 10 systems, the
+ lstat function already has the desired semantics (in treating
+ `lstat ("symlink/", sbuf)' just like `lstat ("symlink/.", sbuf)',
+ but on Solaris 9 and earlier it does not.
+
+ If FILE has a trailing slash and specifies a symbolic link,
+ then use stat() to get more info on the referent of FILE.
+ If the referent is a non-directory, then set errno to ENOTDIR
+ and return -1. Otherwise, return stat's result. */
+
+int
+rpl_lstat (const char *file, struct stat *sbuf)
+{
+ size_t len;
+ int lstat_result = orig_lstat (file, sbuf);
+
+ if (lstat_result != 0)
+ return lstat_result;
+
+ /* This replacement file can blindly check against '/' rather than
+ using the ISSLASH macro, because all platforms with '\\' either
+ lack symlinks (mingw) or have working lstat (cygwin) and thus do
+ not compile this file. 0 len should have already been filtered
+ out above, with a failure return of ENOENT. */
+ len = strlen (file);
+ if (file[len - 1] != '/' || S_ISDIR (sbuf->st_mode))
+ return 0;
+
+ /* At this point, a trailing slash is only permitted on
+ symlink-to-dir; but it should have found information on the
+ directory, not the symlink. Call stat() to get info about the
+ link's referent. Our replacement stat guarantees valid results,
+ even if the symlink is not pointing to a directory. */
+ if (!S_ISLNK (sbuf->st_mode))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+ return stat (file, sbuf);
+}
+
+#endif /* HAVE_LSTAT */
diff --git a/lib/readlink.c b/lib/readlink.c
new file mode 100644
index 00000000000..35d045b9a12
--- /dev/null
+++ b/lib/readlink.c
@@ -0,0 +1,74 @@
+/* Stub for readlink().
+ Copyright (C) 2003-2007, 2009-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#if !HAVE_READLINK
+
+/* readlink() substitute for systems that don't have a readlink() function,
+ such as DJGPP 2.03 and mingw32. */
+
+ssize_t
+readlink (const char *name, char *buf _GL_UNUSED,
+ size_t bufsize _GL_UNUSED)
+{
+ struct stat statbuf;
+
+ /* In general we should use lstat() here, not stat(). But on platforms
+ without symbolic links, lstat() - if it exists - would be equivalent to
+ stat(), therefore we can use stat(). This saves us a configure check. */
+ if (stat (name, &statbuf) >= 0)
+ errno = EINVAL;
+ return -1;
+}
+
+#else /* HAVE_READLINK */
+
+# undef readlink
+
+/* readlink() wrapper that uses correct types, for systems like cygwin
+ 1.5.x where readlink returns int, and which rejects trailing slash,
+ for Solaris 9. */
+
+ssize_t
+rpl_readlink (const char *name, char *buf, size_t bufsize)
+{
+# if READLINK_TRAILING_SLASH_BUG
+ size_t len = strlen (name);
+ if (len && name[len - 1] == '/')
+ {
+ /* Even if name without the slash is a symlink to a directory,
+ both lstat() and stat() must resolve the trailing slash to
+ the directory rather than the symlink. We can therefore
+ safely use stat() to distinguish between EINVAL and
+ ENOTDIR/ENOENT, avoiding extra overhead of rpl_lstat(). */
+ struct stat st;
+ if (stat (name, &st) == 0)
+ errno = EINVAL;
+ return -1;
+ }
+# endif /* READLINK_TRAILING_SLASH_BUG */
+ return readlink (name, buf, bufsize);
+}
+
+#endif /* HAVE_READLINK */
diff --git a/lib/stat.c b/lib/stat.c
new file mode 100644
index 00000000000..f16d9144afc
--- /dev/null
+++ b/lib/stat.c
@@ -0,0 +1,104 @@
+/* Work around platform bugs in stat.
+ Copyright (C) 2009-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* written by Eric Blake */
+
+#include <config.h>
+
+/* Get the original definition of stat. It might be defined as a macro. */
+#define __need_system_sys_stat_h
+#include <sys/types.h>
+#include <sys/stat.h>
+#undef __need_system_sys_stat_h
+
+static inline int
+orig_stat (const char *filename, struct stat *buf)
+{
+ return stat (filename, buf);
+}
+
+/* Specification. */
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* Store information about NAME into ST. Work around bugs with
+ trailing slashes. Mingw has other bugs (such as st_ino always
+ being 0 on success) which this wrapper does not work around. But
+ at least this implementation provides the ability to emulate fchdir
+ correctly. */
+
+int
+rpl_stat (char const *name, struct stat *st)
+{
+ int result = orig_stat (name, st);
+#if REPLACE_FUNC_STAT_FILE
+ /* Solaris 9 mistakenly succeeds when given a non-directory with a
+ trailing slash. */
+ if (result == 0 && !S_ISDIR (st->st_mode))
+ {
+ size_t len = strlen (name);
+ if (ISSLASH (name[len - 1]))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+ }
+#endif /* REPLACE_FUNC_STAT_FILE */
+#if REPLACE_FUNC_STAT_DIR
+ if (result == -1 && errno == ENOENT)
+ {
+ /* Due to mingw's oddities, there are some directories (like
+ c:\) where stat() only succeeds with a trailing slash, and
+ other directories (like c:\windows) where stat() only
+ succeeds without a trailing slash. But we want the two to be
+ synonymous, since chdir() manages either style. Likewise, Mingw also
+ reports ENOENT for names longer than PATH_MAX, when we want
+ ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR.
+ Fortunately, mingw PATH_MAX is small enough for stack
+ allocation. */
+ char fixed_name[PATH_MAX + 1] = {0};
+ size_t len = strlen (name);
+ bool check_dir = false;
+ if (PATH_MAX <= len)
+ errno = ENAMETOOLONG;
+ else if (len)
+ {
+ strcpy (fixed_name, name);
+ if (ISSLASH (fixed_name[len - 1]))
+ {
+ check_dir = true;
+ while (len && ISSLASH (fixed_name[len - 1]))
+ fixed_name[--len] = '\0';
+ if (!len)
+ fixed_name[0] = '/';
+ }
+ else
+ fixed_name[len++] = '/';
+ result = orig_stat (fixed_name, st);
+ if (result == 0 && check_dir && !S_ISDIR (st->st_mode))
+ {
+ result = -1;
+ errno = ENOTDIR;
+ }
+ }
+ }
+#endif /* REPLACE_FUNC_STAT_DIR */
+ return result;
+}
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 62d18c62811..2697a4bd1db 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -274,6 +274,21 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
"use gnulib module malloc-posix for portability");
#endif
+/* Convert a multibyte character to a wide character. */
+#if @GNULIB_MBTOWC@
+# if @REPLACE_MBTOWC@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef mbtowc
+# define mbtowc rpl_mbtowc
+# endif
+_GL_FUNCDECL_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+# else
+_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+# endif
+_GL_CXXALIASWARN (mbtowc);
+#endif
+
#if @GNULIB_MKDTEMP@
/* Create a unique temporary directory from TEMPLATE.
The last six characters of TEMPLATE must be "XXXXXX";
@@ -723,6 +738,21 @@ _GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - "
# endif
#endif
+/* Convert a wide character to a multibyte character. */
+#if @GNULIB_WCTOMB@
+# if @REPLACE_WCTOMB@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef wctomb
+# define wctomb rpl_wctomb
+# endif
+_GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc));
+_GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc));
+# else
+_GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc));
+# endif
+_GL_CXXALIASWARN (wctomb);
+#endif
+
#endif /* _GL_STDLIB_H */
#endif /* _GL_STDLIB_H */
diff --git a/lib/symlink.c b/lib/symlink.c
new file mode 100644
index 00000000000..2896cc9655b
--- /dev/null
+++ b/lib/symlink.c
@@ -0,0 +1,57 @@
+/* Stub for symlink().
+ Copyright (C) 2009-2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+
+#if HAVE_SYMLINK
+
+# undef symlink
+
+/* Create a symlink, but reject trailing slash. */
+int
+rpl_symlink (char const *contents, char const *name)
+{
+ size_t len = strlen (name);
+ if (len && name[len - 1] == '/')
+ {
+ struct stat st;
+ if (lstat (name, &st) == 0)
+ errno = EEXIST;
+ return -1;
+ }
+ return symlink (contents, name);
+}
+
+#else /* !HAVE_SYMLINK */
+
+/* The system does not support symlinks. */
+int
+symlink (char const *contents _GL_UNUSED,
+ char const *name _GL_UNUSED)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif /* !HAVE_SYMLINK */
diff --git a/m4/dos.m4 b/m4/dos.m4
new file mode 100644
index 00000000000..ed9c4cee670
--- /dev/null
+++ b/m4/dos.m4
@@ -0,0 +1,71 @@
+#serial 11 -*- autoconf -*-
+
+# Define some macros required for proper operation of code in lib/*.c
+# on MSDOS/Windows systems.
+
+# Copyright (C) 2000-2001, 2004-2006, 2009-2011 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# From Jim Meyering.
+
+AC_DEFUN([gl_AC_DOS],
+ [
+ AC_CACHE_CHECK([whether system is Windows or MSDOS], [ac_cv_win_or_dos],
+ [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__
+neither MSDOS nor Windows
+#endif]])],
+ [ac_cv_win_or_dos=yes],
+ [ac_cv_win_or_dos=no])
+ ])
+
+ if test x"$ac_cv_win_or_dos" = xyes; then
+ ac_fs_accepts_drive_letter_prefix=1
+ ac_fs_backslash_is_file_name_separator=1
+ AC_CACHE_CHECK([whether drive letter can start relative path],
+ [ac_cv_drive_letter_can_be_relative],
+ [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if defined __CYGWIN__
+drive letters are always absolute
+#endif]])],
+ [ac_cv_drive_letter_can_be_relative=yes],
+ [ac_cv_drive_letter_can_be_relative=no])
+ ])
+ if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then
+ ac_fs_drive_letter_can_be_relative=1
+ else
+ ac_fs_drive_letter_can_be_relative=0
+ fi
+ else
+ ac_fs_accepts_drive_letter_prefix=0
+ ac_fs_backslash_is_file_name_separator=0
+ ac_fs_drive_letter_can_be_relative=0
+ fi
+
+ AC_DEFINE_UNQUOTED([FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX],
+ $ac_fs_accepts_drive_letter_prefix,
+ [Define on systems for which file names may have a so-called
+ `drive letter' prefix, define this to compute the length of that
+ prefix, including the colon.])
+
+ AH_VERBATIM(ISSLASH,
+ [#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#else
+# define ISSLASH(C) ((C) == '/')
+#endif])
+
+ AC_DEFINE_UNQUOTED([FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR],
+ $ac_fs_backslash_is_file_name_separator,
+ [Define if the backslash character may also serve as a file name
+ component separator.])
+
+ AC_DEFINE_UNQUOTED([FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE],
+ $ac_fs_drive_letter_can_be_relative,
+ [Define if a drive letter prefix denotes a relative path if it is
+ not followed by a file name component separator.])
+ ])
diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4
index 10ec34da386..c495389af8f 100644
--- a/m4/gl-comp.m4
+++ b/m4/gl-comp.m4
@@ -40,13 +40,17 @@ AC_DEFUN([gl_EARLY],
# Code from module ignore-value:
# Code from module include_next:
# Code from module intprops:
+ # Code from module lstat:
# Code from module mktime:
# Code from module multiarch:
+ # Code from module readlink:
+ # Code from module stat:
# Code from module stdbool:
# Code from module stddef:
# Code from module stdint:
# Code from module stdlib:
# Code from module strftime:
+ # Code from module symlink:
# Code from module sys_stat:
# Code from module time:
# Code from module time_r:
@@ -94,11 +98,20 @@ AC_DEFUN([gl_INIT],
AC_REQUIRE([AC_C_INLINE])
# Code from module include_next:
# Code from module intprops:
+ # Code from module lstat:
+ gl_FUNC_LSTAT
+ gl_SYS_STAT_MODULE_INDICATOR([lstat])
# Code from module mktime:
gl_FUNC_MKTIME
gl_TIME_MODULE_INDICATOR([mktime])
# Code from module multiarch:
gl_MULTIARCH
+ # Code from module readlink:
+ gl_FUNC_READLINK
+ gl_UNISTD_MODULE_INDICATOR([readlink])
+ # Code from module stat:
+ gl_FUNC_STAT
+ gl_SYS_STAT_MODULE_INDICATOR([stat])
# Code from module stdbool:
AM_STDBOOL_H
# Code from module stddef:
@@ -109,6 +122,9 @@ AC_DEFUN([gl_INIT],
gl_STDLIB_H
# Code from module strftime:
gl_FUNC_GNU_STRFTIME
+ # Code from module symlink:
+ gl_FUNC_SYMLINK
+ gl_UNISTD_MODULE_INDICATOR([symlink])
# Code from module sys_stat:
gl_HEADER_SYS_STAT_H
AC_PROG_MKDIR_P
@@ -276,22 +292,27 @@ AC_DEFUN([gl_FILE_LIST], [
lib/gettext.h
lib/ignore-value.h
lib/intprops.h
+ lib/lstat.c
lib/md5.c
lib/md5.h
lib/mktime-internal.h
lib/mktime.c
+ lib/readlink.c
+ lib/stat.c
lib/stdbool.in.h
lib/stddef.in.h
lib/stdint.in.h
lib/stdlib.in.h
lib/strftime.c
lib/strftime.h
+ lib/symlink.c
lib/sys_stat.in.h
lib/time.in.h
lib/time_r.c
lib/unistd.in.h
m4/00gnulib.m4
m4/c-strtod.m4
+ m4/dos.m4
m4/extensions.m4
m4/filemode.m4
m4/getloadavg.m4
@@ -299,15 +320,19 @@ AC_DEFUN([gl_FILE_LIST], [
m4/gnulib-common.m4
m4/include_next.m4
m4/longlong.m4
+ m4/lstat.m4
m4/md5.m4
m4/mktime.m4
m4/multiarch.m4
+ m4/readlink.m4
m4/st_dm_mode.m4
+ m4/stat.m4
m4/stdbool.m4
m4/stddef_h.m4
m4/stdint.m4
m4/stdlib_h.m4
m4/strftime.m4
+ m4/symlink.m4
m4/sys_stat_h.m4
m4/time_h.m4
m4/time_r.m4
diff --git a/m4/lstat.m4 b/m4/lstat.m4
new file mode 100644
index 00000000000..b9b22a6b20e
--- /dev/null
+++ b/m4/lstat.m4
@@ -0,0 +1,69 @@
+# serial 21
+
+# Copyright (C) 1997-2001, 2003-2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl From Jim Meyering.
+
+AC_DEFUN([gl_FUNC_LSTAT],
+[
+ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+ dnl If lstat does not exist, the replacement <sys/stat.h> does
+ dnl "#define lstat stat", and lstat.c is a no-op.
+ AC_CHECK_FUNCS_ONCE([lstat])
+ if test $ac_cv_func_lstat = yes; then
+ AC_REQUIRE([AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
+ if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
+ dnl Note: AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK does AC_LIBOBJ([lstat]).
+ REPLACE_LSTAT=1
+ fi
+ # Prerequisites of lib/lstat.c.
+ AC_REQUIRE([AC_C_INLINE])
+ else
+ HAVE_LSTAT=0
+ fi
+])
+
+# Redefine AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK, because it is no longer
+# maintained in Autoconf.
+AC_DEFUN([AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK],
+[
+ AC_CACHE_CHECK([whether lstat correctly handles trailing slash],
+ [ac_cv_func_lstat_dereferences_slashed_symlink],
+ [rm -f conftest.sym conftest.file
+ echo >conftest.file
+ if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [AC_INCLUDES_DEFAULT],
+ [[struct stat sbuf;
+ /* Linux will dereference the symlink and fail, as required by
+ POSIX. That is better in the sense that it means we will not
+ have to compile and use the lstat wrapper. */
+ return lstat ("conftest.sym/", &sbuf) == 0;
+ ]])],
+ [ac_cv_func_lstat_dereferences_slashed_symlink=yes],
+ [ac_cv_func_lstat_dereferences_slashed_symlink=no],
+ [# When cross-compiling, be pessimistic so we will end up using the
+ # replacement version of lstat that checks for trailing slashes and
+ # calls lstat a second time when necessary.
+ ac_cv_func_lstat_dereferences_slashed_symlink=no
+ ])
+ else
+ # If the 'ln -s' command failed, then we probably don't even
+ # have an lstat function.
+ ac_cv_func_lstat_dereferences_slashed_symlink=no
+ fi
+ rm -f conftest.sym conftest.file
+ ])
+ test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
+ AC_DEFINE_UNQUOTED([LSTAT_FOLLOWS_SLASHED_SYMLINK], [1],
+ [Define to 1 if `lstat' dereferences a symlink specified
+ with a trailing slash.])
+ if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then
+ AC_LIBOBJ([lstat])
+ fi
+])
diff --git a/m4/readlink.m4 b/m4/readlink.m4
new file mode 100644
index 00000000000..a502ca560fe
--- /dev/null
+++ b/m4/readlink.m4
@@ -0,0 +1,62 @@
+# readlink.m4 serial 9
+dnl Copyright (C) 2003, 2007, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_READLINK],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([readlink])
+ if test $ac_cv_func_readlink = no; then
+ HAVE_READLINK=0
+ AC_LIBOBJ([readlink])
+ gl_PREREQ_READLINK
+ else
+ AC_CACHE_CHECK([whether readlink signature is correct],
+ [gl_cv_decl_readlink_works],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <unistd.h>
+ /* Cause compilation failure if original declaration has wrong type. */
+ ssize_t readlink (const char *, char *, size_t);]])],
+ [gl_cv_decl_readlink_works=yes], [gl_cv_decl_readlink_works=no])])
+ dnl Solaris 9 ignores trailing slash.
+ dnl FreeBSD 7.2 dereferences only one level of links with trailing slash.
+ AC_CACHE_CHECK([whether readlink handles trailing slash correctly],
+ [gl_cv_func_readlink_works],
+ [# We have readlink, so assume ln -s works.
+ ln -s conftest.no-such conftest.link
+ ln -s conftest.link conftest.lnk2
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <unistd.h>
+]], [[char buf[20];
+ return readlink ("conftest.lnk2/", buf, sizeof buf) != -1;]])],
+ [gl_cv_func_readlink_works=yes], [gl_cv_func_readlink_works=no],
+ [gl_cv_func_readlink_works="guessing no"])
+ rm -f conftest.link conftest.lnk2])
+ if test "$gl_cv_func_readlink_works" != yes; then
+ AC_DEFINE([READLINK_TRAILING_SLASH_BUG], [1], [Define to 1 if readlink
+ fails to recognize a trailing slash.])
+ REPLACE_READLINK=1
+ AC_LIBOBJ([readlink])
+ elif test "$gl_cv_decl_readlink_works" != yes; then
+ REPLACE_READLINK=1
+ AC_LIBOBJ([readlink])
+ fi
+ fi
+])
+
+# Like gl_FUNC_READLINK, except prepare for separate compilation (no AC_LIBOBJ).
+AC_DEFUN([gl_FUNC_READLINK_SEPARATE],
+[
+ AC_CHECK_FUNCS_ONCE([readlink])
+ gl_PREREQ_READLINK
+])
+
+# Prerequisites of lib/readlink.c.
+AC_DEFUN([gl_PREREQ_READLINK],
+[
+ :
+])
diff --git a/m4/stat.m4 b/m4/stat.m4
new file mode 100644
index 00000000000..4883fe25eea
--- /dev/null
+++ b/m4/stat.m4
@@ -0,0 +1,67 @@
+# serial 6
+
+# Copyright (C) 2009-2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STAT],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_REQUIRE([gl_AC_DOS])
+ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([lstat])
+ dnl mingw is the only known platform where stat(".") and stat("./") differ
+ AC_CACHE_CHECK([whether stat handles trailing slashes on directories],
+ [gl_cv_func_stat_dir_slash],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <sys/stat.h>
+]], [[struct stat st; return stat (".", &st) != stat ("./", &st);]])],
+ [gl_cv_func_stat_dir_slash=yes], [gl_cv_func_stat_dir_slash=no],
+ [case $host_os in
+ mingw*) gl_cv_func_stat_dir_slash="guessing no";;
+ *) gl_cv_func_stat_dir_slash="guessing yes";;
+ esac])])
+ dnl AIX 7.1, Solaris 9 mistakenly succeed on stat("file/")
+ dnl FreeBSD 7.2 mistakenly succeeds on stat("link-to-file/")
+ AC_CACHE_CHECK([whether stat handles trailing slashes on files],
+ [gl_cv_func_stat_file_slash],
+ [touch conftest.tmp
+ # Assume that if we have lstat, we can also check symlinks.
+ if test $ac_cv_func_lstat = yes; then
+ ln -s conftest.tmp conftest.lnk
+ fi
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <sys/stat.h>
+]], [[int result = 0;
+ struct stat st;
+ if (!stat ("conftest.tmp/", &st))
+ result |= 1;
+#if HAVE_LSTAT
+ if (!stat ("conftest.lnk/", &st))
+ result |= 2;
+#endif
+ return result;
+ ]])],
+ [gl_cv_func_stat_file_slash=yes], [gl_cv_func_stat_file_slash=no],
+ [gl_cv_func_stat_file_slash="guessing no"])
+ rm -f conftest.tmp conftest.lnk])
+ case $gl_cv_func_stat_dir_slash in
+ *no) REPLACE_STAT=1
+ AC_DEFINE([REPLACE_FUNC_STAT_DIR], [1], [Define to 1 if stat needs
+ help when passed a directory name with a trailing slash]);;
+ esac
+ case $gl_cv_func_stat_file_slash in
+ *no) REPLACE_STAT=1
+ AC_DEFINE([REPLACE_FUNC_STAT_FILE], [1], [Define to 1 if stat needs
+ help when passed a file name with a trailing slash]);;
+ esac
+ if test $REPLACE_STAT = 1; then
+ AC_LIBOBJ([stat])
+ dnl Prerequisites of lib/stat.c.
+ AC_REQUIRE([AC_C_INLINE])
+ fi
+])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index d28b552e905..25fdada0de7 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 36
+# stdlib_h.m4 serial 37
dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -44,6 +44,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT])
GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX])
+ GNULIB_MBTOWC=0; AC_SUBST([GNULIB_MBTOWC])
GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP])
GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP])
GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS])
@@ -62,6 +63,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX])
GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT])
GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV])
+ GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE__EXIT=1; AC_SUBST([HAVE__EXIT])
HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL])
@@ -91,6 +93,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC])
REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME])
REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC])
+ REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC])
REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP])
REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV])
REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC])
@@ -98,4 +101,5 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV])
REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD])
REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV])
+ REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB])
])
diff --git a/m4/symlink.m4 b/m4/symlink.m4
new file mode 100644
index 00000000000..917d5f0ec2c
--- /dev/null
+++ b/m4/symlink.m4
@@ -0,0 +1,45 @@
+# serial 4
+# See if we need to provide symlink replacement.
+
+dnl Copyright (C) 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Written by Eric Blake.
+
+AC_DEFUN([gl_FUNC_SYMLINK],
+[
+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_CHECK_FUNCS_ONCE([symlink])
+ dnl The best we can do on mingw is provide a dummy that always fails, so
+ dnl that compilation can proceed with fewer ifdefs. On FreeBSD 7.2, AIX 7.1,
+ dnl and Solaris 9, we want to fix a bug with trailing slash handling.
+ if test $ac_cv_func_symlink = no; then
+ HAVE_SYMLINK=0
+ AC_LIBOBJ([symlink])
+ else
+ AC_CACHE_CHECK([whether symlink handles trailing slash correctly],
+ [gl_cv_func_symlink_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <unistd.h>
+ ]],
+ [[int result = 0;
+ if (!symlink ("a", "conftest.link/"))
+ result |= 1;
+ if (symlink ("conftest.f", "conftest.lnk2"))
+ result |= 2;
+ else if (!symlink ("a", "conftest.lnk2/"))
+ result |= 4;
+ return result;
+ ]])],
+ [gl_cv_func_symlink_works=yes], [gl_cv_func_symlink_works=no],
+ [gl_cv_func_symlink_works="guessing no"])
+ rm -f conftest.f conftest.link conftest.lnk2])
+ if test "$gl_cv_func_symlink_works" != yes; then
+ REPLACE_SYMLINK=1
+ AC_LIBOBJ([symlink])
+ fi
+ fi
+])
diff --git a/src/ChangeLog b/src/ChangeLog
index 8befb78f91f..6673a25f74f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,12 @@
2011-02-22 Paul Eggert <eggert@cs.ucla.edu>
+ Work around some portability problems with symlinks.
+ * fileio.c (Frename_file, Fmake_symbolic_link, Ffile_symlink_p):
+ Simplify the code by assuming that the readlink and symlink calls
+ exist, even if they always fail on this host.
+ (Ffile_readable_p): Likewise, for fifos.
+ * config.in: Regenerate.
+
* dired.c (Ffile_attributes): Simplify and avoid #ifdef.
2011-02-22 Wolfgang Jenkner <wjenkner@inode.at> (tiny change)
diff --git a/src/config.in b/src/config.in
index ded8c6b292a..2a2a71659f5 100644
--- a/src/config.in
+++ b/src/config.in
@@ -72,6 +72,19 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Enable expensive run-time checking of data types? */
#undef ENABLE_CHECKING
+/* Define on systems for which file names may have a so-called `drive letter'
+ prefix, define this to compute the length of that prefix, including the
+ colon. */
+#undef FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+
+/* Define if the backslash character may also serve as a file name component
+ separator. */
+#undef FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
+
+/* Define if a drive letter prefix denotes a relative path if it is not
+ followed by a file name component separator. */
+#undef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
+
/* Define this to check for errors in cons list. */
#undef GC_CHECK_CONS_LIST
@@ -576,6 +589,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
/* Define to 1 if you have the `recvfrom' function. */
#undef HAVE_RECVFROM
@@ -696,6 +712,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define if struct stat has an st_dm_mode member. */
#undef HAVE_ST_DM_MODE
+/* Define to 1 if you have the `symlink' function. */
+#undef HAVE_SYMLINK
+
/* Define to 1 if you have the `sync' function. */
#undef HAVE_SYNC
@@ -888,6 +907,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define to support using a Hesiod database to find the POP server. */
#undef HESIOD
+#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#else
+# define ISSLASH(C) ((C) == '/')
+#endif
+
/* Define to support Kerberos-authenticated POP mail retrieval. */
#undef KERBEROS
@@ -897,6 +922,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Define to 1 if localtime caches TZ. */
#undef LOCALTIME_CACHE
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
+
/* String giving fallback POP mail host. */
#undef MAILHOST
@@ -968,10 +997,21 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
'ptrdiff_t'. */
#undef PTRDIFF_T_SUFFIX
+/* Define to 1 if readlink fails to recognize a trailing slash. */
+#undef READLINK_TRAILING_SLASH_BUG
+
/* Define REL_ALLOC if you want to use the relocating allocator for buffer
space. */
#undef REL_ALLOC
+/* Define to 1 if stat needs help when passed a directory name with a trailing
+ slash */
+#undef REPLACE_FUNC_STAT_DIR
+
+/* Define to 1 if stat needs help when passed a file name with a trailing
+ slash */
+#undef REPLACE_FUNC_STAT_FILE
+
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
diff --git a/src/fileio.c b/src/fileio.c
index 0225e0bf3a9..26006d63052 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2178,14 +2178,11 @@ This is what happens in interactive use with M-x. */)
if (errno == EXDEV)
{
int count;
-#ifdef S_IFLNK
symlink_target = Ffile_symlink_p (file);
if (! NILP (symlink_target))
Fmake_symbolic_link (symlink_target, newname,
NILP (ok_if_already_exists) ? Qnil : Qt);
- else
-#endif
- if (!NILP (Ffile_directory_p (file)))
+ else if (!NILP (Ffile_directory_p (file)))
call4 (Qcopy_directory, file, newname, Qt, Qnil);
else
/* We have already prompted if it was an integer, so don't
@@ -2197,11 +2194,7 @@ This is what happens in interactive use with M-x. */)
count = SPECPDL_INDEX ();
specbind (Qdelete_by_moving_to_trash, Qnil);
- if (!NILP (Ffile_directory_p (file))
-#ifdef S_IFLNK
- && NILP (symlink_target)
-#endif
- )
+ if (!NILP (Ffile_directory_p (file)) && NILP (symlink_target))
call2 (Qdelete_directory, file, Qt);
else
Fdelete_file (file, Qnil);
@@ -2311,7 +2304,6 @@ This happens for interactive use with M-x. */)
RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
linkname, ok_if_already_exists));
-#ifdef S_IFLNK
encoded_filename = ENCODE_FILE (filename);
encoded_linkname = ENCODE_FILE (linkname);
@@ -2338,12 +2330,6 @@ This happens for interactive use with M-x. */)
}
UNGCPRO;
return Qnil;
-
-#else
- UNGCPRO;
- xsignal1 (Qfile_error, build_string ("Symbolic links are not supported"));
-
-#endif /* S_IFLNK */
}
@@ -2482,7 +2468,7 @@ See also `file-exists-p' and `file-attributes'. */)
return Qnil;
#else /* not DOS_NT and not macintosh */
flags = O_RDONLY;
-#if defined (S_IFIFO) && defined (O_NONBLOCK)
+#ifdef O_NONBLOCK
/* Opening a fifo without O_NONBLOCK can wait.
We don't want to wait. But we don't want to mess wth O_NONBLOCK
except in the case of a fifo, on a system which handles it. */
@@ -2584,6 +2570,10 @@ points to a nonexistent file. */)
(Lisp_Object filename)
{
Lisp_Object handler;
+ char *buf;
+ int bufsize;
+ int valsize;
+ Lisp_Object val;
CHECK_STRING (filename);
filename = Fexpand_file_name (filename, Qnil);
@@ -2594,13 +2584,6 @@ points to a nonexistent file. */)
if (!NILP (handler))
return call2 (handler, Qfile_symlink_p, filename);
-#ifdef S_IFLNK
- {
- char *buf;
- int bufsize;
- int valsize;
- Lisp_Object val;
-
filename = ENCODE_FILE (filename);
bufsize = 50;
@@ -2635,10 +2618,6 @@ points to a nonexistent file. */)
xfree (buf);
val = DECODE_FILE (val);
return val;
- }
-#else /* not S_IFLNK */
- return Qnil;
-#endif /* not S_IFLNK */
}
DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,