https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291374
Bug ID: 291374
Summary: getopt(3) GNU extension wrong behavior
Product: Base System
Version: 14.3-STABLE
Hardware: Any
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: bin
Assignee: [email protected]
Reporter: [email protected]
Flags: mfc-stable15?, mfc-stable14?, mfc-stable13?
>From the getopt(3) manual page:
The option string optstring may contain the following elements:
individual characters, and characters followed by a colon to indicate an
option argument is to follow. If an individual character is followed by
two colons, then the option argument is optional; optarg is set to the
rest of the current argv word, or NULL if there were no more characters
in the current word. This is a GNU extension. For example, an option
string "x" recognizes an option "-x", and an option string "x:"
recognizes an option and argument "-x argument". It does not matter to
getopt() if a following argument has leading white space.
Note the last clause about leading white space. It does not match the code.
For example, our date(1) utility uses getopt(argc, argv, "f:I::jnRr:uv:z:") and
look at this:
$ date -Idate
2025-12-04
$ date -I date
date: illegal time format
usage: date [-jnRu] [-I[date|hours|minutes|seconds]] [-f input_fmt]
[-r filename|seconds] [-v[+|-]val[y|m|w|d|H|M|S]]
[[[[[[cc]yy]mm]dd]HH]MM[.SS] | new_date] [+output_fmt]
But this is not all. Consider the following simple test programm:
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int ch;
while ((ch = getopt(argc, argv, "cCd::F:lnoOp:s:u:U:wW")) != -1) {
printf("ch is %c optarg is %s\n",
(char)ch, optarg ? optarg : " NULL");
}
return (0);
}
Option list taken from our tftpd(8) programm that uses "-s path" for a chroot
and optional "-d value" for debugging.
Build it: cc -o getoptest -ansi -pedantic -Wall getoptest.c
Run it:
$ ./getoptest -l -w -d14 -s /usr/local/admin/tftproot -u admin -U 0
ch is l optarg is NULL
ch is w optarg is NULL
ch is d optarg is 14
ch is s optarg is /usr/local/admin/tftproot
ch is u optarg is admin
ch is U optarg is 0
So far, so good. And now:
$ ./getoptest -l -w -d 14 -s /usr/local/admin/tftproot -u admin -U 0
ch is l optarg is NULL
ch is w optarg is NULL
ch is d optarg is NULL
Option list silently truncated. No -s, no chrooting for tftpd.
--
You are receiving this mail because:
You are the assignee for the bug.