mirror of
				git://git.code.sf.net/p/cdesktopenv/code
				synced 2025-03-09 15:50:02 +00:00 
			
		
		
		
	Make 'stop' and 'suspend' regular built-ins
The 'stop' and 'suspend' default aliases are now converted into
regular built-in commands so that 'unalias -a' does not remove
them, 'suspend' can do some sanity checks, and something like
	cmd=stop; $cmd $!
will now work.
src/cmd/ksh93/bltins/trap.c:
- b_kill(): Incorporate 'stop' functionality, which is simply
  setting the same flag and variable as '-s STOP' would have done.
- b_suspend(): Add simple builtin function that sends SIGSTOP to
  the main shell. Check for no operands, and refuse to suspend a
  login shell (which would leave the user stuck with no way out).
  Also check that 'kill' succeeds; if we're in an asynchronous
  subshell, it is possible the main shell no longer exists.
src/cmd/ksh93/data/aliases.c:
- Remove "stop" and "suspend" default aliases. (Why were these
  conditional upon SIGTSTP when they actually issued SIGSTOP?)
src/cmd/ksh93/include/builtins.h,
src/cmd/ksh93/data/builtins.c,
src/cmd/ksh93/data/msg.c:
- Add declarations of "stop" and "suspend" regular built-ins.
- Add option strings (AST manual/--man pages) for them.
- Add e_toomanyops ("too many operands") reusable error message for
  b_suspend(). Other new commands may want this at some point.
src/cmd/ksh93/sh.1:
- Remove "stop" and "suspend" default aliases.
- Document "stop" and "suspend" regular built-in commands.
			
			
This commit is contained in:
		
							parent
							
								
									add82e1984
								
							
						
					
					
						commit
						3ba4900e9c
					
				
					 8 changed files with 108 additions and 11 deletions
				
			
		|  | @ -171,7 +171,16 @@ int	b_kill(int argc,char *argv[],Shbltin_t *context) | |||
| 	register Shell_t *shp = context->shp; | ||||
| 	int usemenu = 0; | ||||
| 	NOT_USED(argc); | ||||
| #if defined(JOBS) && defined(SIGSTOP) | ||||
| 	if(**argv == 's')	/* <s>top == kill -s STOP */ | ||||
| 	{ | ||||
| 		flag |= S_FLAG; | ||||
| 		signame = "STOP"; | ||||
| 	} | ||||
| 	while((n = optget(argv, **argv == 's' ? sh_optstop : sh_optkill))) switch(n) | ||||
| #else | ||||
| 	while((n = optget(argv,sh_optkill))) switch(n) | ||||
| #endif /* defined(JOBS) && defined(SIGSTOP) */ | ||||
| 	{ | ||||
| 		case ':': | ||||
| 			if((signame=argv[opt_info.index++]) && (sig=sig_number(shp,signame+1))>=0) | ||||
|  | @ -233,6 +242,25 @@ endopts: | |||
| 	return(shp->exitval); | ||||
| } | ||||
| 
 | ||||
