rmyorston / busybox-w32

WIN32 native port of BusyBox.
https://frippery.org/busybox
Other
674 stars 124 forks source link

Does $! work? #375

Open DocMAX opened 10 months ago

DocMAX commented 10 months ago

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?

rmyorston commented 10 months ago

When a Unix shell needs to run a command in the background it:

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:

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.