[hackers] [sbase][PATCH] Support -- in all utilities except echo(1)

From: Mattias Andrée <maandree_AT_kth.se>
Date: Sun, 8 Jul 2018 11:43:16 +0200

In POSIX-2017 it was clarified via the documentation for
basename(1) and dirname(1) that all programs should support
-- unless specified otherwise.

Signed-off-by: Mattias Andrée <maandree_AT_kth.se>
---
 arg.h      | 13 +++++++++++++
 basename.c |  5 +----
 chroot.c   |  2 +-
 cksum.c    |  8 +++++++-
 dirname.c  |  5 +----
 expr.c     |  8 +++++++-
 hostname.c |  2 +-
 link.c     |  2 +-
 logname.c  |  2 +-
 nohup.c    |  2 +-
 printenv.c |  8 +++++++-
 printf.c   |  9 +++++----
 rev.c      |  5 +----
 setsid.c   |  2 +-
 sleep.c    |  2 +-
 sponge.c   |  2 +-
 sync.c     |  2 +-
 tsort.c    |  5 +----
 tty.c      |  2 +-
 unlink.c   |  2 +-
 whoami.c   |  2 +-
 yes.c      |  8 +++++++-
 22 files changed, 62 insertions(+), 36 deletions(-)
diff --git a/arg.h b/arg.h
index 0b23c53..e8b84ba 100644
--- a/arg.h
+++ b/arg.h
_AT_@ -62,4 +62,17 @@ extern char *argv0;
 
 #define LNGARG()	&argv[0][0]
 
+#define ENOFLAGS(x)	do {\
+				argv0 = *argv++;\
+				argc--;\
+				if (argc && argv[0][0] == '-') {\
+					if (argv[0][1] == '-' && !argv[0][2]) {\
+						argv++;\
+						argc--;\
+					} else {\
+						(x);\
+					}\
+				}\
+			} while (0)
+
 #endif
diff --git a/basename.c b/basename.c
index 94a2848..de41d86 100644
--- a/basename.c
+++ b/basename.c
_AT_@ -17,10 +17,7 @@ main(int argc, char *argv[])
 	ssize_t off;
 	char *p;
 
-	ARGBEGIN {
-	default:
-		usage();
-	} ARGEND
+	ENOFLAGS(usage());
 
 	if (argc != 1 && argc != 2)
 		usage();
diff --git a/chroot.c b/chroot.c
index 22bc62e..e3d4c3e 100644
--- a/chroot.c
+++ b/chroot.c
_AT_@ -17,7 +17,7 @@ main(int argc, char *argv[])
 	char *shell[] = { "/bin/sh", "-i", NULL }, *aux, *cmd;
 	int savederrno;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (!argc)
 		usage();
diff --git a/cksum.c b/cksum.c
index 4e7dce6..68c8fc6 100644
--- a/cksum.c
+++ b/cksum.c
_AT_@ -92,12 +92,18 @@ cksum(int fd, const char *s)
 	putchar('\n');
 }
 
