There were two copies of the bulk of the code to handle long options.
Now there is only one. (Yes, this is in aid of merging from gnulib.)
The change to bug-getopt4.c clarifies the error messages when the test
fails.
* posix/getopt.c (process_long_option): New function split out
from _getopt_internal_r.
(_getopt_internal_r): Replace both copies of the long-option
processing code with calls to process_long_option.
* posix/bug-getopt4.c (one_test): Print argv[0] in error messages.
(do_test): Differentiate argv[0] in the two subtests.
_getopt_data.__posixly_correct is completely redundant to
_getopt_data.__ordering, and some work that logically belongs in
_getopt_initialize was being done by _getopt_internal_r, making the
code harder to understand.
As a side effect, getenv will no longer be called if the first
character of the options string is '+' or '-', which is probably a
Good Thing. (Perhaps we should have a flag character that
specifically asks for the permutation behavior?)
* posix/getopt_int.h (_getopt_data): Remove __posixly_correct field.
* posix/getopt.c (_getopt_internal_r): Move some initialization code...
(_getopt_initialize): ...here. Don't set d->__posixly_correct.
For standards compliance, getopt, getopt_long, and getopt_long_only in
glibc have to take 'char *const *argv' even though they can mutate the
array. gnulib has tried to clean this up as much as possible: all the
internal functions use 'char **argv', and when used standalone, so do
getopt_long and getopt_long_only.
Also brought over are __nonnull annotations, corrections to documentation,
and apparently it is no longer necessary to worry about conflicting
prototypes for getopt. The macroification of the definitions of
getopt and __posix_getopt goes beyond what is currently in gnulib.
At this point getopt1.c and getopt_int.h are identical to their gnulib
versions.
* posix/getopt.h: Add backup definition of __nonnull for
consistency with gnulib. Define __getopt_argv_const to const
if not already defined.
(getopt): Update doc comment from gnulib. Prototype
unconditionally. Add __nonnull annotation.
(__posix_getopt): Add __nonnull annotation.
(getopt_long, getopt_long_only): Use __getopt_argv_const in
prototypes for consistency with gnulib. Add __nonnull
annotations.
* posix/getopt.c (_getopt_initialize, _getopt_internal_r)
(getopt_internal): Change 'argv' argument to type 'char **'.
Remove now-unnecessary casts.
(getopt, __posix_getopt): Eliminate repetition with a macro.
Cast 'argv' to 'char **' when calling _getopt_internal.
* posix/getopt1.c (getopt_long, getopt_long_only):
Use __getopt_argv_const for consistency with gnulib.
Cast 'argv' to 'char **' when calling _getopt_internal.
(_getopt_long_r, _getopt_long_only_r):
Change 'argv' argument to type 'char **'.
(main): Constify 'long_options'.
* posix/getopt_int.h (getopt_internal, _getopt_internal_r)
(_getopt_long_r, _getopt_long_only_r):
Change 'argv' argument to type 'char **'.
getopt can print a whole bunch of error messages, and when used
standalone (from gnulib) it uses fprintf to do that. But fprintf is a
cancellation point and getopt isn't, and also applying fprintf to a
stream in wide-character mode is not allowed.
glibc has an internal function called __fxprintf that writes a narrow
format string to a stream regardless of mode, but it only handles
ASCII format strings, and it's still a cancellation point. getopt's
messages are translated, so they might not be ASCII. So getopt has an
error message to an asprintf buffer, monkeys with internal flag bits
on stderr to disable cancellation, and then calls
__fxprintf(stderr, "%s", buffer). There isn't even a helper function,
the code is duplicated every time.
This patch fixes __fxprintf to handle arbitrary multibyte format
strings, and adds a variant __fxprintf_nocancel that does the same
thing but also isn't a cancellation point. (It still _works_ by
monkeying with internal flag bits on the FILE, but that's not really a
layering violation for code in stdio-common.) All of the #ifdef _LIBC
blocks can then be reduced to their standalone versions with a little
help from some macros at the top of the file.
I also wrote a test case to verify that getopt really isn't a
cancellation point, and I'm glad I did, because it found two bugs, one
of which wasn't even to do with cancellation (see previous patch).
* stdio-common/fxprintf.c (__fxprintf_nocancel): New function.
(locked_vfxprintf): New helper function. Handle arbitrary
multibyte strings, not just ASCII.
* include/stdio.h: Declare __fxprintf_nocancel.
* posix/getopt.c: When _LIBC is defined, define fprintf to
__fxprintf_nocancel, flockfile to _IO_flockfile, and
funlockfile to _IO_funlockfile. When neither _LIBC nor
_POSIX_THREAD_SAFE_FUNCTIONS is defined, define flockfile and
funlockfile as no-ops. (_getopt_internal_r): Remove all
internal #ifdef _LIBC blocks; the standalone error-printing
code can now be used for libc as well. Add an
flockfile/funlockfile pair around one case where the error
message is printed in several chunks. Don't use fputc.
* posix/tst-getopt-cancel.c: New test.
* posix/Makefile: Run it.
getopt_long contains an undocumented (AFAICT) feature in which, if you
put "W;" in the short-options list, then '-W foo' and '-Wfoo' are
treated as equivalent to '--foo'. This is implemented with a partial
second copy of the code for handling long options, and that code
increments optind one too many times when recovering from an ambiguous
abbreviated option, which can cause the main loop to walk past the end
of argv and crash.
I discovered this while writing a test case that tries to exercise all
of getopt's error reporting paths; I wouldn't be surprised to learn
that this feature is never used by real applications.
* posix/getopt.c (_getopt_internal_r): Don't increment
d->optind a second time when reporting ambiguous -W options.
This covers changes with little or no consequences when the code is
used in glibc.
* posix/getopt_int.h: Include getopt.h.
Use impl-namespace names for all arguments to _getopt_internal and
_getopt_internal_r.
Declare __ordering enum outside the struct.
Harmonize comments with gnulib.
* posix/getopt1.c: Simplify #ifdeffage at top of file. Remove
ELIDE_CODE logic entirely. Move inclusion of stdlib.h to
#ifdef TEST block and make unconditional. Do not define NULL.
* posix/getopt.c: Partial merge from gnulib, covering the
initial includes and global declarations, commentary, and
a couple of semantically-neutral code changes.
I'm not sure whether this is official GNU style now, but `...' quotes
haven't looked properly balanced in most people's terminal fonts since
2001ish? and gnulib has chosen to switch over to '...' quotes.
I'm merging this separately from the other changes in gnulib because
it's very mechanical.
* posix/getopt.c, posix/getopt.h, posix/getopt1.c, posix/getopt_int.h:
Use '...' instead of `...' for quotation marks inside
comments and strings.
glibc's implementation of getopt includes code to parse an environment
variable named _XXX_GNU_nonoption_argv_flags_ (where XXX is the
current process's PID in decimal); but all of it has been #ifdefed out
since 2001, with no official way to turn it back on.
According to commentary in our config.h.in, bash version 2.0 set this
environment variable to indicate argv elements that were the result of
glob expansion and therefore should not be treated as options, but the
feature was "disabled later" because "it caused problems". According
to bash's CHANGES file, "later" was release 2.01; it gives no more
detail about what the problems were.
Version 2.0 of bash was released on the last day of 1996, and version
2.01 in June of 1997. Twenty years later, I think it is safe to
assume that this environment variable isn't coming back.
* config.h.in (USE_NONOPTION_FLAGS): Remove.
* csu/init-first.c: Remove all #ifdef USE_NONOPTION_FLAGS blocks.
* sysdeps/mach/hurd/i386/init-first.c: Likewise.
* posix/getopt_int.h: Likewise.
* posix/getopt.c: Likewise. Also remove SWAP_FLAGS and the
__libc_argc and __libc_argv externs, which were only used by
#ifdef USE_NONOPTION_FLAGS blocks.
* posix/getopt_init.c: Remove file.
* posix/Makefile (routines): Remove getopt_init.
* include/getopt.h: Don't declare __getopt_initialize_environment.
* manual/getopt.texi: Remove mention of USE_NONOPTION_FLAGS in
a comment.
open_memstream is new in the 2008 edition of POSIX. However, the
older functions getopt, closelog and fmtmsg all bring in references to
it. This patch fixes this in the usual way, making open_memstream
into a weak alias of __open_memstream and calling __open_memstream
from the relevant places.
Tested for x86_64 and x86 (testsuite, and that disassembly of
installed shared libraries is unchanged by the patch). 32-bit builds
produce an XPASS for conform/POSIX/unistd.h/linknamespace after this
patch (because the only cause of failure left there now is 64-bit
specific); that will disappear once the 64-bit failure is resolved and
the XFAIL removed at that time.
[BZ #18498]
* libio/memstream.c (open_memstream): Rename to __open_memstream
and define as weak alias of __open_memstream.
* include/stdio.h (__open_memstream): Declare. Use
libc_hidden_proto.
(open_memstream): Don't use libc_hidden_proto.
* misc/syslog.c (__vsyslog_chk): Call __open_memstream instead of
open_memstream.
* posix/getopt.c (_getopt_internal_r): Likewise.
* conform/Makefile (test-xfail-XPG3/stdio.h/linknamespace): Remove
variable.
(test-xfail-XPG4/stdio.h/linknamespace): Likewise.
(test-xfail-UNIX98/stdio.h/linknamespace): Likewise.
(test-xfail-XOPEN2K/unistd.h/linknamespace): Likewise.
According to the getopt documentation, if "W;" is part of optstring, then '-W
foo' should behave like '--foo'. But if "foo" uses an optional_argument, this
is not the case, since optarg is not NULL when using -W.
by default a POSIX mode, also define __USE_POSIX_IMPLICITLY.
* posix/Versions: Export __posix_getopt.
* posix/getopt.c (_getopt_initialize): Take additional parameter.
Use it to alternatively initialize __posixly_correct.
(_getopt_internal_r): Take addition parameter. Pass on to
_getopt_initialize.
(_getopt_internal): Take addition parameter. Pass on to
_getopt_internal_r.
(getopt): Pass additional zero to _getopt_internal.
(__posix_getopt): New function.
* posix/getopt.h: Add redirection for getopt.
* posix/getopt1.c (getopt_long): Pass additional zero to
_getopt_internal.
(getopt_long_only): Likewise.
(_getopt_long_r): Pass additional zero to _getopt_internal_r.
(_getopt_long_only_r): Likewise.
* posix/getopt_int.h: Adjust declarations of _getopt_internal and
_getopt_internal_r.
2004-03-08 Paul Eggert <eggert@cs.ucla.edu>
Merge from gnulib. We now assume C89 or better.
* posix/getopt1.c (const): Remove.
* posix/getopt.c (const): Likewise.
* posix/getopt1.c (getopt_long, _getopt_long_r, getopt_long_only,
_getopt_long_only_r, main): Use prototypes, not old-style definitions.
* posix/getopt.c (exchange, _getopt_initialize, _getopt_internal_r,
_getopt_internal, getopt, main): Likewise.
* posix/getopt.h (getopt, getopt_long, getopt_long_only): Likewise.
* posix/getopt.c [!defined VMS || !HAVE_STRING_H]:
Include <string.h> regardless. No need for <strings.h>.
[!defined _LIBC]: Include "gettext.h" rather than rolling it ourselves.
(_): Define to gettext always.
(my_index): Remove: all uses changed to strchr.
(strlen): Remove declaration.
* posix/getopt.h (struct option.name): Always const char *.
2004-03-08 Marcus Brinkmann <marcus@gnu.org>
* posix/getopt.h (_getopt_internal): Move to ...
* posix/getopt_int.h: ... here. New file.
* include/getopt_int.h: New file.
* include/getopt.h: Remove libc_hidden_proto for getopt_long
and getopt_long_only.
* posix/getopt1.c: Include "getopt_int.h". Remove
libc_hidden_def for getopt_long and getopt_long_only.
(_getopt_long_r, _getopt_long_only_r): New functions.
* posix/getopt.c: Include "getopt_int.h".
(__getopt_initialized): Variable removed.
(nextchar, ordering, posixly_correct, first_nonopt, last_nonopt):
Static variables removed.
(nonoption_flags_max_len, nonoption_flags_len) [_LIBC &&
USE_NONOPTION_FLAGS]: Static variables removed.
(getopt_data): New static variable.
(SWAP_FLAGS): Use d->__nonoption_flags_len instead
nonoption_flags_len.
(exchange): Add new argument D of type struct getopt_data *.
Replace optind with d->optind, optarg with d->optarg, opterr with
d->opterr, optopt with d->optopt, nextchar with d->__nextchar,
first_nonopt with d->__first_nonopt, last_nonopt with
d->__last_nonopt, d->ordering with d->__ordering,
d->posixly_correct with d->__posixly_correct (which is now an
int instead a string, so fix users), nonoption_flags_len
with d->__nonoption_flags_len, nonoption_flags_max_len with
d->__nonoption_flags_max_len.
(_getopt_initialize): Likewise.
(_getopt_internal): Rename to ...
(_getopt_internal_r): ... this. Also add new argument D of type
struct getopt_data * and use of members of D rather than global or
static variables as described for exchange() above. Add new argument
to invocations of _getopt_initialize and exchange.
(_getopt_internal): Reimplement in terms of _getopt_internal_r.
* argp/argp-parse.c: Include <getopt_int.h>.
[_LIBC]: Do not include <bits/libc-lock.h>.
[!_LIBC && HAVE_CTHREADS_H]: Do not include <cthreads.h>.
[!_LIBC] (_argp_hang): Make static.
(getopt_lock, LOCK_GETOPT, UNLOCK_GETOPT): Remove.
(_argp_unlock_xxx): Remove.
(parser_init): Do not use LOCK_GETOPT.
(parser_finalize): Do not use UNLOCK_GETOPT.
(struct parser): New member OPT_DATA.
(parser_init): Initialize parser->opt_data. Use
parser->opt_data.opterr instead of opterr.
(parser_parse_opt): Use parser->opt_data.optarg instead optarg.
(parser_parse_next): Likewise. Use parser->opt_data.optind
instead optind. Use parser->opt_data.optopt instead of optopt.
Call _getopt_long_only_r and _getopt_long_r instead of
getopt_long_only and getopt_long, and pass the extra argument.
2001-12-06 Ulrich Drepper <drepper@redhat.com>
* libio/vasprintf.c (_IO_vasprintf): Free buffer on failure.
* assert/assert.c: Check result of __asprintf call and don't use
string if it failed.
* assert/assert-perr.c: Likewise.
* inet/rcmd.c: Likewise.
* locale/programs/localedef.c (main): Check result of
construct_output_path and exit if it failed.
(construct_output_path): Check result of asprintf and mkdir calls and
fail if they failed.
* posix/getopt.c: Check result of __asprintf calls and fail if
they failed.
Patch by Dmitry V. Levin <ldv@alt-linux.org>.
2001-10-26 Ulrich Drepper <drepper@redhat.com>
* string/strxfrm.c [USE_IN_EXTENDED_LOCALE_MODEL]: Correctly get
nrules value.
2001-10-24 H.J. Lu <hjl@gnu.org>
* sysdeps/generic/bits/dlfcn.h (DL_CALL_FCT): Cast to void *.
Use __BEGIN_DECLS/__END_DECLS around prototypes.
* sysdeps/mips/bits/dlfcn.h (DL_CALL_FCT): Likewise.
2001-10-21 Jim Meyering <meyering@lucent.com>
* malloc/obstack.c (_): Honor the setting of ENABLE_NLS. Otherwise,
this code would end up calling gettext even in packages built
with --disable-nls.
* posix/getopt.c (_): Likewise.
* posix/regex.c (_): Likewise.
2001-10-26 Ulrich Drepper <drepper@redhat.com>
* resolv/gethnamaddr.c (gethostbyaddr): Use ip6.addr for reverse
lookup not ip6.int.
* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyaddr_r): Likewise.
Reported by Martin.v.Loewis@t-online.de [PR libc/2598].
2001-10-19 Jakub Jelinek <jakub@redhat.com>
* misc/sys/cdefs.h (__attribute_used__): Define.
* elf/rtld.c (_dl_start): Add __attribute_used__.
* elf/dl-runtime.c (fixup, profile_fixup): Likewise.
2001-08-11 Ulrich Drepper <drepper@redhat.com>
* config.h.in: Add #undef line for USE_NONOPTION_FLAGS.
* posix/getopt_init.c: Produce code only if USE_NONOPTION_FLAGS is
defined.
* posix/getopt.c: Use __getopt_nonoption_flags only if
USE_NONOPTION_FLAGS is defined.
* sysdeps/mach/hurd/i386/init-first.c: Use __getopt_clean_environment
only if USE_NONOPTION_FLAGS is defined.
* sysdeps/mach/hurd/mips/init-first.c: Likewise.
* sysdeps/unix/sysv/linux/init-first.c: Likewise.
2001-07-06 Paul Eggert <eggert@twinsun.com>
* manual/argp.texi: Remove ignored LGPL copyright notice; it's
not appropriate for documentation anyway.
* manual/libc-texinfo.sh: "Library General Public License" ->
"Lesser General Public License".
2001-07-06 Andreas Jaeger <aj@suse.de>
* All files under GPL/LGPL version 2: Place under LGPL version
2.1.
2000-09-09 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/dl-osinfo.h (DL_SYSDEP_OSCHECK): Use uname
before trying to read /proc.
Patch by Matt Wilson <msw@redhat.com>.
* include/sys/utsname.h: Declare __uname.
* sysdeps/generic/uname.c: Make uname a weak alias of __uname.
* sysdeps/mach/hurd/uname.c: Likewise.
* sysdeps/unix/syscalls.list: Likewise.
* iconv/gconv_dl.c (do_release_shlib): Rewrite condition for
unloading a bit.
2000-09-08 Ulrich Drepper <drepper@redhat.com>
* posix/getopt.c (_getopt_internal): When long_only is set always
recognize conflicts just like before.
2000-09-08 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* sysdeps/ia64/Makefile (sysdep-rtld-routines): New variable.