Open DocMAX opened 10 months ago
When a Unix shell needs to run a command in the background it:
fork(2)
to create a new process as a duplicate of the current shell. This is necessary to set up the correct execution environment for the new process. The value of $!
is set to the PID of this process.exec(2)
to execute the required command in that process, replacing the second shell.Windows doesn't have separate fork()
and exec()
functions, instead it has spawn()
functions in the C runtime and CreateProcess()
in the WIN32 API. These create a new process and execute a binary within it.
busybox-w32 has to work with what's available to it. Thus, when the shell has to execute a background command:
spawn()
to create a copy of the current shell. The PID of this process is put in $!
.spawn()
to execute it. There is no exec(2)
on Windows.On Unix there are two processes involved, on Windows there are three. On Windows:
~ $ ./sleep 100 &
[1] 3220
~ $ ps
988 1204 rmy 0:00 1h08 sh -l
3220 988 rmy 0:00 0:11 sh --fs 0000019C
2820 3220 rmy 0:00 0:11 sleep.exe
~ $
(The output of ps
has been edited to show only the relevant processes.)
The PID reported for the background command is 3220, but that's the second shell. The PID of the actual command here is 2820.
That's what happens when an external program has to be run. As an optimisation, if the second shell finds that the required command is a BusyBox applet it can emulate exec(2)
by running the main function of the applet in the current process. In this case we get:
~ $ sleep 100 &
[1] 1616
~ $ ps
988 1204 rmy 0:00 1h08 sh -l
1616 988 rmy 0:00 0:03 sleep 100
~ $
There are only two processes and $!
has the correct PID.
Can it be fixed for external commands? I haven't come up with anything yet.
I try to run some exe.. myapp.exe & echo $!. The returned PID is not the exes one, but another busybox.exe instance. Can it be fixed or isn't $! supported at all?