Index | Thread | Search

From:
Manuel Giraud <manuel@ledu-giraud.fr>
Subject:
Support for /usr/bin/env -S (kind of)
To:
tech@openbsd.org
Date:
Fri, 18 Jul 2025 15:54:31 +0200

Download raw body.

Thread
Hi,

Here's an attempt to support "-S" for env.  I don't know if this
approach is a good idea and it surely needs some polishing.

Index: env.c
===================================================================
RCS file: /cvs/src/usr.bin/env/env.c,v
diff -u -p -r1.19 env.c
--- env.c	28 Jul 2024 21:44:42 -0000	1.19
+++ env.c	18 Jul 2025 13:43:41 -0000
@@ -45,11 +45,41 @@ main(int argc, char *argv[])
 	extern int optind;
 	char **ep, *p;
 	int ch;
+	int nargc;
+	char **nargv;
+	char **ap;
+	int i, j;
 
 	if (pledge("stdio exec", NULL) == -1)
 		err(1, "pledge");
 
-	while ((ch = getopt(argc, argv, "iu:-")) != -1)
+	/* argv[1] needs to be splitted most probably being called
+	 * from a shebang script. */
+	if ((argc > 1) &&
+	    (strchr(argv[1], ' ') ||
+	     strchr(argv[1], '\t'))) {
+		nargv = calloc(20 + argc, sizeof (char *));
+		nargc = 1;
+		nargv[0] = argv[0];
+		for (ap = &nargv[1]; ap < &nargv[19 + argc] &&
+		     (*ap = strsep(&argv[1], " \t")) != NULL;) {
+			if (**ap != '\0') {
+				ap++;
+				nargc++;
+			}
+		}
+
+		/* Fill with what's left in argv. */
+		for (i = nargc, j = 2; j < argc;  i++, j++) {
+			nargv[i] = argv[j];
+			nargc++;
+		}
+
+		argv = nargv;
+		argc = nargc;
+	}
+
+	while ((ch = getopt(argc, argv, "iSu:-")) != -1)
 		switch(ch) {
 		case '-':			/* obsolete */
 		case 'i':
@@ -60,6 +90,9 @@ main(int argc, char *argv[])
 			if (unsetenv(optarg) == -1)
 				err(126, "unsetenv");
 			break;
+		case 'S':	/* Does nothing as the input is
+				 * already splitted here. */
+			break;
 		default:
 			usage();
 		}
@@ -95,7 +128,7 @@ usage(void)
 {
 	extern char *__progname;
 
-	(void)fprintf(stderr, "usage: %s [-i] [-u name] [name=value ...] "
+	(void)fprintf(stderr, "usage: %s [-i] [-S] [-u name] [name=value ...] "
 	    "[utility [argument ...]]\n", __progname);
 	exit(1);
 }

-- 
Manuel Giraud