News for hackers. Stuff that matters.
Re:Hacking the OS X Kernel for Fun and Profiles by mikeash on Tuesday August 13, 2013 @03:12PM (#6207623)
Last time I checked on this, there was no safe way (i.e. using only async-signal-safe calls) to list the contents of /dev/fd post-fork. Did I miss something?
Re:Hacking the OS X Kernel for Fun and Profiles by klodolph on Tuesday August 13, 2013 @03:58PM (#6207890)
You can call functions that aren't async-signal-safe after a fork(). The standard library has prefork handlers that fire ensuring that you can e.g. opendir() safely after fork(), even if another thread was halfway through malloc() at the time of the fork.

Forking + threads is very messy, but it's not quite that pathological. I'd like to see an interface similar to posix_spawn() become the norm for spawning processes, with a fallback to fork()+exec() for more difficult use cases, but I don't think posix_spawn() is good enough.

Re:Hacking the OS X Kernel for Fun and Profiles by mikeash on Tuesday August 13, 2013 @04:02PM (#6207909)
Well, the man page says otherwise, and I'd hate to rely on undocumented safety buried in the standard library.

Edit: upon re-reading the man page, this bit caught my eye:

"If you need to use these frameworks in the child process, you must exec. In this situation it is reasonable to exec yourself."

So that would be one (highly painful) way to handle this safely. Fork, then self-exec, passing in arguments that tell the newly execed process what you really want to run. The new process can then do the /dev/fd listing in peace, then call exec again. Eww.

Re:Hacking the OS X Kernel for Fun and Profiles by klodolph on Tuesday August 13, 2013 @04:20PM (#6208027)
Seems like you're right. Whoops, time to go fix some of my code, which is why I really want a non-broken posix_spawn().

Another silly way to do things is to have the parent process send a list of fds to close over a pipe, which at least doesn't require a second call to exec().

I think the problem with close-on-exec is always going to be simple though: you have to make sure every library you use sets the flag.

Re:Hacking the OS X Kernel for Fun and Profiles by bdash on Tuesday August 13, 2013 @04:33PM (#6208089)
OS X provides the POSIX_SPAWN_CLOEXEC_DEFAULT flag to posix_spawn, which results in it automatically closing all file descriptors that aren't described by the file actions passed to posix_spawn.
Re:Hacking the OS X Kernel for Fun and Profiles by asveikau on Tuesday August 13, 2013 @08:22PM (#6209235)
It's interesting that starting a new process in a signal handler is something you want to do. (I just searched and yes I understand fork() and exec() are spec'd by POSIX to be safe.) It seems like writing safe signal handlers is hard enough, making them multiprocess seems like a "now you have two problems" kind of thing.

I suppose if I am not mistaken you could go the pre-readdir() route and open a directory with open() and read it with read(). Probably a portability mess though.

Re:Hacking the OS X Kernel for Fun and Profiles by mikeash on Wednesday August 14, 2013 @10:37AM (#6211740)
I don't think it's so much that starting a new process in a signal handler is an intended use case, but rather than the post-fork environment is very similar to the signal handler environment, and so calls that work in one will work in the other.

(In both cases, you can't count on currently acquired locks ever being released. In a signal handler, this is because it could be acquired on the current thread, and post-fork, this is because all other threads have been killed from the perspective of the child process. As such, no lock-based code can safely be called.)