zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH] exec compatibility
@ 2007-05-01  0:26 Phil Pennock
  2007-05-04 12:00 ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Phil Pennock @ 2007-05-01  0:26 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 791 bytes --]

I saw two options for cleaning the env:

 (1) *environ = NULL;
     in zexecve, make setting $_ conditional upon there being any
     environmental variables at all
 (2) pass a new envp around, which if NULL is new environ.

The second is more intrusive but doesn't have an ugly hack and it does
let _exactly_ the environment specified be passed.  I decided that "env"
could easily be a shell builtin if an explicit envp is passed, so
decided in favour of intrusiveness against hackiness.

I think that env-as-builtin is best left pending BINF-handler functions.
So this just leaves the way open.

I know that using a static data-segment variable for an envp is normally
not the best of ideas, I'm relying upon nothing messing with the explict
non-current newenvp before an execve().

-Phil

[-- Attachment #2: zsh-exec-compat.patch --]
[-- Type: text/x-diff, Size: 7638 bytes --]

diff -ur zsh-head/Doc/Zsh/builtins.yo zsh-exec/Doc/Zsh/builtins.yo
--- zsh-head/Doc/Zsh/builtins.yo	Fri Mar 23 10:14:05 2007
+++ zsh-exec/Doc/Zsh/builtins.yo	Sun Apr 29 21:17:32 2007
@@ -375,7 +375,24 @@
 Read the arguments as input to the shell and execute the resulting
 command in the current shell process.
 )
