aboutsummaryrefslogtreecommitdiff
path: root/win32/mingw.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* win32: allow for trailing separator in PATHpath_searchRon Yorston2024-06-121-0/+26
| | | | | | | | | | | | | | | | | In recent versions of Windows the PATH environment variable has a trailing semicolon. This is insignificant to Windows because it's ignored. busybox-w32 conforms to the POSIX interpretation of PATH which treats an empty path element as denoting the current directory. As result, on these versions of Windows executables may by default be run from the current directory, contrary to usual Unix practice. Attempt to detect and remove the trailing semicolon on applet start up. If the user insists, they can add a trailing semicolon to the shell variable PATH and it will be respected in the conventional manner. Adds 88-112 bytes.
* win32: try to avoid downloading offline filesRon Yorston2024-04-301-2/+5
| | | | | | | | It's possible that files in remote storage may not be available locally. Avoid downloading such files just to obtain file attributes. (GitHub issue #414)
* win32: adjust handling of executable extensionsRon Yorston2024-04-221-8/+12
| | | | | | | | | | | | | | | Mixing Windows and Unix-style filename extensions was causing problems. Tweak how extensions are handled to try and improve matters: - Consistently check whether the unaltered filename is an executable before trying adding extensions. - Check .exe and .com before .sh. Saves up to 16 bytes. (GitHub issue #405)
* win32: make stat(2) fail for /dev/zero, /dev/urandomRon Yorston2024-04-201-1/+2
| | | | | | | | | | /dev/zero and /dev/urandom are only available internally and as arguments to 'dd'. Since users can't otherwise access them they shouldn't be treated as existing by stat(2). With this change stat(1) and test(1) will deny their existence. (GitHub issue #282)
* win32: improvements to realpath(3)Ron Yorston2024-03-091-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | The previous commit unnecessarily duplicated the path returned from resolve_symlinks(), resulting in a memory leak. Thanks to avih for spotting this. Even if we can't canonicalise the path in resolve_symlinks() we can at least return the result of resolving the trailing symlink. Moreover, this can be done both when the necessary API is missing and when the filesystem doesn't support it. Not perfect, but better than nothing, and there's no cost. This change gets rid of a handful of realpath-related test failures on ReactOS and Windows XP. Some background: Commit 8ebe81483 returned the raw path when the required API was missing. This was reverted in commit f902184fa because it caused an infinite loop (GitHub issue #204). Commit 31467ddfc fixed the cause of the loop, which is why it's now safe to reintroduce a fallback return. (GitHub commit #389)
* win32: let realpath(3) work on flaky filesystemsRon Yorston2024-03-081-0/+3
| | | | | | | | | | | | Some filesystems don't support the feature required to resolve symlinks for realpath(3). In such cases just carry on without resolving symlinks. This is a trade-off between correctness and convenience. Adds 16 bytes. (GitHub issue #389)
* win32: fix detection of directories in stat(2)Ron Yorston2024-01-041-3/+5
| | | | | | | | | | | | | | | | The implementation of stat(2) detected whether a pathname ending with a directory separator was valid by checking for the error code ERROR_INVALID_NAME when GetFileAttributesExA() failed. This works if the path refers to an actual disk but not if it's on a share. In the latter case the glob '*/' incorrectly returned files that weren't directories. Add code to handle this case. Costs 16-32 bytes. (GitHub issue #381)
* win32: fix handling of relative pathsRon Yorston2023-10-041-12/+3
| | | | | | | | | | | | | | Commit 548ec7045b (win32: interpret absolute paths as relative to %SYSTEMDRIVE%) introduced the function xabsolute_path() to make relative paths absolute. This is used in 'dkpg' and 'man' to avoid having to tinker with absolute paths from upstream. Unfortunately, it's too eager to use the relative path. This results in dpkg failing to install deb files with a relative path. Saves 32-48 bytes. (GitHub issue #371)
* win32: replace readlink(2)Ron Yorston2023-08-211-11/+15
| | | | | | | | | | | | | | | The Windows implementation of readlink(2) has caused problems in the past. As, for example, with commit c29dc205d2 (win32: fix implementation of readlink(2)). Most uses of readlink(2) in BusyBox are actually calls to the (considerably more convenient) library function xmalloc_readlink(). Implement a Windows version of that and used it instead of readlink(2). This improves the handling of symbolic links (and similar reparse points) in CJK and UTF-8 code pages. Saves 48-80 bytes.
* ash: detect console state on shell start upnoconsole2Ron Yorston2023-08-201-14/+0
| | | | | | | | | | | Set 'noconsole' to match the actual state of the console (normal/ iconified) when the shell is started. Thus ShowWindow() will only be called if the actual state differs from the default or user defined state. Costs 20-24 bytes. (GitHub issue #325)
* win32: support build with FEATURE_UNICODE_SUPPORTAvi Halachmi (:avih)2023-07-221-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | FEATURE_UTF8_MANIFEST enables Unicode args and filenames on Win 10+. FEATURE_UTF8_INPUT allows the shell prompt to digest correctly Unicode strings (as UTF8) which are typed or pasted. This commit adds support for building with FEATURE_UNICODE_SUPPORT (mostly by supporting 32 bit wchar_t which busybox expects): - Unicode-aware line-edit - for the most part cursor movement/del being (UTF8) codepoint-aware rather than assuming that one-byte equals one-char-on-screen. - Codepoint-aware operations in some other utils, like rev or wc -c. - When UNICODE_COMBINING_WCHARS and UNICODE_WIDE_WCHARS are enabled, some screen-width-aware operations, like with fold, ls, expand, etc. The busybox Unicode support is incomplete, and even less so with the builtin libc replacement functions, like wcwidth, which are active when UNICODE_USING_LOCALE is unset (mingw lacks those functions). FEATURE_CHECK_UNICODE_IN_ENV should be set so that Unicode is not hardcoded but rather depends on the ANSI codepage and some env vars: LC_ALL=C disables Unicode support, else it's enabled if ACP is UTF8. There's at least one known issue where the tab-completion-prefix-case is not updated correctly, e.g. ~/desk<tab> completes to ~/desktop/ instead of ~/Desktop/, because the code which handles it exists only at the non-unicode code paths, but that's not very critical. That seems to be the only case where mingw-specific code is disabled when Unicode is enabled, but there could be other unknown issues. None of the Unicode options is enabled by default, and the next commit will make it easier to create a build which supports Unicode.
* date: allow system date to be setRon Yorston2023-07-161-0/+23
| | | | | | | | | Implement clock_settime(2) and enable the '-s' option to allow the system time to be set. This requires elevated privileges. The code in date.c is now identical to upstream BusyBox. Costs 256-272 bytes.
* win32: code shrinkRon Yorston2023-06-041-7/+2
| | | | | | | | | | | | | | | | | | | getsysdir() wasn't used in get_proc_addr() because the former called realpath() which in turn called the latter. (Commit 4c6c8d61bc) realpath() was used to adjust the case of the path name as it was visible to the user as root's home directory. (Commit b04bbc0109) Later the home directory for "root" was changed so it no longer needed getsysdir(). (Commit 385decd6bf) The remaining uses of getsysdir() don't require the path to be canonicalised, so realpath() can be removed from getsysdir() and getsysdir() can be used in get_proc_addr(). Saves 32-64 bytes
* ash: enable 'set -/+o noconsole'Ron Yorston2023-06-011-8/+6
| | | | | | | | | | | | | | Previously the 'noconsole' shell option could only be set as a shell command line option. Allow it to be changed from within the shell by 'set -o noconsole' or 'set +o noconsole'. The console window is now minimised rather than hidden. This makes it easier for the user to access the console when 'noconsole' is in effect. Adds 8-32 bytes. (GitHub issue #325)
* win32: support "app exec link" reparse pointsRon Yorston2023-05-271-1/+36
| | | | | | | | | | | | | | | | | | Reparse points with the tag IO_REPARSE_TAG_APPEXECLINK are present in ~/AppData/Local/Microsoft/WindowsApps in Windows 10 and 11. They are: Used by Universal Windows Platform (UWP) packages to encode information that allows the application to be launched by CreateProcess. Modify readlink(2) and lsattr(1) to treat them as symbolic links, in much the same way as was done previously for junctions. They aren't really symbolic links but they're similar. Costs 128-160 bytes. (GitHub issue #327)
* win32: export xappendword()Ron Yorston2023-04-231-0/+12
| | | | | | | Export the function xappendword() from make. Use it in drop and watch. Saves 8-80 bytes, an unusually large disparity.
* win32: use CheckTokenMembership() to check privilegeRon Yorston2023-03-251-14/+16
| | | | | | | Rewrite the test for the reduced-privilege token: check whether the BUILTIN\Administrators group is enabled. This seems more directly relevant than the previous check for restrictions on the token.
* drop: add cdrop and pdrop aliasesRon Yorston2023-03-191-1/+1
| | | | | | | | | | | | | | | | Add cdrop and pdrop applets as aliases for drop. If a command isn't specified these use cmd.exe and PowerShell instead of the BusyBox shell. This makes it possible to choose the default shell used for SSH connections even in older versions of OpenSSH that don't support the DefaultShellArguments registry key. Note that to get cmd.exe to run a command rather than an interactive shell it's necessary to set the DefaultShellCommandOption registry key to '/c'. Costs 248-272 bytes.
* runuser,drop: drop runuser, tweak dropRon Yorston2023-03-191-1/+1
| | | | | | | | | | | | | | Remove the runuser applet, leaving only drop. Move drop from util-linux to miscutils. A command of the form 'drop -c command' causes the BusyBox shell to be used, just like 'drop' without any arguments. A simple OpenSSH configuration with 'drop.exe' as DefaultShell and no DefaultShellArguments now works both for interactive login and to run a command. This is useful for older versions of OpenSSH which don't support DefaultShellArguments. Saves 208-232 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-9/+25
| | | | | | | | | | | | 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-12/+31
| | | | | | | | | | | | | | | | | | | | | 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: skip ACL check in stat(2) when running as rootFRP-4881-ga6c5fd4ebRon Yorston2023-02-131-1/+2
| | | | | | | | | | Commit 88965fe20 (win32: use ACL check to clarify write permission) added code to check if a file had write permission due to an ACL entry. When running with elevated privileges this check is unnecessary as "user" permissions will be sufficient. This also prevents write permission for "other" being set without respecting umask.
* ash,make: fix CRLF handlingRon Yorston2023-01-301-2/+3
| | | | | | | Fix remove_cr() so it only removes CRs which are part of a CRLF pair, not every CR. Add a test case for the shell.
* win32: another stat(2) + access time fixRon Yorston2023-01-261-1/+1
| | | | | | | | Use FILE_SHARE_READ when opening a file to check if it's an executable. Without that other processes running in parallel might be unable to access the file. (GitHub issue #284)
* win32: only count subdirectories if necessaryRon Yorston2023-01-231-3/+15
| | | | | | | | | | | | | | | | | Commit 7fb95a2a5 (win32: try to get link count for directories) allowed stat(2) to report accurate values of st_nlink for directories. There are only a couple of places in busybox-w32 where these values are required. Disable counting of subdirectories by default and only enable it when necessary. Microsoft kindly provide directories to test edge cases like this: C:/Windows/WinSxS (contains many subdirectories) C:/Windows/WinSxS/Manifests (contains many files) Adds 84-112 bytes.
* win32: limit setting of errno when lazy loading failsRon Yorston2023-01-221-3/+3
| | | | | | | | | | | | The function get_proc_addr() facilitates dynamic loading of functions from DLLs. In the event of failure it set errno to ENOSYS. This is sometimes useful, such as in the implementations of link(2), symlink(2) and realpath(3). However, many other uses of lazy loading can recover from failure or simply don't care. In these cases setting errno is unnecessary and may be counterproductive. (GitHub issue #283)
* win32: more minor improvements to stat(2)Ron Yorston2023-01-181-29/+26
| | | | | | | | | | | | | | | | The previous commit incorrectly stated that preventing the access time of a file from being updated only required it to be opened with GENERIC_READ access. In fact, even though we don't want to update the access time, SetFileTime() also requires the file to have been opened with FILE_WRITE_ATTRIBUTES access. There's no need to explicitly avoid device files when checking for execute mode: since device files are now 'character special' they are excluded by the test that the file is 'regular'. Device files should be excluded when trying to obtain extra file data using GetFileInformationByHandle(). It shouldn't be possible for CreateFile() to open then, so there's no point in trying.
* win32: minor improvements to stat(2)Ron Yorston2023-01-171-9/+9
| | | | | | | | | | | Commit b11352dcb (win32: prevent stat(2) from updating access times) requested GENERIC_ALL access when opening files. It appears that GENERIC_READ is sufficient and also faster. The code to find the actual size of compressed or sparse files only needs to be invoked for regular files. Avoiding unnecessary calls to GetCompressedFileSize() makes stat(2) slightly faster and gives a more accurate number of blocks for symbolic links.
* win32: use ACL check to clarify write permissionRon Yorston2023-01-161-27/+30
| | | | | | | | | | | | | | | | | On Microsoft Windows a user's home directory doesn't belong to them: it actually belongs to the 'system' user. stat(2) was only using ownership to determine write permissions, so it seemed that the user was unable to write to their own home directory. Use a call to AccessCheck() to determine if files can be accessed due to an entry in their ACL. User home directories and a few other files (e.g. C:/Users/Public) now have the correct write permission. This feature is enabled by FEATURE_EXTRA_FILE_DATA. Costs 220-256 bytes. (GitHub issue #280)
* win32: fix permissions of read-only directoryRon Yorston2023-01-111-1/+1
| | | | | | | | | | | | Commit 15fcbd19c8 (win32: special case for devices files in stat(2)) caused write permissions on directories to respect the read-only attribute. This is incorrect: the read-only attribute doesn't apply to directories in the same way as to normal files. Give directories write permission unconditionally, as before, though respecting umask. (GitHub issue #280)
* win32: prevent stat(2) from updating access timesRon Yorston2022-12-221-4/+19
| | | | | | | | | | | | | | | | | The WIN32 implementation of stat(2) reads the contents of some files to see if they're executable. This may update the file access time. Avoid this by a special call to SetFileTime() after opening the file. For details see: https://devblogs.microsoft.com/oldnewthing/20111010-00/?p=9433 https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfiletime File access times aren't updated by default in recent versions of Windows. This commit is only necessary if updating of file access times is explicitly enabled: fsutil behavior set DisableLastAccess 0
* win32: revert special treatment of Unix-style absolute pathsRon Yorston2022-10-261-6/+5
| | | | | | | | | | | | | | | | | | | | | | | | | 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: use xmalloc_follow_symlinks() in stat(2)Ron Yorston2022-09-271-16/+9
| | | | | | | | Commit 31467ddfc (win32: changes to stat(2) implementation) followed symlinks manually. Unfortunately the implementation was incorrect. Use xmalloc_follow_symlinks() instead. Saves 32-48 bytes.
* Workaround for incomplete junctions created by PowerShellRon Yorston2022-06-251-12/+32
| | | | | | | | | | | | | Scoop uses PowerShell's New-Item to create junctions. However, these junctions lack a PrintName. This is a known issue which has caused problems even for Windows' File Explorer: https://github.com/PowerShell/PowerShell/issues/12923 Revert commit 32de287bb (win32: code shrink readlink(2)) to that readlink(2) uses SubstituteName instead. (GitHub issue #261)
* win32: changes to stat(2) implementationFRP-4716-g31467ddfcRon Yorston2022-05-231-15/+22
| | | | | | | | | | | - Use repeated calls to readlink(2) rather than xmalloc_realpath() when asked to follow symlinks. - Drop the non-standard feature that caused readlink(2) to return only the target string length. This improves compatibility with BusyBox on Linux at a cost of 16-32 bytes.
* win32: code shrink fstat(2)Ron Yorston2022-05-231-11/+8
| | | | Reduce duplicated code. Saves 16-48 bytes.
* win32: let stat(2) return correct st_size for symlinkRon Yorston2022-05-221-5/+8
| | | | | | Previously stat(2) set st_size to the length of the canonicalised symlink target. Call readlink(2) to get the actual length of the target string.
* win32: code shrink readlink(2)Ron Yorston2022-05-221-32/+12
| | | | | | | Use PrintName rather than SubstituteName from the reparse data buffer. This avoids the need to normalise the name. Saves 240 bytes.
* win32: code shrink directory testsRon Yorston2022-05-221-15/+19
| | | | | | | | | | Add a function to check if a file is a directory and use it in various places. Replace some uses of S_ISDIR() with a test of the Windows file attributes. Saves 32-48 bytes.
* win32: return reparse tag in struct statRon Yorston2022-05-191-6/+14
| | | | | | | | If a file is a junction or symlink return its tag in the st_tag member of struct stat. get_symlink_data() and is_symlink() also return the tag or zero, as appropriate.
* jn: make junctions acceptable to WindowsRon Yorston2022-05-171-5/+9
| | | | | | | Junctions created by 'jn' contained incorrect data: the length of the target name was off-by-one. (GitHub issue #251)
* jn: new appletRon Yorston2022-05-161-1/+132
| | | | | | | | | | | | Add a Windows-specific applet to create a directory junction. Usage: jn DIR JUNC where DIR must be an existing directory on a local drive and JUNC must not currently exist. There isn't a simple WIN32 API to create directory junctions. The implementation of mklink in ReactOS provided useful inspiration.
* win32: try to get link count for directoriesRon Yorston2022-05-151-1/+22
| | | | | | | | | | | | | On Unix the link count of a directory reflects the number of subdirectories it contains. Enhance readdir(3) to return file types and use this to count subdirectories when stat(2) is called for a directory. As with other features that might slow down stat(2) this is controlled by the build-time setting FEATURE_EXTRA_FILE_DATA. (Commit d82db8e9a 'win32: make stat(2) fetch additional metadata'). (GitHub issue #254)
* win32: treat junctions as symlinksRon Yorston2022-05-141-6/+13
| | | | | | | | | | | | | | | | | Directory junctions were always followed to their target so they appeared to *be* directories. This resulted in counter-intuitive behaviour: - a directory junction could be removed with rmdir even though the directory wasn't empty; - 'rm -rf' on a directory junction deleted it but also deleted the contents of the linked directory. A better approximation is to treat directory junctions as symbolic links. (GitHub issue #254)
* ash: export certain variables to the environment immediatelyRon Yorston2022-05-081-1/+1
| | | | | | | | | | | The environment variables BB_OVERRIDE_APPLETS, BB_SKIP_ANSI_EMULATION and BB_SYSTEMROOT affect of the behaviour of the shell itself. Setting them as shell variables is insufficient for them to affect the current shell. When these three variables are exported from the shell they are now placed in the environment immediately. Conversely, when they're unset or unexported they're removed from the environment.
* win32: fix 'cd' to symlink with relative path as targetRon Yorston2022-05-071-1/+1
| | | | | | | | | | | | | Commit 69d328022 (win32: track current directory of mapped drives) replaced a call to xmalloc_realpath() with one to xmalloc_readlink(). This was incorrect. Although the argument is now guaranteed to be a symlink it's still necessary to resolve it to an absolute path. Otherwise the fix in commit 585d17d26 (win32: canonicalize path in chdir(2)) doesn't work for symlinks with a relative path as their target. (GitHub issue #147)
* win32: search PATH for missing Unix-style executablesRon Yorston2022-05-061-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* which,ash: changes to which/command/typeRon Yorston2022-05-011-0/+21
| | | | | | | | | | | | | | | | | | | Change how 'which' detects if it was run from a standalone shell: the shell passes the undocumented '-s' option. This is stricter and more reliable than the previous method of checking the name of the binary. Add a function to determine the binary associated with a given applet name. This makes it possible for 'which' and 'command -v' to list the correct binary even for applets other than 'busybox'. For example, when the binary is called 'sh.exe' 'which sh' will report its path. In standalone shell mode 'command -V' and 'type' now report "xxx is a builtin applet" rather than "xxx is xxx", which is true but not very illuminating. (GitHub issue #248)
* win32: clarify documentation of is_relative_path()Ron Yorston2022-04-301-3/+8
|