hush: initial trap support
Denys Vlasenko
vda.linux at googlemail.com
Sun Mar 29 21:57:32 UTC 2009
On Sun, Mar 29, 2009 at 10:29 PM, Mike Frysinger <vapier at gentoo.org> wrote:
> On Sunday 29 March 2009 15:53:16 Denys Vlasenko wrote:
>> 2009/3/29 Mike Frysinger <vapier at gentoo.org>:
>> > On Sunday 29 March 2009 11:24:10 Denys Vlasenko wrote:
>> >> (a) I prefer all data to go to struct globals, never to .data.
>> >> (b) It would be nice to allocate it on first use, it's big
>> >> (so that scripts which never use traps don't waste memory for it).
>> >> (c) int sig; const char *name; is wasting 8 bytes,
>> >> uint8_t sig; char name[7]; is more compact.
>> >> (d) libbb has get_signum(str) which already does signal name or number
>> >> -> signal number conversion. get_signame(num) is an opposite convertor.
>> >> Use them, this allows you to not duplicate signal names.
>> >
>> > using the common sig funcs to do translation allows for quite a bit of
>> > reduction. delaying the alloc also saves on bloat. i was hoping there
>> > was a way we could unify the code so that hush wouldnt have to
>> > save/restore the sigaction at all though.
>>
>> This is possible, but is it worth the trouble? struct sigaction is not
>> THAT big. Let's make it work correctly first.
>
> fair enough. next iteration attached.
+ sig = bb_strtou(argv[i], NULL, 10);
+ if (errno)
+ sig = get_signum(argv[i]);
get_signum() already does this check for "numericity".
+ if (strcmp(argv[1], "-") == 0)
+ /* nothing! */;
+ else
+ new_cmd = argv[1];
+ if (strcmp(argv[1], "") == 0)
Smaller code would be:
+ if (LONE_CHAR(argv[1], '-'))
+ /* nothing! */;
+ else
+ new_cmd = argv[1];
+ if (argv[1][0] == '\0')
Otherwise looks ok, please apply, unless you want to go all the way
and implement "delayed handling" correctly.
Basically, traps need to be executed after each pipe (i.e. cmd | cmd | cmd
construct) has finished. Signal handler needs to only
record which signals were received (a bitmask is ideal for that)
and return at once.
Bitmask needs to be checked here (my added pseudo-code
is at column 1):
rcode = r = run_pipe(pi); /* NB: rcode is a smallint */
if (r != -1) {
/* we only ran a builtin: rcode is already known
* and we don't need to wait for anything. */
// pipe completed. example: echo Hi
if bitmask != 0, handle all traps
...
...
} else if (pi->followup == PIPE_BG) {
/* what does bash do with attempts to
background builtins? */
/* even bash 3.2 doesn't do that well
with nested bg:
* try "{ { sleep 10; echo DEEP; } &
echo HERE; } &".
* I'm NOT treating inner &'s as jobs */
// pipe is bg'ed: example: sleep 9 &
if bitmask != 0, handle all traps
...
...
} else {
#if ENABLE_HUSH_JOB
if (G.run_list_level == 1 && G.interactive_fd) {
// pipe created children. waiting
/* waits for completion, then
fg's main shell */
rcode = checkjobs_and_fg_shell(pi);
if bitmask != 0, handle all traps
debug_printf_exec(":
checkjobs_and_fg_shell returned %d\n", rcode);
} else
#endif
{ /* this one just waits for completion */
rcode = checkjobs(pi);
if bitmask != 0, handle all traps
debug_printf_exec(": checkjobs
returned %d\n", rcode);
}
--
vda
More information about the busybox
mailing list