-prefix(exec)
+findex(exec)
+item(tt(exec) [ tt(-cl) ] [ tt(-a) var(argv0) ] var(simple command))(
+The simple command argument is run in place of the current process,
+rather than as a sub-process.  The shell does not fork and is replaced.
+The shell does not invoke tT(TRAPEXIT), nor does it source tt(zlogout)
+files.
+The options are provided for compatibility with other shells.
+The tt(-c) flag clears the environment.
+The tt(-l) flag is equivalent to the tt(-) precommand modifier, to
+treat the replacement command as a login shell; the command is executed
+with a tt(-) prepended to its argv[0] string.  This flag has no effect
+if used together with the tt(-a) option.
+The tt(-a) option is used to explicitly specify the argv[0] string to be
+used by the replacement command and is directly equivalent to putting
+the tt($ARGV0) variable into the environment.
+
+See also noderef(Precommand Modifiers).
+)
 findex(exit)
 item(tt(exit) [ var(n) ])(
 Exit the shell with the exit status specified by var(n); if none
diff -ur zsh-head/Src/exec.c zsh-exec/Src/exec.c
--- zsh-head/Src/exec.c	Wed Feb 14 00:21:58 2007
+++ zsh-exec/Src/exec.c	Mon Apr 30 17:08:57 2007
@@ -144,6 +144,7 @@
 
 static int doneps4;
 static char *STTYval;
+static char *blank_env[] = { NULL };
 
 /* Execution functions. */
 
@@ -361,7 +362,7 @@
 
 /**/
 static int
-zexecve(char *pth, char **argv)
+zexecve(char *pth, char **argv, char **newenvp)
 {
     int eno;
     static char buf[PATH_MAX * 2];
@@ -379,7 +380,10 @@
 	sprintf(buf + 2, "%s/%s", pwd, pth);
     zputenv(buf);
     closedumps();
-    execve(pth, argv, environ);
+
+    if (newenvp == NULL)
+	    newenvp = environ;
+    execve(pth, argv, newenvp);
 
     /* If the execve returns (which in general shouldn't happen),   *
      * then check for an errno equal to ENOEXEC.  This errno is set *
@@ -414,14 +418,14 @@
 			    *ptr = '\0';
 			    argv[-2] = ptr2;
 			    argv[-1] = ptr + 1;
-			    execve(ptr2, argv - 2, environ);
+			    execve(ptr2, argv - 2, newenvp);
 			} else {
 			    argv[-1] = ptr2;
-			    execve(ptr2, argv - 1, environ);
+			    execve(ptr2, argv - 1, newenvp);
 			}
 		    } else if (eno == ENOEXEC) {
 			argv[-1] = "sh";
-			execve("/bin/sh", argv - 1, environ);
+			execve("/bin/sh", argv - 1, newenvp);
 		    }
 		} else if (eno == ENOEXEC) {
 		    for (t0 = 0; t0 != ct; t0++)
@@ -429,7 +433,7 @@
 			    break;
 		    if (t0 == ct) {
 			argv[-1] = "sh";
-			execve("/bin/sh", argv - 1, environ);
+			execve("/bin/sh", argv - 1, newenvp);
 		    }
 		}
 	    } else
@@ -467,13 +471,13 @@
 /* execute an external command */
 
 /**/
-void
-execute(LinkList args, int dash, int defpath)
+static void
+execute(LinkList args, int flags, int defpath)
 {
     Cmdnam cn;
     char buf[MAXCMDLEN], buf2[MAXCMDLEN];
     char *s, *z, *arg0;
-    char **argv, **pp;
+    char **argv, **pp, **newenvp = NULL;
     int eno = 0, ee;
 
     arg0 = (char *) peekfirst(args);
@@ -502,7 +506,7 @@
     if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
 	setdata(firstnode(args), (void *) ztrdup(z));
 	delenvvalue(z - 6);
-    } else if (dash) {
+    } else if (flags & BINF_DASH) {
     /* Else if the pre-command `-' was given, we add `-' *
      * to the front of argv[0] for this command.         */
 	sprintf(buf2, "-%s", arg0);
@@ -510,6 +514,9 @@
     }
 
     argv = makecline(args);
+    if (flags & BINF_CLEARENV)
+	newenvp = blank_env;
+
     /*
      * Note that we don't close fd's attached to process substitution
      * here, which should be visible to external processes.
@@ -522,7 +529,7 @@
     }
     for (s = arg0; *s; s++)
 	if (*s == '/') {
-	    int lerrno = zexecve(arg0, argv);
+	    int lerrno = zexecve(arg0, argv, newenvp);
 	    if (arg0 == s || unset(PATHDIRS) ||
 		(arg0[0] == '.' && (arg0 + 1 == s ||
 				    (arg0[1] == '.' && arg0 + 2 == s)))) {
@@ -559,7 +566,7 @@
 	    _exit(127);
 	}
 
-	ee = zexecve(pbuf, argv);
+	ee = zexecve(pbuf, argv, newenvp);
 
 	if ((dptr = strrchr(pbuf, '/')))
 	    *dptr = '\0';
@@ -576,7 +583,7 @@
 	    else {
 		for (pp = path; pp < cn->u.name; pp++)
 		    if (!**pp || (**pp == '.' && (*pp)[1] == '\0')) {
-			ee = zexecve(arg0, argv);
+			ee = zexecve(arg0, argv, newenvp);
 			if (isgooderr(ee, *pp))
 			    eno = ee;
 		    } else if (**pp != '/') {
@@ -584,7 +591,7 @@
 			strucpy(&z, *pp);
 			*z++ = '/';
 			strcpy(z, arg0);
-			ee = zexecve(buf, argv);
+			ee = zexecve(buf, argv, newenvp);
 			if (isgooderr(ee, *pp))
 			    eno = ee;
 		    }
@@ -592,7 +599,7 @@
 		strcat(nn, "/");
 		strcat(nn, cn->node.nam);
 	    }
-	    ee = zexecve(nn, argv);
+	    ee = zexecve(nn, argv, newenvp);
 
 	    if ((dptr = strrchr(nn, '/')))
 		*dptr = '\0';
@@ -601,7 +608,7 @@
 	}
 	for (pp = path; *pp; pp++)
 	    if (!(*pp)[0] || ((*pp)[0] == '.' && !(*pp)[1])) {
-		ee = zexecve(arg0, argv);
+		ee = zexecve(arg0, argv, newenvp);
 		if (isgooderr(ee, *pp))
 		    eno = ee;
 	    } else {
@@ -609,7 +616,7 @@
 		strucpy(&z, *pp);
 		*z++ = '/';
 		strcpy(z, arg0);
-		ee = zexecve(buf, argv);
+		ee = zexecve(buf, argv, newenvp);
 		if (isgooderr(ee, *pp))
 		    eno = ee;
 	    }
@@ -2026,6 +2033,49 @@
 		if (!strcmp(next, "--"))
 		     uremnode(args, firstnode(args));   
 	    }
+	    if (cflags & BINF_EXEC && nextnode(firstnode(args))) {
+		/* check for compatibility options to exec builtin */
+		char *next = (char *) getdata(nextnode(firstnode(args)));
+		char *cmdopt, *exec_argv0 = NULL;
+		while (next && *next == '-' && strlen(next) >= 2) {
+		    uremnode(args, firstnode(args));
+		    if (!strcmp(next, "--"))
+			break;
+		    for (cmdopt = &next[1]; *cmdopt; ++cmdopt) {
+			switch (*cmdopt) {
+			case 'a':
+			    exec_argv0 = (char *) getdata(nextnode(firstnode(args)));
+			    if (!exec_argv0) {
+				zerr("exec flag -a requires a parameter");
+				errflag = lastval = 1;
+				return;
+			    }
+			    uremnode(args, firstnode(args));
+			    break;
+			case 'c':
+			    cflags |= BINF_CLEARENV;
+			    break;
+			case 'l':
+			    cflags |= BINF_DASH;
+			    break;
+			default:
+			    zerr("unknown exec flag -%c", *cmdopt);
+			    errflag = lastval = 1;
+			    return;
+			}
+		    }
+		    next = (char *) getdata(nextnode(firstnode(args)));
+		}
+		if (exec_argv0) {
+		    char *str, *s;
+		    size_t sz = strlen(exec_argv0);
+		    str = s = zalloc(5 + 1 + sz + 1);
+		    strcpy(s, "ARGV0=");
+		    s+=6;
+		    strcpy(s, exec_argv0);
+		    zputenv(str);
+		}
+	    }
 	    uremnode(args, firstnode(args));
 	    hn = NULL;
 	    if ((cflags & BINF_COMMAND) && unset(POSIXBUILTINS))
@@ -2726,7 +2776,7 @@
 		    zsfree(STTYval);
 		    STTYval = 0;
 		}
