summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2015-02-20 23:31:17 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2015-02-20 23:32:45 -0800
commit066b17df681fabb40108d719086669957aebbc51 (patch)
tree27f9362ed6a6e68ef6b61925932f84bb1afb37b8 /lib
parent43fb42da8bd6851b5b22d2bbb5d2cd8ceede9c09 (diff)
downloademacs-066b17df681fabb40108d719086669957aebbc51.tar.gz
Merge from gnulib
* doc/misc/texinfo.tex: Update from gnulib. * lib/getdtablesize.c, lib/getopt.c, lib/signal.in.h, lib/tempname.c: * lib/tempname.h, m4/dup2.m4, m4/fcntl.m4, m4/getdtablesize.m4: Update from gnulib, incorporating: 2015-02-20 getdtablesize: port better for Android 2015-02-19 fcntl: Fix cross compiling 2015-02-18 dup2, fcntl: cross-compile better for Android 2015-02-18 getopt: don't crash on memory exhaustion 2015-02-17 tempname: allow compilation with C++ (trivial) 2015-02-17 dup2, fcntl: port to AIX 2015-02-16 getdtablesize, dup2, fcntl: port to Android 2015-02-11 getdtablesize, signal_h: Fix Android build 2015-02-11 maint: various whitespace cleanups in tempname
Diffstat (limited to 'lib')
-rw-r--r--lib/getdtablesize.c35
-rw-r--r--lib/getopt.c52
-rw-r--r--lib/signal.in.h8
-rw-r--r--lib/tempname.c118
-rw-r--r--lib/tempname.h15
5 files changed, 146 insertions, 82 deletions
diff --git a/lib/getdtablesize.c b/lib/getdtablesize.c
index 59b97360bc5..bad45f7e32f 100644
--- a/lib/getdtablesize.c
+++ b/lib/getdtablesize.c
@@ -84,32 +84,31 @@ getdtablesize (void)
return dtablesize;
}
-#elif HAVE_GETDTABLESIZE
+#else
+# include <limits.h>
# include <sys/resource.h>
-# undef getdtablesize
+
+# ifdef __CYGWIN__
+ /* Cygwin 1.7.25 auto-increases the RLIMIT_NOFILE soft limit until it
+ hits the compile-time constant hard limit of 3200. We might as
+ well just report the hard limit. */
+# define rlim_cur rlim_max
+# endif
int
-rpl_getdtablesize(void)
+getdtablesize (void)
{
- /* To date, this replacement is only compiled for Cygwin 1.7.25,
- which auto-increased the RLIMIT_NOFILE soft limit until it
- hits the compile-time constant hard limit of 3200. Although
- that version of cygwin supported a child process inheriting
- a smaller soft limit, the smaller limit is not enforced, so
- we might as well just report the hard limit. */
struct rlimit lim;
- if (!getrlimit (RLIMIT_NOFILE, &lim) && lim.rlim_max != RLIM_INFINITY)
- return lim.rlim_max;
- return getdtablesize ();
-}
-#elif defined _SC_OPEN_MAX
+ if (getrlimit (RLIMIT_NOFILE, &lim) == 0
+ && 0 <= lim.rlim_cur && lim.rlim_cur <= INT_MAX
+ && lim.rlim_cur != RLIM_INFINITY
+ && lim.rlim_cur != RLIM_SAVED_CUR
+ && lim.rlim_cur != RLIM_SAVED_MAX)
+ return lim.rlim_cur;
-int
-getdtablesize (void)
-{
- return sysconf (_SC_OPEN_MAX);
+ return INT_MAX;
}
#endif
diff --git a/lib/getopt.c b/lib/getopt.c
index 3b9c585a28c..212cbf73410 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -487,7 +487,20 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
const struct option *p;
struct option_list *next;
} *ambig_list = NULL;
+#ifdef _LIBC
+/* malloc() not used for _LIBC to simplify failure messages. */
+# define free_option_list(l)
+#else
+# define free_option_list(l) \
+ while (l != NULL) \
+ { \
+ struct option_list *pn = l->next; \
+ free (l); \
+ l = pn; \
+ }
+#endif
int exact = 0;
+ int ambig = 0;
int indfound = -1;
int option_index;
@@ -514,22 +527,37 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
pfound = p;
indfound = option_index;
}
+ else if (ambig)
+ ; /* Taking simpler path to handling ambiguities. */
else if (long_only
|| pfound->has_arg != p->has_arg
|| pfound->flag != p->flag
|| pfound->val != p->val)
{
/* Second or later nonexact match found. */
+#ifdef _LIBC
+ struct option_list *newp = alloca (sizeof (*newp));
+#else
struct option_list *newp = malloc (sizeof (*newp));
- newp->p = p;
- newp->next = ambig_list;
- ambig_list = newp;
+ if (newp == NULL)
+ {
+ free_option_list (ambig_list);
+ ambig_list = NULL;
+ ambig = 1; /* Use simpler fallback message. */
+ }
+ else
+#endif
+ {
+ newp->p = p;
+ newp->next = ambig_list;
+ ambig_list = newp;
+ }
}
}
- if (ambig_list != NULL && !exact)
+ if ((ambig || ambig_list) && !exact)
{
- if (print_errors)
+ if (print_errors && ambig_list)
{
struct option_list first;
first.p = pfound;
@@ -585,18 +613,20 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
fputc ('\n', stderr);
#endif
}
+ else if (print_errors && ambig)
+ {
+ fprintf (stderr,
+ _("%s: option '%s' is ambiguous\n"),
+ argv[0], argv[d->optind]);
+ }
d->__nextchar += strlen (d->__nextchar);
d->optind++;
d->optopt = 0;
+ free_option_list (ambig_list);
return '?';
}
- while (ambig_list != NULL)
- {
- struct option_list *pn = ambig_list->next;
- free (ambig_list);
- ambig_list = pn;
- }
+ free_option_list (ambig_list);
if (pfound != NULL)
{
diff --git a/lib/signal.in.h b/lib/signal.in.h
index 0f2ff5af843..265b72ab0ec 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -55,11 +55,13 @@
#ifndef _@GUARD_PREFIX@_SIGNAL_H
#define _@GUARD_PREFIX@_SIGNAL_H
-/* Mac OS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6 declare
- pthread_sigmask in <pthread.h>, not in <signal.h>.
+/* Mac OS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6, Android
+ declare pthread_sigmask in <pthread.h>, not in <signal.h>.
But avoid namespace pollution on glibc systems.*/
#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \
- && ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ || defined __sun) \
+ && ((defined __APPLE__ && defined __MACH__) \
+ || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ \
+ || defined __sun || defined __ANDROID__) \
&& ! defined __GLIBC__
# include <pthread.h>
#endif
diff --git a/lib/tempname.c b/lib/tempname.c
index 088b224ab96..8e6d26cc485 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -62,6 +62,7 @@
# define struct_stat64 struct stat64
#else
# define struct_stat64 struct stat
+# define __try_tempname try_tempname
# define __gen_tempname gen_tempname
# define __getpid getpid
# define __gettimeofday gettimeofday
@@ -176,21 +177,9 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-/* Generate a temporary file name based on TMPL. TMPL must match the
- rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
- The name constructed does not exist at the time of the call to
- __gen_tempname. TMPL is overwritten with the result.
-
- KIND may be one of:
- __GT_NOCREATE: simply verify that the name does not exist
- at the time of the call.
- __GT_FILE: create the file using open(O_CREAT|O_EXCL)
- and return a read-write fd. The file is mode 0600.
- __GT_DIR: create a directory, which will be mode 0700.
-
- We use a clever algorithm to get hard-to-predict names. */
int
-__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
+__try_tempname (char *tmpl, int suffixlen, void *args,
+ int (*tryfunc) (char *, void *))
{
int len;
char *XXXXXX;
@@ -199,7 +188,6 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
unsigned int count;
int fd = -1;
int save_errno = errno;
- struct_stat64 st;
/* A lower bound on the number of temporary files to attempt to
generate. The maximum total number of temporary file names that
@@ -256,41 +244,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
v /= 62;
XXXXXX[5] = letters[v % 62];
- switch (kind)
- {
- case __GT_FILE:
- fd = __open (tmpl,
- (flags & ~O_ACCMODE)
- | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
- break;
-
- case __GT_DIR:
- fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
- break;
-
- case __GT_NOCREATE:
- /* This case is backward from the other three. __gen_tempname
- succeeds if __xstat fails because the name does not exist.
- Note the continue to bypass the common logic at the bottom
- of the loop. */
- if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
- {
- if (errno == ENOENT)
- {
- __set_errno (save_errno);
- return 0;
- }
- else
- /* Give up now. */
- return -1;
- }
- continue;
-
- default:
- assert (! "invalid KIND in __gen_tempname");
- abort ();
- }
-
+ fd = tryfunc (tmpl, args);
if (fd >= 0)
{
__set_errno (save_errno);
@@ -304,3 +258,67 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
__set_errno (EEXIST);
return -1;
}
+
+static int
+try_file (char *tmpl, void *flags)
+{
+ int *openflags = flags;
+ return __open (tmpl,
+ (*openflags & ~O_ACCMODE)
+ | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+}
+
+static int
+try_dir (char *tmpl, void *flags)
+{
+ return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
+}
+
+static int
+try_nocreate (char *tmpl, void *flags)
+{
+ struct_stat64 st;
+
+ if (__lxstat64 (_STAT_VER, tmpl, &st) == 0)
+ __set_errno (EEXIST);
+ return errno == ENOENT ? 0 : -1;
+}
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
+ The name constructed does not exist at the time of the call to
+ __gen_tempname. TMPL is overwritten with the result.
+
+ KIND may be one of:
+ __GT_NOCREATE: simply verify that the name does not exist
+ at the time of the call.
+ __GT_FILE: create the file using open(O_CREAT|O_EXCL)
+ and return a read-write fd. The file is mode 0600.
+ __GT_DIR: create a directory, which will be mode 0700.
+
+ We use a clever algorithm to get hard-to-predict names. */
+int
+__gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
+{
+ int (*tryfunc) (char *, void *);
+
+ switch (kind)
+ {
+ case __GT_FILE:
+ tryfunc = try_file;
+ break;
+
+ case __GT_DIR:
+ tryfunc = try_dir;
+ break;
+
+ case __GT_NOCREATE:
+ tryfunc = try_nocreate;
+ break;
+
+ default:
+ assert (! "invalid KIND in __gen_tempname");
+ abort ();
+ }
+ return __try_tempname (tmpl, suffixlen, &flags, tryfunc);
+}
diff --git a/lib/tempname.h b/lib/tempname.h
index b560ee5cb14..e6093607463 100644
--- a/lib/tempname.h
+++ b/lib/tempname.h
@@ -32,6 +32,10 @@
# define GT_NOCREATE 2
# endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Generate a temporary file name based on TMPL. TMPL must match the
rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix).
The name constructed does not exist at the time of the call to
@@ -47,4 +51,15 @@
We use a clever algorithm to get hard-to-predict names. */
extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind);
+/* Similar to gen_tempname, but TRYFUNC is called for each temporary
+ name to try. If TRYFUNC returns a non-negative number, TRY_GEN_TEMPNAME
+ returns with this value. Otherwise, if errno is set to EEXIST, another
+ name is tried, or else TRY_GEN_TEMPNAME returns -1. */
+extern int try_tempname (char *tmpl, int suffixlen, void *args,
+ int (*tryfunc) (char *, void *));
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GL_TEMPNAME_H */