| #if defined(JOBS) && defined(SIGSTOP) | ||||
| /*
 | ||||
|  * former default alias suspend='kill -s STOP $$' | ||||
|  */ | ||||
| int	b_suspend(int argc,char *argv[],Shbltin_t *context) | ||||
| { | ||||
| 	NOT_USED(argc); | ||||
| 	if(optget(argv, sh_optsuspend))	/* no options supported (except AST --man, etc.) */ | ||||
| 		errormsg(SH_DICT, ERROR_exit(2), "%s", opt_info.arg); | ||||
| 	if(argv[opt_info.index])	/* no operands supported */ | ||||
| 		errormsg(SH_DICT, ERROR_exit(2), e_toomanyops); | ||||
| 	if(sh_isoption(SH_LOGIN_SHELL)) | ||||
| 		errormsg(SH_DICT, ERROR_exit(1), "cannot suspend a login shell"); | ||||
| 	if(kill(context->shp->gd->pid, SIGSTOP) != 0) | ||||
| 		errormsg(SH_DICT, ERROR_exit(1), "could not signal main shell at PID %d", context->shp->gd->pid); | ||||
| 	return(0); | ||||
| } | ||||
| #endif /* defined(JOBS) && defined(SIGSTOP) */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Given the name or number of a signal return the signal number | ||||
|  */ | ||||
|  |  | |||
|  | @ -37,10 +37,6 @@ const struct shtable2 shtab_aliases[] = | |||
| 	"integer",	NV_NOFREE|BLT_DCL,	"typeset -li", | ||||
| 	"nameref",	NV_NOFREE|BLT_DCL,	"typeset -n", | ||||
| 	"r",		NV_NOFREE,		"hist -s", | ||||
| #ifdef SIGTSTP | ||||
| 	"stop",		NV_NOFREE,		"kill -s STOP", | ||||
| 	"suspend", 	NV_NOFREE,		"kill -s STOP $$", | ||||
| #endif /*SIGTSTP */ | ||||
| 	"",		0,			(char*)0 | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -109,6 +109,10 @@ const struct shtable3 shtab_builtins[] = | |||
| 	"/bin/kill",	NV_BLTIN|BLT_ENV,		bltin(kill), | ||||
| #   endif	/* SIGTSTP */ | ||||
| 	"jobs",		NV_BLTIN|BLT_ENV,		bltin(jobs), | ||||
| #   ifdef SIGSTOP | ||||
| 	"stop",		NV_BLTIN|BLT_ENV,		bltin(kill), | ||||
| 	"suspend", 	NV_BLTIN|BLT_ENV,		bltin(suspend), | ||||
| #   endif	/* SIGSTOP */ | ||||
| #endif	/* JOBS */ | ||||
| 	"false",	NV_BLTIN|BLT_ENV,		bltin(false), | ||||
| 	"getopts",	NV_BLTIN|BLT_ENV,		bltin(getopts), | ||||
|  | @ -1060,6 +1064,42 @@ _JOB_ | |||
| "[+SEE ALSO?\bps\b(1), \bjobs\b(1), \bkill\b(2), \bsignal\b(2)]" | ||||
| ; | ||||
| 
 | ||||
| #if defined(JOBS) && defined(SIGSTOP) | ||||
| const char sh_optstop[] = | ||||
| "[-1c?\n@(#)$Id: stop (ksh93) 2020-06-22 $\n]" | ||||
| "[+NAME?stop - suspend a process]" | ||||
| "[+DESCRIPTION?\bstop\b sends a \bSIGSTOP\b signal to one or more processes " | ||||
| 	"specified by \ajob\a, suspending them until they receive \bSIGCONT\b.]" | ||||
| _JOB_ | ||||
| "\n" | ||||
| "\njob ...\n" | ||||
| "\n" | ||||
| "[+EXIT STATUS?]{" | ||||
| 	"[+0?At least one matching process was found for each \ajob\a " | ||||
| 	"operand, and \bSIGSTOP\b was successfully sent to at least one " | ||||
| 	"matching process.]" | ||||
| 	"[+>0?An error occurred.]" | ||||
| "}" | ||||
| "[+SEE ALSO?\bkill\b(1)]" | ||||
| ; | ||||
| 
 | ||||
| const char sh_optsuspend[] = | ||||
| "[-1c?\n@(#)$Id: suspend (ksh93) 2020-06-22 $\n]" | ||||
| "[+NAME?suspend - stop the shell]" | ||||
| "[+DESCRIPTION?\bsuspend\b sends a \bSIGSTOP\b signal to the main shell " | ||||
| 	"process, suspending the script or child shell session until it " | ||||
| 	"receives \bSIGCONT\b (for instance, when typing \bfg\b in the " | ||||
| 	"parent shell).]" | ||||
| "[+?\bsuspend\b is equivalent to \bkill -s STOP \"$$\"\b, except that " | ||||
| 	"it accepts no operands and refuses to suspend a login shell.]" | ||||
| "[+EXIT STATUS?]{" | ||||
| 	"[+0?The shell was successfully suspended and continued.]" | ||||
| 	"[+>0?An error occurred.]" | ||||
| "}" | ||||
| "[+SEE ALSO?\bkill\b(1)]" | ||||
| ; | ||||
| #endif /* defined(JOBS) && defined(SIGSTOP) */ | ||||
| 
 | ||||
