Thread overview
[Issue 14770] std.process should use lightweight forks where available
Jul 07, 2015
David Soria Parra
Jul 30, 2018
Hiroki Noda
Aug 01, 2018
anonymous4
Aug 02, 2018
Hiroki Noda
Dec 17, 2022
Iain Buclaw
July 06, 2015
https://issues.dlang.org/show_bug.cgi?id=14770

Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@kyllingen.net,
                   |                            |schveiguy@yahoo.com

--- Comment #1 from Steven Schveighoffer <schveiguy@yahoo.com> ---
CC'ing Lars, this is a good idea.

--
July 07, 2015
https://issues.dlang.org/show_bug.cgi?id=14770

David Soria Parra <dsp@experimentalworks.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dsp@experimentalworks.net

--- Comment #2 from David Soria Parra <dsp@experimentalworks.net> ---
https://github.com/D-Programming-Language/phobos/pull/3476

I opted for using vfork. It seems we are in all cases doing the right thing, not tempering with the process space and correctly calling execv* or _exit.

It seems that the "correct" method would be using posix_spawn, however we need support for this in druntime, so at the moment, I think going with vfork is less invasive while providing the proposed enhancements.

--
July 31, 2015
https://issues.dlang.org/show_bug.cgi?id=14770

--- Comment #3 from Lars T. Kyllingstad <bugzilla@kyllingen.net> ---
I think the "correct" thing to do here (on Linux, at least) is to use the
clone() function, as described in this article:


http://blog.famzah.net/2009/11/20/a-much-faster-popen-and-system-implementation-for-linux/

NOTE: If anyone wants to take a stab at implementing this for Phobos, don't look at the actual source code for the "popen-noshell" library, as it is LGPL-licensed.

Both clone() and vfork() are GNU library wrappers around Linux' clone system
call, but clone() allows a much finer control over which data gets copied into
the new process. Unlike vfork(), however, clone() is not a drop-in replacement
for fork(). It takes a function to execute and a stack space in which to
execute it, as opposed to continuing execution from the same point in the child
process. In other words, there's a bit more work needed to incorporate it in
spawnProcess().

Note that vfork() seems to be generally frowned upon; see for example the NOTES section of the man page:

    http://man7.org/linux/man-pages/man2/vfork.2.html#NOTES

--
July 30, 2018
https://issues.dlang.org/show_bug.cgi?id=14770

Hiroki Noda <kubo39@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kubo39@gmail.com

--- Comment #4 from Hiroki Noda <kubo39@gmail.com> ---
tl;dr: I think spawnProcess uses vfork internally iff Linux available.

* We must care about the process privilege, since if the parent process or
child process can change effective UID/GID, different privileged processes
shares memory.
* We must use _exit(2), same as before.
* signal handlers may rewrite global variables, so set SIG_DFL before vfork.
* Solaris has bug.
* Other platform planed(e.g, NetBSD has nice posix_spawn systemcall), but not
implement now.

Okay, I try to do this.

## References.

* posix_spawn(3) requires glibc 2.24+.
* posix_spawn(IEEE Std 1003.1-2008) cannot specifies working directory(chdir).
* http://www.tedunangst.com/flak/post/OpenBSD-and-vfork OpenBSD's vfork doesn't
share memory.
*
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9ff72da471a509a8c19791efe469f47fa6977410
glibc's posix_spawn uses clone(2) instead of vfork(2).
* https://bugs.ruby-lang.org/issues/11265#note-8 In Solaris, vfork causes
dynamic linker problem.
* https://github.com/golang/go/commit/9e6b79a5dfb2f6fe4301ced956419a0da83bd025
Go uses clone(CLONE_VFORK | CLONE_VM,..) Linux only.
* https://github.com/rust-lang/rust/pull/48624 Rust uses posix_spawn(3) on
FreeBSD/macOS/Linux.

--
July 30, 2018
https://issues.dlang.org/show_bug.cgi?id=14770

--- Comment #5 from Steven Schveighoffer <schveiguy@yahoo.com> ---
FYI, new PR by Hiroki Nada: https://github.com/dlang/phobos/pull/6644

--
August 01, 2018
https://issues.dlang.org/show_bug.cgi?id=14770

--- Comment #6 from anonymous4 <dfj1esp02@sneakemail.com> ---
Maybe have a branch for linux and call clone there, call posix_spawn or fork for other systems. vfork looks scary and posix deprecated it.

--
August 02, 2018
https://issues.dlang.org/show_bug.cgi?id=14770

--- Comment #7 from Hiroki Noda <kubo39@gmail.com> ---
(In reply to anonymous4 from comment #6)
> Maybe have a branch for linux and call clone there, call posix_spawn or fork for other systems. vfork looks scary and posix deprecated it.

If we use clone(2), the stack of the child process is newly allocated and the stack of the parent process is not shared. It's preferred.

Maybe I should add clone(2) to druntime before...

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9ff72da471a509a8c19791efe469f47fa6977410

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=14770

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--