[Toybox] [musl] toybox: Rough edges in pending
Szabolcs Nagy
nsz at port70.net
Tue Mar 19 04:09:39 PDT 2013
* Szabolcs Nagy <nsz at port70.net> [2013-03-19 10:42:25 +0100]:
> * Isaac Dunham <idunham at lavabit.com> [2013-03-18 23:50:43 -0700]:
> > execve("./toybox-musl", ["./toybox-musl", "sh", "-c", "ls"], [/* 22 vars */]) = 0
> ...
> > ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B9600 opost isig icanon echo ...}) = 0
> > vfork(Config.in README kconfig scripts toybox_unstripped toys.h
> > LICENSE configure lib toybox toynet.h www
> > Makefile generated main.c toybox-musl toys
> > ) = 27832
> > --- SIGCHLD (Child exited) @ 0 (0) ---
> > wait4(27832, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 27832
> > pause(^C <unfinished ...>
>
> exit tries to flush some stdio buffers but it is locked
>
> maybe an issue around the way vfork is used by the shell
this is what toybox sh does:
cmd->pid = vfork();
if (!cmd->pid) xexec(cmd->argv);
else waitpid(cmd->pid, &status, 0);
it's an incorrect use of vfork
either exec or _exit should be called after vfork but
xexec calls toy_exec that runs ls in-place then calls
exit (so the exit lock gets locked hence the
deadlock when the parent tries to exit)
void xexec(char **argv)
{
toy_exec(argv);
execvp(argv[0], argv);
perror_exit("exec %s", argv[0]);
}
void toy_exec(char *argv[])
{
struct toy_list *which;
which = toy_find(argv[0]);
if (!which) return;
toy_init(which, argv);
toys.which->toy_main();
if (fflush(NULL) || ferror(stdout)) perror_exit("write");
exit(toys.exitval);
}
More information about the Toybox
mailing list