| const char sh_optlet[]	= | ||||
| "[-1c?@(#)$Id: let (AT&T Research) 2000-04-02 $\n]" | ||||
| USAGE_LICENSE | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ const char e_option[]		= "%s: bad option(s)"; | |||
| const char e_toomany[]		= "open file limit exceeded"; | ||||
| const char e_argtype[]		= "invalid argument of type %c"; | ||||
| const char e_oneoperand[]	= "one operand expected"; | ||||
| const char e_toomanyops[]	= "too many operands"; | ||||
| const char e_formspec[]		= "%c: unknown format specifier"; | ||||
| const char e_badregexp[]	= "%s: invalid regular expression"; | ||||
| const char e_number[]		= "%s: bad number"; | ||||
|  |  | |||
|  | @ -86,6 +86,9 @@ extern int b_unalias(int, char*[],Shbltin_t*); | |||
| #   ifdef SIGTSTP | ||||
| 	extern int b_bg(int, char*[],Shbltin_t*); | ||||
| #   endif	/* SIGTSTP */ | ||||
| #   ifdef SIGSTOP | ||||
| 	extern int b_suspend(int, char*[],Shbltin_t*); | ||||
| #   endif	/* SIGSTOP */ | ||||
| #endif | ||||
| 
 | ||||
| /* The following utilities are built-in because of side-effects */ | ||||
|  | @ -131,6 +134,7 @@ extern const char	e_overlimit[]; | |||
| 
 | ||||
| extern const char	e_eneedsarg[]; | ||||
| extern const char	e_oneoperand[]; | ||||
| extern const char	e_toomanyops[]; | ||||
| extern const char	e_toodeep[]; | ||||
| extern const char	e_badname[]; | ||||
| extern const char	e_badsyntax[]; | ||||
|  | @ -172,6 +176,10 @@ extern const char sh_opthash[]; | |||
| extern const char sh_opthist[]; | ||||
| extern const char sh_optjobs[]; | ||||
| extern const char sh_optkill[]; | ||||
| #if defined(JOBS) && defined(SIGSTOP) | ||||
| extern const char sh_optstop[]; | ||||
| extern const char sh_optsuspend[]; | ||||
| #endif /* defined(JOBS) && defined(SIGSTOP) */ | ||||
| extern const char sh_optksh[]; | ||||
| extern const char sh_optlet[]; | ||||
| extern const char sh_optprint[]; | ||||
|  |  | |||
|  | @ -803,10 +803,6 @@ but can be unset or redefined: | |||
| .B "nameref=\(fmtypeset \-n\(fm" | ||||
| .TP | ||||
| .B "r=\(fmhist \-s\(fm" | ||||
| .TP | ||||
| .B "stop=\(fmkill \-s \s-1STOP\s+1\(fm" | ||||
| .TP | ||||
| .B "suspend=\(fmkill \-s \s-1STOP\s+1 $$\(fm" | ||||
| .PD | ||||
| .RE | ||||
| .SS Tilde Substitution. | ||||
|  | @ -7133,6 +7129,28 @@ Same as | |||
| .BR \|.\^ , | ||||
| except it is not treated as a special built-in command. | ||||
| .TP | ||||
| \f3stop\fP \f2job\^\fP .\|.\|. | ||||
| Sends a | ||||
| .B SIGSTOP | ||||
| signal to one or more processes specified by | ||||
| .IR job , | ||||
| suspending them until they receive | ||||
| .BR SIGCONT . | ||||
| The same as | ||||
| .BR kill\ -s\ STOP . | ||||
| .TP | ||||
| \f3suspend\fP | ||||
| Sends a | ||||
| .B SIGSTOP | ||||
| signal to the main shell process, suspending the script | ||||
| or child shell session until it receives | ||||
| .B SIGCONT | ||||
| (for instance, when typing | ||||
| .B fg | ||||
| in the parent shell). Equivalent to | ||||
| .BR kill\ -s\ STOP\ "$$" , | ||||
| except that it accepts no operands and refuses to suspend a login shell. | ||||
| .TP | ||||
| \f3times\fP | ||||
| Displays the accumulated user and system CPU times, one line with the times | ||||
| used by the shell and another with those used by all of the shell's child | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue