Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20161216181501.GA25534@brightrain.aerifal.cx>
Date: Fri, 16 Dec 2016 13:15:01 -0500
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: getsubopt behavior

POSIX leaves a lot about getsubopt under-specified:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsubopt.html

It's not clear what happens to any of the pointed-to objects in the
case where no keys match, but it seems generally agreed upon that
*optionp advances to the next option (or end of string) and that the
separator ',' if any is nulled out.

What's explicitly not specified is what happens to *valuep when
getsubopt returns -1 (no key match):

    "APPLICATION USAGE

    The value of *valuep when getsubopt() returns -1 is unspecified.
    Historical implementations provide various incompatible extensions
    to allow an application to access the suboption text that was not
    found in the keylistp array."

Glibc updates *valuep to point to the original value of *optionp (the
whole "unrecognized_key=value" component, with any final ',' nulled
out). This is rather useless, since the caller can just save the old
value of *optionp and use it when getsubopt returns -1, but I found
some code in v4l2-ctl that depends on it:

https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-common.cpp?id=fd7e1db71eabbb81ff20a2ab97948612ef061edf#n693

On the other hand, FreeBSD nulls the pointer at *valuep, any final
',', AND any '=' character in the unrecognized subopt string, so that
the "unrecognized_key=value" component is not even easily recoverable:

https://github.com/freebsd/freebsd/blob/22c7ee83f61dc73c60942c528108e8b6220ed350/lib/libc/stdlib/getsubopt.c

Reportedly Solaris and other sysv-type implementations match the glibc
behavior.

musl currently nulls the pointer at *valuep but doesn't clobber the
'='.

Being that POSIX allows any of them (by leaving it unspecified) and
that the BSD behavior is actively destructive and undesirable (and
perhaps not even conforming in that it clobbers data it doesn't seem
to be specified to clobber), my leaning is to adopt the glibc/sysv
behavior.

Note that the Linux man page documents the glibc behavior without
documenting as an extensions:

    "Otherwise, -1 is returned and *valuep is the entire name[=value]
    string."


Source: http://man7.org/linux/man-pages/man3/getsubopt.3.html

Thoughts?

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.