From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from math.gatech.edu (euclid.skiles.gatech.edu [130.207.146.50]) by werple.net.au (8.7/8.7.1) with SMTP id CAA04572 for ; Sat, 4 Nov 1995 02:46:56 +1100 (EST) Received: by math.gatech.edu (SMI-8.6/SMI-SVR4) id KAA03139; Fri, 3 Nov 1995 10:02:28 -0500 Resent-Date: Fri, 3 Nov 1995 10:02:28 -0500 Old-Return-Path: From: Zoltan Hidvegi Message-Id: <199511031506.QAA08638@bolyai.cs.elte.hu> Subject: Re: Background jobs with no job control / disown bug? To: coleman@math.gatech.edu (Richard Coleman) Date: Fri, 3 Nov 1995 16:05:45 +0100 (MET) In-Reply-To: <199511031136.GAA02019@redwood.skiles.gatech.edu> from "Richard Coleman" at Nov 3, 95 06:36:01 am X-Mailer: ELM [version 2.4 PL24] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: hzoli@cs.elte.hu Resent-Message-ID: <"nfYn82.0.wm.3yYcm"@euclid> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/524 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu > I had thought that adding a new pre-command `nojob' would be > a good idea. But to do this right would probably require some > work. Zefram posted a solution for that which I like quite much. It is part of my releases sine it appeared. I had to rewrite it for the latest test releases and now it is much simpler than the original. The large patch to zsh.h only renumbers the symbols. Cheers, Zoltan diff -c Doc/zshbuiltins.1.orig Doc/zshbuiltins.1 *** Doc/zshbuiltins.1.orig Sun Oct 29 11:52:03 1995 --- Doc/zshbuiltins.1 Fri Nov 3 13:48:25 1995 *************** *** 225,231 **** --- 225,237 ---- are disabled. Disabled objects can be enabled with the \fBenable\fP command. .TP + .PD 0 \fBdisown\fP [ \fIjob\fP ... ] + .TP + \fIjob\fP ... \fB&|\fP + .TP + \fIjob\fP ... \fB&!\fP + .PD Remove the specified jobs from the job table; the shell will no longer report their status, and will not complain if you try to exit an interactive shell with them running or stopped. diff -c Doc/zshmisc.1.orig Doc/zshmisc.1 *** Doc/zshmisc.1.orig Sun Oct 29 11:52:06 1995 --- Doc/zshmisc.1 Fri Nov 3 13:49:00 1995 *************** *** 35,46 **** operators have equal precedence and are left associative. .PP A \fIlist\fP is a sequence of one or more sublists ! separated by, and optionally terminated by, \fB;\fP, \fB&\fP, ! or a newline. Normally the shell waits for each list to finish before executing the next one. ! If a list is terminated by a \fB&\fP, the shell executes ! it in the background, and does not wait for it to finish. .SH "PRECOMMAND MODIFIERS" A simple command may be preceded by a \fIprecommand\fP modifier which will alter how the command is interpreted. --- 35,46 ---- operators have equal precedence and are left associative. .PP A \fIlist\fP is a sequence of one or more sublists ! separated by, and optionally terminated by, \fB;\fP, \fB&\fP, \fB&|\fP, ! \fB&!\fP or a newline. Normally the shell waits for each list to finish before executing the next one. ! If a list is terminated by \fB&\fP, \fB&|\fP or \fB&!\fP, the shell ! executes it in the background, and does not wait for it to finish. .SH "PRECOMMAND MODIFIERS" A simple command may be preceded by a \fIprecommand\fP modifier which will alter how the command is interpreted. *************** *** 642,647 **** --- 642,655 ---- .PP indicating that the job which was started asynchronously was job number 1 and had one (top-level) process, whose process id was 1234. + .PP + If a job is started with + .BR &| + or + .BR &! , + then that job is immediately disowned. After startup, it + does not have a place in the job table, and is not subject + to the job control features described here. .PP If you are running a job and wish to do something else you may hit the key \fB^Z\fR (control-Z) which sends a TSTP signal to the current job. diff -c Src/exec.c.orig Src/exec.c *** Src/exec.c.orig Sun Oct 29 11:50:12 1995 --- Src/exec.c Fri Nov 3 13:07:52 1995 *************** *** 647,653 **** lastwj = newjob; if (l->flags & PFLAG_COPROC) close(ipipe[1]); ! spawnjob(); child_unblock(); return 0; } else { --- 647,658 ---- lastwj = newjob; if (l->flags & PFLAG_COPROC) close(ipipe[1]); ! if (how & Z_DISOWN) { ! deletejob(jobtab + thisjob); ! thisjob = -1; ! } ! else ! spawnjob(); child_unblock(); return 0; } else { *************** *** 1131,1137 **** /* If the command begins with `%', then assume it is a * * reference to a job in the job table. */ if (nonempty(args) && *(char *)peekfirst(args) == '%') { ! pushnode(args, dupstring((how & Z_ASYNC) ? "bg" : "fg")); how = Z_SYNC; } --- 1136,1142 ---- /* If the command begins with `%', then assume it is a * * reference to a job in the job table. */ if (nonempty(args) && *(char *)peekfirst(args) == '%') { ! pushnode(args, dupstring((how & Z_DISOWN) ? "disown" : (how & Z_ASYNC) ? "bg" : "fg")); how = Z_SYNC; } *************** *** 1298,1304 **** close(synch[1]); read(synch[0], &dummy, 1); close(synch[0]); ! if (how & Z_ASYNC) { lastpid = pid; } else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) { /* search for STTY=... */ --- 1303,1309 ---- close(synch[1]); read(synch[0], &dummy, 1); close(synch[0]); ! if ((how & Z_ASYNC) && !(how & Z_DISOWN)) { lastpid = pid; } else if (!jobtab[thisjob].stty_in_env && nonempty(cmd->vars)) { /* search for STTY=... */ diff -c Src/lex.c.orig Src/lex.c *** Src/lex.c.orig Sun Oct 29 11:50:23 1995 --- Src/lex.c Fri Nov 3 13:05:38 1995 *************** *** 187,192 **** --- 187,193 ---- case SEMI: case DSEMI: case AMPER: + case AMPERBANG: case INPAR: case INBRACE: case DBAR: *************** *** 425,435 **** break; case LX1_AMPER: d = hgetc(); ! if (d != '&') { ! hungetc(d); ! return AMPER; ! } ! return DAMPER; case LX1_BAR: d = hgetc(); if (d == '|') --- 426,437 ---- break; case LX1_AMPER: d = hgetc(); ! if (d == '&') ! return DAMPER; ! else if (d == '!' || d == '|') ! return AMPERBANG; ! hungetc(d); ! return AMPER; case LX1_BAR: d = hgetc(); if (d == '|') diff -c Src/parse.c.orig Src/parse.c *** Src/parse.c.orig Sun Oct 29 11:50:30 1995 --- Src/parse.c Fri Nov 3 13:05:39 1995 *************** *** 48,54 **** /* * event : ENDINPUT * | SEPER ! * | sublist [ SEPER | AMPER ] */ /**/ List --- 48,54 ---- /* * event : ENDINPUT * | SEPER ! * | sublist [ SEPER | AMPER | AMPERBANG ] */ /**/ List *************** *** 90,95 **** --- 90,100 ---- l->type = Z_ASYNC; l->left = sl; yylex(); + } else if (tok == AMPERBANG) { + l = (List) make_list(); + l->type = Z_ASYNC | Z_DISOWN; + l->left = sl; + yylex(); } else l = NULL; if (!l) { *************** *** 135,141 **** } /* ! * list : { SEPER } [ sublist [ { SEPER | AMPER } list ] ] */ /**/ --- 140,146 ---- } /* ! * list : { SEPER } [ sublist [ { SEPER | AMPER | AMPERBANG } list ] ] */ /**/ *************** *** 148,159 **** while (tok == SEPER) yylex(); if ((sl = par_sublist())) ! if (tok == SEPER || tok == AMPER) { l = (List) make_list(); l->left = sl; ! l->type = (tok == SEPER) ? Z_SYNC : Z_ASYNC; incmdpos = 1; ! while (tok == SEPER || tok == AMPER) yylex(); l->right = par_list(); } else { --- 153,165 ---- while (tok == SEPER) yylex(); if ((sl = par_sublist())) ! if (tok == SEPER || tok == AMPER || tok == AMPERBANG) { l = (List) make_list(); l->left = sl; ! l->type = (tok == SEPER) ? Z_SYNC : ! (tok == AMPER) ? Z_ASYNC : Z_ASYNC | Z_DISOWN; incmdpos = 1; ! while (tok == SEPER || tok == AMPER || tok == AMPERBANG) yylex(); l->right = par_list(); } else { *************** *** 928,934 **** break; yylex(); } ! if (tok == AMPER) YYERROR; for (;;) { if (tok == STRING) { --- 934,940 ---- break; yylex(); } ! if (tok == AMPER || tok == AMPERBANG) YYERROR; for (;;) { if (tok == STRING) { diff -c Src/text.c.orig Src/text.c *** Src/text.c.orig Sun Oct 29 11:50:34 1995 --- Src/text.c Fri Nov 3 13:05:39 1995 *************** *** 164,171 **** switch (NT_TYPE(n->ntype)) { case N_LIST: gt2(_List(n)->left); ! if (_List(n)->type & Z_ASYNC) taddstr(" &"); simplifyright(_List(n)); if (_List(n)->right) { if (tnewlins) --- 164,174 ---- switch (NT_TYPE(n->ntype)) { case N_LIST: gt2(_List(n)->left); ! if (_List(n)->type & Z_ASYNC) { taddstr(" &"); + if (_List(n)->type & Z_DISOWN) + taddstr("|"); + } simplifyright(_List(n)); if (_List(n)->right) { if (tnewlins) diff -c Src/zle_tricky.c.orig Src/zle_tricky.c *** Src/zle_tricky.c.orig Sun Oct 29 11:50:53 1995 --- Src/zle_tricky.c Fri Nov 3 13:05:39 1995 *************** *** 931,937 **** /* We reached the end. */ if (tok == ENDINPUT) break; ! if (tok == BAR || tok == AMPER || tok == BARAMP || tok == DBAR || tok == DAMPER) /* This is one of the things that separate commands. If we already have the things we need (e.g. the token strings), --- 931,937 ---- /* We reached the end. */ if (tok == ENDINPUT) break; ! if (tok == BAR || tok == AMPER || tok == AMPERBANG || tok == BARAMP || tok == DBAR || tok == DAMPER) /* This is one of the things that separate commands. If we already have the things we need (e.g. the token strings), diff -c Src/zsh.h.orig Src/zsh.h *** Src/zsh.h.orig Fri Nov 3 13:05:39 1995 --- Src/zsh.h Fri Nov 3 13:47:01 1995 *************** *** 130,161 **** #define INOUTPAR 35 #define DINPAR 36 #define DOUTPAR 37 /* Tokens for reserved words */ ! #define DASH 38 /* - */ ! #define CASE 39 /* case */ ! #define COMMAND 40 /* command */ ! #define COPROC 41 /* coproc */ ! #define DO 42 /* do */ ! #define DONE 43 /* done */ ! #define ELIF 44 /* elif */ ! #define ELSE 45 /* else */ ! #define ZEND 46 /* end */ ! #define ESAC 47 /* esac */ ! #define EXEC 48 /* exec */ ! #define FI 49 /* fi */ ! #define FOR 50 /* for */ ! #define FOREACH 51 /* foreach */ ! #define FUNC 52 /* function */ ! #define IF 53 /* if */ ! #define NOCORRECT 54 /* nocorrect */ ! #define NOGLOB 55 /* noglob */ ! #define REPEAT 56 /* repeat */ ! #define SELECT 57 /* select */ ! #define THEN 58 /* then */ ! #define TIME 59 /* time */ ! #define UNTIL 60 /* until */ ! #define WHILE 61 /* while */ #define WRITE 0 #define WRITENOW 1 --- 130,162 ---- #define INOUTPAR 35 #define DINPAR 36 #define DOUTPAR 37 + #define AMPERBANG 38 /* Tokens for reserved words */ ! #define DASH 39 /* - */ ! #define CASE 40 /* case */ ! #define COMMAND 41 /* command */ ! #define COPROC 42 /* coproc */ ! #define DO 43 /* do */ ! #define DONE 44 /* done */ ! #define ELIF 45 /* elif */ ! #define ELSE 46 /* else */ ! #define ZEND 47 /* end */ ! #define ESAC 48 /* esac */ ! #define EXEC 49 /* exec */ ! #define FI 50 /* fi */ ! #define FOR 51 /* for */ ! #define FOREACH 52 /* foreach */ ! #define FUNC 53 /* function */ ! #define IF 54 /* if */ ! #define NOCORRECT 55 /* nocorrect */ ! #define NOGLOB 56 /* noglob */ ! #define REPEAT 57 /* repeat */ ! #define SELECT 58 /* select */ ! #define THEN 59 /* then */ ! #define TIME 60 /* time */ ! #define UNTIL 61 /* until */ ! #define WHILE 62 /* while */ #define WRITE 0 #define WRITENOW 1 *************** *** 325,330 **** --- 326,332 ---- #define Z_TIMED (1<<0) /* pipeline is being timed */ #define Z_SYNC (1<<1) /* run this sublist synchronously (;) */ #define Z_ASYNC (1<<2) /* run this sublist asynchronously (&) */ + #define Z_DISOWN (1<<3) /* run this sublist without job control (&|) */ /* tree element for sublists */