| This is how hush runs commands: |
| |
| /* callsite: process_command_subs */ |
| generate_stream_from_list(struct pipe *head) - handles `cmds` |
| create UNIX pipe |
| [v]fork |
| child: |
| redirect pipe output to stdout |
| _exit(run_list(head)); /* leaks memory */ |
| parent: |
| return UNIX pipe's output fd |
| /* head is freed by the caller */ |
| |
| /* callsite: parse_and_run_stream */ |
| run_and_free_list(struct pipe *) |
| run_list(struct pipe *) |
| free_pipe_list(struct pipe *) |
| |
| /* callsites: generate_stream_from_list, run_and_free_list, pseudo_exec, run_pipe */ |
| run_list(struct pipe *) - handles "cmd; cmd2 && cmd3", while/for/do loops |
| run_pipe - for every pipe in list |
| |
| /* callsite: run_list */ |
| run_pipe - runs "cmd1 | cmd2 | cmd3 [&]" |
| run_list - used if only one cmd and it is of the form "{cmds;}" |
| forks for every cmd if more than one cmd or if & is there |
| pseudo_exec - runs each "cmdN" (handles builtins etc) |
| |
| /* callsite: run_pipe */ |
| pseudo_exec - runs "cmd" (handles builtins etc) |
| exec - execs external programs |
| run_list - used if cmdN is "(cmds)" or "{cmds;}" |
| /* problem: putenv's malloced strings into environ - |
| ** with vfork they will leak into parent process |
| */ |
| /* problem with ENABLE_FEATURE_SH_STANDALONE: |
| ** run_applet_no_and_exit(a, argv) uses exit - this can interfere |
| ** with vfork - switch to _exit there? |
| */ |