hush for non-mmu system

Denys Vlasenko vda.linux at googlemail.com
Tue Sep 2 09:13:07 UTC 2014


On Mon, Sep 1, 2014 at 3:58 PM, Waldemar Brodkorb
<mail at waldemar-brodkorb.de> wrote:
>> Let's find out how far do you get in this code
>> Add two debug statements:
>>
>>              childpid = waitpid(-1, &status, attributes);
>>              debug_printf("AFTER WAIT-1\n");   <<<THIS
>>
>> static void record_pending_signo(int sig)
>> {
>>         debug_printf("IN SIGHANDLER\n");   <<< THIS
>>         sigaddset(&G.pending_set, sig);
>>
>> rerun the test, and post the output.
>
> Sash command shell (version 1.1.1)
> /> hush
> unsetenv 'HUSH_VERSION'
> putenv 'HUSH_VERSION=1.22.1'
> set_local_var: putenv 'PWD=/'
> saved_tty_pgrp:35
> interactive_fd:255
> parse_stream entered, end_trigger=';'
>   o_addchr: '' o->length=0 o=0x41fe5d8c
>   done_command: initializing, num_cmds=0
>   setup_prompt_string 0   result '\w \$ '
> / # ls
>   file_get: got 'l' 108
>   : ch=l (108) escape=0
>   o_addchr: 'l' o->length=0 o=0x41fe5dd4
>   file_get: got 's' 115
>   : ch=s (115) escape=0
>   o_addchr: 's' o->length=1 o=0x41fe5dd4
>   file_get: got '
> ' 10
>   : ch=
>  (10) escape=0
>   o_addchr: '
> ' o->length=2 o=0x41fe5dd4
>   done_word entered: 'ls' 0x41d96a74
>   checking for reserved-ness: 0
>   word->o_assignment='NOT_ASSIGNMENT'
>   word appended to argv:
>  'ls'
>   done_word return 0
>   done_pipe entered, followup 1
>   done_command: ++num_cmds=1
>   done_pipe: adding new pipe: not_null:1 ctx->ctx_res_w:0
>   done_command: initializing, num_cmds=0
>   done_pipe return
>   heredoc_cnt:0
>   dest.o_assignment='MAYBE_ASSIGNMENT'
>   done_word entered: '' 0x41d96a74
>   done_word return 0: true null, ignored
>   done_pipe entered, followup 1
>   done_command: skipping null cmd, num_cmds=0
>   done_pipe return
>   dest.o_assignment='MAYBE_ASSIGNMENT'
>   as_string 'ls
> '
> parse_stream return 0x41d96a44: end_trigger char found
> pipe 0 res_word=NONE followup=1 SEQ
>  cmd 0 assignment_cnt:0 'ls'
> pipe 1 res_word=NONE followup=1 SEQ
> parse_and_run_stream: run_and_free_list
> run_and_free_list entered
> : run_list: 1st pipe with 1 cmds
> run_list start lvl 0
>   : rword=0 cond_code=0 last_rword=17
>   : run_pipe with 1 members
>   run_pipe start: members:1
>     : group:(nil) argv:'ls'
>     expand_vars_to_list: arg:'ls' singleword:0
>     expand_vars_to_list: list:(nil) n:0 string_start:0 length:0
> maxlen:0 glob:1 quoted:0 escape:1
>     start perform_glob: n:0 o->data:(nil)
>     list[0]=0 string_start=0 (growing)
>     expand_vars_to_list[0]: list:0x41d969bc n:1 string_start:64
> length:64 maxlen:64 glob:1 quoted:0 escape:1
>      list[0]=0 '' 0x41d969fc
>      total_sz:65
>     expand_vars_to_list[a]: list:0x41d969bc n:1 string_start:64
> length:64 maxlen:64 glob:1 quoted:0 escape:1
>      list[0]=0 '' 0x41d969fc
>      total_sz:65
>     expand_vars_to_list[b]: list:0x41d96e04 n:1 string_start:64
> length:67 maxlen:192 glob:1 quoted:0 escape:1
>      list[0]=0 'ls' 0x41d96e44
>      total_sz:67
>     expand_variables: list:0x41d96e04 n:1 string_start:64 length:67
> maxlen:192 glob:1 quoted:0 escape:1
>      list[0]=0 'ls' 0x41d96e44
>      total_sz:67
>     start perform_glob: n:1 o->data:0x41d96e04
>     glob pattern 'ls'
>     glob pattern 'ls' is literal
>     list[1]=3 string_start=64
>     finalized: list:0x41d96e04 n:2 string_start:64 length:67
> maxlen:192 glob:1 quoted:0 escape:1
>      list[0]=0 'ls' 0x41d96e44
>      list[1]=3 '' 0x41d96e47
>      total_sz:68
>     finalized n:2
>     expand_variables[1]:
>  'ls'
>     : pipe member 'ls' '(null)'...
>     execing 'ls'
>   run_pipe return -1 (1 children started)
>   checkjobs 0x41d96a44
> bin      dev      lib      media    proc     sbin     tmp      var
> boot     etc      linuxrc  mnt      root     sys      usr
>   IN SIGHANDLER
> />


This shows that signal handler fails to return properly.

Let's check whether it works with this simple program:

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
static void sighandler(int sig)
{
        write(1, "SIGNAL\n", 7);
}
int main()
{
        int pid;

        write(1, "VFORK1\n", 7);
        pid = vfork();
        if (pid == 0) {
                write(1, "EXIT1\n", 6);
                _exit(1);
        }
        wait(NULL);
        signal(SIGCHLD, sighandler);
        write(1, "VFORK2\n", 7);
        pid = vfork();
        if (pid == 0) {
                write(1, "EXIT2\n", 6);
                _exit(1);
        }
        wait(NULL);
        write(1, "EXIT\n", 5);
        return 0;
}

On my machine, it works like this:

$ gcc -Wall -Os t.c
$ ./a.out
VFORK1
EXIT1
VFORK2
EXIT2
SIGNAL
EXIT

i.e. signal handler did not mess up the parent.

What do you see?


More information about the busybox mailing list