-		execute(args, cflags & BINF_DASH, use_defpath);
+		execute(args, cflags, use_defpath);
 	    } else {		/* ( ... ) */
 		DPUTS(varspc,
 		      "BUG: assignment before complex command");
diff -ur zsh-head/Src/zsh.h zsh-exec/Src/zsh.h
--- zsh-head/Src/zsh.h	Thu Mar 29 14:35:39 2007
+++ zsh-exec/Src/zsh.h	Mon Apr 30 16:32:26 2007
@@ -1143,6 +1143,7 @@
 #define BINF_KEEPNUM		(1<<13) /* `[-+]NUM' can be an option */
 #define BINF_SKIPDASH		(1<<14) /* Treat `-' as argument (maybe `+') */
 #define BINF_DASHDASHVALID	(1<<15) /* Handle `--' even if SKIPINVALD */
+#define BINF_CLEARENV		(1<<16) /* new process started with cleared env */
 
 struct module {
     char *nam;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] exec compatibility
  2007-05-01  0:26 [PATCH] exec compatibility Phil Pennock
@ 2007-05-04 12:00 ` Peter Stephenson
  2007-05-07  5:56   ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2007-05-04 12:00 UTC (permalink / raw)
  To: zsh-workers

This is what I've ended up with for the exec patch.  I've tweaked the
following:

- Add parentheses around (cflags & BINF_EXEC).
- Handle "exec -aname" with no space.
- Error handling on "exec -a" with no argument tests the presence of
  the node rather than dereferencing to get the data.
- Added a couple of minor comments in exec.c
- Tweaked the documentation: moved the exec doc back to the precommand
  modifiers section, and also moved all findex() markers for precommand
  modifiers into there---if you looked in the index you just got taken
  to an entry that said "see Precommand Modifiers", which was stupid
  (it's always been this way).
- Added some tests to A01grammar.ztst.

I'm not sure how much to worry about compatibilty with previous uses
of "exec -prog" which tried to execute a programme "-prog".  This was never
very portable, but it was a simple rule.  I've added a note to README.

It's a bit nasty that other precommand modifiers don't even handle "--" to
indicate the next word isn't an option.  Maybe if we change exec in this
fashion we should at least do that.

Index: README
===================================================================
RCS file: /cvsroot/zsh/zsh/README,v
retrieving revision 1.43
diff -u -r1.43 README
--- README	1 May 2007 09:29:35 -0000	1.43
+++ README	4 May 2007 11:56:05 -0000
@@ -40,6 +40,14 @@
 applies to expressions with forced splitting such as ${=1+"$@"}, but
 otherwise the case where SH_WORD_SPLIT is not set is unaffected.
 
+The "exec" precommand modifier now takes various options for compatibility
+with other shells.  This means that whereas "exec -prog" previously
+tried to execute a command name "-prog", it will now report an error
+in option handling.  "exec -- -prog" will execute "-prog".  If
+the option EQUALS is set, as it is by default in zsh's native mode,
+"exec =-prog" behaves the same way in all versions of zsh provided
+the command can be found.
+
 The "unset" builtin now does not regard the unsetting of non-existent
 variables as an error, so can still return status 0 (depending on the
 handling of other arguments).  This appears to be the standard shell
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.92
diff -u -r1.92 builtins.yo
--- Doc/Zsh/builtins.yo	23 Mar 2007 17:14:05 -0000	1.92
+++ Doc/Zsh/builtins.yo	4 May 2007 11:56:06 -0000
@@ -6,7 +6,6 @@
 cindex(builtin commands)
 cindex(commands, builtin)
 def(prefix)(1)(\
-findex(ARG1)
 item(tt(ARG1) var(simple command))(
 See noderef(Precommand Modifiers).
 )\
@@ -375,7 +374,9 @@
 Read the arguments as input to the shell and execute the resulting
 command in the current shell process.
 )
-prefix(exec)
+item(tt(exec) [ tt(-cl) ] [ tt(-a) var(argv0) ] var(simple command))(
+See noderef(Precommand Modifiers).
+)
 findex(exit)
 item(tt(exit) [ var(n) ])(
 Exit the shell with the exit status specified by var(n); if none
Index: Doc/Zsh/grammar.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/grammar.yo,v
retrieving revision 1.12
diff -u -r1.12 grammar.yo
--- Doc/Zsh/grammar.yo	19 Jan 2007 21:36:03 -0000	1.12
+++ Doc/Zsh/grammar.yo	4 May 2007 11:56:06 -0000
@@ -105,26 +105,48 @@
 a reserved word.
 
 startitem()
+findex(-)
 item(tt(-))(
 The command is executed with a `tt(-)' prepended to its
 tt(argv[0]) string.
 )
