aboutsummaryrefslogtreecommitdiff
path: root/win32/process.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* win32: some changes to kill(2)Ron Yorston2024-05-181-26/+27
| | | | | | | | 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.
* win32: implement getppid(2)Ron Yorston2024-05-161-9/+24
| | | | | | | | | | | | | | 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.
* win32: ensure PIDs are read early in procps_scan()Ron Yorston2024-05-161-10/+15
| | | | | | | | | | | 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.
* win32: code shrinkRon Yorston2024-05-151-2/+0
| | | | Saves 16-32 bytes
* ps: report unknown parent PID as 1Ron Yorston2024-05-141-2/+20
| | | | | | | | | | 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)
* kill: killing a zombie process should failRon Yorston2024-05-141-106/+90
| | | | | | | | | | | | | | | | | | | | | | | 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)
* win32: avoid console windows from CGI scriptsRon Yorston2024-02-071-1/+1
| | | | | | | | | 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.
* win32: code shrink procps_scan()Ron Yorston2023-12-311-2/+2
| | | | | | Use getpid() instead of GetProcessId(GetCurrentProcess()). Saves 16 bytes.
* httpd: consistently leak memory, or notRon Yorston2023-12-311-3/+8
| | | | | | | | | | | | | 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.
* httpd: enable support for CGIRon Yorston2023-12-201-2/+58
| | | | | | | | | | | | | | | | | | | | | | | | | 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)
* win32: code shrink execve(2) implementationRon Yorston2023-12-181-2/+2
| | | | | | | | | | | 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.
* httpd: fix return code when run in backgroundRon Yorston2023-12-151-11/+5
| | | | | | | | | | | 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.
* win32: convert exit codesRon Yorston2023-09-141-2/+35
| | | | | | | | | | | | | | | | | 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.
* win32: change interpretation of BB_OVERRIDE_APPLETSRon Yorston2023-06-021-10/+2
| | | | | | | | | | | | | | | | | | | | | | | | | 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)
* win32: skip test for non-console apps if necessaryRon Yorston2023-06-021-0/+4
| | | | | | | | | 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.
* win32: crtl-c interrupts non-console applicationsRon Yorston2023-05-231-1/+36
| | | | | | | | | | | | | | | | | | | 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.
* win32: changes to signal handlingRon Yorston2023-05-231-8/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* win32: further code shrink quote_args()Ron Yorston2023-04-281-19/+3
| | | | | | | | Squeeze a few more bytes out of quote_args(). (Thanks to GitHub user avih.) Saves 16 bytes.
* win32: code shrink copying of argvRon Yorston2023-04-281-4/+14
| | | | | | | 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.
* win32: improved error for overlong command lineRon Yorston2023-04-271-1/+6
| | | | | | | | 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.
* win32: code shrink quote_args()Ron Yorston2023-04-271-58/+20
| | | | | | | | | | | | | | | 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.
* win32: further fix incorrect path search in spawnvpRon Yorston2023-04-161-1/+3
| | | | | | | | 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)
* win32: fix incorrect path search in spawnvpRon Yorston2023-04-141-3/+1
| | | | | | | | | 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)
* win32: ignore ctrl-c in parent of execve(2)Ron Yorston2023-04-051-4/+14
| | | | | | | | | | | | | | | | | | 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)
* runuser,drop: code shrinkRon Yorston2023-03-191-3/+2
| | | | | | | | | 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.
* runuser: add 'drop' as an alias for runuserRon Yorston2023-03-161-1/+1
| | | | | | | | | | | | | | | | | | | 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)
* win32: code shrink detection of executablesRon Yorston2023-03-161-7/+4
| | | | | | | | | | | | 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.
* runuser: new appletRon Yorston2023-03-131-1/+1
| | | | | | | | | | | | | | | | | | | | | 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)
* win32: revert special treatment of Unix-style absolute pathsRon Yorston2022-10-261-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | 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)
* win32: search PATH for missing Unix-style executablesRon Yorston2022-05-061-29/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* win32: better fix for empty environment variablesRon Yorston2022-05-051-9/+4
| | | | | | | | | | | | | | | | | | | 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)
* win32: revert changes related to environment variablesRon Yorston2022-05-041-4/+9
| | | | | | | | | | 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)
* win32: conditional compilation in process.cRon Yorston2022-04-241-10/+10
| | | | | | | 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.
* win32: add link to LWN article on shebangRon Yorston2021-11-141-1/+2
|
* win32: rename mingw_spawn_1Ron Yorston2021-11-011-8/+8
| | | | | | | | | | 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.
* win32: pass NULL to spawnve, not environRon Yorston2021-10-281-4/+4
| | | | | | | | | | | | 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.
* win32: handle -1 return status from execve(2)Ron Yorston2021-06-191-2/+3
| | | | | | | | 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.
* ash: code shrinkRon Yorston2021-02-141-9/+0
| | | | | Since there's only one call to mingw_spawn_forkshell() we might as well just call spawnve() directly from ash.
* win32: code shrink Unix-style path handlingRon Yorston2020-08-231-19/+9
| | | | | | | | Replace auto_add_system_drive() with alloc_system_drive() which leaves space for a possible filename extension. This makes it possible to drop alloc_win32_extension() and auto_win32_extension(). Saves 144 bytes.
* win32: use built-in applets for non-existent binaries with Unix-style pathsRon Yorston2020-08-131-2/+13
| | | | | | | | | | | | | | | | | | | | Shell scripts moved from Unix may contain hard-coded paths to binaries such as /bin/sh. A recent commit made it possible to execute such binaries reliably, but that does require them to be installed. As an alternative solution: if a binary with a standard Unix path prefix can't be found but is available as a built-in applet, run the applet. Add the function unix_path() to detect paths starting with /bin, /usr/bin, /sbin or /usr/sbin. Use this function in: - the 'which' applet - shellexec(), describe_command() and find_command() in ash - mingw_spawn_1() See GitHub issue #195.
* win32: handle Unix-style absolute paths for executablesRon Yorston2020-08-131-1/+10
| | | | | | | | | | | | | | | | | | | | | | As noted in commit 548ec7045 (win32: interpret absolute paths as relative to %SYSTEMDRIVE%) a path starting with a '/' in the Unix world is treated as relative to the current drive by Windows. To avoid ambiguity that commit considered certain such paths to be relative to %SYSTEMDRIVE%. Extend this to paths representing executables. Add the functions need_system_drive() and auto_add_system_drive() to detect the need for a system drive prefix and to add it if necessary. Use these functions in: - the 'which' applet - the find_executable() function - tab-completion code - PATH look-up, shellexec(), describe_command() and find_command() in ash - parse_interpreter() and mingw_spawn_1() With these changes executable paths starting with a slash are handled consistently, whatever the current drive.
* win32: code shrinkRon Yorston2020-08-131-1/+1
| | | | | | | | | | Add a new function, has_path(), to detect that an executable name doesn't require a path look-up. Also, since is_absolute_path() is now only used in shell/ash.c move its definition there from include/mingw.h. Saves 128 bytes.
* win32: code shrink kill(2)Ron Yorston2020-07-251-31/+17
| | | | | | | | - Drop exit_code argument from kill_SIGTERM_by_handle() - Pass signal number rather than exit code to other functions - Merge kill_SIGKILL() and kill_SIGTEST() Saves 112 bytes.
* win32: update link to Microsoft document on command-line argumentsRon Yorston2020-07-211-1/+1
|
* win32: minor improvements to process spawningRon Yorston2020-06-121-3/+2
| | | | | | | | | | | | | | The function mingw_spawn_forkshell() was introduced to handle spawning a forkshell process. Since we know that: - the binary being executed doesn't meet any of the special cases handled by spawnveq() - the arguments don't require quoting we can call spawnve() directly instead of spawnveq(). Also, use xzalloc() to allocate new_argv so we don't need to set the final NULL pointer explicitly.
* time: detect when spawn failsRon Yorston2020-06-041-1/+1
| | | | | | | In the 64-bit build the time applet reported garbage when it was unable to run the program to be timed. The error return from mingw_spawn_pid() was incorrect.
* win32: use lazy loading for certain DLLsRon Yorston2020-06-021-2/+13
| | | | | | | | | Only a handful of functions are used from shell32.dll, userenv.dll and psapi.dll. Mostly these functions are in out of the way places. By loading the functions only when required we can avoid the startup cost of linking the three DLLs in the common case that they aren't needed.
* ash: simplify spawning during forkshellRon Yorston2020-06-011-0/+9
| | | | | | | | | | | | | spawn_forkshell() uses mingw_spawn_proc() to start the child shell. mingw_spawn_proc() then calls mingw_spawn_1() which determines that "sh" is an applet, thus calling mingw_spawn_applet() which finally calls spawnveq(). Not only is this convoluted it also won't work if PREFER_APPLETS and SH_STANDALONE aren't enabled. Simplify matters by adding a new function, mingw_spawn_forkshell(), which is tailored for just this case.
* win32: changes to '#!' supportRon Yorston2020-05-241-10/+12
| | | | | | | | | | | | | Since the earliest days of busybox-w32 '#!' has searched PATH for the interpreter. This doesn't seem to be supported by precedent. In testing I also found that additional code was needed for the case where PATH has been altered in the current shell or is modified on the command line: PATH has to be extracted from envp rather than getenv("PATH"). Drop this non-standard feature. *NIX implementations disagree on whether the interpreter can itself be a script. Follow Linux and allow this with a limit of four levels of nesting.
* time: WIN32 portRon Yorston2020-04-061-7/+34
| | | | | | | | Port the time applet to WIN32. This requires the implemntation of a replacement for wait3(2). Only elapsed, user and system times are supported, not the memory and i/o statistics reported by GNU time.