| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem with UCRT seems to be that if a process has been
started with a non-NULL environment block passed to CreateProcess()
any subsequent call to spawnve() with a non-NULL environment pointer
fails.
Commit 5b48ca53b (win32: pass NULL to spawnve, not environ) fixed
the problem in busybox-w32 for those cases where a NULL environment
pointer was sufficient. It didn't handle the case where the shell
passes a modified environment to its child.
All calls to spawnve() in the shell occur in a process which will
terminate whether or not the call succeeds. It therefore doesn't
matter if we mess with the environment of this process such that
spawnve() can be passed a NULL environment pointer. (I think.)
|
|
|
|
|
|
|
|
| |
Only apply the UCRT hack if we're about to call spawnve() with
a non-NULL environment pointer.
Add the pid of the process to the name of the environment variable
to provide greater assurance that the environment will be changed.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
Implement getpeername(2).
Add mingw_spawn_detach() to allow the spawned process to detach from
the console.
|
|
|
|
|
|
|
|
| |
Tab-completion of 'c:file' paths was leaking memory and incorrectly
included BusyBox applets and shell built-ins.
Fix handling of 'c:file' paths used as arguments to spawn functions.
Otherwise things like 'timeout 5 c:busybox sleep 99' don't work.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 97e2c4a05 (win32: changes to treatment of scripts) attempted
to use strtok(3) to simplify the parsing of shebang lines.
Unfortunately it resulted in leading and trailing whitespace being
left in the option string. Fix this by trimming the options before
they're returned.
Reported-by: Niklas DAHLQUIST <niklas.dahlquist@st.com>
Signed-off-by: Ron Yorston <rmy@pobox.com>
|
|
|
|
|
|
|
|
|
| |
There are now two places where slashes are converted to backslashes
throughout a string so it makes sense to create a function to do
this.
To avoid confusion rename convert_slashes() to bs_to_slash() and
call the new function slash_to_bs().
|
| |
|
| |
|
|
|
|
|
|
| |
In parse_interpreter return an error when the file doesn't exist.
The current code tries to run non-existent scripts with a .sh suffix,
thus breaking the test ash-misc/exec.tests.
|
|
|
|
|
|
|
|
| |
In desktop mode the state column is disabled and doesn't affect
output.
When desktop mode is disabled the state column is displayed in long
output. Put some fake data in the column to improve the display.
|
|
|
|
|
|
|
|
|
|
|
| |
When an interpreted script is being run the comm column in ps
should display the name of the script not the name of the
interpreter.
Use a fake applet pathname to indicate which argument contains
the script.
This also allows pidof to obtain the pid of a script.
|
|
|
|
|
|
|
|
|
| |
Implement read_cmdline() for WIN32 by storing the command line in
the same way as the applet name.
The applet name is actually used for the comm column which is
truncated to COMM_LEN. Using this as the size of the bb_comm
array avoids the need to calculate MAX_APPLET_NAME_LEN.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The PATH shell variable is a special case. It can be exported to
the environment where it might be interpreted by native applications
which assume the separator is ';'. Hence:
- require that the separator used in PATH is ';'
- enforce this by intercepting calls to setvareq() that set PATH
and adjusting its value if necessary.
As a result of this the code to parse PATH can be simplified by
replacing the hardcoded Unix ':' path separator by the platform-
dependent macro PATH_SEP.
The MANPATH variable is also required to use ';' as its separator
but since it's less likely to be used this isn't enforced.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Files with the extension '.sh' are considered to be executable.
Those that start with a '#!' line will be run using the specified
interpreter. If no '#!' is present the script will be run by the
shell.
When searching for an executable the '.sh' extension will be
tested in the same way as the standard extensions understood
by spawnve(). '.sh' takes precedence over the standard
extensions.
|
| |
|
|
|
|
|
|
|
| |
Microsoft Windows' spawnve returns ERROR_BAD_EXE_FORMAT when passed
an empty batch file.
Work around this by skipping spawnve and returning success.
|
|
|
|
|
|
|
|
|
| |
It appears that when a batch file is executed the first argument
must contain backslashes if it's a relative path. Absolute paths
work either way. In both cases the extension is optional.
This allows for a considerable simplification of the special case
in spawnveq.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Previously there was one function to handle adding extensions to
executable filenames, add_win32_extension(). Refactor this into
three functions:
add_win32_extension() appends the suffix to the argument string
in-place. The argument must be long enough to cope with this,
as is the case in ash where path_advance() adds 4 bytes to each
filename for just this reason.
alloc_win32_extension() is equivalent to the old add_win32_extension().
It allocates a string to hold the new filename then calls the new
add_win32_extension() function. The caller is responsible for
managing the returned string.
auto_win32_extension() calls alloc_win32_extension() and saves the
resulting string using auto_string(). It's used where the new
filename is consumed immediately or the actual value isn't needed.
Rewrite code to use the most appropriate function. Also reorder
some code in find_executable() and find_command().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ash tests exitcode_EACCES and exitcode_ENOENT both failed.
In commit 92dbd3c09 a test was added to tryexec to check that
the file being run existed and was executable. The error codes
returned by this test were incorrect.
The slightly later commit f5783ef14 added a similar test in
spawnveq which got the error codes right.
Remove the test from tryexec and some superfluous error messages
from spawnveq.
|
|
|
|
|
|
| |
Recalculate the system boot time on every pass through the process
scanning loop. It's less efficient than storing the value in a
static variable but not noticeably so and it saves a few bytes.
|
|
|
|
| |
Saves 16 bytes.
|
|
|
|
|
|
| |
When the process architecture of busybox-w32 didn't match that of
the target process the error reported was 'Function not implemented'.
Change this to 'Permission denied'.
|
|
|
|
|
| |
Now that we're calling memset to clear data for each process it's
no longer necessary to zero the process times by hand.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remove the code which passed applet names to child processes using
environment variables. This only allowed ps to display names for
its ancestors.
Instead attempt to read applet names from the memory of unrelated
processes.
The Microsoft documentation alone wasn't enough to figure out how
to do this. Additional hints from:
https://stackoverflow.com/questions/4298331/exe-or-dll-image-base-address
https://stackoverflow.com/questions/14467229/get-base-address-of-process
|
|
|
|
|
|
|
|
|
|
|
| |
The exit status from _cwait wasn't being correctly returned. This
resulted, for example, in the exit status of xargs being incorrect.
Running this:
$ ls | xargs ls
in a directory containing filenames with spaces should cause 'ls' to
fail and 'xargs' to return an exit status of 123.
|
|
|
|
|
|
|
|
| |
In the recently-added code to pass applet names to child processes use
local arrays to build the environment variables rather that allocating
them every time.
mingw_spawn can call mingw_spawn_proc instead of mingw_spawn_1.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In standalone shell mode all busybox-w32 applets are displayed as
'busybox.exe' in a process listing.
I haven't found a satisfactory way to query a running instance of
busybox-w32 to determine which applet it's running. Handle a couple
of cases:
- the process running the process scan knows its own PID and knows
which applet it is;
- just before invoking applet_main set an environment variable whose
name contains the PID and whose value is the current applet name.
Children running a process scan will inherit their parent's environment
and can therefore match the parent's PID to its applet name.
|
|
|
|
|
|
|
|
|
| |
The original procps_scan function takes care to clear the status
information before handling each process. Do the same for the
WIN32 version.
This requires moving the snapshot handle to the part of the structure
that isn't cleared on each iteration.
|
|
|
|
|
|
|
|
|
| |
The names of the callbacks to kill processes with a given signal were
confusing because they referred to the implementation rather than
the intent.
Create the new function kill_SIGTERM_by_handle which is more efficient
when a handle to the process to be killed is already available.
|
|
|
|
|
|
|
|
| |
Reduce the size of the binary by about 32 bytes:
- use xzalloc to allocate static buffers so we don't have to
initialise them;
- avoid duplicated code in spawnveq.
|
|
|
|
|
|
|
| |
It appears that uninitialised static variables are placed in the
data section rather than bss, increasing the size of the binary.
Rewrite some code to reduce the amount of static data.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consistent processing of file extensions, as described in the previous
commit, has been applied to the 'which' applet and the functions
find_executable and mingw_spawn_interpreter.
In spawnveq check that the file to be executed exists and is executable,
and ensure that it won't have any extensions added by spawnve.
It's intended that all files passed to spawnve should have their names
fully specified. If this isn't the case the tests here will cause errors
which will need to be fixed.
|