[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.
This commit is contained in:
Paul Eggert 2011-02-22 11:30:07 -08:00
parent 8d40723d1e
commit ae0d725005
22 changed files with 1449 additions and 149 deletions

View file

@ -1,3 +1,14 @@
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.

View file

@ -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)

5
aclocal.m4 vendored
View file

@ -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])

702
configure vendored
View file

@ -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 :

View file

@ -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)

View file

@ -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)'; \

View file

@ -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

91
lib/lstat.c Normal file
View file

@ -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 */

74
lib/readlink.c Normal file
View file

@ -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 */

104
lib/stat.c Normal file
View file

@ -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;
}

View file

@ -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 */

57
lib/symlink.c Normal file
View file

@ -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 */

71
m4/dos.m4 Normal file
View file

@ -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.])
])

View file

@ -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

69
m4/lstat.m4 Normal file
View file

@ -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
])

62
m4/readlink.m4 Normal file
View file

@ -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],
[
:
])

67
m4/stat.m4 Normal file
View file

@ -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
])

View file

@ -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])
])

45
m4/symlink.m4 Normal file
View file

@ -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
])

View file

@ -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)

View file

@ -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

View file

@ -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,