| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Some installer programs have an entry in their manifest to indicate
that they need elevated privileges. The shell in busybox-w32 was
unable to run such programs.
When a program fails to run with ERROR_ELEVATION_REQUIRED, try
again using ShellExecuteEx() with the 'runas' verb to give it
elevated privileges.
Adds 272-288 bytes.
(GitHub issue #481)
|
|
|
|
|
| |
Compiling with FEATURE_SH_NOFORK disabled resulted in an error and
a warning. Fixing these doesn't change the default build.
|
|
|
|
|
|
|
|
| |
Alter quote_arg() to perform a single pass over the string in the
case where no change is required. Based on a proposal by @avih in
GitHub PR #317.
Saves 16 bytes.
|
|
|
|
|
|
|
|
|
| |
If a process performing an exec is an orphan there's no reason for
it to wait for its child's exit code. Let it exit immediately.
Adds 16 bytes.
(GitHub issue #461)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'kill -9' was found to fail with an 'Invalid argument' error.
This is a regression introduced by commit 569de936a (kill: killing
a zombie process should fail).
Use the correct argument to OpenProcess() for SIGKILL so it can
query the exit code of the target process.
Adds 16 bytes.
(GitHub issue #465)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It proved to be almost impossible to interrupt a loop like:
while true; do sleep 1; done
where 'sleep' was an external program, not an applet. The issue
was introduced by commit 0475b7a64 (win32: convert exit codes).
This passed a POSIX error code to the exit() in wait_for_child()
so a parent was unable to detect when its child was interrupted.
Pass the Windows exit code to exit() instead. Work around the
changes introduced by commit 790e377273 (win32: revert 'don't set
error mode').
Adds 16-32 bytes.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The BusyBox shell detects certain cases where forking a command is
unnecessary (last command in a script or subshell, for example) and
calls execve(2) instead. This doesn't help in the Windows port
because execve(2) is implemented by creating a process.
There is one case where it is possible to apply this optimisation:
if the command is a script and the script interpreter is an applet.
- Have evalcommand() pass a flag to indicate this situation to
shellexec(). Also, allocate two spare elements before the start
of the argv array.
- If the flag is TRUE shellexec() passes the shell's PATH variable
down to tryexec() so it can perform a test for applet override.
- If tryexec() finds that all the necessary conditions apply it
can run a script by directly invoking the interpreter's main().
Adds 192-224 bytes.
|
|
|
|
|
| |
Add the FAST_FUNC qualifier to several Windows-specific functions.
This has no effect in 64-bit builds but saves 336 bytes for 32-bit.
|
|
|
|
|
|
|
| |
Rewrite mingw_spawn_interpreter() to remove a duplicated recursive
call.
Saves 32-48 bytes.
|
|
|
|
| |
Saves 16 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit eb376b5d1 (win32: don't set error mode) removed a call to
SetErrorMode(SEM_FAILCRITICALERRORS).
But the documentation says:
Best practice is that all applications call the process-wide
SetErrorMode function with a parameter of SEM_FAILCRITICALERRORS
at startup. This is to prevent error mode dialogs from hanging
the application.
Doing this prevents the system from displaying useful information,
though. The application should attempt to tell the user what went
wrong.
Reinstate the call to SetErrorMode() and try to provide an error
message, at least for the situation mentioned in issue #423 and
other similar cases.
Adds 360-368 bytes.
(GitHub issue #423)
|
|
|
|
|
|
|
|
| |
Merge the kill() and kill_pids() functions.
Allocate an array for the PIDs rather than use a hardcoded one.
Adds 32 bytes to the 32-bit build, none to 64-bit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
busybox-w32 had a dummy implementation of getppid(2) which always
returned 1. Provide a more realistic version.
The effect is limited:
- The PPID shell variable should report a sensible value.
- The special value to omit the parent PID 'pidof -o %PPID'
should work.
Costs 48 bytes.
|
|
|
|
|
|
|
|
|
|
|
| |
Recent changes to allow orphaned processes to report a parent PID
of 1 rely on the assumption that Process32First/Process32Next
return parents before children. This isn't guaranteed by the API.
Obtain all known PIDs on the first call to procps_scan() so that
dead parents can be detected reliably.
Costs 48 bytes.
|
|
|
|
| |
Saves 16-32 bytes
|
|
|
|
|
|
|
|
|
|
| |
If the parent PID doesn't appear in the process table, report it
as 1. This more closely matches how orphaned children are handled
on UNIX.
Adds 96-128 bytes.
(GitHub issue #416)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A process which has exited may still have its process handle
held open by its children. Such a process doesn't appear in
the process table. It is thus similar to a zombie process in
UNIX. Using kill(1) to interact with such a process was seen
to succeed, contrary to expectation.
The code for "ordinary" signals in kill(2) did check if the
process was still active but didn't treat an attempt to kill
an inactive process as an error. Furthermore, sending SIGKILL
or the fake signal 0 to a process didn't even check if the
process was still active.
Rearrange the implementation of kill(2) so that an attempt to
signal an inactive process is treated as an error. This also
consolidates handling of SIGKILL and signal 0 with "ordinary"
signals.
Saves 96 bytes.
(GitHub issue #416)
|
|
|
|
|
|
|
|
|
| |
When httpd is run in the background its processes are detached
from the console. CGI scripts could create subprocesses which
needed a console, resulting in annoying console windows appearing.
Prevent this by changing the creation flags for CGI scripts to
CREATE_NO_WINDOW.
|
|
|
|
|
|
| |
Use getpid() instead of GetProcessId(GetCurrentProcess()).
Saves 16 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
create_detached_process() is only used when running a CGI script.
Previously it leaked the return values from quote_arg() but freed
the command line it built.
Whether or not the CGI script is successfully run its parent process
exits almost immediately, so there's no pressing need to free the
memory. If FEATURE_CLEAN_UP is disabled (which it is by default)
don't bother.
Saves 16 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The upstream code uses fork/exec when running a CGI process.
Emulate this by:
- Spawning a child httpd process with the special '-I 0' option,
along with the options provided on the server command line. This
sets up the proper state then calls the cgi_handler() function.
- The cgi_handler() function fixes the pipe file descriptors and
starts another child process to run the CGI script.
These processes are detached from the console on creation. When
spawn() functions are run in P_DETACH mode they don't connect to
the standard file descriptors. Normally this doesn't matter but
the process which runs the CGI scripts needs to inherit the pipe
endpoints. The create_detached_process() function handles this.
See:
https://github.com/rprichard/win32-console-docs/blob/master/README.md
Adds about 2.9Kb to the size of the binary.
(GitHub issue #266)
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 6d6856355a (win32: handle -1 return status from execve(2))
added a test of errno to distinguish between failure to run a
program and the program returning -1.
Subsequent changes in commit 9db9b34ada (win32: ignore ctrl-c in
parent of execve(2)) make this test unnecessary. Remove it.
Saves 16-32 bytes.
|
|
|
|
|
|
|
|
|
|
|
| |
When httpd was run in the background the return code of the parent
process was incorrect. It seems when spawn() is run in _P_DETACH
mode it returns 0 on success, not a process handle.
Fix the test for the return code and alter mingw_spawn_detach()
so it doesn't treat the return from spawn() as a handle.
Saves 32 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add two utility functions to convert Windows process exit codes.
- exit_code_to_wait_status() converts to a POSIX wait status.
This is used in ash and the implementations of system(3) and
mingw_wait3().
- exit_code_to_posix() converts to a POSIX exit code. (Not that
POSIX has much to say about them.)
As a result it's possible for more applets to report when child
processes are killed as if by a signal. 'time', 'drop' and 'su -W',
for example.
Adds 64-80 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Make the following changes to BB_OVERRIDE_APPLETS:
- Applet names in the list can be separated by spaces, commas or
semicolons.
- Applets before the first semicolon are disabled unconditionally.
- Applets after the first semicolon are overridden if a matching
external command exists.
- '-' alone disables all applets.
- '+' alone overrides every applet for which a matching external
command exists.
This doesn't change the existing documented behaviour. It adds
the ability to have applets overridden if an external command
exists but to remain available if not.
Adds 80-88 bytes.
(GitHub issue #329)
|
|
|
|
|
|
|
|
|
| |
Commit 20b6a57af (win32: crtl-c interrupts non-console applications)
introduced a test for non-console apps in the Ctrl-C handler.
Skip this if GetConsoleProcessList() isn't available.
Costs 68-88 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 9db9b34ad (win32: ignore ctrl-c in parent of execve(2))
prevented a parent process from reacting to Ctrl-C while it was
waiting for its child to complete. This avoids the problem where
a shell and an interactive child end up competing for input after
a Ctrl-C.
However, a child process which isn't attached to the console
(a GUI application, for example) can't then be killed by Ctrl-C.
Instead of completely ignoring Ctrl-C give the parent a handler
which detects if its child is attached to the console. If so it's
left to handle Ctrl-C itself and the parent ignores the interrupt.
If not the parent terminates the child and all its children as if
by SIGINT.
Costs 200 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Use an exit code of the form (signal << 24) when a process exits
due to a signal. This replaces the previous use of (signal + 128).
This makes it easier to distinguish exit codes from signals.
Allow kill(2) to handle all defined signals, not just EXIT, TERM
and KILL.
The kill and timeout applets now accept any defined signals.
Convert certain Windows status codes Unix-style signal codes.
In ash:
- Exit as if with SIGINT in raise_interrupt() rather than call
raise(SIGINT). The latter returns an exit code of 3.
- Detect if a child process exits as if with SIGINT. If not and if
the parent is an interactive top-level shell, reset pending_int.
This prevents the parent from seeing an INT if the child hasn't
reported it exited due to INT. (Probably due to it being an
interactive shell.)
Costs 132-136 bytes.
|
|
|
|
|
|
|
|
| |
Squeeze a few more bytes out of quote_args().
(Thanks to GitHub user avih.)
Saves 16 bytes.
|
|
|
|
|
|
|
| |
There are two places where a copy of an argv array is made with
extra space at the start. Move this code into a function.
Saves 56-64 bytes.
|
|
|
|
|
|
|
|
| |
Report 'Arg list too long' rather than 'Invalid argument' when
spawnveq() detects that the EINVAL return from spawnve() is due to
the command line being too long.
Costs 48-64 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Replace parts of quote_args() with code from avih's GitHub
PR #317.
This overestimates the size of the buffer to avoid having to
calculate the exact size.
Retain the code to determine whether the argument needs to be
quoted. Quoting arguments unconditionally wastes space on the
command line and causes the test "xargs argument line too long"
to fail.
Saves 144-176 bytes.
|
|
|
|
|
|
|
|
| |
Commit 9581d2396 (win32: fix incorrect path search in spawnvp)
fixed the unwanted PATH search for relative or absolute paths but
broke the desired PATH search for Unix-style paths.
(GitHub issue #310)
|
|
|
|
|
|
|
|
|
| |
Commit 26ba73098e (win32: search PATH for missing Unix-style
executables) rearranged the code of mingw_spawnvp(). As a
result commands with a relative or absolute path could be
incorrectly searched for on PATH.
(GitHub issue #310)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The execve(2) system call is emulated for Microsoft Windows. This
requires the creation of a new process. The old process remains
active, waiting for the "execed" child to exit so it can pass on
its exit status.
Previously this was achieved using P_WAIT mode in the call to
spawnve(). However the parent of the execve(2) process may still
be able to catch Ctrl-C interrupts. This can lead to unwanted
behaviour, such as a shell and its children competing for input.
Force the waiting process to ignore Ctrl-C interrupts.
Costs 64-80 bytes.
(GitHub issue #303)
|
|
|
|
|
|
|
|
|
| |
Make quote_arg() always return an allocated string so we can free
it unconditionally.
Always use argv[1] as the first part of the command string.
Saves 48 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The 'drop' alias for 'runuser' relaxes a number of constraints
that were introduced for compatibility:
- It works even if the current process doesn't have elevated
privileges.
- It isn't necessary to specify the name of the user.
- Any command can be invoked, not just the BusyBox shell.
- If the command doesn't specify a path 'drop' will first look for
a BusyBox applet then search PATH.
Adds 320-336 when built along with runuser.
(GitHub issue #240)
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a function, file_is_win32_exe(), to detect if a path refers
to an executable. It tries adding extensions if necessary.
Use this in a number of places to replace common code of the form
path = alloc_ext_space(cmd);
if (add_win32_extension(path) || file_is_executable(path))
Saves 32-48 bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a cut down, Windows-specific implementation of `runuser` from
util-linux.
This allows elevated privileges to be dropped when running in an
SSH session. It also works when using `su` or starting busybox-w32
'as administrator'.
There are complications:
- The method used to drop privileges leaves the access token in the
TokenIsElevated state. Detecting this is likely to be fragile.
- The unprivileged shell is started by CreateProcessAsUserA(). In
older versions of Windows this has to be loaded dynamically.
Adds about 900 bytes.
(GitHub issue #240)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 605972390 (win32: handle Unix-style absolute paths for
executables) added special treatment of paths for executables
starting with a slash. Such paths are absolute on Unix but are
relative to the current drive on Windows. On reflection this
commit did more than necessary. Later commits provided special
treatment only for paths starting with locations traditionally
used to contain binaries on Unix. This is probably sufficient.
Problems introduced by commit 605972390 include:
- If the current drive isn't the system drive tab completion of a
command starting with a slash confusingly references the system
drive.
- Building busybox-w32 with w64devkit fails on drives other than
the system drive.
Revert the changes introduced by commit 605972390.
This saves 192 bytes.
(GitHub issue #239)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 41ef232fc5 (win32: use built-in applets for non-existent
binaries with Unix-style paths) alters what happens when trying
to find an executable. If all of the following apply:
- the pathname starts with one of the standard directories for Unix
executables (/bin, /usr/bin, /sbin, /usr/sbin);
- the file isn't found relative to the system root;
- the basename matches an applet
then the applet is run.
Further extend the procedure so that if the first two conditions are
met and either:
- the PREFER_APPLETS and SH_STANDALONE features are enabled and the
basename *doesn't* match an applet
or
- the PREFER_APPLETS and SH_STANDALONE features are disabled
then PATH is searched for the basename.
This affects:
- how interpreters and binaries are spawned by mingw_spawn_interpreter()
and mingw_spawnvp();
- how 'which' and the shell search for binaries.
Special steps need to be taken in the shell to avoid treating shell
built-ins and functions as applets.
As a consequence of this change:
- An executable that isn't an applet, say curl.exe, can be run as
/usr/bin/curl so long as it's in a directory in PATH. It doesn't
have to be in C:/usr/bin.
- If the PREFER_APPLETS and SH_STANDALONE features are disabled binaries
can be run using paths referring to standard Unix directories even if
they're installed elsewhere in PATH.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It appears the CRT and OS each have a copy of the environment.
mingw_putenv() fools the CRT into accepting an empty environment
variable by calling _putenv("V=0") then truncating the new value
by hand. But _putenv() also updates the OS environment with the
fake 'V=0' value. Commit 5b48ca53b (win32: pass NULL to spawnve,
not environ) resulted in this fake value being used and hence empty
variables getting the value '0'.
- Add a call to SetEnvironmentVariable() in mingw_putenv() to update
the OS environment.
- Restore the use of NULL environment pointers in mingw_spawnvp().
- Add a test.
(GitHub issue #250)
|
|
|
|
|
|
|
|
|
|
| |
Revert the change to mingw_putenv() in the previous commit.
When compiling for MSVCRT (i.e. not for UCRT) revert some of the
changes from commit 5b48ca53b (win32: pass NULL to spawnve, not
environ).
(GitHub issue #250)
|
|
|
|
|
|
|
| |
Drop the use of ENABLE_FEATURE_SH_STANDALONE in process.c
In mingw_spawn_interpreter() check for an applet *before* trying
to run the interpreter using the path provided.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The name of the function mingw_spawn_1() wasn't particularly
meaningful. Remove its envp argument (as all of its current callers
pass a NULL pointer) and rename it mingw_spawnvp() to better reflect
what it does.
The path search it performs isn't the standard one: it has features
specific to busybox-w32.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Building busybox-w32 for use with UCRT results in mysterious
failures. (GitHub issue #234)
These are somehow related to the environment values passed to
spawnve. In several places the global environ pointer was being
passed to spawnve so the child would inherit its environment from
the parent. This can also be achieved by passing a NULL pointer.
This prevents the failures in at least some cases and also makes
the binary smaller.
|
|
|
|
|
|
|
|
| |
The implementations of execve(2) and execvp(3) were unable to
distinguish between failure and a program returning a status of -1.
Check the error return code to discriminate between these cases.
See GitHub issue #218.
|
|
|
|
|
| |
Since there's only one call to mingw_spawn_forkshell() we might
as well just call spawnve() directly from ash.
|