diff options
author | Rich Felker <dalias@aerifal.cx> | 2014-12-19 23:59:54 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-12-19 23:59:54 -0500 |
commit | 1d8d86aeb54c0c5439eb07a4bc1b03983fb9d6e8 (patch) | |
tree | cad0aab0c0fca2c341795c5de18e60b9a722a25d /src/misc | |
parent | 7d3512126db7044525cf402255e0a85ac68dc2e9 (diff) | |
download | musl-1d8d86aeb54c0c5439eb07a4bc1b03983fb9d6e8.tar.gz musl-1d8d86aeb54c0c5439eb07a4bc1b03983fb9d6e8.tar.bz2 musl-1d8d86aeb54c0c5439eb07a4bc1b03983fb9d6e8.tar.xz musl-1d8d86aeb54c0c5439eb07a4bc1b03983fb9d6e8.zip |
fix stderr locking and ferror semantics in getopt message printing
if writing the error message fails, POSIX requires that ferror(stderr)
be set. and as a function that operates on a stdio stream, getopt is
required to lock the stream it uses, stderr.
fwrite calls are used instead of fprintf since there is a demand from
some users not to pull in heavy stdio machinery via getopt. this
mimics the original code using write.
Diffstat (limited to 'src/misc')
-rw-r--r-- | src/misc/getopt.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/src/misc/getopt.c b/src/misc/getopt.c index e77e460a..104b5f70 100644 --- a/src/misc/getopt.c +++ b/src/misc/getopt.c @@ -11,6 +11,17 @@ int optind=1, opterr=1, optopt, __optpos, __optreset=0; #define optpos __optpos weak_alias(__optreset, optreset); +void __getopt_msg(const char *a, const char *b, const char *c, int l) +{ + FILE *f = stderr; + flockfile(f); + fwrite(a, strlen(a), 1, f) + && fwrite(b, strlen(b), 1, f) + && fwrite(c, l, 1, f) + && putc('\n', f); + funlockfile(f); +} + int getopt(int argc, char * const argv[], const char *optstring) { int i; @@ -66,24 +77,17 @@ int getopt(int argc, char * const argv[], const char *optstring) } while (l && d != c); if (d != c) { - if (optstring[0] != ':' && opterr) { - write(2, argv[0], strlen(argv[0])); - write(2, ": illegal option: ", 18); - write(2, optchar, k); - write(2, "\n", 1); - } + if (optstring[0] != ':' && opterr) + __getopt_msg(argv[0], ": illegal option: ", optchar, k); return '?'; } if (optstring[i] == ':') { if (optstring[i+1] == ':') optarg = 0; else if (optind >= argc) { if (optstring[0] == ':') return ':'; - if (opterr) { - write(2, argv[0], strlen(argv[0])); - write(2, ": option requires an argument: ", 31); - write(2, optchar, k); - write(2, "\n", 1); - } + if (opterr) __getopt_msg(argv[0], + ": option requires an argument: ", + optchar, k); return '?'; } if (optstring[i+1] != ':' || optpos) { |