summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2016-01-24 14:50:47 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2016-01-24 14:51:22 -0800
commit1698036a43d9e2c55ead6216ea7156df8615da47 (patch)
tree60bb61c907536ebc38c6b301fd754028b8a9b542 /lib
parentfbce4757a874cc43806eb41b8637538b101c3c69 (diff)
Merge from gnulib
This incorporates: 2016-01-24 openat_proc_name: fix last '/' overwritten on OS/2 kLIBC 2016-01-24 closedir, dirfd, opendir: port to OpenSolaris 5.10 2016-01-15 detect utimes() correctly on OS/2 kLIBC 2016-01-15 openat_proc_name: port to OS/2 kLIBC 2016-01-14 stdint: check _INTPTR_T_DECLARED for intptr_t etc. 2016-01-14 opendir, closedir, dirfd, fdopendir: port to OS/2 kLIBC 2016-01-14 dup, dup2, fcntl: support a directory fd on OS/2 kLIBC 2016-01-14 binary-io: don't put fd in binary mode if a console on EMX 2016-01-14 sig2str: list all signals on FreeBSD >= 7 2016-01-13 acl-permissions: port to USE_ACL==0 platforms 2016-01-12 mktime: rename macro to avoid glibc clash 2016-01-12 Port "$@" to OpenIndiana ksh93 2016-01-12 Port Universal Time settings to strict POSIX * build-aux/gitlog-to-changelog, build-aux/update-copyright: * doc/misc/texinfo.tex, lib/acl-internal.c, lib/acl-internal.h: * lib/binary-io.h, lib/dirent.in.h, lib/dirfd.c, lib/dup2.c: * lib/fcntl.c, lib/fdopendir.c, lib/mktime.c, lib/openat-proc.c: * lib/sig2str.h, lib/stdint.in.h, m4/dirfd.m4, m4/dup2.m4: * m4/fcntl.m4, m4/utimes.m4: Copy from gnulib. * m4/gnulib-comp.m4: Regenerate.
Diffstat (limited to 'lib')
-rw-r--r--lib/acl-internal.c2
-rw-r--r--lib/acl-internal.h2
-rw-r--r--lib/binary-io.h2
-rw-r--r--lib/dirent.in.h7
-rw-r--r--lib/dirfd.c66
-rw-r--r--lib/dup2.c51
-rw-r--r--lib/fcntl.c87
-rw-r--r--lib/fdopendir.c36
-rw-r--r--lib/mktime.c12
-rw-r--r--lib/openat-proc.c144
-rw-r--r--lib/sig2str.h2
-rw-r--r--lib/stdint.in.h5
12 files changed, 351 insertions, 65 deletions
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 */