Hello James and Alex, On 8/8/21 10:41 AM, Alejandro Colomar wrote: > From: "James O. D. Hunt" <jamesodhunt@xxxxxxxxx> > > Explain that `optstring` cannot contain a semi-colon (`;`) character. > > Also explain that `optstring` can include `+` as an option character, > possibly in addition to that character being used as the first character > in `optstring` to denote `POSIXLY_CORRECT` behaviour. > > Signed-off-by: James O. D. Hunt <jamesodhunt@xxxxxxxxx> > Signed-off-by: Alejandro Colomar <alx.manpages@xxxxxxxxx> > --- > man3/getopt.3 | 10 +++++++++- > 1 file changed, 9 insertions(+), 1 deletion(-) > > diff --git a/man3/getopt.3 b/man3/getopt.3 > index ce4c28088..315224c64 100644 > --- a/man3/getopt.3 > +++ b/man3/getopt.3 > @@ -130,7 +130,7 @@ A legitimate option character is any visible one byte > .BR ascii (7) > character (for which > .BR isgraph (3) > -would return nonzero) that is not \(aq\-\(aq or \(aq:\(aq. > +would return nonzero) that is not \(aq\-\(aq, \(aq:\(aq or \(aq;\(aq. > If such a > character is followed by a colon, the option requires an argument, so > .BR getopt () > @@ -166,6 +166,14 @@ If the first character of > .B POSIXLY_CORRECT > is set, then option processing stops as soon as a nonoption argument is > encountered. > +If \(aq+\(aq is not the first character of > +.IR optstring , > +it is treated as a normal option. > +If > +.B POSIXLY_CORRECT > +behaviour is required in this case > +.I optstring > +will contain two \(aq+\(aq symbols. > If the first character of \fIoptstring\fP is \(aq\-\(aq, then > each nonoption \fIargv\fP-element is handled as if it were the argument of > an option with character code 1. (This is used by programs that were Thanks. The patch is good and I applied it @James: it would be helpful to explain in the commit message how you verified these details. @Alex: do not be shy of asking people to improve there commit messages in this way :-). See my modified commit message below. Cheers, Michael getopt.3: Further clarification of optstring Explain that `optstring` cannot contain a semi-colon (`;`) character. [mtk: verfiried with a small test program; see also posix/getopt.c in the glibc sources: if (temp == NULL || c == ':' || c == ';') { if (print_errors) fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); d->optopt = c; return '?'; } ] Also explain that `optstring` can include `+` as an option character, possibly in addition to that character being used as the first character in `optstring` to denote `POSIXLY_CORRECT` behaviour. [mtk: verified with a small test program.] Test program below. Example runs: $ ./a.out -+ opt = 43 (+); optind = 2 Got plus $ ./a.out -';' ./a.out: invalid option -- ';' opt = 63 (?); optind = 2; optopt = 59 (;) Unrecognized option (-;) Usage: ./a.out [-p arg] [-x] Signed-off-by: James O. D. Hunt <jamesodhunt@xxxxxxxxx> Signed-off-by: Alejandro Colomar <alx.manpages@xxxxxxxxx> Signed-off-by: Michael Kerrisk <mtk.manpages@xxxxxxxxx> 8x---8x---8x---8x---8x---8x---8x---8x---8x---8x---8x--- #include <ctype.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define printable(ch) (isprint((unsigned char) ch) ? ch : '#') static void /* Print "usage" message and exit */ usageError(char *progName, char *msg, int opt) { if (msg != NULL && opt != 0) fprintf(stderr, "%s (-%c)\n", msg, printable(opt)); fprintf(stderr, "Usage: %s [-p arg] [-x]\n", progName); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int opt, xfnd; char *pstr; xfnd = 0; pstr = NULL; while ((opt = getopt(argc, argv, "p:x+;")) != -1) { printf("opt =%3d (%c); optind = %d", opt, printable(opt), optind); if (opt == '?' || opt == ':') printf("; optopt =%3d (%c)", optopt, printable(optopt)); printf("\n"); switch (opt) { case 'p': pstr = optarg; break; case 'x': xfnd++; break; case ';': printf("Got semicolon\n"); break; case '+': printf("Got plus\n"); break; case ':': usageError(argv[0], "Missing argument", optopt); case '?': usageError(argv[0], "Unrecognized option", optopt); default: printf("Unexpected case in switch()\n"); exit(EXIT_FAILURE); } } if (xfnd != 0) printf("-x was specified (count=%d)\n", xfnd); if (pstr != NULL) printf("-p was specified with the value \"%s\"\n", pstr); if (optind < argc) printf("First nonoption argument is \"%s\" at argv[%d]\n", argv[optind], optind); exit(EXIT_SUCCESS); } -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/