Michael Norrish wrote:
It turns out that on Mac OS X execv returns ENOTSUP if the process is multi-threaded. You need to use Posix.Process.fork first to start a new process: case Posix.Process.fork() of SOME _ => OS.Process.exit OS.Process.success | NONE => Posix.Process.exec("/bin/ls", ["ls"]);
Hmm. Thanks for going to the trouble of figuring this out. Is it clear what exit code the invoker will get in this situation? It looks to me as if it will get success, regardless of what happens in the forked child. If that's what happens, my feeling is that it's a bug (in Apple's design), and I'll have to have the parent hang around waiting for the child to finish. Of course, this is exactly what I was hoping to avoid by using exec in the first place. And it is important to get the right error code because it's all part of a build system that needs to know when to stop and when to continue.
(I just did a very simple-minded test which seemed to confirm that the exec-ed process's code is indeed lost if you use the idiom above. Boo hiss.)
In the above code the invoker will return immediately with "success". It ought to be possible to modify the code to use Posix.Process.waitpid to wait for the child process. Possibly something along the lines of SOME pid => (case Posix.Process.waitpid(Posix.Process.W_CHILD pid, []) of W_EXITED => OS.Process.exit OS.Process.success | W_EXITSTATUS n => Posix.Process.exit n | _ => ??? ) However you do this you probably want to avoid using Posix.Process.fork on Cygwin (if that's relevant) since it's very expensive so it might be a good idea to try using Posix.Process.exec first and only use "fork" if you get ENOTSUP. It would certainly be worth looking at Makarius' code.
This does look like something non-standard in Apple's code. The detailed page for Posix "exec" simply says, "A call to any exec function from a process with more than one thread shall result in all threads being terminated and the new executable image being loaded and executed. No destructor functions or cleanup handlers shall be called."
David