+static void
+usage(void)
+{
+	eprintf("usage: %s [file ...]\n", argv0);
+}
+
 int
 main(int argc, char *argv[])
 {
 	int fd;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (!argc) {
 		cksum(0, NULL);
diff --git a/dirname.c b/dirname.c
index 45e1a7e..fcc12e1 100644
--- a/dirname.c
+++ b/dirname.c
_AT_@ -13,10 +13,7 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	ARGBEGIN {
-	default:
-		usage();
-	} ARGEND
+	ENOFLAGS(usage());
 
 	if (argc != 1)
 		usage();
diff --git a/expr.c b/expr.c
index d9c758d..b9bed3f 100644
--- a/expr.c
+++ b/expr.c
_AT_@ -252,12 +252,18 @@ parse(char *expr[], int numexpr)
 	return (valp->str && *valp->str) || valp->num;
 }
 
+static void
+usage(void)
+{
+	eprintf("usage: %s expression\n", argv0);
+}
+
 int
 main(int argc, char *argv[])
 {
 	int ret;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	ret = !parse(argv, argc);
 
diff --git a/hostname.c b/hostname.c
index 495d40d..cd66893 100644
--- a/hostname.c
+++ b/hostname.c
_AT_@ -16,7 +16,7 @@ main(int argc, char *argv[])
 {
 	char host[HOST_NAME_MAX + 1];
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (!argc) {
 		if (gethostname(host, sizeof(host)) < 0)
diff --git a/link.c b/link.c
index a260136..cf76f32 100644
--- a/link.c
+++ b/link.c
_AT_@ -12,7 +12,7 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc != 2)
 		usage();
diff --git a/logname.c b/logname.c
index 8eb8eea..04a2aaa 100644
--- a/logname.c
+++ b/logname.c
_AT_@ -15,7 +15,7 @@ main(int argc, char *argv[])
 {
 	char *login;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc)
 		usage();
diff --git a/nohup.c b/nohup.c
index c75ea45..436c072 100644
--- a/nohup.c
+++ b/nohup.c
_AT_@ -19,7 +19,7 @@ main(int argc, char *argv[])
 {
 	int fd, savederrno;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (!argc)
 		usage();
diff --git a/printenv.c b/printenv.c
index 7ff5393..7ba0e47 100644
--- a/printenv.c
+++ b/printenv.c
_AT_@ -6,13 +6,19 @@
 
 extern char **environ;
 
+static void
+usage(void)
+{
+	eprintf("usage: %s [var ...]\n", argv0);
+}
+
 int
 main(int argc, char *argv[])
 {
 	char *var;
 	int ret = 0;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (!argc) {
 		for (; *environ; environ++)
diff --git a/printf.c b/printf.c
index 4bc645b..234f06d 100644
--- a/printf.c
+++ b/printf.c
_AT_@ -25,11 +25,12 @@ main(int argc, char *argv[])
 	int cooldown = 0, width, precision, ret = 0;
 	char *format, *tmp, *arg, *fmt, flag;
 
-	argv0 = argv[0];
-	if (argc < 2)
+	ENOFLAGS(usage());
+
+	if (argc < 1)
 		usage();
 
-	format = argv[1];
+	format = argv[0];
 	if ((tmp = strstr(format, "\\c"))) {
 		*tmp = 0;
 		cooldown = 1;
_AT_@ -38,7 +39,7 @@ main(int argc, char *argv[])
 	if (formatlen == 0)
 		return 0;
 	lastargi = 0;
-	for (i = 0, argi = 2; !cooldown || i < formatlen; i++, i = cooldown ? i : (i % formatlen)) {
+	for (i = 0, argi = 1; !cooldown || i < formatlen; i++, i = cooldown ? i : (i % formatlen)) {
 		if (i == 0) {
 			if (lastargi == argi)
 				break;
diff --git a/rev.c b/rev.c
index 2d89df1..07f754f 100644
--- a/rev.c
+++ b/rev.c
_AT_@ -45,10 +45,7 @@ main(int argc, char *argv[])
 	FILE *fp;
 	int ret = 0;
 
-	ARGBEGIN {
-	default:
-		usage();
-	} ARGEND
+	ENOFLAGS(usage());
 
 	if (!argc) {
 		rev(stdin);
diff --git a/setsid.c b/setsid.c
index eb682f2..dea934f 100644
--- a/setsid.c
+++ b/setsid.c
_AT_@ -15,7 +15,7 @@ main(int argc, char *argv[])
 {
 	int savederrno;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (!argc)
 		usage();
diff --git a/sleep.c b/sleep.c
index 36dfb1c..d2aa825 100644
--- a/sleep.c
+++ b/sleep.c
_AT_@ -14,7 +14,7 @@ main(int argc, char *argv[])
 {
 	unsigned seconds;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc != 1)
 		usage();
diff --git a/sponge.c b/sponge.c
index 11c8ad4..4cc2f42 100644
--- a/sponge.c
+++ b/sponge.c
_AT_@ -17,7 +17,7 @@ main(int argc, char *argv[])
 	char tmp[] = "/tmp/sponge-XXXXXX";
 	int fd, tmpfd;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc != 1)
 		usage();
diff --git a/sync.c b/sync.c
index d3390de..cd3f837 100644
--- a/sync.c
+++ b/sync.c
_AT_@ -12,7 +12,7 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc)
 		usage();
diff --git a/tsort.c b/tsort.c
index d093df8..a97681d 100644
--- a/tsort.c
+++ b/tsort.c
_AT_@ -185,10 +185,7 @@ main(int argc, char *argv[])
 	const char *fn = "<stdin>";
 	int ret = 0;
 
-	ARGBEGIN {
-	default:
-		usage();
-	} ARGEND;
+	ENOFLAGS(usage());
 
 	if (argc > 1)
 		usage();
diff --git a/tty.c b/tty.c
index 7ffb04a..dabf786 100644
--- a/tty.c
+++ b/tty.c
_AT_@ -15,7 +15,7 @@ main(int argc, char *argv[])
 {
 	char *tty;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc)
 		usage();
diff --git a/unlink.c b/unlink.c
index 241cf25..60e4874 100644
--- a/unlink.c
+++ b/unlink.c
_AT_@ -12,7 +12,7 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc != 1)
 		usage();
diff --git a/whoami.c b/whoami.c
index c991ac2..7f04cf3 100644
--- a/whoami.c
+++ b/whoami.c
_AT_@ -18,7 +18,7 @@ main(int argc, char *argv[])
 	uid_t uid;
 	struct passwd *pw;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	if (argc)
 		usage();
diff --git a/yes.c b/yes.c
index dd97ea6..e0b657a 100644
--- a/yes.c
+++ b/yes.c
_AT_@ -3,12 +3,18 @@
 
 #include "util.h"
 
+static void
+usage(void)
+{
+	eprintf("usage: %s [string ...]\n", argv0);
+}
+
 int
 main(int argc, char *argv[])
 {
 	char **p;
 
-	argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
+	ENOFLAGS(usage());
 
 	for (p = argv; ; p = (*p && *(p + 1)) ? p + 1 : argv) {
 		fputs(*p ? *p : "y", stdout);
-- 
2.11.1
Received on Sun Jul 08 2018 - 11:43:16 CEST

This archive was generated by hypermail 2.3.0 : Sun Jul 08 2018 - 11:48:27 CEST