1
0
Fork 0
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:
Martijn Dekker 2020-06-22 14:59:24 +02:00
parent add82e1984
commit 3ba4900e9c
8 changed files with 108 additions and 11 deletions

8
NEWS
View file

@ -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
View file

@ -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

View file

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

View file

@ -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
};

View file

@ -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

View file

@ -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";

View file

@ -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[];

View file

@ -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