+findex(noglob)
 item(tt(noglob))(
 Filename generation (globbing) is not performed on any of
 the words.
 )
+findex(nocorrect)
 item(tt(nocorrect))(
 Spelling correction is not done on any of the words.  This must appear
 before any other precommand modifier, as it is interpreted immediately,
 before any parsing is done.  It has no effect in non-interactive shells.
 )
-item(tt(exec))(
-The command is executed in the parent shell without forking.
+findex(exec)
+item(tt(exec) [ tt(-cl) ] [ tt(-a) var(argv0) ] var(simple command))(
+The var(simple command) (a set of commands and arguments) is run in place
+of the current process, rather than as a sub-process.  The shell does not
+fork and is replaced.  The shell does not invoke tt(TRAPEXIT), nor does it
+source tt(zlogout) files.
+The options are provided for compatibility with other shells.
+
+The tt(-c) option clears the environment.
+
+The tt(-l) option is equivalent to the tt(-) precommand modifier, to
+treat the replacement command as a login shell; the command is executed
+with a tt(-) prepended to its tt(argv[0]) string.  This flag has no effect
+if used together with the tt(-a) option.
+
+The tt(-a) option is used to specify explicitly the tt(argv[0]) string
+(the name of the command as seen by the process itself) to be used by the
+replacement command and is directly equivalent to setting a value
+for the tt(ARGV0) environment variable.
 )
+findex(command)
 item(tt(command))(
 The command word is taken to be the name of an external command,
 rather than a shell function or builtin.
 )
+findex(builtin)
 item(tt(builtin))(
 The command word is taken to be the name of a builtin command,
 rather than a shell function or external command.
Index: Src/exec.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/exec.c,v
retrieving revision 1.110
diff -u -r1.110 exec.c
--- Src/exec.c	14 Feb 2007 08:21:58 -0000	1.110
+++ Src/exec.c	4 May 2007 11:56:07 -0000
@@ -144,6 +144,7 @@
 
 static int doneps4;
 static char *STTYval;
+static char *blank_env[] = { NULL };
 
 /* Execution functions. */
 
@@ -361,7 +362,7 @@
 
 /**/
 static int
-zexecve(char *pth, char **argv)
+zexecve(char *pth, char **argv, char **newenvp)
 {
     int eno;
     static char buf[PATH_MAX * 2];
@@ -379,7 +380,10 @@
 	sprintf(buf + 2, "%s/%s", pwd, pth);
     zputenv(buf);
     closedumps();
-    execve(pth, argv, environ);
+
+    if (newenvp == NULL)
+	    newenvp = environ;
+    execve(pth, argv, newenvp);
 
     /* If the execve returns (which in general shouldn't happen),   *
      * then check for an errno equal to ENOEXEC.  This errno is set *
@@ -414,14 +418,14 @@
 			    *ptr = '\0';
 			    argv[-2] = ptr2;
 			    argv[-1] = ptr + 1;
-			    execve(ptr2, argv - 2, environ);
+			    execve(ptr2, argv - 2, newenvp);
 			} else {
 			    argv[-1] = ptr2;
-			    execve(ptr2, argv - 1, environ);
+			    execve(ptr2, argv - 1, newenvp);
 			}
 		    } else if (eno == ENOEXEC) {
 			argv[-1] = "sh";
-			execve("/bin/sh", argv - 1, environ);
+			execve("/bin/sh", argv - 1, newenvp);
 		    }
 		} else if (eno == ENOEXEC) {
 		    for (t0 = 0; t0 != ct; t0++)
@@ -429,7 +433,7 @@
 			    break;
 		    if (t0 == ct) {
 			argv[-1] = "sh";
-			execve("/bin/sh", argv - 1, environ);
+			execve("/bin/sh", argv - 1, newenvp);
 		    }
 		}
 	    } else
@@ -467,13 +471,13 @@
 /* execute an external command */
 
 /**/
-void
-execute(LinkList args, int dash, int defpath)
+static void
+execute(LinkList args, int flags, int defpath)
 {
     Cmdnam cn;
     char buf[MAXCMDLEN], buf2[MAXCMDLEN];
     char *s, *z, *arg0;
-    char **argv, **pp;
+    char **argv, **pp, **newenvp = NULL;
     int eno = 0, ee;
 
     arg0 = (char *) peekfirst(args);
@@ -502,7 +506,7 @@
     if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
 	setdata(firstnode(args), (void *) ztrdup(z));
 	delenvvalue(z - 6);
-    } else if (dash) {
+    } else if (flags & BINF_DASH) {
     /* Else if the pre-command `-' was given, we add `-' *
      * to the front of argv[0] for this command.         */
 	sprintf(buf2, "-%s", arg0);
@@ -510,6 +514,9 @@
     }
 
     argv = makecline(args);
+    if (flags & BINF_CLEARENV)
+	newenvp = blank_env;
+
     /*
      * Note that we don't close fd's attached to process substitution
      * here, which should be visible to external processes.
@@ -522,7 +529,7 @@
     }
     for (s = arg0; *s; s++)
 	if (*s == '/') {
-	    int lerrno = zexecve(arg0, argv);
+	    int lerrno = zexecve(arg0, argv, newenvp);
 	    if (arg0 == s || unset(PATHDIRS) ||
 		(arg0[0] == '.' && (arg0 + 1 == s ||
 				    (arg0[1] == '.' && arg0 + 2 == s)))) {
@@ -559,7 +566,7 @@
 	    _exit(127);
 	}
 
-	ee = zexecve(pbuf, argv);
+	ee = zexecve(pbuf, argv, newenvp);
 
 	if ((dptr = strrchr(pbuf, '/')))
 	    *dptr = '\0';
@@ -576,7 +583,7 @@
 	    else {
 		for (pp = path; pp < cn->u.name; pp++)
 		    if (!**pp || (**pp == '.' && (*pp)[1] == '\0')) {
-			ee = zexecve(arg0, argv);
+			ee = zexecve(arg0, argv, newenvp);
 			if (isgooderr(ee, *pp))
 			    eno = ee;
 		    } else if (**pp != '/') {
@@ -584,7 +591,7 @@
 			strucpy(&z, *pp);
 			*z++ = '/';
 			strcpy(z, arg0);
-			ee = zexecve(buf, argv);
+			ee = zexecve(buf, argv, newenvp);
 			if (isgooderr(ee, *pp))
 			    eno = ee;
 		    }
@@ -592,7 +599,7 @@
 		strcat(nn, "/");
 		strcat(nn, cn->node.nam);
 	    }
-	    ee = zexecve(nn, argv);
+	    ee = zexecve(nn, argv, newenvp);
 
 	    if ((dptr = strrchr(nn, '/')))
 		*dptr = '\0';
@@ -601,7 +608,7 @@
 	}
 	for (pp = path; *pp; pp++)
 	    if (!(*pp)[0] || ((*pp)[0] == '.' && !(*pp)[1])) {
-		ee = zexecve(arg0, argv);
+		ee = zexecve(arg0, argv, newenvp);
 		if (isgooderr(ee, *pp))
 		    eno = ee;
 	    } else {
@@ -609,7 +616,7 @@
 		strucpy(&z, *pp);
 		*z++ = '/';
 		strcpy(z, arg0);
-		ee = zexecve(buf, argv);
+		ee = zexecve(buf, argv, newenvp);
 		if (isgooderr(ee, *pp))
 		    eno = ee;
 	    }
@@ -2024,7 +2031,63 @@
 		    }
 		}
 		if (!strcmp(next, "--"))
-		     uremnode(args, firstnode(args));   
+		     uremnode(args, firstnode(args));
+	    }
+	    if ((cflags & BINF_EXEC) && nextnode(firstnode(args))) {
+		/*
+		 * Check for compatibility options to exec builtin.
+		 * It would be nice to do these more generically,
+		 * but currently we don't have a mechanism for
+		 * precommand modifiers.
+		 */
+		char *next = (char *) getdata(nextnode(firstnode(args)));
+		char *cmdopt, *exec_argv0 = NULL;
+		while (next && *next == '-' && strlen(next) >= 2) {
+		    uremnode(args, firstnode(args));
+		    if (!strcmp(next, "--"))
+			break;
+		    for (cmdopt = &next[1]; *cmdopt; ++cmdopt) {
+			switch (*cmdopt) {
+			case 'a':
+			    /* argument is ARGV0 string */
+			    if (cmdopt[1]) {
+				exec_argv0 = cmdopt+1;
+				/* position on last non-NULL character */
+				cmdopt += strlen(cmdopt+1);
+			    } else {
+				if (!nextnode(firstnode(args))) {
+				    zerr("exec flag -a requires a parameter");
+				    errflag = lastval = 1;
+				    return;
+				}
+				exec_argv0 = (char *)
+				    getdata(nextnode(firstnode(args)));
+				uremnode(args, firstnode(args));
+			    }
+			    break;
+			case 'c':
+			    cflags |= BINF_CLEARENV;
+			    break;
+			case 'l':
+			    cflags |= BINF_DASH;
+			    break;
+			default:
+			    zerr("unknown exec flag -%c", *cmdopt);
+			    errflag = lastval = 1;
+			    return;
+			}
+		    }
+		    next = (char *) getdata(nextnode(firstnode(args)));
+		}
+		if (exec_argv0) {
+		    char *str, *s;
+		    size_t sz = strlen(exec_argv0);
+		    str = s = zalloc(5 + 1 + sz + 1);
+		    strcpy(s, "ARGV0=");
+		    s+=6;
+		    strcpy(s, exec_argv0);
+		    zputenv(str);
+		}
 	    }
 	    uremnode(args, firstnode(args));
 	    hn = NULL;
@@ -2726,7 +2789,7 @@
 		    zsfree(STTYval);
 		    STTYval = 0;
 		}
-		execute(args, cflags & BINF_DASH, use_defpath);
+		execute(args, cflags, use_defpath);
 	    } else {		/* ( ... ) */
 		DPUTS(varspc,
 		      "BUG: assignment before complex command");
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.113
diff -u -r1.113 zsh.h
--- Src/zsh.h	1 May 2007 22:05:06 -0000	1.113
+++ Src/zsh.h	4 May 2007 11:56:07 -0000
@@ -1144,6 +1144,7 @@
 #define BINF_KEEPNUM		(1<<13) /* `[-+]NUM' can be an option */
 #define BINF_SKIPDASH		(1<<14) /* Treat `-' as argument (maybe `+') */
 #define BINF_DASHDASHVALID	(1<<15) /* Handle `--' even if SKIPINVALD */
+#define BINF_CLEARENV		(1<<16) /* new process started with cleared env */
 
 struct module {
     char *nam;
Index: Test/A01grammar.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/A01grammar.ztst,v
retrieving revision 1.13
diff -u -r1.13 A01grammar.ztst
--- Test/A01grammar.ztst	19 Jan 2007 21:36:04 -0000	1.13
+++ Test/A01grammar.ztst	4 May 2007 11:56:07 -0000
@@ -62,6 +62,22 @@
   (exec /bin/sh; echo bar)
 0:`exec' precommand modifier
 
+  (exec -l /bin/sh -c 'echo $0')
+0:`exec' with -l option
+>-/bin/sh
+
+  (exec -a /bin/SPLATTER /bin/sh -c 'echo $0')
+0:`exec' with -a option
+>/bin/SPLATTER
+
+  (exec -a/bin/SPLOOSH /bin/sh -c 'echo $0')
+0:`exec' with -a option, no space
+>/bin/SPLOOSH
+
+  (export FOO=bar; exec -c /bin/sh -c 'echo x${FOO}x')
+0:`exec' with -c option
+>xx
+
   cat() { echo Function cat executed; }
   command cat && unfunction cat
 0:`command' precommand modifier

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php

To get further information regarding CSR, please visit our Investor Relations page at http://ir.csr.com/csr/about/overview


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] exec compatibility
  2007-05-04 12:00 ` Peter Stephenson
@ 2007-05-07  5:56   ` Bart Schaefer
  2007-05-07  7:32     ` Phil Pennock
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2007-05-07  5:56 UTC (permalink / raw)
  To: zsh-workers

On May 4,  1:00pm, Peter Stephenson wrote:
}
} This is what I've ended up with for the exec patch.

One thing that rather annoys me about all this is that

	zsh% - exec sh
and
	zsh% exec - sh

seem no longer to be equivalent.  Am I wrong about that?

I'd be inclined to have these -c/-l/-a flags depend on the emulation mode,
or on POSIX_BUILTINS (though they aren't really POSIX, are they?) or on
something else, so that they're not available in default "zsh mode".

(Hmmm:  Make them a zmodload -F feature of the zsh/main module ...?)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] exec compatibility
  2007-05-07  5:56   ` Bart Schaefer
@ 2007-05-07  7:32     ` Phil Pennock
  2007-05-08 10:09       ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Phil Pennock @ 2007-05-07  7:32 UTC (permalink / raw)
  To: zsh-workers

On 2007-05-06 at 22:56 -0700, Bart Schaefer wrote:
> One thing that rather annoys me about all this is that
> 
> 	zsh% - exec sh
> and
> 	zsh% exec - sh
> 
> seem no longer to be equivalent.  Am I wrong about that?

Uhm, I think so.  Test results below, and I didn't change anything that
would affect the prefix processing of - as the first modifier and I was
very careful to ensure that a single - would be left unmolested, with
this:
  while (next && *next == '-' && strlen(next) >= 2) {
bit in the options processing for the BINF_EXEC case.  That code's still
there in pws's improved patch.  So - always sets BINF_DASH which will be
handled as before.

Perhaps with a commit an extra comment should be added just above that
line, noting that - needs to be carefully left alone as it's a
precommand modifier in its own right.  I really shouldn't have left that
unremarked upon in the code.


Nuked ~/dbg/bin/zsh* and ~/dbg/lib/zsh
Took cvs HEAD and patched with pws's patch.  Built and installed, with
--prefix=$HOME/dbg set.

Below:
 * Double-nesting of ./dbg/bin/zsh to protect against an accidental
   extra EOF or similar mishap
 * leading [N] is SHLVL, so "$ [2]" means there's a Ctrl-D in there


-pdp@redoubt.spodhuis:p0[0:20](1032)~% ./dbg/bin/zsh
[2]-pdp@redoubt.spodhuis:p0[0:20](1025)~% ./dbg/bin/zsh
[3]-pdp@redoubt.spodhuis:p0[0:20](1001)~% exec -l sh
$ echo $0
-sh
$ [2]-pdp@redoubt.spodhuis:p0[0:21](1026)~% ./dbg/bin/zsh
[3]-pdp@redoubt.spodhuis:p0[0:21](1001)~% - exec sh
$ echo $0
-sh
$ [2]-pdp@redoubt.spodhuis:p0[0:21](1027)~% ./dbg/bin/zsh
[3]-pdp@redoubt.spodhuis:p0[0:21](1001)~% exec - sh
$ echo $0
-sh
$ [2]-pdp@redoubt.spodhuis:p0[0:21](1028)~% 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] exec compatibility
  2007-05-07  7:32     ` Phil Pennock
@ 2007-05-08 10:09       ` Peter Stephenson
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2007-05-08 10:09 UTC (permalink / raw)
  To: zsh-workers

Phil Pennock <zsh-workers+phil.pennock@spodhuis.org> wrote:
> On 2007-05-06 at 22:56 -0700, Bart Schaefer wrote:
> > One thing that rather annoys me about all this is that
> > 
> > 	zsh% - exec sh
> > and
> > 	zsh% exec - sh
> > 
> > seem no longer to be equivalent.  Am I wrong about that?
> 
> Uhm, I think so.
> 
> Perhaps with a commit an extra comment should be added just above that
> line, noting that - needs to be carefully left alone as it's a
> precommand modifier in its own right.  I really shouldn't have left
> that unremarked upon in the code.

It works for me, too; I've added a comment and committed it.

Oliver pointed out that "command" was documented in the builtins list
instead of Precommand Modifiers (which is presumably why you did the
same).  I've simple copied the "command" documentation.  It does mean there
was already one precommand modifier that treated options specially---it
does therefore look like a good idea to extend "--" handling to all of them
for futureproofing, which I haven't done yet.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php

To get further information regarding CSR, please visit our Investor Relations page at http://ir.csr.com/csr/about/overview


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-05-08 10:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-01  0:26 [PATCH] exec compatibility Phil Pennock
2007-05-04 12:00 ` Peter Stephenson
2007-05-07  5:56   ` Bart Schaefer
2007-05-07  7:32     ` Phil Pennock
2007-05-08 10:09       ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).