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
8
NEWS
8
NEWS
|
@ -3,6 +3,14 @@ For full details, see the git log at: https://github.com/ksh93/ksh
|
|||
|
||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||
|
||||
2020-06-22:
|
||||
|
||||
- The 'stop' and 'suspend' default aliases have been converted into regular
|
||||
built-in commands, so that 'unalias -a' does not remove them, 'suspend'
|
||||
can do a couple of sanity checks, and something like
|
||||
cmd=stop; $cmd $!
|
||||
will now work. See 'stop --man' and 'suspend --man' for more information.
|
||||
|
||||
2020-06-20:
|
||||
|
||||
- Fixed a bug that caused setting the following variables as readonly in
|
||||
|
|
4
TODO
4
TODO
|
@ -29,13 +29,11 @@ Fix or remove broken or misguided default aliases:
|
|||
- functions='typeset -f'
|
||||
- integer='typeset -li'
|
||||
- nameref='typeset -n'
|
||||
- stop='kill -s STOP'
|
||||
- suspend='kill -s STOP $$'
|
||||
Keep these default aliases for the benefit of interactive shells:
|
||||
+ history='hist -l'
|
||||
+ r='hist -s'
|
||||
To avoid interfering with shell functions by those names that POSIX
|
||||
scripts may set, those should only intialise on interactive shells.
|
||||
scripts may set, those should only initialise on interactive shells.
|
||||
|
||||
______
|
||||
Fix currently known bugs affecting shell scripting. These are identified by
|
||||
|
|
|
@ -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