aboutsummaryrefslogtreecommitdiff
path: root/scripts/basic (unfollow)
Commit message (Collapse)AuthorFilesLines
2026-07-16xargs: limit number of processes to 64Ron Yorston1-18/+4
Upstream limits the number of processes invoked with the '-P 0' option to 100. On Windows the limit was set to MAXIMUM_WAIT_OBJECTS, as that's the most WaitForMultipleObjects() can handle. Apply the same limit to user-supplied '-P' values. This avoids the need to loop over blocks of MAXIMUM_WAIT_OBJECTS. "64 processes ought to be enough for anyone." Saves 64-80 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-15win32: code shrink procps_scan()Ron Yorston3-28/+29
The principal change is to replace four separate arrays (one for pids and three for time values) with a single array of structs. There are some other minor adjustments. Saves 96-144 bytes. (GitHub PR #609) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-15fix: procps_scan: do not confirm a process to be parent if either creation ↵Shun Zi1-4/+4
time is unknown.
2026-07-15fix: procps_scan: compare process creation times to ensure ppid is realshunf43-16/+55
Windows aggressively reuses PIDs of exited processes. When a new irrelevant process gets assigned the former PID of the parent of an orphaned process, `pkill -P`, `pgrep -P`, `ps -o ppid` sees the new process as the parent of the orphaned process, and PPID of the orphan is no longer 1. So in theory, all `pkill -P`, `pgrep -P` calls are potentially dangerous and possible to kill an innocent process which outlives its parent. This issue is already discussed in various Internet communities: - https://stackoverflow.com/questions/6593003/how-can-i-reliably-check-whether-one-windows-process-is-the-parent-of-another-in - https://web.archive.org/web/20140701081232/https://www.sapphiresteel.com/Blog/Killing-Trees-the-Windows-way Comparing process creation times seems a feasible mitigation that should almost always work (though not theoretically sound). The executable is added 512 bytes after the patch.
2026-07-14win32: workaround for overflow of 8.3 short name (2)Ron Yorston1-1/+1
Replace a call to 'FindNextFileA()' in 'get_reparse_tag()'. This has no effect on the standard builds. Builds with the UTF-8 manifest included save 4-8 bytes as this removes the only remaining call to 'FindNextFileA()'. (GitHub issue #506) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-13win32: workaround for overflow of 8.3 short nameRon Yorston3-2/+36
In certain circumstances 'FindNextFileA()' can fail because the legacy DOS 8.3 short name doesn't fit in the buffer supplied. This can be avoided by using 'FindFirstFileExA()' instead, but with a setting that isn't available on Windows XP. - The problem doesn't arise in the standard 32 and 64 bit builds, so no change is required. - Builds with full Unicode support target platforms which have the required setting. They can use 'FindFirstFileExA()' unconditionally, at the cost of 36-56 bytes. - Builds which include the UTF-8 manifest but which are allowed to run on systems prior to Windows 10 need to check whether they need to call 'FindFirstFileExA()' at runtime. This adds 100 bytes. (GitHub issue #506) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-13xxd: allow '-p -c 0' to cause a single line to be outputRon Yorston2-2/+26
Since 2022 the 'xxd' which comes with 'vim' has allowed the combination of options '-p -c 0' as a way to request output on a single line. Details: https://github.com/vim/vim/pull/9524 Add this feature to the BusyBox 'xxd' applet. Adds 64 bytes. (GitHub issue #610) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-08join: code shrink by making some variables "global"Denys Vlasenko1-50/+58
function old new delta readfields 442 437 -5 printfields 462 457 -5 join_main 843 760 -83 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-93) Total: -93 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-08join: new appletRon Yorston2-0/+595
function old new delta join_main - 843 +843 printfields - 462 +462 readfields - 442 +442 .rodata 107120 107332 +212 packed_usage 36078 36237 +159 applet_names 2870 2875 +5 applet_main 1652 1656 +4 ------------------------------------------------------------------------------ (add/remove: 4/0 grow/shrink: 4/0 up/down: 2127/0) Total: 2127 bytes text data bss dec hex filename 1080964 555 4992 1086511 10942f busybox_old 1083091 555 4992 1088638 109c7e busybox_unstripped v2: Add a missing return statement which broke the '-t' option. Thanks to Roberto A. Foglietta for pointing this out. Signed-off-by: Morgan Bartlett <mjmouse9999@gmail.com> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-06make: fix build with FEATURE_CLEAN_UP enabledRon Yorston1-0/+1
The 'make' applet failed to build with FEATURE_CLEAN_UP enabled. Add an early declaration of freerules() to avoid this. This doesn't affect the default builds. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-06ash: fix out-of-bounds read in ifsbreakup()Sanghyun Park1-9/+15
ifsfree() does not only release allocated ifsregion nodes; it also clears the global IFS region state used by ifsbreakup(). If argstr() raises an error while expanding an argument, ash longjmps out of expandarg() before that cleanup runs, leaving stale IFS split offsets behind. A later expansion can reuse the stack for a shorter string. ifsbreakup() then sees the stale IFS state, trusts the old offsets, and can walk past the current stack block before dereferencing p. Follow dash's root-cause fix: when an expansion-related handler catches EXERROR and continues, restore the handler and call ifsfree(). Apply the cleanup to redirectsafe(), expandstr(), and evaltree(). Upstream commit: Date: Mon Dec 5 23:02:01 2022 +0800 expand: Add ifsfree to expand to fix a logic error that causes a buffer over-read On Mon, Jun 20, 2022 at 02:27:10PM -0400, Alex Gorinson wrote: > Due to a logic error in the ifsbreakup function in expand.c if a > heredoc and normal command is run one after the other by means of a > semi-colon, when the second command drops into ifsbreakup the command > will be evaluated with the ifslastp/ifsfirst struct that was set when > the here doc was evaluated. This results in a buffer over-read that > can leak the program's heap, stack, and arena addresses which can be > used to beat ASLR. > > Steps to Reproduce: > First bug: > cmd args: ~/exampleDir/example> dash > $ M='AAAAAAAAAAAAAAAAA' <note: 17 A's> > $ q00(){ > $ <<000;echo > $ ${D?$M$M$M$M$M$M} <note: 6 $M's> > $ 000 > $ } > $ q00 <note: After the q00 is typed in, the leak > should be echo'd out; this works with ash, busybox ash, and dash and > with all option args.> > > Patch: > Adding the following to expand.c will fix both bugs in one go. > (Thank you to Harald van Dijk and Michael Greenberg for doing the > heavy lifting for this patch!) > ========================== > --- a/src/expand.c > +++ b/src/expand.c > @@ -859,6 +859,7 @@ > if (discard) > return -1; > > +ifsfree(); > sh_error("Bad substitution"); > } > > @@ -1739,6 +1740,7 @@ > } else > msg = umsg; > } > +ifsfree(); > sh_error("%.*s: %s%s", end - var - 1, var, msg, tail); > } > ========================== Thanks for the report! I think it's better to add the ifsfree() call to the exception handling path as other sh_error calls may trigger this too. function old new delta restore_handler_expandarg - 33 +33 evaltree 725 711 -14 static.redirectsafe 141 124 -17 expandstr 262 242 -20 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/3 up/down: 36/-45) Total: -18 bytes Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-06join: re-add accidentally removed returnmbartlett212-0/+7
It broke single-character splitting
2026-07-06awk: fix printf "%o\n", -1Denys Vlasenko2-5/+7
function old new delta awk_printf 1381 1387 +6 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-05join: code shrink (5)Ron Yorston1-10/+14
Add a freelines() function to free the line data associated with an FDAT struct. This has no effect in the default build but saves 48-64 bytes if FEATURE_CLEAN_UP is enabled. Change the type of the 'first' flag in readfields() to be consistent with that in printfields(). The 'lines' array should be freed for each FDAT struct during clean up, as it was before I broke it. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-05join: changesmbartlett212-38/+39
Fix combinatorial field_split() now takes in LINE as a parameter, rather than just the fields parameter. Saves 16 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-03join: code shrink (4)Ron Yorston1-25/+26
The user supplies field numbers with the -o, -1 and -2 options. It feels more natural to convert these to 0-based field indices in the code. Saves 32-48 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-03join: code shrink (3)Ron Yorston1-22/+21
When splitting the fields of a line, keep the string allocated for the line and make the 'fields' array point into it rather than allocating a new string for each field. Saves 48 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-03join: code shrink (2)Ron Yorston1-42/+25
Reduce the amount of duplicated code in readfields() by handling a pushed back line inside the main loop, with a flag to indicate the first pass through the loop. Replace some memcpy() calls with structure assignments. Fix a bug in the code to increase the size of the 'lines' array. It set the capacity to either 8 or 0. Saves 112-128 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-03svlogd: fix buffer overrunDenys Vlasenko1-2/+2
Patch by mjmouse9999@gmail.com When running svlogd -tt with a long line of input, the code assumes a buffer of at least linemax+26 length, but that is two bytes longer than the actual buffer with the default of linemax = 1000. fixing that. No code size change. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-03cmp: add KMG suffix for cmp -n MAXCOUNTAnubhav Kokane2-6/+36
Change input to getopt32 from int to char * so that max_count is parsed as string. Use xatol_sfx to convert string to long. function old new delta cmp_main 595 631 +36 .rodata 107121 107120 -1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 36/-1) Total: 35 bytes Signed-off-by: Anubhav Kokane <dev.anubhavk@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-02rpm: respect BB_SYSTEMROOTRon Yorston5-12/+10
Update the 'rpm' applet so it also respects the BB_SYSTEMROOT environment variable. Replace chdir_system_drive() with xchdir_system_drive(), which exits on failure to change directory. Saves 32-36 bytes. (GitHub PR #603) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-07-02dpkg: update prefix (#603)mbartlett211-20/+53
* dpkg: update prefix The prefix now works properly with BB_SYSTEMROOT as it no longer writes everything with a prefixed / For example, with BB_SYSTEMROOT=C:/somepath, the /var/lib/dpkg directory is now underneath that, rather than the root of that drive. Also added handling so that the extracted files are also there. * dpkg: prefix updates For clarity, the .list files now always include leading slashes, matching what happens in upstream. There is then special handling under remove_file_array to turn them back into relative paths. The handling assumes that files can be both, since it does get called with some relative paths. Adds 14-54 bytes.
2026-07-02awk: optimize 'print "no format specs here\n"' caseDenys Vlasenko1-20/+26
function old new delta awk_printf 1349 1381 +32 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-02awk: fix printing of very large numbers with printf("%d")Denys Vlasenko2-89/+179
function old new delta awk_printf 1086 1349 +263 .rodata 107108 107121 +13 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 276/0) Total: 276 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-02awk: rename variables in awk_printf(), no code changesDenys Vlasenko1-34/+36
awk_printf() got bigger, and now variables need better names, even if this makes them longer. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-07-01awk: add '*' as a valid specifier for width and precision in printfDenys Vlasenko2-9/+111
Based on a patch by Anubhav Kokane <dev.anubhavk@gmail.com> function old new delta awk_printf 640 1086 +446 .rodata 107131 107108 -23 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 446/-23) Total: 423 bytes text data bss dec hex filename 1080210 555 4992 1085757 10913d busybox_old 1080633 555 4992 1086180 1092e4 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2026-06-30ash: only report background jobs in root shellRon Yorston1-1/+1
Background jobs were being reported in shells other than an interactive, top-level shell. Suppress this unnecessary report. Adds 16 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-30ash: only copy jobtab if needed for job hackRon Yorston1-6/+9
This script: #!/bin/bash ( ( true ) & ( true ) & ( true ) & ( true ) & ( true ) & ) resulted in a crash. The problem was introduced by commit 7b692ddf0c (ash: improved support for jobs built-in). This commit copies the job table into child shells for use by the 'jobs' built-in. The crash happens because when the job table is cleared in the child it becomes available for reuse. If only four jobs are required this is OK but going over four causes the table to be reallocated. This doesn't work because in the child it's in shared memory. The fix is not to pass the job table to the child unless it's required by the 'jobs' built-in. This is also more efficient. Adds 0-16 bytes. (GitHub issue #604) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-30join: code shrinkRon Yorston1-35/+17
Adopt some BusyBox idioms in join_main(). In particular: - The '-a' and '-v' options are mutually exclusive. Enforce this in getopt32() instead of by hand. Also, since they're mutually exclusive we don't need a distinct list for each. - Control some clean-up code with ENABLE_FEATURE_CLEAN_UP. There are also a few cosmetic changes. Saves 204-256 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-30build system: allow bloatcheck to work (a bit) for llvmRon Yorston1-1/+1
'make bloatcheck' didn't work in the ARM build because it didn't handle the different output formats of llvm's 'objdump' and 'nm'. Allow for 'objdump -h' printing 5 rather than 7 fields. This at least gets us some output. 'nm' always seems to print symbol sizes of zero, though, which isn't very useful. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-26win32: tweak bitmap icon appearanceRon Yorston1-0/+0
Make the corners of the symbolic bitmap icon look more rounded. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-23win32: shrink bitmap iconsRon Yorston2-0/+0
Reduce the colour depth of the bitmap icons from 24-bits colour/ 8-bit alpha to 8-bit colour/1-bit alpha for aterm.ico and 1-bit colour/1-bit alpha for sterm.ico. This reduces the size of the standard builds by 21KB. The builds targeting Windows 10/11 already used smaller PNG icons. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-23sync: handle certain edge casesRon Yorston1-2/+9
Recent changes to our mntent routines added support for Windows volume names. If such a name is available use it in our sync(2) implementation to flush file buffers. Failing that, use the drive letter as before. This handles edge cases where only one or other of the volume name or drive letter is available. Adds 32 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-22test: fix POSIX buildRon Yorston1-0/+2
One Windows-specific line of code wasn't protected by #ifdef. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-22Fix the flags for stat (again) (#601)mbartlett216-30/+33
* Revert "find: reset stat(2) flags before terminating" This reverts commit 228ee18fbe8cf408440e7bbe91db4ef201312983. * test: fix flags for stat with NOFORK test is a NOFORK applet, so the flags under mingw_stat may not have been reset before calling it. We have it so it also restores the flags after, since it could be called in the middle of another applet. This also needed a way to retrieve the flags, so they are just done through the return value. * Add comments about not having to restore flags Just for future reference * lineedit: use new flag restoring * win32: simplify mingw_access calling Since we now have a way to get the previous flags, mingw_access can be changed to ignore any stat flags * stat: comments from PR Adds 32 bytes.
2026-06-19find: reset stat(2) flags before terminatingRon Yorston1-1/+7
Commit a717c6844 (find: skip check for execute when not needed) didn't reset stat(2) to its default behaviour (at my insistence). This was incorrect. The '-exec cmd {} +' action calls a nofork 'cmd' directly without spawning a new process. If 'cmd' calls 'stat(2)' it won't be in its default state which can affect the result. Reintroduce the code to reset 'stat(2)'. Adds 16 bytes. (GitHub PR #600) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-19find: skip check for execute when not neededmbartlett211-0/+25
See previous commits: 1fb1a65064748a54fba4bf4b5e8700f8e61f003f 6a7ccb6ca3bd9b661760879478ecf0d5f6112fc3 My testing shows a speedup of around 30%, but that will vary with whether files are cached. Test inside busybox repository with files cached: Command | before | after find >/dev/null | 0.83s | 0.56s find -executable >/dev/null | 1.56s | 1.35s
2026-06-15df,lsattr: support Unix-like mount pointsmount_pointRon Yorston3-1/+24
Update 'lsattr' to distinguish between mount points and junctions. Use the new 'mntent' functions in 'df' to display mount points as well as drive letters. If mount point is associated with a drive letter this is displayed as the filesystem. The Windows-specific '-w' option forces the volume name to be displayed instead, if avaialable. Adds 87-111 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-15win32: Unix-like support for volume mountsRon Yorston5-98/+229
Add code to distinguish between volume mount points and junctions. Volume mount points are to be treated like directries while junctions are like symlinks. Update the 'mntent' functions to scan drive letters first, then volume names and their associated mount points. By default the filesystem is returned as a drive letter, if possible, though the volume name is also returned. The function 'find_mount_point()' has been updated to use the new 'mntent' routines. Adds 772-803 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-15ash: scan drives directly for 'pwd -a'Ron Yorston1-8/+6
The shell builtin 'pwd' takes a Windows-specific '-a' option to display the current directory on each drive. Use Windows APIs directly to scan for valid drives instead of 'getmntent()'. Future changes will result in 'getmntent()' returning mounted volumes as well as drives. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-08win32: extend handling of virtual disksRon Yorston3-7/+20
Commit 62e4c5d29 (win32: special treatment for virtual hard disk) added special treatment for mount points associated with virtual hard disks. One statement made there was incorrect: a VHD without a drive letter containing no files *does* have a '.' directory. The error message for this case was misleading. The changes made to handle VHDs were insufficiently general: - lstat(2) only resolved symlinks for the explicit path '.'. It should also do so for paths of the form 'path/to/.'. - opendir(3) only generated entries for '.' and '..' directories when FindFirstFileA() failed for the path '.'. It should also do so for any path which resolves to a volume mount point. Make the necessary changes. Adds 64-80 bytes. (GitHub issue #597) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-07win32: special treatment for virtual hard diskRon Yorston2-4/+14
Virtual hard disks (VHD) without a drive letter gave incorrect results in 'ls' and 'stat'. There were two problems: - If the disk is empty it doesn't have a '.' directory. - If it contains files the '.' directory is actually the mount point, which looks like a symbolic link and can't be opened as a directory. Modify our 'stat(2)' and 'opendir(3)' implementations to handle these quirks. Adds 78-80 bytes. (GitHub issue #597) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-06win32: update current directory to target of symlinkRon Yorston1-0/+4
If busybox.exe was started from a Windows command line in a directory which was the target of a symlink (or equivalent) 'ls' and 'stat' were unable to report the correct details of the current directory. Call 'chdir()' from the BusyBox main program to update our notion of our current directory. Adds 16 bytes. (GitHub issue #597) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-06win32: avoid problems with forward slashes in path to cmd.exeRon Yorston1-3/+5
Running 'C:/Windows/System32/cmd.exe' from the shell was found to have the unxpected result of creating the directory '.exe'. This is due to the weirdness of cmd.exe. A similar problem with batch files was already being handled in `spawnveq()` by converting forward slashes to backslashes in the path to the executable file. Doing this unconditionally will fix the above case too. (GitHub issue #598) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-05lsattr: clarify output for reparse/mount pointsRon Yorston2-4/+4
The 'lsattr' applet identified three specific types of reparse points: junctions, symbolic links and app exec links. Any other type was just shown as a reparse point. A junction is actually a specific type of mount point; a volume mount is another. The description 'junction' has been changed to the more generic 'mount point'. 'lsattr' doesn't distinguish between volume mounts and junctions. Change the help text to say 'Unidentified reparse point' for reparse point which aren't a mount point, symlink or app exec link. Adds 29 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-06-04win32: special treatment for mounted volumesRon Yorston1-0/+9
It was reported that a mounted volume looked like a broken symlink and that changing to the mount directory failed. Preserve the format of the volume name when resolving the link. Adds 84-96 bytes. (GitHub issue #597) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-05-31ash: don't treat process substitutions as background jobsRon Yorston1-3/+7
Commit bda604a70 (ash: prevent leakage of process handles) added job tracking for process substitutions. This had the unwanted side-effect that if the user tried to exit from the shell after a command involving process substitution the shell reported that background jobs were present and refused to exit. Use the flag introduced in commit e6c716317 (ash: don't report completion of process substitution) to avoid this. Adds 16 bytes. (GitHub issue #587) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-05-26stty: code shrinkRon Yorston2-4/+12
The current implementation of 'stty' for Windows only uses a limited subset of the flags in 'struct termios'. Remove some unused features. Saves 16-40 bytes. Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-05-24ash: read built-in should respect stty -echoRon Yorston1-1/+11
If echo has been disabled by the command 'stty -echo' the shell 'read' built-in should match its behaviour on Linux and not echo keyboard input. Adds 32-48 bytes. (GitHub issue #594) Signed-off-by: Ron Yorston <rmy@pobox.com>
2026-05-22win32: fix incorrect change to tcgetattr()Ron Yorston1-1/+1
Commit a560fdf23 (win32: better handling of console state) changed to using CONIN$/CONOUT$ to handle terminal modes. In tcgetattr() CONOUT$ was used instead of CONIN$, leading to incorrect mode bits being fetched. Saves 8-16 bytes. (GitHub issue #594) Signed-off-by: Ron Yorston <rmy@pobox.com>