Hacker News new | past | comments | ask | show | jobs | submit login

libuv supports child processes via fork, such as in uv_spawn. It also uses multiple threads to support uv_fs_stat, etc.

How does it handle the well known incompatibility between fork and threads?




Which incompatibility do you mean? If you're forking to create a child process, usually you're just careful not to do anything that might acquire a lock (including allocating memory) in between the fork and the exec, and then I think you're good?

Forking for something else, though, god help you.


The tricky part of this approach is error handling. What if a system call fails in between fork and exec, or exec itself?

It looks like libuv creates a pipe for every new process, and uses that to send errno back on any failing system call. This has the disadvantage that you only get the error code, and none of the context. You get ENOENT, but you don't know which path was invalid.


They could just write the entire error string to an fd, right? It's annoying in C to write a formatted string without doing dynamic allocations, but it's possible.

(Or, if you want to be weird, do a PTRACE_TRACEME after fork and have the parent trace the child process and only detach when it sees a successful return from execve. If ptrace is unavailable, fall back to less-useful errors)


Piping back the error string is probably the best one can do.


Do you need to know ? If you're fork/exec and get ENOENT, there's only one path that could relate to, the path to the program you wanted to run.


Or the path to the interpreter (e.g. if you're trying to run a x86-32 binary on an x86-64 system without 32-bit libc, or if you're trying to run a binary linked against glibc on a system with musl).


Fair enough - but there's still no more info you could learn from the ENOENT error.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: