diff options
Diffstat (limited to 'posix/getopt.c')
-rw-r--r-- | posix/getopt.c | 362 |
1 files changed, 53 insertions, 309 deletions
diff --git a/posix/getopt.c b/posix/getopt.c index e616aa6e4d..248fe5b03a 100644 --- a/posix/getopt.c +++ b/posix/getopt.c @@ -27,14 +27,30 @@ #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <string.h> +#include <unistd.h> #ifdef _LIBC +/* When used as part of glibc, error printing must be done differently + for standards compliance. getopt is not a cancellation point, so + it must not call functions that are, and it is specified by an + older standard than stdio locking, so it must not refer to + functions in the "user namespace" related to stdio locking. + Finally, it must use glibc's internal message translation so that + the messages are looked up in the proper text domain. */ # include <libintl.h> +# define fprintf __fxprintf_nocancel +# define flockfile(fp) _IO_flockfile (fp) +# define funlockfile(fp) _IO_funlockfile (fp) #else # include "gettext.h" # define _(msgid) gettext (msgid) +/* When used standalone, flockfile and funlockfile might not be + available. */ +# ifndef _POSIX_THREAD_SAFE_FUNCTIONS +# define flockfile(fp) /* nop */ +# define funlockfile(fp) /* nop */ +# endif #endif /* This implementation of 'getopt' has three modes for handling @@ -98,7 +114,6 @@ int optopt = '?'; /* Keep a global copy of all internal members of getopt_data. */ static struct _getopt_data getopt_data; - /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -271,7 +286,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, if (d->optind == 0 || !d->__initialized) { if (d->optind == 0) - d->optind = 1; /* Don't scan ARGV[0], the program name. */ + d->optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct); d->__initialized = 1; @@ -441,42 +456,8 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, first.next = ambig_list; ambig_list = &first; -#if defined _LIBC - char *buf = NULL; - size_t buflen = 0; - - FILE *fp = __open_memstream (&buf, &buflen); - if (fp != NULL) - { - fprintf (fp, - _("%s: option '%s' is ambiguous; possibilities:"), - argv[0], argv[d->optind]); - - do - { - fprintf (fp, " '--%s'", ambig_list->p->name); - ambig_list = ambig_list->next; - } - while (ambig_list != NULL); - - fputc_unlocked ('\n', fp); - - if (__glibc_likely (fclose (fp) != EOF)) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + flockfile (stderr); - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } - } -#else fprintf (stderr, _("%s: option '%s' is ambiguous; possibilities:"), argv[0], argv[d->optind]); @@ -487,8 +468,11 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, } while (ambig_list != NULL); - fputc ('\n', stderr); -#endif + /* This must use 'fprintf' even though it's only printing a + single character, so that it goes through __fxprintf_nocancel + when compiled as part of glibc. */ + fprintf (stderr, "\n"); + funlockfile (stderr); } d->__nextchar += strlen (d->__nextchar); d->optind++; @@ -510,57 +494,17 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC - char *buf; - int n; -#endif - if (argv[d->optind - 1][1] == '-') - { - /* --option */ -#if defined _LIBC - n = __asprintf (&buf, _("\ -%s: option '--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#else - fprintf (stderr, _("\ + /* --option */ + fprintf (stderr, _("\ %s: option '--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } + argv[0], pfound->name); else - { - /* +option or -option */ -#if defined _LIBC - n = __asprintf (&buf, _("\ -%s: option '%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#else - fprintf (stderr, _("\ + /* +option or -option */ + fprintf (stderr, _("\ %s: option '%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#endif - } - -#if defined _LIBC - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif + argv[0], argv[d->optind - 1][0], + pfound->name); } d->__nextchar += strlen (d->__nextchar); @@ -576,33 +520,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else { if (print_errors) - { -#if defined _LIBC - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '--%s' requires an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + fprintf (stderr, + _("%s: option '--%s' requires an argument\n"), + argv[0], pfound->name); - free (buf); - } -#else - fprintf (stderr, - _("%s: option '--%s' requires an argument\n"), - argv[0], pfound->name); -#endif - } d->__nextchar += strlen (d->__nextchar); d->optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; @@ -628,50 +549,14 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, { if (print_errors) { -#if defined _LIBC - char *buf; - int n; -#endif - if (argv[d->optind][1] == '-') - { - /* --option */ -#if defined _LIBC - n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), - argv[0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option '--%s'\n"), - argv[0], d->__nextchar); -#endif - } + /* --option */ + fprintf (stderr, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); else - { - /* +option or -option */ -#if defined _LIBC - n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#endif - } - -#if defined _LIBC - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); } d->__nextchar = (char *) ""; d->optind++; @@ -693,36 +578,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, if (temp == NULL || c == ':' || c == ';') { if (print_errors) - { -#if defined _LIBC - char *buf; - int n; -#endif - -#if defined _LIBC - n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); -#endif - -#if defined _LIBC - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } + fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); d->optopt = c; return '?'; } @@ -751,32 +607,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else if (d->optind == argc) { if (print_errors) - { -#if defined _LIBC - char *buf; - - if (__asprintf (&buf, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c); -#endif - } d->optopt = c; if (optstring[0] == ':') c = ':'; @@ -825,30 +659,9 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, if (ambig && !exact) { if (print_errors) - { -#if defined _LIBC - char *buf; - - if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), - argv[0], d->optarg) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), + argv[0], d->optarg); - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), - argv[0], d->optarg); -#endif - } d->__nextchar += strlen (d->__nextchar); return '?'; } @@ -864,33 +677,9 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else { if (print_errors) - { -#if defined _LIBC - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '-W %s' doesn't allow an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ + fprintf (stderr, _("\ %s: option '-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } + argv[0], pfound->name); d->__nextchar += strlen (d->__nextchar); return '?'; @@ -903,33 +692,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else { if (print_errors) - { -#if defined _LIBC - char *buf; - - if (__asprintf (&buf, _("\ + fprintf (stderr, _("\ %s: option '-W %s' requires an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + argv[0], pfound->name); - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option '-W %s' requires an argument\n"), - argv[0], pfound->name); -#endif - } d->__nextchar += strlen (d->__nextchar); return optstring[0] == ':' ? ':' : '?'; } @@ -978,32 +744,10 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, else if (d->optind == argc) { if (print_errors) - { -#if defined _LIBC - char *buf; + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); - if (__asprintf (&buf, _("\ -%s: option requires an argument -- '%c'\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c); -#endif - } d->optopt = c; if (optstring[0] == ':') c = ':'; |