--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: getopt: optarg is NULL outside of loop
- From: John Scott <jscott@posteo.net>
- Date: Sat, 05 Sep 2020 21:24:33 -0400
- Message-id: <159935547355.118419.17417828024358220511.reportbug@T450>
Package: libc6
Version: 2.31-3
Severity: normal
X-Debbugs-Cc:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
I suspect this is an upstream problem but I'm reporting it here
first per their policy [1] since I'm unsure.
Both POSIX (including the Issue 8 draft) and the GNU C Library
manual say that when an argument is provided for an option, a
pointer to it is provided as optarg.
It seems like after leaving the while() loop getopt is usually
used in, optarg points to NULL instead, even if no other options,
bearing arguments or not, are used. It's a little grey but POSIX
doesn't seem to permit this, and the (non-DFSG) glibc manual could
be construed as saying it should work fine this way:
> If the option has an argument, getopt returns the argument by storing
> it in the variable optarg. You don’t ordinarily need to copy the optarg
> string, since it is a pointer into the original argv array, not into a
> static area that might be overwritten.
Everything works fine with Musl libc which can be tried with musl-gcc.
Consider this example program:
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int opt;
while((opt = getopt(argc, argv, "a:")) != -1) {}
assert(optarg != NULL);
}
If this is invoked as './a.out -afoo', the inner assertion will
the last assertion will fail with glibc. In the absence of
a compelling reason (such as if I were using the GNU extension of
having an optional argument via '::'), standards aside, it would
be helpful for me if the variable could be left alone.
[1] https://sourceware.org/glibc/wiki/FilingBugs
[2] https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html
- -- System Information:
Debian Release: bullseye/sid
APT prefers testing
APT policy: (500, 'testing'), (2, 'unstable'), (1, 'testing-debug'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 5.7.0-3-amd64 (SMP w/2 CPU threads)
Kernel taint flags: TAINT_USER, TAINT_FIRMWARE_WORKAROUND
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages libc6 depends on:
ii libcrypt1 1:4.4.17-1
ii libgcc-s1 10.2.0-5
Versions of packages libc6 recommends:
ii libidn2-0 2.3.0-1
Versions of packages libc6 suggests:
ii debconf [debconf-2.0] 1.5.74
ii glibc-doc 2.31-3
ii libc-l10n 2.31-3
ii locales 2.31-3
- -- debconf information:
glibc/restart-failed:
glibc/upgrade: true
glibc/kernel-too-old:
glibc/kernel-not-supported:
* libraries/restart-without-asking: true
glibc/disable-screensaver:
glibc/restart-services:
-----BEGIN PGP SIGNATURE-----
iHUEARYIAB0WIQT287WtmxUhmhucNnhyvHFIwKstpwUCX1Q6TgAKCRByvHFIwKst
p+D0AQDqLFwxGh/oTV+13E5stB3WvG9zD0tpMiol/xHW0QuERgEAsPKsGbQBW2nG
VFzkfExA5cGyGj0GW7IyKg42+wLaZgI=
=WQf5
-----END PGP SIGNATURE-----
--- End Message ---
--- Begin Message ---
- To: John Scott <jscott@posteo.net>
- Cc: 969618-done@bugs.debian.org
- Subject: Re: Bug#969618: getopt: optarg is NULL outside of loop
- From: Aurelien Jarno <aurelien@aurel32.net>
- Date: Sun, 11 Oct 2020 13:11:57 +0200
- Message-id: <20201011111157.GA1454307@aurel32.net>
- In-reply-to: <20200906194721.GB2269915@aurel32.net>
- References: <159935547355.118419.17417828024358220511.reportbug@T450> <159935547355.118419.17417828024358220511.reportbug@T450> <877dt7e593.fsf@mid.deneb.enyo.de> <159935547355.118419.17417828024358220511.reportbug@T450> <20200906194721.GB2269915@aurel32.net>
On 2020-09-06 21:47, Aurelien Jarno wrote:
> Hi,
>
> On 2020-09-06 09:25, Florian Weimer wrote:
> > * John Scott:
> >
> > > #define _POSIX_C_SOURCE 200809L
> > > #include <assert.h>
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > > #include <unistd.h>
> > > int main(int argc, char *argv[]) {
> > > int opt;
> > > while((opt = getopt(argc, argv, "a:")) != -1) {}
> > > assert(optarg != NULL);
> > > }
> > >
> > > If this is invoked as './a.out -afoo', the inner assertion will
> > > the last assertion will fail with glibc.
> >
> > POSIX leaves it unspecified if optarg is changed if getopt returns -1.
> > Only optind must be left unchanged. I do not think this is a glibc
> > bug (or a musl bug).
>
> Thanks Florian for the explanations. This can be confirmed that optarg
> is not NULL by moving the assert in the while loop. So it doesn't seems
> like a bug to me.
I am therefore closing it.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
--- End Message ---