3581 Commits

Author SHA1 Message Date
Rob Landley
5d1fd7a302 Instead of warming, make logpath depend on the multiplexer being disabled. 2025-05-01 14:04:04 -05:00
Rob Landley
5131a2bc6d Don't wildcard expand . and .. 2025-04-29 12:21:18 -05:00
Rob Landley
df570102af Implement chmod -cv 2025-04-28 17:39:27 -05:00
Rob Landley
c8ad718b72 Add a simple no option hd. 2025-04-25 15:18:46 -05:00
Rob Landley
7e099a6d54 Add TOYFLAG_MOREHELP(CFG_BLAH) to allow annotated help text to drop out
when a second config symbol isn't defined. Use this for various LSM -Z
flags, PASSWD_SAD, sort -g, and wget's https support. This replaces the
old help text merging scripts/config2help.c used to do.

The annotation is a leading !, which removes the next char from usage:
lines and the whole line from the rest of the help text. The ! is always
removed, and the data it marks is only shown if the argument to
TOYFLAG_MOREHELP() is true at compile time.

In theory this plumbing should drop out when not used, like lib/args.c.
2025-04-23 07:35:05 -05:00
Rob Landley
ab1de187e2 Add printf -r NUM to repeat, with -r 0 acting like "yes".
(Note: you can't output a NUL byte with yes, but can with printf.)
2025-04-22 08:06:44 -05:00
Rob Landley
84749b1b7f test -nt and -ot treat existing file as always newer than missing. 2025-04-20 13:06:38 -05:00
Rob Landley
66fabe6c31 Allow tar -T /dev/null to create an empty archive. 2025-04-18 11:08:03 -05:00
Jeffery Miller
3cdebafe3f dd: Add support for conv=nocreat
With `conv=nocreat` set O_CREAT will not be set when
creating the output file, causing an error if of does
not exist.

Test: dd if=/dev/zero of=/tmp/doesnotexist conv=nocreat count=1
2025-04-17 20:30:30 -05:00
Rob Landley
811d660743 Inline and clean up a function that Dmitry Koroban pointed out was
trying to memcpy of a byte into an int.
2025-04-17 20:08:33 -05:00
Rob Landley
71e619c473 Properly indent help text. 2025-04-07 08:53:57 -05:00
Rob Landley
2e23fe9487 No need for killall5 to depend on kill, and let kill -l list multiple
signals (which bash's kill can do but debian's /bin/kill can't).
2025-04-07 07:53:26 -05:00
Rob Landley
2422a3060d Use strany() instead of enum and strcmp staircase. 2025-03-25 20:13:14 -05:00
Aleksander Morgado
61211fb63a android/log: allow selecting log buffer with '-b'
Instead of unconditionally logging on the main buffer, allow choosing
the buffer where the log should be sent. The default Android buffers
are supported.
2025-03-25 04:49:35 -05:00
Rob Landley
2cc5e25fb1 Fix xattr error test. 2025-03-09 21:27:05 -05:00
LuK1337
d1101f2fc8 Fix tar SELinux header
When comparing with files created by GNU tar, I noticed the following
difference:

61 RHT.security.selinux=unconfined_u:object_r:user_tmp_t:s0\x00\n
->
60 RHT.security.selinux=unconfined_u:object_r:user_tmp_t:s0\n

After making toybox tar match GNU one, it no longer complains about bad
header when trying to list the files inside.

Test: tar --selinux -cvf /tmp/a.tar /tmp/a
      tar --list -f /tmp/a.tar
2025-03-09 21:10:13 -05:00
Rob Landley
12bbc85e8a Add nologin. 2025-03-03 16:46:06 -06:00
Rob Landley
e54dfcc066 Fix the read() and write() path: zero for small reads and support big endian. 2025-03-02 11:42:57 -06:00
Brian Norris
81cd8a229d lspci: Support 3+ digit register offsets
When dumping registers with -xxxx, addresses will be larger than 2 hex
digits (256), which means we truncate the column/address. This can
confuse attempts at post-processing this output.
2025-02-25 17:38:46 -06:00
Rob Landley
bb23558abe toysh fix: Move input search after initialing $PATH, and fix reversed test. 2025-02-25 15:10:28 -06:00
Rob Landley
f1c49253d1 fix SHLVL increment (getvar() returns value, not name=value) 2025-02-24 11:35:09 -06:00
Kana Steimle
e1f7fa6567 crontab: Make sure crond detects crontab modifications
Currently crond uses the modification time of the crontabs directory
to detect changes to the crontab files to decide whether to reload
them. This works fine when crontab creates or removes crontab files,
but when an existing crontab file is modified or replaced, it doesn't
change the modification time of the directory, so crond doesn't know
it should reload the crontab files. This patch fixes this by making
crontab remove the old crontab file (if it exists) before recreating
it, so the directory's modification time always changes when a crontab
is modified.
2025-02-22 08:23:02 -06:00
Rob Landley
f6d6f933e4 Fix musl build. (The man page documents a typedef, not a struct.) 2025-02-17 21:28:00 -06:00
Rob Landley
f415909d9d Minor cleanup. 2025-02-17 21:16:50 -06:00
Brian Mayer
1f2db32973 getty: fixed double backslash not being printed 2025-02-17 20:31:30 -06:00
Rob Landley
6225bb45dc Preserve original exitval after trap handler. 2025-02-14 14:08:33 -06:00
Rob Landley
751b5399a9 Implement trap and signal handling. 2025-02-10 22:20:21 -06:00
Brian Norris
ff667cc643 pgrep: Implement -a
pgrep currently implements -l and -f, but not -a. It also inadvertently
treats -f as a combination of -a and -f, where we both filter via the
full command line and display the full command line. This violates
--help, where -f says "Check full command line for PATTERN".

Implement -a, which takes care of displaying the full command line, and
return -f to simply checking (filtering) via command line.
2025-02-06 16:13:42 -06:00
Brian Norris
b0fd644dc9 pgrep: Complain about invalid options
pgrep will silently eat unknown args and treat them as process filters.
This is especially confusing for unimplemented options, like "-a".

If one needs to filter on a flag-like filter, there's always a "--"
separator, like:

  pgrep -- -process-with-dashes
2025-02-06 16:13:10 -06:00
Rob Landley
fd8d5ebc32 Search fields in modinfo need leading \0 to avoid false positives.
Reported by moetayuko.
2025-02-03 07:24:35 -06:00
Rob Landley
1f8deceaaa Start of trap support (not there yet). 2025-01-26 13:40:30 -06:00
Rob Landley
e28bab04a6 Update starter links to SUSv5 2025-01-18 12:24:33 -06:00
Rob Landley
2e9d501730 Move anystr() to lib and have ps.c use it. 2025-01-14 11:42:04 -06:00
Kana Steimle
e3f35d48ce crond: Fix timing
I found a few more issues I wanted to fix, all related to environment
variables.
- When setting a variable in the crontab file, the value would have a
newline at the end of it. That's because getline() returns the line
with a newline at the end, and the code didn't strip that newline out.
- The HOME variable was being sourced from what HOME was set to when
crond was run, rather than what the user's home is in the passwd file.
I believe the intention was to set HOME to what it is in the passwd
file, but allow the crontab to override it.
- I decided to also set LOGNAME to the username of the crontab's
owner, since the posix manpage for crontab mentions that as one of the
variables that should be set.
2025-01-13 10:57:05 -06:00
Kana Steimle
bade4db092 crond: Fix timing
It seems the original author of crond slightly messed up the logic for
checking whether the current time matches the time that was specified.
This patch fixes it.

For some reason there was an OR where there should have been an AND,
which meant if the time and day of month OR the month and day of week
match the current time, the job would run. So you'd get jobs running
every minute if the day of week and month match. And if they didn't
match, you'd still get the job running if the time and day of month
match.

Also, in the tm struct, the day of the month (tm_mday) starts at 1,
not the month (tm_mon).
2025-01-12 16:39:29 -06:00
Rob Landley
4ae60331b0 Cleanup. 2025-01-12 16:03:56 -06:00
Rob Landley
ae55ed7a29 Minor klogd cleanup: fix typos, remove documented NOP operations,
use stpcpy(x, blah) - x instead of strlen+strcpy.
2025-01-12 15:32:07 -06:00
Rob Landley
b099b26fbc Test -nt and -ot should only check nanoseconds when seconds match. 2025-01-05 17:47:03 -06:00
Rob Landley
7a2f81c82d Delete do_source(), replacing blocking recursive calls with FILE *source
in sh_fcall stack. The main processing loop moved back at the end of
sh_main() doing read/parse/run on TT.ff->source, popping the fcall
stack at EOF and exiting when the stack is empty.

The motivation was "trap" needed to call do_source() from a signal handler
(which it couldn't, even with longjmp) but the result is a noticeably
cleaner design removing several special cases.

Each sh_fcall entry now has a FILE *source which (if not NULL) is where to
read the next line from: "source" is now basically TT.ff->source = fopen(name)
and and "eval" is fmemopen(s, strlen(s), "r"). The starting script and
/etc/profile work like "source", the -c argument works like "eval".
When run_lines() runs out of parsed lines (I.E. TT.ff->pl==NULL),
if TT.ff->source isn't NULL it returns to sh_main(), otherwise it
pops the fcall stack and continues. When sh_main() hits EOF/error on
TT.ff->source it fclose()s it and sets it to NULL so the next call
to run_lines() can pop it and handle trailing cleanup like "eval x && y".
When everything is popped (TT.ff==NULL) the loop exits.

The old design would block until things completed, the new design means
things like "source" add TODO items to the fcall stack which have not
even been started when source_main() returns, so a lot of the
lifetime rules changed, sometimes subtly. For example, the old
do_source(fmemopen("cd .")) style calls in the setup code now run after
the initialization functions return, so the initial value of $_ (the shell
name) was getting overwritten with the "." argument to cd. (It's now
effectively doing "_= cd ." with a prefix assignment to absorb/discard
the update.) The new ff->_ member ("_" is a legal C variable name) solves
a similar problem of $_ updates at the end of "source" and "eval" calls
happening long after source_main() and eval_main() return.

Added reference counting to sh_process, and added sh_process *pp to sh_fcall
to track the TT.ff->arg string lifetimes because free_process() frees them but
when to call that is non-obvious (pp could be backgrounded, etc).
Also removed TT.ff->delete and just have its users always use
TT.ff->pp->delete: the previous code had deletion lists in both places
and the prefix assignment case transplanted pp->delete into ff->delete, which
is one such tangle this redesign smoothed out.

Previously the sh_process's filehandle unredirect list was always processed
at the end of run_command(), but since "command | thingy" and
"function | thingy" do very different things now that doesn't work.
Both need to unredirect() before running "thingy", and most commands finish
before run_command() exits, but source/eval/functions need the redirects to
persist until the fcall context is eventually popped after running the body.
We can't move pp->urd into ff->urd because the redirects are performed
when creating the process (parsing the command line or preparing a pipe
to the next command) before run_command() is called, the relevant fcall
context doesn't exist yet. Answer: have end_fcall() flush and clear urd
for the attached process, if ff->pp isn't NULL end_fcall will
unredirect(ff->pp->urd) of any ff->pp attached to the popped fcall.
(So delete is processed when the last user drops it, but urd is processed
when the FIRST user drops it.)

And run_subshell() sets ff->pp to (void *)1 in the CFG_TOYBOX_FORK child
codepath to signal that end_fcall() should _exit() instead of returning
when this fcall is popped, because a child process running in a subshell
still needs the full fcall stack to resolve layers of local variables,
but should NOT proceeed past the end of its domain to run shell script
that belongs to the parent process. (The previous logic for figuring this
out was one of the most opaque sharp edges in the codebase. There's also
a new TT.forkchild which run_subshell() longjmp()s back to from there,
because the forked child sequencing is unusual at both ends.)

The new design replaces the previous implicit rules to figure out what each
fcall entry meant with much simpler explicit rules. No more "funconly"
argument to end_fcall(): now it always frees one fcall entry (even the last
one, leaving TT.ff null). Each fcall has ->function set if it's a function()
call, ->source set if it's a source of text script lines ("eval" leaves
->name null, "source" sets it), and it's still got the ->var entry with
whiteouts for local variable processing. Calling run_command() creates ONE
fcall entry, which is always there, containing prefix assignments and getting
its source set by source_main() and eval_main(). This means lots of nofork
commands messing with TT.ff got adjusted to look at TT.ff->next instead
because the command's transient function context is not what "break",
"return", "set", or "shift" should be messing with. The old magic "is
ff->var null or not" tests now just check for ff->function.

More cleanup: removed recfile[] (it fclose()s each TT.ff->source instead),
lineno now lives in TT.ff->lineno instead of TT.lineno (no more "oldlineno"
shuffle to match bash behavior), fewer nommu recursion limit checks
(recalculate() still recurses on the C stack but eval eval eval
eval eval eval does not; $(a=$(b=$(c)) forks (subshell) children and waits
for them), parse_line() no longer takes an sh_pipeline argument (just uses
TT.ff->pl) and no longer has a second instance of cleanup code in its
error path (sh_main handles it), get_next_line() no longer returns (void *)1
for "invalid" but just NULL or a string (things like sourcing an ELF binary
now force invalid UTF-8 sequence detection), get_next_line() no longer
takes a special NULL argument meaning "stdin but interactive": when the
first argument is NULL it returns NULL (meaning EOF/error) immediately,
nommu_entry() and subshell_setup() behave similarly: both return instead
of one blocking and the other returning, each cues up the appropriate
input source(s) in the TT.ff stack, and the setup logic has mostly moved
into the setup functions instead of being at the start of sh_main().

Deleting do_source() removed the need for a function prototype (alas
free_pipeline()/free_function() and setvar()/recalculate() can still loop),

New sherror_msg() function to display source/function and lineno,
replacing calls to perror_msg() and being called by syntax_err().
Switch perror_msg() to sherror_msg() to display source/function and lineno.

Cleaned up setvar_found()'s handling of the freeable argument,
call_function() now returns the new TT.ff so we can just -> tweak it
right after the call.
2024-12-30 18:44:15 -06:00
Rob Landley
ce5c8ab344 Use tar -Z as short option for --zstd.
Yes I'm aware of "compress" but don't expect it to make a comeback.
2024-12-07 23:40:27 -06:00
Elliott Hughes
2b58072c46 file, tar: basic zstd awareness.
We're seeing ever more zstd-compressed files in the wild, so even though
toybox can't compress/decompress zstd without an external helper, it
still seems useful to integrate with any that happens to be on the
system.
2024-12-07 23:33:35 -06:00
Rob Landley
b1f23f37b5 patch -F0 should disable fuzz support. 2024-12-07 05:59:37 -06:00
Ray Gardner
46e22bce88 Remove getline() / getdelim() declarations
getdelim() is no longer used; getline() declaration not needed in toybox. Make adjustments.
2024-12-03 14:09:49 -06:00
Ray Gardner
538b7620f5 Fix bugs setting NF=0 or negative
Setting NF=0 didn't work and setting it negative failed to abort. Setting NF=0 now sets $0 to an empty string. Also fixed call to wrong err msg func in run.c
2024-12-03 14:09:00 -06:00
Ray Gardner
c7cfe2d949 Fix clang warning; remove incorrect comment 2024-12-03 14:08:38 -06:00
Rob Landley
6b02f02915 For compatibility with gcc 14. 2024-12-02 21:50:39 -06:00
Rob Landley
97b5ea16cf Fix backslash parsing in $'' so \' doesn't end quote context. 2024-11-23 02:53:29 -06:00
Rob Landley
cfef2aabc1 Cleanups and bugfixes. Leak less memory, pass tests with ASAN=1. 2024-11-22 23:29:04 -06:00
Rob Landley
4b238cf6c5 Don't output "length" byte at start of text replies. 2024-11-16 17:03:27 -06:00
Rob Landley
30f6d6ca77 Detect truncated replies, minor cleanups, better error messages. 2024-11-16 17:02:47 -06:00