commit: 703cc6141d6b197d10f53e89292b4713f7f88571
parent b2a3ecac944ef4b306c593a92d12e644b73f7170
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 11 May 2025 14:33:33 +0200
Handle unknown long-option gracefully when getlopt_long is available
Diffstat:
49 files changed, 78 insertions(+), 57 deletions(-)
diff --git a/cmd/base64.c b/cmd/base64.c
@@ -288,7 +288,7 @@ base64_main(int argc, char *argv[])
fprintf(stderr, "%s: error: Missing operand for option '-%c'\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
}
}
@@ -491,7 +491,7 @@ uuencode_main(int argc, char *argv[])
fprintf(stderr, "%s: error: Missing operand for option '-%c'\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
}
}
diff --git a/cmd/basename.c b/cmd/basename.c
@@ -70,7 +70,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/cat.c b/cmd/cat.c
@@ -37,7 +37,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/chmod.c b/cmd/chmod.c
@@ -380,7 +380,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?': // GNU
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/chown.c b/cmd/chown.c
@@ -249,7 +249,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/cmp.c b/cmd/cmp.c
@@ -132,7 +132,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/cut.c b/cmd/cut.c
@@ -429,7 +429,7 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: error: Option '-%c' requires an operand\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unhandled option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
fprintf(stderr, "%s: error: Unhandled getopt case '%c'\n", argv0, c);
diff --git a/cmd/date.c b/cmd/date.c
@@ -267,7 +267,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/df.c b/cmd/df.c
@@ -89,7 +89,7 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
}
}
diff --git a/cmd/env.c b/cmd/env.c
@@ -123,7 +123,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "env: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/head.c b/cmd/head.c
@@ -224,7 +224,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/id.c b/cmd/id.c
@@ -210,7 +210,7 @@ main(int argc, char *argv[])
real_flag = true;
break;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unhandled option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
free(groups);
return 1;
diff --git a/cmd/install.c b/cmd/install.c
@@ -277,7 +277,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "install: error: Unknown option '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/join.c b/cmd/join.c
@@ -201,7 +201,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/ln.c b/cmd/ln.c
@@ -162,7 +162,7 @@ main(int argc, char *argv[])
verbose = true;
break;
case '?':
- if(!got_long_opt) fprintf(stderr, "ln: error: Unknown option '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/mkdir.c b/cmd/mkdir.c
@@ -77,7 +77,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/mkfifo.c b/cmd/mkfifo.c
@@ -47,7 +47,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "mkfifo: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/mknod.c b/cmd/mknod.c
@@ -71,7 +71,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "mknod: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/mktemp.c b/cmd/mktemp.c
@@ -119,7 +119,7 @@ main(int argc, char *argv[])
o_unsafe = true;
break;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
fprintf(stderr, "%s: error: Unhandled getopt case '%c'\n", argv0, c);
diff --git a/cmd/mv.c b/cmd/mv.c
@@ -445,7 +445,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "mv: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/nice.c b/cmd/nice.c
@@ -52,7 +52,7 @@ main(int argc, char *argv[])
usage();
return 125;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 125;
default:
diff --git a/cmd/nproc.c b/cmd/nproc.c
@@ -44,7 +44,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/paste.c b/cmd/paste.c
@@ -253,7 +253,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/pathchk.c b/cmd/pathchk.c
@@ -62,7 +62,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "pathchk: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/pwd.c b/cmd/pwd.c
@@ -91,7 +91,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/realpath.c b/cmd/realpath.c
@@ -122,7 +122,7 @@ main_realpath(int argc, char *argv[])
usage_realpath();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage_realpath();
return 1;
}
@@ -184,7 +184,7 @@ main_readlink(int argc, char *argv[])
usage_readlink();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage_readlink();
return 1;
}
diff --git a/cmd/renice.c b/cmd/renice.c
@@ -124,7 +124,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "renice: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/rm.c b/cmd/rm.c
@@ -197,7 +197,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "rm: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/rmdir.c b/cmd/rmdir.c
@@ -70,7 +70,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "rmdir: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/sha1sum.c b/cmd/sha1sum.c
@@ -179,7 +179,7 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
abort();
diff --git a/cmd/sha256sum.c b/cmd/sha256sum.c
@@ -179,7 +179,7 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
abort();
diff --git a/cmd/sha512sum.c b/cmd/sha512sum.c
@@ -179,7 +179,7 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: error: Missing operand for option: '-%c'\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
abort();
diff --git a/cmd/shuf.c b/cmd/shuf.c
@@ -132,7 +132,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/strings.c b/cmd/strings.c
@@ -172,7 +172,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "strings: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/sync.c b/cmd/sync.c
@@ -43,12 +43,8 @@ main(int argc, char *argv[])
break;
#endif
case '?':
- if(!got_long_opt)
- fprintf(stderr,
- "sync: error: Unrecognized option '-%c', continuing with error status set\n",
- optopt);
- err = 1;
- break;
+ GETOPT_UNKNOWN_OPT
+ return 1;
default:
abort();
}
diff --git a/cmd/tee.c b/cmd/tee.c
@@ -45,7 +45,7 @@ main(int argc, char *argv[])
fprintf(stderr, "tee: error: Missing operand for option: '-%c'\n", optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "tee: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
abort();
diff --git a/cmd/time.c b/cmd/time.c
@@ -56,7 +56,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "time: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/timeout.c b/cmd/timeout.c
@@ -142,7 +142,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "timeout: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
}
diff --git a/cmd/touch.c b/cmd/touch.c
@@ -209,7 +209,7 @@ main(int argc, char *argv[])
fprintf(stderr, "touch: error: Missing operand for option: '-%c'\n", optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "touch: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
}
}
diff --git a/cmd/tr.c b/cmd/tr.c
@@ -97,7 +97,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unhandled option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/truncate.c b/cmd/truncate.c
@@ -73,7 +73,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "truncate: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/uname.c b/cmd/uname.c
@@ -80,7 +80,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "uname: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/uniq.c b/cmd/uniq.c
@@ -99,7 +99,7 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: error: Option '-%c' requires an operand\n", argv0, optopt);
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unhandled option '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
fprintf(stderr, "%s: error: Unhandled getopt case '%c'\n", argv0, c);
diff --git a/cmd/wc.c b/cmd/wc.c
@@ -272,7 +272,7 @@ main(int argc, char *argv[])
usage();
return 1;
case '?':
- if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+ GETOPT_UNKNOWN_OPT
usage();
return 1;
default:
diff --git a/cmd/which.c b/cmd/which.c
@@ -38,7 +38,7 @@ main(int argc, char *argv[])
opt_s = true;
break;
case '?':
- if(!got_long_opt) fprintf(stderr, "which: error: Unrecognised option: '-%c'\n", optopt);
+ GETOPT_UNKNOWN_OPT
return 1;
default:
abort();
diff --git a/lib/getopt_nolong.h b/lib/getopt_nolong.h
@@ -8,3 +8,19 @@ extern const char *argv0;
extern bool got_long_opt;
int getopt_nolong(int argc, char *const argv[], const char *optstring);
+
+#ifdef HAS_GETOPT_LONG
+#define GETOPT_UNKNOWN_OPT \
+ if(argv[optind - 1] && argv[optind - 1][0] == '-' && argv[optind - 1][1] == '-' && \
+ argv[optind - 1][2] != '\0') \
+ { \
+ fprintf(stderr, "%s: error: Unrecognised long option: '%s'\n", argv0, argv[optind - 1]); \
+ } \
+ else if(!got_long_opt) \
+ { \
+ fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt); \
+ }
+#else
+#define GETOPT_UNKNOWN_OPT \
+ if(!got_long_opt) fprintf(stderr, "%s: error: Unrecognised option: '-%c'\n", argv0, optopt);
+#endif
diff --git a/test-cmd/id.sh b/test-cmd/id.sh
@@ -34,5 +34,5 @@ t G_nobody '-G nobody' "$(id -G nobody)
t G_root '-G root' "$(id -G root)
"
-t --exit=1 badarg '-a' "id: error: Unhandled option '-a'
+t --exit=1 badarg '-a' "id: error: Unrecognised option: '-a'
${usage}"
diff --git a/test-cmd/mktemp.sh b/test-cmd/mktemp.sh
@@ -2,9 +2,10 @@
# SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
# SPDX-License-Identifier: MPL-2.0
-target="$(dirname "$0")/../cmd/mktemp"
-plans=14
-. "$(dirname "$0")/tap.sh"
+WD="$(dirname "$0")/../"
+target="${WD}/cmd/mktemp"
+plans=15
+. "${WD}/test-cmd/tap.sh"
t_mktemp()
{
@@ -99,3 +100,11 @@ t_cmd unsafe:dir_template '' cmd_mktemp_u -u -d template.XXXXXX
t_args --exit=1 unsafe:dir_template_line 'mktemp: error: Invalid character (newline) in template
' -u -d 'template
XXXXXX'
+
+if grep -q HAS_GETOPT_LONG "${WD}/config.h"; then
+ t --exit=1 unknown_long_opt --foobar "mktemp: error: Unrecognised long option: '--foobar'
+"
+else
+ t --exit=1 unknown_long_opt --foobar "mktemp: error: Long options unsupported: '--foobar'
+"
+fi
diff --git a/test-cmd/pwd.sh b/test-cmd/pwd.sh
@@ -10,7 +10,7 @@ plans=6
t noargs '' "${PWD?}
"
-t --exit=1 usage '-H' "pwd: error: Unrecognised option '-H'
+t --exit=1 usage '-H' "pwd: error: Unrecognised option: '-H'
Usage: pwd [-L|-P]
"