[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