bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Server-realm configuration stanzas.


From: Simon Josefsson
Subject: Re: Server-realm configuration stanzas.
Date: Thu, 30 Aug 2012 12:15:21 +0200
User-agent: Gnus/5.130006 (Ma Gnus v0.6) Emacs/23.3 (gnu/linux)

Mats Erik Andersson <address@hidden> writes:

> In order to enhance my credibility, let me produce
> a test case for getsubopt() that illuminates the
> failure of the present implementation of shishi_cfg().

Thank you!  I believe you have identified a difference between GNU and
POSIX getsubopt.  Possibly gnulib should work around this problem.  I'm
redirecting this to the gnulib list for further discussion by the
experts.

Gnulib's getsubopt portability issues are documented here:

http://www.gnu.org/software/gnulib/manual/html_node/getsubopt.html

It only says the function is missing on some platforms, not any other
portability concerns.

The POSIX spec is here:

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

Note:

    If the string at *optionp contains only one suboption argument
    (equivalently, no commas), getsubopt() shall update *optionp to
    point to the null character at the end of the string. Otherwise, it
    shall isolate the suboption argument by replacing the comma
    separator with a null character, and shall update *optionp to point
    to the start of the next suboption argument. If the suboption
    argument has an associated value (equivalently, contains an equal
    sign), getsubopt() shall update *valuep to point to the value's
    first character. Otherwise, it shall set *valuep to a null
    pointer. The calling application may use this information to
    determine whether the presence or absence of a value for the
    suboption is an error.

    Additionally, when getsubopt() fails to match the suboption argument
    with a token in the keylistp array, the calling application should
    decide if this is an error, or if the unrecognized option should be
    processed in another way.

Alas the final paragraph doesn't demand any specific behaviour of
getsubopt when there is no match, however the paragraph begins with
"Additionaly" so presumably (*) whatever is done when there is no match
is done on top of what is normally done, which is covered by the
previous paragraph.

(*) This is debatable, but was my initial reading.

The GNU libc documentation is here:

http://www.gnu.org/software/libc/manual/html_node/Suboptions.html#Suboptions

Note:

     In case the suboption has an associated value introduced by a `='
     character, a pointer to the value is returned in VALUEP.  The
     string is `\0' terminated.  If no argument is available VALUEP is
     set to the null pointer.  By doing this the caller can check
     whether a necessary value is given or whether no unexpected value
     is present.

     In case the next suboption in the string is not mentioned in the
     TOKENS array the starting address of the suboption including a
     possible value is returned in VALUEP and the return value of the
     function is `-1'.

I'm not sure the final paragraph is POSIX compliant.  The first
paragraph in the POSIX spec quoted above says VALUEP should be NULL if
there is no argument, and presumably that applies even if there is no
token match.  GNU behaves different when there is no token match.

The glibc implemtation is here:

http://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/getsubopt.c;h=e770c2d8471f348b083b3a92ee87b74395bf0a9b;hb=HEAD#l32

Note:

  /* Parse comma separated suboption from *OPTIONP and match against
     strings in TOKENS.  If found return index and set *VALUEP to
     optional value introduced by an equal sign.  If the suboption is
     not part of TOKENS return in *VALUEP beginning of unknown
     suboption.  On exit *OPTIONP is set to the beginning of the next
     token or at the terminating NUL character.  */
  int
  getsubopt (char **optionp, char *const *tokens, char **valuep)

So I think a portable program that uses getsubopt needs to save a copy
of optionp before passing it to getsubopt, and then if getsubopt returns
-1 it needs to look at that copy instead of value.  If the application
is interested in what the unknown suboption was, that is.

> The test program "test_subopt.c", contained in the present
> message, produces the following output at execution time.
>
>  GNU libc, OpenSolaris:
>
>     INPUT: name=this,that,those
>
>     NAME: value = 'this', tail = 'that,those'
>     default: value = 'that', tail = 'those'
>     default: value = 'those', tail = ''

This seems to be the problem: value should be NULL in the last two
lines.

>  FreeBSD 8.2, FreeBSD 9.0, OpenBSD 5.0, NetBSD 5.1, DragonflyBSD 3.1:
>
>     INPUT: name=this,that,those
>
>     NAME: value = 'this', tail = 'that,those'
>     default: value = '(null)', tail = 'those'
>     default: value = '(null)', tail = ''

This seems consistent with POSIX.

> A common feature in the BSD implementation is to empty VALUE in
>
>   getsubopt(&tail, token, &value);
>
> in case an unrecognised suboption is found. The implementations
> in eglibc and in SunOS libc do not behave that way.

Can you also print out what the return value from getsubopt is in the
'default' value?  Is it -1 or something else?

I'm leaving your test case in this email below for the record.

/Simon

>
> Best regards,
>
>   Mats Erik Andersson
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <errno.h>
>
> char *const token[] = {
>       "name",
>       NULL
> };
>
> int main(void) {
>       char *value, *tail = strdup("name=this,that,those");
>
>       printf("INPUT: %s\n\n", tail);
>       while (tail && *tail) {
>               switch (getsubopt(&tail, token, &value)) {
>                       case 0:
>                               printf("NAME: value = '%s', tail = '%s'\n",
>                                       value, tail);
>                               break;
>                       default:
>                               printf("default: value = '%s', tail = '%s'\n",
>                                       value, tail);
>               }
>       }
>
>       return errno;
> }
>
> _______________________________________________
> Help-shishi mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/help-shishi



reply via email to

[Prev in Thread] Current Thread [Next in Thread]