diff options
| author | Paul Eggert | 2015-02-20 23:31:17 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-02-20 23:32:45 -0800 |
| commit | 066b17df681fabb40108d719086669957aebbc51 (patch) | |
| tree | 27f9362ed6a6e68ef6b61925932f84bb1afb37b8 /lib | |
| parent | 43fb42da8bd6851b5b22d2bbb5d2cd8ceede9c09 (diff) | |
| download | emacs-066b17df681fabb40108d719086669957aebbc51.tar.gz emacs-066b17df681fabb40108d719086669957aebbc51.zip | |
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.c | 35 | ||||
| -rw-r--r-- | lib/getopt.c | 52 | ||||
| -rw-r--r-- | lib/signal.in.h | 8 | ||||
| -rw-r--r-- | lib/tempname.c | 118 | ||||
| -rw-r--r-- | lib/tempname.h | 15 |
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) | |||
| 84 | return dtablesize; | 84 | return dtablesize; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | #elif HAVE_GETDTABLESIZE | 87 | #else |
| 88 | 88 | ||
| 89 | # include <limits.h> | ||
| 89 | # include <sys/resource.h> | 90 | # include <sys/resource.h> |
| 90 | # undef getdtablesize | 91 | |
| 92 | # ifdef __CYGWIN__ | ||
| 93 | /* Cygwin 1.7.25 auto-increases the RLIMIT_NOFILE soft limit until it | ||
| 94 | hits the compile-time constant hard limit of 3200. We might as | ||
| 95 | well just report the hard limit. */ | ||
| 96 | # define rlim_cur rlim_max | ||
| 97 | # endif | ||
| 91 | 98 | ||
| 92 | int | 99 | int |
| 93 | rpl_getdtablesize(void) | 100 | getdtablesize (void) |
| 94 | { | 101 | { |
| 95 | /* To date, this replacement is only compiled for Cygwin 1.7.25, | ||
| 96 | which auto-increased the RLIMIT_NOFILE soft limit until it | ||
| 97 | hits the compile-time constant hard limit of 3200. Although | ||
| 98 | that version of cygwin supported a child process inheriting | ||
| 99 | a smaller soft limit, the smaller limit is not enforced, so | ||
| 100 | we might as well just report the hard limit. */ | ||
| 101 | struct rlimit lim; | 102 | struct rlimit lim; |
| 102 | if (!getrlimit (RLIMIT_NOFILE, &lim) && lim.rlim_max != RLIM_INFINITY) | ||
| 103 | return lim.rlim_max; | ||
| 104 | return getdtablesize (); | ||
| 105 | } | ||
| 106 | 103 | ||
| 107 | #elif defined _SC_OPEN_MAX | 104 | if (getrlimit (RLIMIT_NOFILE, &lim) == 0 |
| 105 | && 0 <= lim.rlim_cur && lim.rlim_cur <= INT_MAX | ||
| 106 | && lim.rlim_cur != RLIM_INFINITY | ||
| 107 | && lim.rlim_cur != RLIM_SAVED_CUR | ||
| 108 | && lim.rlim_cur != RLIM_SAVED_MAX) | ||
| 109 | return lim.rlim_cur; | ||
| 108 | 110 | ||
| 109 | int | 111 | return INT_MAX; |
| 110 | getdtablesize (void) | ||
| 111 | { | ||
| 112 | return sysconf (_SC_OPEN_MAX); | ||
| 113 | } | 112 | } |
| 114 | 113 | ||
| 115 | #endif | 114 | #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, | |||
| 487 | const struct option *p; | 487 | const struct option *p; |
| 488 | struct option_list *next; | 488 | struct option_list *next; |
| 489 | } *ambig_list = NULL; | 489 | } *ambig_list = NULL; |
| 490 | #ifdef _LIBC | ||
| 491 | /* malloc() not used for _LIBC to simplify failure messages. */ | ||
| 492 | # define free_option_list(l) | ||
| 493 | #else | ||
| 494 | # define free_option_list(l) \ | ||
| 495 | while (l != NULL) \ | ||
| 496 | { \ | ||
| 497 | struct option_list *pn = l->next; \ | ||
| 498 | free (l); \ | ||
| 499 | l = pn; \ | ||
| 500 | } | ||
| 501 | #endif | ||
| 490 | int exact = 0; | 502 | int exact = 0; |
| 503 | int ambig = 0; | ||
| 491 | int indfound = -1; | 504 | int indfound = -1; |
| 492 | int option_index; | 505 | int option_index; |
| 493 | 506 | ||
| @@ -514,22 +527,37 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
| 514 | pfound = p; | 527 | pfound = p; |
| 515 | indfound = option_index; | 528 | indfound = option_index; |
| 516 | } | 529 | } |
| 530 | else if (ambig) | ||
| 531 | ; /* Taking simpler path to handling ambiguities. */ | ||
| 517 | else if (long_only | 532 | else if (long_only |
| 518 | || pfound->has_arg != p->has_arg | 533 | || pfound->has_arg != p->has_arg |
| 519 | || pfound->flag != p->flag | 534 | || pfound->flag != p->flag |
| 520 | || pfound->val != p->val) | 535 | || pfound->val != p->val) |
| 521 | { | 536 | { |
| 522 | /* Second or later nonexact match found. */ | 537 | /* Second or later nonexact match found. */ |
| 538 | #ifdef _LIBC | ||
| 539 | struct option_list *newp = alloca (sizeof (*newp)); | ||
| 540 | #else | ||
| 523 | struct option_list *newp = malloc (sizeof (*newp)); | 541 | struct option_list *newp = malloc (sizeof (*newp)); |
| 524 | newp->p = p; | 542 | if (newp == NULL) |
| 525 | newp->next = ambig_list; | 543 | { |
| 526 | ambig_list = newp; | 544 | free_option_list (ambig_list); |
| 545 | ambig_list = NULL; | ||
| 546 | ambig = 1; /* Use simpler fallback message. */ | ||
| 547 | } | ||
| 548 | else | ||
| 549 | #endif | ||
| 550 | { | ||
| 551 | newp->p = p; | ||
| 552 | newp->next = ambig_list; | ||
| 553 | ambig_list = newp; | ||
| 554 | } | ||
| 527 | } | 555 | } |
| 528 | } | 556 | } |
| 529 | 557 | ||
| 530 | if (ambig_list != NULL && !exact) | 558 | if ((ambig || ambig_list) && !exact) |
| 531 | { | 559 | { |
| 532 | if (print_errors) | 560 | if (print_errors && ambig_list) |
| 533 | { | 561 | { |
| 534 | struct option_list first; | 562 | struct option_list first; |
| 535 | first.p = pfound; | 563 | first.p = pfound; |
| @@ -585,18 +613,20 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, | |||
| 585 | fputc ('\n', stderr); | 613 | fputc ('\n', stderr); |
| 586 | #endif | 614 | #endif |
| 587 | } | 615 | } |
| 616 | else if (print_errors && ambig) | ||
| 617 | { | ||
| 618 | fprintf (stderr, | ||
| 619 | _("%s: option '%s' is ambiguous\n"), | ||
| 620 | argv[0], argv[d->optind]); | ||
| 621 | } | ||
| 588 | d->__nextchar += strlen (d->__nextchar); | 622 | d->__nextchar += strlen (d->__nextchar); |
| 589 | d->optind++; | 623 | d->optind++; |
| 590 | d->optopt = 0; | 624 | d->optopt = 0; |
| 625 | free_option_list (ambig_list); | ||
| 591 | return '?'; | 626 | return '?'; |
| 592 | } | 627 | } |
| 593 | 628 | ||
| 594 | while (ambig_list != NULL) | 629 | free_option_list (ambig_list); |
| 595 | { | ||
| 596 | struct option_list *pn = ambig_list->next; | ||
| 597 | free (ambig_list); | ||
| 598 | ambig_list = pn; | ||
| 599 | } | ||
| 600 | 630 | ||
| 601 | if (pfound != NULL) | 631 | if (pfound != NULL) |
| 602 | { | 632 | { |
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 @@ | |||
| 55 | #ifndef _@GUARD_PREFIX@_SIGNAL_H | 55 | #ifndef _@GUARD_PREFIX@_SIGNAL_H |
| 56 | #define _@GUARD_PREFIX@_SIGNAL_H | 56 | #define _@GUARD_PREFIX@_SIGNAL_H |
| 57 | 57 | ||
| 58 | /* Mac OS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6 declare | 58 | /* Mac OS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6, Android |
| 59 | pthread_sigmask in <pthread.h>, not in <signal.h>. | 59 | declare pthread_sigmask in <pthread.h>, not in <signal.h>. |
| 60 | But avoid namespace pollution on glibc systems.*/ | 60 | But avoid namespace pollution on glibc systems.*/ |
| 61 | #if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \ | 61 | #if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \ |
| 62 | && ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ || defined __sun) \ | 62 | && ((defined __APPLE__ && defined __MACH__) \ |
| 63 | || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ \ | ||
| 64 | || defined __sun || defined __ANDROID__) \ | ||
| 63 | && ! defined __GLIBC__ | 65 | && ! defined __GLIBC__ |
| 64 | # include <pthread.h> | 66 | # include <pthread.h> |
| 65 | #endif | 67 | #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 @@ | |||
| 62 | # define struct_stat64 struct stat64 | 62 | # define struct_stat64 struct stat64 |
| 63 | #else | 63 | #else |
| 64 | # define struct_stat64 struct stat | 64 | # define struct_stat64 struct stat |
| 65 | # define __try_tempname try_tempname | ||
| 65 | # define __gen_tempname gen_tempname | 66 | # define __gen_tempname gen_tempname |
| 66 | # define __getpid getpid | 67 | # define __getpid getpid |
| 67 | # define __gettimeofday gettimeofday | 68 | # define __gettimeofday gettimeofday |
| @@ -176,21 +177,9 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, | |||
| 176 | static const char letters[] = | 177 | static const char letters[] = |
| 177 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | 178 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; |
| 178 | 179 | ||
| 179 | /* Generate a temporary file name based on TMPL. TMPL must match the | ||
| 180 | rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). | ||
| 181 | The name constructed does not exist at the time of the call to | ||
| 182 | __gen_tempname. TMPL is overwritten with the result. | ||
| 183 | |||
| 184 | KIND may be one of: | ||
| 185 | __GT_NOCREATE: simply verify that the name does not exist | ||
| 186 | at the time of the call. | ||
| 187 | __GT_FILE: create the file using open(O_CREAT|O_EXCL) | ||
| 188 | and return a read-write fd. The file is mode 0600. | ||
| 189 | __GT_DIR: create a directory, which will be mode 0700. | ||
| 190 | |||
| 191 | We use a clever algorithm to get hard-to-predict names. */ | ||
| 192 | int | 180 | int |
| 193 | __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) | 181 | __try_tempname (char *tmpl, int suffixlen, void *args, |
| 182 | int (*tryfunc) (char *, void *)) | ||
| 194 | { | 183 | { |
| 195 | int len; | 184 | int len; |
| 196 | char *XXXXXX; | 185 | char *XXXXXX; |
| @@ -199,7 +188,6 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) | |||
| 199 | unsigned int count; | 188 | unsigned int count; |
| 200 | int fd = -1; | 189 | int fd = -1; |
| 201 | int save_errno = errno; | 190 | int save_errno = errno; |
| 202 | struct_stat64 st; | ||
| 203 | 191 | ||
| 204 | /* A lower bound on the number of temporary files to attempt to | 192 | /* A lower bound on the number of temporary files to attempt to |
| 205 | generate. The maximum total number of temporary file names that | 193 | generate. The maximum total number of temporary file names that |
| @@ -256,41 +244,7 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) | |||
| 256 | v /= 62; | 244 | v /= 62; |
| 257 | XXXXXX[5] = letters[v % 62]; | 245 | XXXXXX[5] = letters[v % 62]; |
| 258 | 246 | ||
| 259 | switch (kind) | 247 | fd = tryfunc (tmpl, args); |
| 260 | { | ||
| 261 | case __GT_FILE: | ||
| 262 | fd = __open (tmpl, | ||
| 263 | (flags & ~O_ACCMODE) | ||
| 264 | | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); | ||
| 265 | break; | ||
| 266 | |||
| 267 | case __GT_DIR: | ||
| 268 | fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); | ||
| 269 | break; | ||
| 270 | |||
| 271 | case __GT_NOCREATE: | ||
| 272 | /* This case is backward from the other three. __gen_tempname | ||
| 273 | succeeds if __xstat fails because the name does not exist. | ||
| 274 | Note the continue to bypass the common logic at the bottom | ||
| 275 | of the loop. */ | ||
| 276 | if (__lxstat64 (_STAT_VER, tmpl, &st) < 0) | ||
| 277 | { | ||
| 278 | if (errno == ENOENT) | ||
| 279 | { | ||
| 280 | __set_errno (save_errno); | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | else | ||
| 284 | /* Give up now. */ | ||
| 285 | return -1; | ||
| 286 | } | ||
| 287 | continue; | ||
| 288 | |||
| 289 | default: | ||
| 290 | assert (! "invalid KIND in __gen_tempname"); | ||
| 291 | abort (); | ||
| 292 | } | ||
| 293 | |||
| 294 | if (fd >= 0) | 248 | if (fd >= 0) |
| 295 | { | 249 | { |
| 296 | __set_errno (save_errno); | 250 | __set_errno (save_errno); |
| @@ -304,3 +258,67 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) | |||
| 304 | __set_errno (EEXIST); | 258 | __set_errno (EEXIST); |
| 305 | return -1; | 259 | return -1; |
| 306 | } | 260 | } |
| 261 | |||
| 262 | static int | ||
| 263 | try_file (char *tmpl, void *flags) | ||
| 264 | { | ||
| 265 | int *openflags = flags; | ||
| 266 | return __open (tmpl, | ||
| 267 | (*openflags & ~O_ACCMODE) | ||
| 268 | | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); | ||
| 269 | } | ||
| 270 | |||
| 271 | static int | ||
| 272 | try_dir (char *tmpl, void *flags) | ||
| 273 | { | ||
| 274 | return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); | ||
| 275 | } | ||
| 276 | |||
| 277 | static int | ||
| 278 | try_nocreate (char *tmpl, void *flags) | ||
| 279 | { | ||
| 280 | struct_stat64 st; | ||
| 281 | |||
| 282 | if (__lxstat64 (_STAT_VER, tmpl, &st) == 0) | ||
| 283 | __set_errno (EEXIST); | ||
| 284 | return errno == ENOENT ? 0 : -1; | ||
| 285 | } | ||
| 286 | |||
| 287 | /* Generate a temporary file name based on TMPL. TMPL must match the | ||
| 288 | rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). | ||
| 289 | The name constructed does not exist at the time of the call to | ||
| 290 | __gen_tempname. TMPL is overwritten with the result. | ||
| 291 | |||
| 292 | KIND may be one of: | ||
| 293 | __GT_NOCREATE: simply verify that the name does not exist | ||
| 294 | at the time of the call. | ||
| 295 | __GT_FILE: create the file using open(O_CREAT|O_EXCL) | ||
| 296 | and return a read-write fd. The file is mode 0600. | ||
| 297 | __GT_DIR: create a directory, which will be mode 0700. | ||
| 298 | |||
| 299 | We use a clever algorithm to get hard-to-predict names. */ | ||
| 300 | int | ||
| 301 | __gen_tempname (char *tmpl, int suffixlen, int flags, int kind) | ||
| 302 | { | ||
| 303 | int (*tryfunc) (char *, void *); | ||
| 304 | |||
| 305 | switch (kind) | ||
| 306 | { | ||
| 307 | case __GT_FILE: | ||
| 308 | tryfunc = try_file; | ||
| 309 | break; | ||
| 310 | |||
| 311 | case __GT_DIR: | ||
| 312 | tryfunc = try_dir; | ||
| 313 | break; | ||
| 314 | |||
| 315 | case __GT_NOCREATE: | ||
| 316 | tryfunc = try_nocreate; | ||
| 317 | break; | ||
| 318 | |||
| 319 | default: | ||
| 320 | assert (! "invalid KIND in __gen_tempname"); | ||
| 321 | abort (); | ||
| 322 | } | ||
| 323 | return __try_tempname (tmpl, suffixlen, &flags, tryfunc); | ||
| 324 | } | ||
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 @@ | |||
| 32 | # define GT_NOCREATE 2 | 32 | # define GT_NOCREATE 2 |
| 33 | # endif | 33 | # endif |
| 34 | 34 | ||
| 35 | #ifdef __cplusplus | ||
| 36 | extern "C" { | ||
| 37 | #endif | ||
| 38 | |||
| 35 | /* Generate a temporary file name based on TMPL. TMPL must match the | 39 | /* Generate a temporary file name based on TMPL. TMPL must match the |
| 36 | rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). | 40 | rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). |
| 37 | The name constructed does not exist at the time of the call to | 41 | The name constructed does not exist at the time of the call to |
| @@ -47,4 +51,15 @@ | |||
| 47 | We use a clever algorithm to get hard-to-predict names. */ | 51 | We use a clever algorithm to get hard-to-predict names. */ |
| 48 | extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind); | 52 | extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind); |
| 49 | 53 | ||
| 54 | /* Similar to gen_tempname, but TRYFUNC is called for each temporary | ||
| 55 | name to try. If TRYFUNC returns a non-negative number, TRY_GEN_TEMPNAME | ||
| 56 | returns with this value. Otherwise, if errno is set to EEXIST, another | ||
| 57 | name is tried, or else TRY_GEN_TEMPNAME returns -1. */ | ||
| 58 | extern int try_tempname (char *tmpl, int suffixlen, void *args, | ||
| 59 | int (*tryfunc) (char *, void *)); | ||
| 60 | |||
| 61 | #ifdef __cplusplus | ||
| 62 | } | ||
| 63 | #endif | ||
| 64 | |||
| 50 | #endif /* GL_TEMPNAME_H */ | 65 | #endif /* GL_TEMPNAME_H */ |