tcsh printexitvalue query

Jeff Bastian jbastian at redhat.com
Fri Oct 30 02:38:52 EET 2009


On Jun 8 2006 16:13:33 EEST, Christos Zoulas wrote:
> On Jun 8 2006 03:58:29 EEST, Ben Hall wrote:
> > An example of the current behavour (Kubuntu 5.10 - tcsh 6.14.00):
> >
> > # set printexitvalue;echo X"`echo foo | grep bar`"X
> > XExit 1X
> > Exit 1
> >
> > Why has this behavior changed? Is it intentional?
>
> No this is not intentional. Builtins in the foreground should do it,
> but not in ``.



This is still a bug with tcsh-6.17.00 from July 2009.  Attached is a patch 
to fix it.

With this patch, the above command now does:
    # set printexitvalue
    # echo X"`echo foo | grep bar`"X
    XX
    Exit 1
    #

I've also reported this for Fedora 11 at
    https://bugzilla.redhat.com/show_bug.cgi?id=531957

Jeff Bastian
-------------- next part --------------
diff --git a/sh.glob.c b/sh.glob.c
index 6ee5ecc..82e5801 100644
--- a/sh.glob.c
+++ b/sh.glob.c
@@ -776,6 +776,10 @@ backeval(struct blk_buf *bb, struct Strbuf *word, Char *cp, int literal)
 	    alias(&paraml);
 	    t = syntax(paraml.next, &paraml, 0);
 	    cleanup_push(t, syntax_cleanup);
+	    /* The F_BACKQ flag must set so the job output is correct if
+	     * printexitvalue is set.  If it's not set, the job output
+	     * will have "Exit N" appended where N is the exit status. */
+	    t->t_dflg = F_BACKQ;
 	    if (seterr)
 		stderror(ERR_OLD);
 #ifdef SIGTSTP
diff --git a/sh.sem.c b/sh.sem.c
index c9e2581..440e7db 100644
--- a/sh.sem.c
+++ b/sh.sem.c
@@ -664,31 +664,31 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
 #endif /* !CLOSE_ON_EXEC */
 	didfds = 0;
 	wanttty = -1;
-	t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT;
+	t->t_dspr->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ);
 	execute(t->t_dspr, wanttty, NULL, NULL, do_glob);
 	exitstat();
 
     case NODE_PIPE:
 #ifdef BACKPIPE
 	t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg &
-			(F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT));
+	    (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT | F_BACKQ));
 	execute(t->t_dcdr, wanttty, pv, pipeout, do_glob);
-	t->t_dcar->t_dflg |= F_PIPEOUT |
-	    (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT));
+	t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg &
+	    (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT | F_BACKQ));
 	execute(t->t_dcar, wanttty, pipein, pv, do_glob);
 #else /* !BACKPIPE */
-	t->t_dcar->t_dflg |= F_PIPEOUT |
-	    (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT));
+	t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg &
+	    (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT | F_BACKQ));
 	execute(t->t_dcar, wanttty, pipein, pv, do_glob);
 	t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg &
-			(F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT));
+	    (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT | F_BACKQ));
 	execute(t->t_dcdr, wanttty, pv, pipeout, do_glob);
 #endif /* BACKPIPE */
 	break;
 
     case NODE_LIST:
 	if (t->t_dcar) {
-	    t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
+	    t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ);
 	    execute(t->t_dcar, wanttty, NULL, NULL, do_glob);
 	    /*
 	     * In strange case of A&B make a new job after A
@@ -699,7 +699,7 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
 	}
 	if (t->t_dcdr) {
 	    t->t_dcdr->t_dflg |= t->t_dflg &
-		(F_NOFORK | F_NOINTERRUPT);
+		(F_NOFORK | F_NOINTERRUPT | F_BACKQ);
 	    execute(t->t_dcdr, wanttty, NULL, NULL, do_glob);
 	}
 	break;
@@ -707,7 +707,7 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
     case NODE_OR:
     case NODE_AND:
 	if (t->t_dcar) {
-	    t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
+	    t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ);
 	    execute(t->t_dcar, wanttty, NULL, NULL, do_glob);
 	    if ((getn(varval(STRstatus)) == 0) !=
 		(t->t_dtyp == NODE_AND)) {
@@ -716,7 +716,7 @@ execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout,
 	}
 	if (t->t_dcdr) {
 	    t->t_dcdr->t_dflg |= t->t_dflg &
-		(F_NOFORK | F_NOINTERRUPT);
+		(F_NOFORK | F_NOINTERRUPT | F_BACKQ);
 	    execute(t->t_dcdr, wanttty, NULL, NULL, do_glob);
 	}
 	break;


More information about the Tcsh-Bugs mailing list