Remix.run Logo
cestith a day ago

The man page on macOS suggests that if you need the child to be a copy of the parent like you’d get after fork(), that you can fork() then exec() the same program in the child. That gives it enough independence to be safe.

Using fork() without exec() was once a tried and true way to have a parent manage one or more children that just run a different branch of the code after the fork. It doesn’t work as well when you have a lot of async and a lot of fired signals right after forking, though. It gets worse if your signal handlers do more than, for example, assigning a value to a scalar variable and that’s honestly partially true of signal handlers no matter whether you’ve forked or not. That’s probably why Go blocks signals during that time after a fork(), for better or worse. So, TL;DR, if you need to run a child with the same code as the parent, exec() a copy like the manpage suggests especially on macOS.

It’s a shame old Unix code that used this model won’t work as well as they used to across different Unix flavors. At least it's not much hassle to fix.