diff options
-rwxr-xr-x | build-aux/gitlog-to-changelog | 4 | ||||
-rwxr-xr-x | build-aux/update-copyright | 4 | ||||
-rw-r--r-- | doc/misc/texinfo.tex | 25 | ||||
-rw-r--r-- | lib/acl-internal.c | 2 | ||||
-rw-r--r-- | lib/acl-internal.h | 2 | ||||
-rw-r--r-- | lib/binary-io.h | 2 | ||||
-rw-r--r-- | lib/dirent.in.h | 7 | ||||
-rw-r--r-- | lib/dirfd.c | 66 | ||||
-rw-r--r-- | lib/dup2.c | 51 | ||||
-rw-r--r-- | lib/fcntl.c | 87 | ||||
-rw-r--r-- | lib/fdopendir.c | 36 | ||||
-rw-r--r-- | lib/mktime.c | 12 | ||||
-rw-r--r-- | lib/openat-proc.c | 144 | ||||
-rw-r--r-- | lib/sig2str.h | 2 | ||||
-rw-r--r-- | lib/stdint.in.h | 5 | ||||
-rw-r--r-- | m4/dirfd.m4 | 16 | ||||
-rw-r--r-- | m4/dup2.m4 | 14 | ||||
-rw-r--r-- | m4/fcntl.m4 | 13 | ||||
-rw-r--r-- | m4/gnulib-comp.m4 | 3 | ||||
-rw-r--r-- | m4/utimes.m4 | 22 |
20 files changed, 424 insertions, 93 deletions
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog index a42650478a..a2513d0efc 100755 --- a/build-aux/gitlog-to-changelog +++ b/build-aux/gitlog-to-changelog @@ -1,9 +1,9 @@ -eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' +eval '(exit $?0)' && eval 'exec perl -wS "$0" "$@"' & eval 'exec perl -wS "$0" $argv:q' if 0; # Convert git log output to ChangeLog format. -my $VERSION = '2016-01-11 22:04'; # UTC +my $VERSION = '2016-01-12 23:09'; # UTC # The definition above must lie within the first 8 lines in order # for the Emacs time-stamp write hook (at end) to update it. # If you change this file with Emacs, please let the write hook diff --git a/build-aux/update-copyright b/build-aux/update-copyright index 8c6ee1fdd3..17ee6b14d1 100755 --- a/build-aux/update-copyright +++ b/build-aux/update-copyright @@ -1,9 +1,9 @@ -eval '(exit $?0)' && eval 'exec perl -wS -0777 -pi "$0" ${1+"$@"}' +eval '(exit $?0)' && eval 'exec perl -wS -0777 -pi "$0" "$@"' & eval 'exec perl -wS -0777 -pi "$0" $argv:q' if 0; # Update an FSF copyright year list to include the current year. -my $VERSION = '2016-01-11.22:04'; # UTC +my $VERSION = '2016-01-12.23:13'; # UTC # Copyright (C) 2009-2016 Free Software Foundation, Inc. # diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 936c32dc5f..8b3c9490f0 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2016-01-11.19} +\def\texinfoversion{2016-01-20.20} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -4737,11 +4737,10 @@ end \def\_{\normalunderscore}% \def\-{}% @- shouldn't affect sorting % - \def\lbracechar{{\indexlbrace}}% - \def\rbracechar{{\indexrbrace}}% - \let\{=\lbracechar - \let\}=\rbracechar - % + \uccode`\1=`\{ \uppercase{\def\{{1}}% + \uccode`\1=`\} \uppercase{\def\}{1}}% + \let\lbracechar\{ + \let\rbracechar\} % % Non-English letters. \def\AA{AA}% @@ -4901,9 +4900,15 @@ end \indexdummies % Must do this here, since \bf, etc expand at this stage \useindexbackslash % \indexbackslash isn't defined now so it will be output % as is; and it will print as backslash. + % The braces around \indexbrace are recognized by texindex. + % % Get the string to sort by, by processing the index entry with all % font commands turned off. {\indexnofonts + \def\lbracechar{{\indexlbrace}}% + \def\rbracechar{{\indexrbrace}}% + \let\{=\lbracechar + \let\}=\rbracechar \indexnonalnumdisappear \xdef\indexsortkey{}% \let\sortas=\indexwritesortas @@ -8526,10 +8531,6 @@ end }% \setcolor{\linkcolor}% \fi - % - % Float references are printed completely differently: "Figure 1.2" - % instead of "[somenode], p.3". We distinguish them by the - % LABEL-title being set to a magic string. {% % Have to otherify everything special to allow the \csname to % include an _ in the xref name, etc. @@ -8538,6 +8539,10 @@ end \expandafter\global\expandafter\let\expandafter\Xthisreftitle \csname XR#1-title\endcsname }% + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". \iffloat distinguishes them by + % \Xthisreftitle being set to a magic string. \iffloat\Xthisreftitle % If the user specified the print name (third arg) to the ref, % print it instead of our usual "Figure 1.2". diff --git a/lib/acl-internal.c b/lib/acl-internal.c index 569e2f9c9e..4de60c30ec 100644 --- a/lib/acl-internal.c +++ b/lib/acl-internal.c @@ -478,7 +478,7 @@ acl_nontrivial (int count, struct acl *entries) void free_permission_context (struct permission_context *ctx) { -#ifdef USE_ACL +#if USE_ACL # if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */ if (ctx->acl) acl_free (ctx->acl); diff --git a/lib/acl-internal.h b/lib/acl-internal.h index 526e9f0778..636273e0fb 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -255,7 +255,7 @@ extern int acl_nontrivial (int count, struct acl *entries); struct permission_context { mode_t mode; -#ifdef USE_ACL +#if USE_ACL # if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */ acl_t acl; # if !HAVE_ACL_TYPE_EXTENDED diff --git a/lib/binary-io.h b/lib/binary-io.h index d5c8233570..9f17c0d398 100644 --- a/lib/binary-io.h +++ b/lib/binary-io.h @@ -60,7 +60,7 @@ set_binary_mode (int fd, int mode) /* SET_BINARY (fd); changes the file descriptor fd to perform binary I/O. */ -#ifdef __DJGPP__ +#if defined __DJGPP__ || defined __EMX__ # include <unistd.h> /* declares isatty() */ /* Avoid putting stdin/stdout in binary mode if it is connected to the console, because that would make it impossible for the user diff --git a/lib/dirent.in.h b/lib/dirent.in.h index 4c62737bdc..65482d7b7a 100644 --- a/lib/dirent.in.h +++ b/lib/dirent.in.h @@ -158,6 +158,13 @@ _GL_WARN_ON_USE (closedir, "closedir is not portable - " # endif _GL_FUNCDECL_RPL (dirfd, int, (DIR *) _GL_ARG_NONNULL ((1))); _GL_CXXALIAS_RPL (dirfd, int, (DIR *)); + +# ifdef __KLIBC__ +/* Gnulib internal hooks needed to maintain the dirfd metadata. */ +_GL_EXTERN_C int _gl_register_dirp_fd (int fd, DIR *dirp) + _GL_ARG_NONNULL ((2)); +_GL_EXTERN_C void _gl_unregister_dirp_fd (int fd); +# endif # else # if defined __cplusplus && defined GNULIB_NAMESPACE && defined dirfd /* dirfd is defined as a macro and not as a function. diff --git a/lib/dirfd.c b/lib/dirfd.c index 1ea2a6373d..a32584856a 100644 --- a/lib/dirfd.c +++ b/lib/dirfd.c @@ -22,11 +22,77 @@ #include <dirent.h> #include <errno.h> +#ifdef __KLIBC__ +# include <stdlib.h> +# include <io.h> + +static struct dirp_fd_list +{ + DIR *dirp; + int fd; + struct dirp_fd_list *next; +} *dirp_fd_start = NULL; + +/* Register fd associated with dirp to dirp_fd_list. */ +int +_gl_register_dirp_fd (int fd, DIR *dirp) +{ + struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd); + if (!new_dirp_fd) + return -1; + + new_dirp_fd->dirp = dirp; + new_dirp_fd->fd = fd; + new_dirp_fd->next = dirp_fd_start; + + dirp_fd_start = new_dirp_fd; + + return 0; +} + +/* Unregister fd from dirp_fd_list with closing it */ +void +_gl_unregister_dirp_fd (int fd) +{ + struct dirp_fd_list *dirp_fd; + struct dirp_fd_list *dirp_fd_prev; + + for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd; + dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next) + { + if (dirp_fd->fd == fd) + { + if (dirp_fd_prev) + dirp_fd_prev->next = dirp_fd->next; + else /* dirp_fd == dirp_fd_start */ + dirp_fd_start = dirp_fd_start->next; + + close (fd); + free (dirp_fd); + break; + } + } +} +#endif + int dirfd (DIR *dir_p) { int fd = DIR_TO_FD (dir_p); if (fd == -1) +#ifndef __KLIBC__ errno = ENOTSUP; +#else + { + struct dirp_fd_list *dirp_fd; + + for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next) + if (dirp_fd->dirp == dir_p) + return dirp_fd->fd; + + errno = EINVAL; + } +#endif + return fd; } diff --git a/lib/dup2.c b/lib/dup2.c index c913f473ad..5d026f21fa 100644 --- a/lib/dup2.c +++ b/lib/dup2.c @@ -85,6 +85,57 @@ ms_windows_dup2 (int fd, int desired_fd) # define dup2 ms_windows_dup2 +# elif defined __KLIBC__ + +# include <InnoTekLIBC/backend.h> + +static int +klibc_dup2dirfd (int fd, int desired_fd) +{ + int tempfd; + int dupfd; + + tempfd = open ("NUL", O_RDONLY); + if (tempfd == -1) + return -1; + + if (tempfd == desired_fd) + { + close (tempfd); + + char path[_MAX_PATH]; + if (__libc_Back_ioFHToPath (fd, path, sizeof (path))) + return -1; + + return open(path, O_RDONLY); + } + + dupfd = klibc_dup2dirfd (fd, desired_fd); + + close (tempfd); + + return dupfd; +} + +static int +klibc_dup2 (int fd, int desired_fd) +{ + int dupfd; + struct stat sbuf; + + dupfd = dup2 (fd, desired_fd); + if (dupfd == -1 && errno == ENOTSUP \ + && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) + { + close (desired_fd); + + return klibc_dup2dirfd (fd, desired_fd); + } + + return dupfd; +} + +# define dup2 klibc_dup2 # endif int diff --git a/lib/fcntl.c b/lib/fcntl.c index 1ccc5acea8..fd17e962f8 100644 --- a/lib/fcntl.c +++ b/lib/fcntl.c @@ -162,6 +162,93 @@ dupfd (int oldfd, int newfd, int flags) } #endif /* W32 */ +#ifdef __KLIBC__ + +# define INCL_DOS +# include <os2.h> + +static int +klibc_fcntl (int fd, int action, /* arg */...) +{ + va_list arg_ptr; + int arg; + struct stat sbuf; + int result = -1; + + va_start (arg_ptr, action); + arg = va_arg (arg_ptr, int); + result = fcntl (fd, action, arg); + /* EPERM for F_DUPFD, ENOTSUP for others */ + if (result == -1 && (errno == EPERM || errno == ENOTSUP) + && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) + { + ULONG ulMode; + + switch (action) + { + case F_DUPFD: + /* Find available fd */ + while (fcntl (arg, F_GETFL) != -1 || errno != EBADF) + arg++; + + result = dup2 (fd, arg); + break; + + /* Using underlying APIs is right ? */ + case F_GETFD: + if (DosQueryFHState (fd, &ulMode)) + break; + + result = (ulMode & OPEN_FLAGS_NOINHERIT) ? FD_CLOEXEC : 0; + break; + + case F_SETFD: + if (arg & ~FD_CLOEXEC) + break; + + if (DosQueryFHState (fd, &ulMode)) + break; + + if (arg & FD_CLOEXEC) + ulMode |= OPEN_FLAGS_NOINHERIT; + else + ulMode &= ~OPEN_FLAGS_NOINHERIT; + + /* Filter supported flags. */ + ulMode &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR + | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT); + + if (DosSetFHState (fd, ulMode)) + break; + + result = 0; + break; + + case F_GETFL: + result = 0; + break; + + case F_SETFL: + if (arg != 0) + break; + + result = 0; + break; + + default : + errno = EINVAL; + break; + } + } + + va_end (arg_ptr); + + return result; +} + +# define fcntl klibc_fcntl +#endif + /* Perform the specified ACTION on the file descriptor FD, possibly using the argument ARG further described below. This replacement handles the following actions, and forwards all others on to the diff --git a/lib/fdopendir.c b/lib/fdopendir.c index f30ab2431b..c1f4dcbaca 100644 --- a/lib/fdopendir.c +++ b/lib/fdopendir.c @@ -62,6 +62,41 @@ static DIR *fd_clone_opendir (int, struct saved_cwd const *); If this function returns successfully, FD is under control of the dirent.h system, and the caller should not close or modify the state of FD other than by the dirent.h functions. */ +# ifdef __KLIBC__ +# include <InnoTekLIBC/backend.h> + +DIR * +fdopendir (int fd) +{ + char path[_MAX_PATH]; + DIR *dirp; + + /* Get a path from fd */ + if (__libc_Back_ioFHToPath (fd, path, sizeof (path))) + return NULL; + + dirp = opendir (path); + if (!dirp) + return NULL; + + /* Unregister fd registered by opendir() */ + _gl_unregister_dirp_fd (dirfd (dirp)); + + /* Register our fd */ + if (_gl_register_dirp_fd (fd, dirp)) + { + int saved_errno = errno; + + closedir (dirp); + + errno = saved_errno; + + dirp = NULL; + } + + return dirp; +} +# else DIR * fdopendir (int fd) { @@ -84,6 +119,7 @@ fdopendir (int fd) return dir; } +# endif /* Like fdopendir, except that if OLDER_DUPFD is not -1, it is known to be a dup of FD which is less than FD - 1 and which will be diff --git a/lib/mktime.c b/lib/mktime.c index adbf8d482a..c9738d0daf 100644 --- a/lib/mktime.c +++ b/lib/mktime.c @@ -19,7 +19,7 @@ /* Define this to have a standalone program to test this implementation of mktime. */ -/* #define DEBUG 1 */ +/* #define DEBUG_MKTIME 1 */ #ifndef _LIBC # include <config.h> @@ -38,13 +38,13 @@ #include <string.h> /* For the real memcpy prototype. */ -#if defined DEBUG && DEBUG +#if defined DEBUG_MKTIME && DEBUG_MKTIME # include <stdio.h> # include <stdlib.h> /* Make it work even if the system's libc has its own mktime routine. */ # undef mktime # define mktime my_mktime -#endif /* DEBUG */ +#endif /* DEBUG_MKTIME */ /* Some of the code in this file assumes that signed integer overflow silently wraps around. This assumption can't easily be programmed @@ -600,7 +600,7 @@ libc_hidden_def (mktime) libc_hidden_weak (timelocal) #endif -#if defined DEBUG && DEBUG +#if defined DEBUG_MKTIME && DEBUG_MKTIME static int not_equal_tm (const struct tm *a, const struct tm *b) @@ -732,10 +732,10 @@ main (int argc, char **argv) return status; } -#endif /* DEBUG */ +#endif /* DEBUG_MKTIME */ /* Local Variables: -compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime" +compile-command: "gcc -DDEBUG_MKTIME -I. -Wall -W -O2 -g mktime.c -o mktime" End: */ diff --git a/lib/openat-proc.c b/lib/openat-proc.c index 15a8c799c8..1712340a00 100644 --- a/lib/openat-proc.c +++ b/lib/openat-proc.c @@ -30,24 +30,21 @@ #include <string.h> #include <unistd.h> -#include "intprops.h" - -#define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/%s" - -#define PROC_SELF_FD_NAME_SIZE_BOUND(len) \ - (sizeof PROC_SELF_FD_FORMAT - sizeof "%d%s" \ - + INT_STRLEN_BOUND (int) + (len) + 1) +#ifdef __KLIBC__ +# include <InnoTekLIBC/backend.h> +#endif +#include "intprops.h" -/* Set BUF to the expansion of PROC_SELF_FD_FORMAT, using FD and FILE - respectively for %d and %s. If successful, return BUF if the - result fits in BUF, dynamically allocated memory otherwise. But - return NULL if /proc is not reliable, either because the operating - system support is lacking or because memory is low. */ +/* Set BUF to the name of the subfile of the directory identified by + FD, where the subfile is named FILE. If successful, return BUF if + the result fits in BUF, dynamically allocated memory otherwise. + Return NULL (setting errno) on error. */ char * openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) { - static int proc_status = 0; + char *result = buf; + int dirlen; /* Make sure the caller gets ENOENT when appropriate. */ if (!*file) @@ -56,47 +53,82 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) return buf; } - if (! proc_status) - { - /* Set PROC_STATUS to a positive value if /proc/self/fd is - reliable, and a negative value otherwise. Solaris 10 - /proc/self/fd mishandles "..", and any file name might expand - to ".." after symbolic link expansion, so avoid /proc/self/fd - if it mishandles "..". Solaris 10 has openat, but this - problem is exhibited on code that built on Solaris 8 and - running on Solaris 10. */ - - int proc_self_fd = open ("/proc/self/fd", - O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); - if (proc_self_fd < 0) - proc_status = -1; - else - { - /* Detect whether /proc/self/fd/%i/../fd exists, where %i is the - number of a file descriptor open on /proc/self/fd. On Linux, - that name resolves to /proc/self/fd, which was opened above. - However, on Solaris, it may resolve to /proc/self/fd/fd, which - cannot exist, since all names in /proc/self/fd are numeric. */ - char dotdot_buf[PROC_SELF_FD_NAME_SIZE_BOUND (sizeof "../fd" - 1)]; - sprintf (dotdot_buf, PROC_SELF_FD_FORMAT, proc_self_fd, "../fd"); - proc_status = access (dotdot_buf, F_OK) ? -1 : 1; - close (proc_self_fd); - } - } - - if (proc_status < 0) - return NULL; - else - { - size_t bufsize = PROC_SELF_FD_NAME_SIZE_BOUND (strlen (file)); - char *result = buf; - if (OPENAT_BUFFER_SIZE < bufsize) - { - result = malloc (bufsize); - if (! result) - return NULL; - } - sprintf (result, PROC_SELF_FD_FORMAT, fd, file); - return result; - } +#ifndef __KLIBC__ +# define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/" + { + enum { + PROC_SELF_FD_DIR_SIZE_BOUND + = (sizeof PROC_SELF_FD_FORMAT - (sizeof "%d" - 1) + + INT_STRLEN_BOUND (int)) + }; + + static int proc_status = 0; + if (! proc_status) + { + /* Set PROC_STATUS to a positive value if /proc/self/fd is + reliable, and a negative value otherwise. Solaris 10 + /proc/self/fd mishandles "..", and any file name might expand + to ".." after symbolic link expansion, so avoid /proc/self/fd + if it mishandles "..". Solaris 10 has openat, but this + problem is exhibited on code that built on Solaris 8 and + running on Solaris 10. */ + + int proc_self_fd = open ("/proc/self/fd", + O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); + if (proc_self_fd < 0) + proc_status = -1; + else + { + /* Detect whether /proc/self/fd/%i/../fd exists, where %i is the + number of a file descriptor open on /proc/self/fd. On Linux, + that name resolves to /proc/self/fd, which was opened above. + However, on Solaris, it may resolve to /proc/self/fd/fd, which + cannot exist, since all names in /proc/self/fd are numeric. */ + char dotdot_buf[PROC_SELF_FD_DIR_SIZE_BOUND + sizeof "../fd" - 1]; + sprintf (dotdot_buf, PROC_SELF_FD_FORMAT "../fd", proc_self_fd); + proc_status = access (dotdot_buf, F_OK) ? -1 : 1; + close (proc_self_fd); + } + } + + if (proc_status < 0) + return NULL; + else + { + size_t bufsize = PROC_SELF_FD_DIR_SIZE_BOUND + strlen (file); + if (OPENAT_BUFFER_SIZE < bufsize) + { + result = malloc (bufsize); + if (! result) + return NULL; + } + + dirlen = sprintf (result, PROC_SELF_FD_FORMAT, fd); + } + } +#else + /* OS/2 kLIBC provides a function to retrieve a path from a fd. */ + { + char dir[_MAX_PATH]; + size_t bufsize; + + if (__libc_Back_ioFHToPath (fd, dir, sizeof dir)) + return NULL; + + dirlen = strlen (dir); + bufsize = dirlen + 1 + strlen (file) + 1; /* 1 for '/', 1 for null */ + if (OPENAT_BUFFER_SIZE < bufsize) + { + result = malloc (bufsize); + if (! result) + return NULL; + } + + strcpy (result, dir); + result[dirlen++] = '/'; + } +#endif + + strcpy (result + dirlen, file); + return result; } diff --git a/lib/sig2str.h b/lib/sig2str.h index f3471702ba..2730774d16 100644 --- a/lib/sig2str.h +++ b/lib/sig2str.h @@ -44,6 +44,8 @@ int str2sig (char const *, int *); #if defined _sys_nsig # define SIGNUM_BOUND (_sys_nsig - 1) +#elif defined _SIG_MAXSIG +# define SIGNUM_BOUND (_SIG_MAXSIG - 2) /* FreeBSD >= 7. */ #elif defined NSIG # define SIGNUM_BOUND (NSIG - 1) #else diff --git a/lib/stdint.in.h b/lib/stdint.in.h index d241391795..0bb9ad41b2 100644 --- a/lib/stdint.in.h +++ b/lib/stdint.in.h @@ -288,12 +288,17 @@ typedef gl_uint_fast32_t gl_uint_fast16_t; /* 7.18.1.4. Integer types capable of holding object pointers */ +/* kLIBC's stdint.h defines _INTPTR_T_DECLARED and needs its own + definitions of intptr_t and uintptr_t (which use int and unsigned) + to avoid clashes with declarations of system functions like sbrk. */ +#ifndef _INTPTR_T_DECLARED #undef intptr_t #undef uintptr_t typedef long int gl_intptr_t; typedef unsigned long int gl_uintptr_t; #define intptr_t gl_intptr_t #define uintptr_t gl_uintptr_t +#endif /* 7.18.1.5. Greatest-width integer types */ diff --git a/m4/dirfd.m4 b/m4/dirfd.m4 index e9532e60a9..1d7cb080d8 100644 --- a/m4/dirfd.m4 +++ b/m4/dirfd.m4 @@ -1,4 +1,4 @@ -# serial 22 -*- Autoconf -*- +# serial 24 -*- Autoconf -*- dnl Find out how to get the file descriptor associated with an open DIR*. @@ -35,13 +35,15 @@ AC_DEFUN([gl_FUNC_DIRFD], gl_cv_func_dirfd_macro=yes, gl_cv_func_dirfd_macro=no)]) - # Use the replacement only if we have no function or macro with that name. - if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then - if test $ac_cv_have_decl_dirfd = yes; then - # If the system declares dirfd already, let's declare rpl_dirfd instead. + # Use the replacement if we have no function or macro with that name, + # or if OS/2 kLIBC whose dirfd() does not work. + # Replace only if the system declares dirfd already. + case $ac_cv_func_dirfd,$gl_cv_func_dirfd_macro,$host_os,$ac_cv_have_decl_dirfd in + no,no,*,yes | *,*,os2*,yes) REPLACE_DIRFD=1 - fi - fi + AC_DEFINE([REPLACE_DIRFD], [1], + [Define to 1 if gnulib's dirfd() replacement is used.]);; + esac ]) dnl Prerequisites of lib/dirfd.c. diff --git a/m4/dup2.m4 b/m4/dup2.m4 index 63d6d8eb6e..5b68312b1e 100644 --- a/m4/dup2.m4 +++ b/m4/dup2.m4 @@ -1,4 +1,4 @@ -#serial 24 +#serial 25 dnl Copyright (C) 2002, 2005, 2007, 2009-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -62,6 +62,16 @@ AC_DEFUN([gl_FUNC_DUP2], result |= 32; dup2 (2, 255); dup2 (2, 256); + /* On OS/2 kLIBC, dup2() does not work on a directory fd. */ + { + int fd = open (".", O_RDONLY); + if (fd == -1) + result |= 64; + else if (dup2 (fd, fd + 1) == -1) + result |= 128; + + close (fd); + } return result;]]) ], [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no], @@ -78,6 +88,8 @@ AC_DEFUN([gl_FUNC_DUP2], gl_cv_func_dup2_works="guessing no" ;; *-android*) # implemented using dup3(), which fails if oldfd == newfd gl_cv_func_dup2_works="guessing no" ;; + os2*) # on OS/2 kLIBC, dup2() does not work on a directory fd. + gl_cv_func_dup2_works="guessing no" ;; *) gl_cv_func_dup2_works="guessing yes" ;; esac]) ]) diff --git a/m4/fcntl.m4 b/m4/fcntl.m4 index 0037e5fb65..bb61470b2e 100644 --- a/m4/fcntl.m4 +++ b/m4/fcntl.m4 @@ -1,4 +1,4 @@ -# fcntl.m4 serial 8 +# fcntl.m4 serial 9 dnl Copyright (C) 2009-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -54,6 +54,17 @@ AC_DEFUN([gl_FUNC_FCNTL], if (errno != EINVAL) result |= 2; if (fcntl (0, F_DUPFD, bad_fd) != -1) result |= 4; if (errno != EINVAL) result |= 8; + /* On OS/2 kLIBC, F_DUPFD does not work on a directory fd */ + { + int fd; + fd = open (".", O_RDONLY); + if (fd == -1) + result |= 16; + else if (fcntl (fd, F_DUPFD, STDERR_FILENO + 1) == -1) + result |= 32; + + close (fd); + } return result;]])], [gl_cv_func_fcntl_f_dupfd_works=yes], [gl_cv_func_fcntl_f_dupfd_works=no], diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 27ca70a0d0..547af6641a 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -436,7 +436,8 @@ AC_DEFUN([gl_INIT], { if ! $gl_gnulib_enabled_dirfd; then gl_FUNC_DIRFD - if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then + if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no \ + || test $REPLACE_DIRFD = 1; then AC_LIBOBJ([dirfd]) gl_PREREQ_DIRFD fi diff --git a/m4/utimes.m4 b/m4/utimes.m4 index a016723e24..1876bec799 100644 --- a/m4/utimes.m4 +++ b/m4/utimes.m4 @@ -1,5 +1,5 @@ # Detect some bugs in glibc's implementation of utimes. -# serial 3 +# serial 4 dnl Copyright (C) 2003-2005, 2009-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -33,6 +33,7 @@ AC_DEFUN([gl_FUNC_UTIMES], #include <stdlib.h> #include <stdio.h> #include <utime.h> +#include <errno.h> static int inorder (time_t a, time_t b, time_t c) @@ -45,7 +46,10 @@ main () { int result = 0; char const *file = "conftest.utimes"; - static struct timeval timeval[2] = {{9, 10}, {999999, 999999}}; + /* On OS/2, file timestamps must be on or after 1980 in local time, + with an even number of seconds. */ + static struct timeval timeval[2] = {{315620000 + 10, 10}, + {315620000 + 1000000, 999998}}; /* Test whether utimes() essentially works. */ { @@ -82,9 +86,19 @@ main () result |= 1; else if (fstat (fd, &st0) != 0) result |= 1; - else if (utimes (file, timeval) != 0) + else if (utimes (file, timeval) != 0 + && (errno != EACCES + /* OS/2 kLIBC utimes fails on opened files. */ + || close (fd) != 0 + || utimes (file, timeval) != 0 + || (fd = open (file, O_WRONLY)) < 0)) result |= 2; - else if (utimes (file, NULL) != 0) + else if (utimes (file, NULL) != 0 + && (errno != EACCES + /* OS/2 kLIBC utimes fails on opened files. */ + || close (fd) != 0 + || utimes (file, NULL) != 0 + || (fd = open (file, O_WRONLY)) < 0)) result |= 8; else if (fstat (fd, &st1) != 0) result |= 1; |