313
318
/* ============ Shell options */
315
320
/* If you add/change options hare, update --help text too */
316
static const char *const optletters_optnames[] = {
321
static const char *const optletters_optnames[] ALIGN_PTR = {
319
324
/* bash has '-o ignoreeof', but no short synonym -I for it */
665
670
* Called when a SIGINT is received. (If the user specifies
666
671
* that SIGINT is to be trapped or ignored using the trap builtin, then
667
* this routine is not called.) Suppressint is nonzero when interrupts
672
* this routine is not called.) suppress_int is nonzero when interrupts
668
673
* are held using the INT_OFF macro. (The test for iflag is just
669
674
* defensive programming.)
7186
7195
len = orig_len - pos;
7189
loc = mempcpy(startp, startp + pos, len);
7198
/* want: loc = mempcpy(startp, startp + pos, len)
7199
* but it does not allow overlapping arguments */
7201
while (--len >= 0) {
7191
7206
for (vstr = startp; pos != 0; pos--) {
7192
7207
if ((unsigned char)*vstr == CTLESC)
7365
/* The STPUTC invocations above may resize and move the
7366
* stack via realloc(3). Since repl is a pointer into the
7367
* stack, we need to reconstruct it relative to stackblock().
7370
repl = (char *)stackblock() + strloc + slash_pos + 1;
7348
7372
//bb_error_msg("repl:'%s'", repl);
7349
7373
for (loc = (char*)repl; *loc; loc++) {
7350
7374
char *restart_detect = stackblock();
9748
9773
#if ENABLE_FEATURE_EDITING
9749
9774
if (!line_input_state) {
9750
9775
line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
9751
# if EDITING_HAS_get_exe_name
9776
# if ENABLE_FEATURE_TAB_COMPLETION
9752
9777
line_input_state->get_exe_name = get_builtin_name;
9779
# if EDITING_HAS_sh_get_var
9780
line_input_state->sh_get_var = lookupvar;
10136
10164
#if ENABLE_ASH_TEST || BASH_TEST2
10137
10165
static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); }
10167
#if ENABLE_ASH_SLEEP
10168
static int FAST_FUNC sleepcmd(int argc, char **argv) { return sleep_main(argc, argv); }
10140
10171
/* Keep these in proper order since it is searched via bsearch() */
10141
10172
static const struct builtincmd builtintab[] = {
10198
10229
{ BUILTIN_SPEC_REG "return" , returncmd },
10199
10230
{ BUILTIN_SPEC_REG "set" , setcmd },
10200
10231
{ BUILTIN_SPEC_REG "shift" , shiftcmd },
10232
#if ENABLE_ASH_SLEEP
10233
{ BUILTIN_REGULAR "sleep" , sleepcmd },
10201
10235
#if BASH_SOURCE
10202
10236
{ BUILTIN_SPEC_REG "source" , dotcmd },
10784
10818
line_input_state->path_lookup = pathval();
10786
10820
reinit_unicode_for_ash();
10822
/* For shell, LI_INTERRUPTIBLE is set:
10823
* read_line_input will abort on either
10824
* getting EINTR in poll(), or if it sees bb_got_signal != 0
10825
* (IOW: if signal arrives before poll() is reached).
10826
* Interactive testcases:
10827
* (while kill -INT $$; do sleep 1; done) &
10828
* #^^^ prints ^C, prints prompt, repeats
10829
* trap 'echo I' int; (while kill -INT $$; do sleep 1; done) &
10830
* #^^^ prints ^C, prints "I", prints prompt, repeats
10831
* trap 'echo T' term; (while kill $$; do sleep 1; done) &
10832
* #^^^ prints "T", prints prompt, repeats
10833
* #(bash 5.0.17 exits after first "T", looks like a bug)
10836
INT_OFF; /* no longjmp'ing out of read_line_input please */
10787
10837
nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
10838
if (bb_got_signal == SIGINT)
10839
write(STDOUT_FILENO, "^C\n", 3);
10840
INT_ON; /* here non-blocked SIGINT will longjmp */
10788
10841
if (nr == 0) {
10789
10842
/* ^C pressed, "convert" to SIGINT */
10790
write(STDOUT_FILENO, "^C", 2);
10843
write(STDOUT_FILENO, "^C\n", 3);
10844
raise(SIGINT); /* here non-blocked SIGINT will longjmp */
10845
/* raise(SIGINT) did not work! (e.g. if SIGINT
10846
* is SIG_IGNed on startup, it stays SIG_IGNed)
10792
10848
if (trap[SIGINT]) {
10793
10850
buf[0] = '\n';
10794
10851
buf[1] = '\0';
10797
10854
exitstatus = 128 + SIGINT;
10855
/* bash behavior on ^C + ignored SIGINT: */
10800
10858
if (nr < 0) {
10801
10859
if (errno == 0) {
10802
/* Ctrl+D pressed */
10863
else if (errno == EINTR) { /* got signal? */
10864
if (bb_got_signal != SIGINT)
10865
write(STDOUT_FILENO, "\n", 1);
10866
goto empty_line_input;
10805
10868
# if ENABLE_ASH_IDLE_TIMEOUT
10806
10869
else if (errno == EAGAIN && timeout > 0) {
10807
10870
puts("\007timed out waiting for input: auto-logout");
11202
11265
* Print appropriate message(s) if mail has arrived.
11203
11266
* If mail_var_path_changed is set,
11204
* then the value of MAIL has mail_var_path_changed,
11205
* so we just update the values.
11267
* then the value of MAIL has changed,
11268
* so we just update the hash value.
11208
11271
chkmail(void)