Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Background jobs with no job control / disown bug?



> 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 */
  



Messages sorted by: Reverse Date, Date, Thread, Author