Oh, and posix_spawn_file_actions_init() should return errno, not -1,
if malloc(3) fails.

On Fri, Mar 9, 2012 at 10:54 AM, Matthew Dempsky <matt...@dempsky.org> wrote:
> On Thu, Mar 8, 2012 at 1:24 PM, Frank Denis <a...@me.com> wrote:
>> See http://download.pureftpd.org/misc/OpenBSD/patches/posix_spawn.diff
>
> Hi Frank,
>
> I briefly looked over this code, and the diff looks good to me except
> for one subtle FreeBSDism: memory writes done in a vfork(2)'d child
> process will not affect the parent process.  This is critical for how
> FreeBSD's posix_spawn() propagates errors from the spawned child
> process.
>
> I haven't tested this, but I suspect if (e.g.) you try to
> posix_spawn() a non-existent program, that posix_spawn() will still
> return a successful return value.
>
> Instead of using a volatile int on the stack, you'll need to allocate
> some extra memory using mmap and MAP_SHARED.  E.g., see the sample
> program below.
>
> If you can fix that, I think it's good to commit.  Some regress tests
> would be good too though.  (However, I'll be offline until March 18
> though, so someone else will need to actually commit it.)
>
> Thanks!
>
>
> $ ./beep
> error=42
>
> $ cat beep.c
> #include <sys/mman.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <err.h>
>
> int main()
> {
>  void *mem;
>  volatile int *errorp;
>
>  mem = mmap(0, sizeof(*errorp), PROT_READ|PROT_WRITE,
>   MAP_SHARED|MAP_ANON, -1, 0);
>  if (mem == MAP_FAILED) err(100, "mmap");
>  errorp = mem;
>  *errorp = 0;
>
>  switch (vfork()) {
>  case -1: err(100, "vfork\n"); return 0; break;
>  case 0: *errorp = 42; return 0; break;
>  }
>
>  printf("error=%d\n", *errorp);
>  if (munmap(mem, sizeof(*errorp)) == -1) err(100, "munmap");
>  return 0;
> }

Reply via email to