aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-28 16:48:27 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-28 16:48:27 +0000
commite3f2f8989139f00e94473882366bd665d4fcc800 (patch)
treec837d9d68385cb55f96f428e0e02de16f1fb9031
parentb81b3df1fa387fa5c6a3fe577969285858f494ce (diff)
downloadbusybox-w32-e3f2f8989139f00e94473882366bd665d4fcc800.tar.gz
busybox-w32-e3f2f8989139f00e94473882366bd665d4fcc800.tar.bz2
busybox-w32-e3f2f8989139f00e94473882366bd665d4fcc800.zip
hush: make job control and interactiveness configurable, part 2
-rw-r--r--shell/Config.in18
-rw-r--r--shell/hush.c133
2 files changed, 99 insertions, 52 deletions
diff --git a/shell/Config.in b/shell/Config.in
index 81289e4fd..f3726e302 100644
--- a/shell/Config.in
+++ b/shell/Config.in
@@ -181,9 +181,21 @@ config HUSH_INTERACTIVE
181 default y 181 default y
182 depends on HUSH 182 depends on HUSH
183 help 183 help
184 Enable interactive mode (Ctrl-Z, Ctrl-C, command editing) 184 Enable interactive mode (prompt and command editing).
185 in the hush shell. Without this, hush reads and executes 185 Without this, hush simply reads and executes commands
186 stdin just like a shell script from the file. 186 from stdin just like a shell script from the file.
187 No prompt, no PS1/PS2 magic shell variables.
188
189config HUSH_JOB
190 bool "Job control"
191 default n
192 depends on HUSH_INTERACTIVE
193 help
194 Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
195 command (not entire shell), fg/bg builtins work. Without this option,
196 "cmd &" still works by simply spawning a process and immediately
197 prompting for next command (or executing next command in a script),
198 but no separate process group is formed.
187 199
188 200
189config LASH 201config LASH
diff --git a/shell/hush.c b/shell/hush.c
index 57a4ac04f..850b38f37 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -86,10 +86,6 @@
86/* Finer-grained debug switch */ 86/* Finer-grained debug switch */
87//#define DEBUG_SHELL_JOBS 87//#define DEBUG_SHELL_JOBS
88 88
89//TODO: rename HUSH_INTERACTIVE -> HUSH_JOB,
90//create HUSH_INTERACTIVE which controls only prompt + line editing,
91//make HUSH_JOB dependent on it
92
93#if !ENABLE_HUSH_INTERACTIVE 89#if !ENABLE_HUSH_INTERACTIVE
94#undef ENABLE_FEATURE_EDITING 90#undef ENABLE_FEATURE_EDITING
95#define ENABLE_FEATURE_EDITING 0 91#define ENABLE_FEATURE_EDITING 0
@@ -204,7 +200,7 @@ struct pipe {
204 int num_progs; /* total number of programs in job */ 200 int num_progs; /* total number of programs in job */
205 int running_progs; /* number of programs running (not exited) */ 201 int running_progs; /* number of programs running (not exited) */
206 char *cmdbuf; /* buffer various argv's point into */ 202 char *cmdbuf; /* buffer various argv's point into */
207#if ENABLE_HUSH_INTERACTIVE 203#if ENABLE_HUSH_JOB
208 int jobid; /* job number */ 204 int jobid; /* job number */
209 char *cmdtext; /* name of job */ 205 char *cmdtext; /* name of job */
210 pid_t pgrp; /* process group ID for the job */ 206 pid_t pgrp; /* process group ID for the job */
@@ -243,25 +239,26 @@ static int fake_mode;
243static struct close_me *close_me_head; 239static struct close_me *close_me_head;
244static const char *cwd; 240static const char *cwd;
245static unsigned last_bg_pid; 241static unsigned last_bg_pid;
246#if ENABLE_HUSH_INTERACTIVE 242#if !ENABLE_HUSH_INTERACTIVE
247static int last_jobid; 243enum { interactive_fd = 0 };
248static struct pipe *job_list; 244#else
249/* 'interactive_fd' is a fd# open to ctty, if we have one 245/* 'interactive_fd' is a fd# open to ctty, if we have one
250 * _AND_ if we decided to mess with job control */ 246 * _AND_ if we decided to mess with job control */
251static int interactive_fd; 247static int interactive_fd;
248#if ENABLE_HUSH_JOB
252static pid_t saved_task_pgrp; 249static pid_t saved_task_pgrp;
253static pid_t saved_tty_pgrp; 250static pid_t saved_tty_pgrp;
254#else 251static int last_jobid;
255enum { interactive_fd = 0 }; 252static struct pipe *job_list;
256#endif 253#endif
257
258static const char *PS1; 254static const char *PS1;
259static const char *PS2; 255static const char *PS2;
256#endif
257
260static struct variables shell_ver = { NULL, "HUSH_VERSION", "0.01", 1, 1 }; 258static struct variables shell_ver = { NULL, "HUSH_VERSION", "0.01", 1, 1 };
261static struct variables *top_vars = &shell_ver; 259static struct variables *top_vars = &shell_ver;
262 260
263 261#define B_CHUNK 100
264#define B_CHUNK (100)
265#define B_NOSPAC 1 262#define B_NOSPAC 1
266 263
267typedef struct { 264typedef struct {
@@ -280,8 +277,10 @@ typedef struct {
280struct in_str { 277struct in_str {
281 const char *p; 278 const char *p;
282 char peek_buf[2]; 279 char peek_buf[2];
280#if ENABLE_HUSH_INTERACTIVE
283 int __promptme; 281 int __promptme;
284 int promptmode; 282 int promptmode;
283#endif
285 FILE *file; 284 FILE *file;
286 int (*get) (struct in_str *); 285 int (*get) (struct in_str *);
287 int (*peek) (struct in_str *); 286 int (*peek) (struct in_str *);
@@ -323,12 +322,11 @@ static char *indenter(int i)
323 322
324#define final_printf debug_printf 323#define final_printf debug_printf
325 324
326static void __syntax(const char *file, int line) 325static void __syntax(int line)
327{ 326{
328 bb_error_msg("syntax error %s:%d", file, line); 327 bb_error_msg("syntax error hush.c:%d", line);
329} 328}
330/* NB: was __FILE__, but that produces full path sometimes, so... */ 329#define syntax() __syntax(__LINE__)
331#define syntax() __syntax("hush.c", __LINE__)
332 330
333/* Index of subroutines: */ 331/* Index of subroutines: */
334/* function prototypes for builtins */ 332/* function prototypes for builtins */
@@ -338,7 +336,7 @@ static int builtin_eval(char **argv);
338static int builtin_exec(char **argv); 336static int builtin_exec(char **argv);
339static int builtin_exit(char **argv); 337static int builtin_exit(char **argv);
340static int builtin_export(char **argv); 338static int builtin_export(char **argv);
341#if ENABLE_HUSH_INTERACTIVE 339#if ENABLE_HUSH_JOB
342static int builtin_fg_bg(char **argv); 340static int builtin_fg_bg(char **argv);
343static int builtin_jobs(char **argv); 341static int builtin_jobs(char **argv);
344#endif 342#endif
@@ -405,7 +403,7 @@ static int parse_string_outer(const char *s, int flag);
405static int parse_file_outer(FILE *f); 403static int parse_file_outer(FILE *f);
406/* job management: */ 404/* job management: */
407static int checkjobs(struct pipe* fg_pipe); 405static int checkjobs(struct pipe* fg_pipe);
408#if ENABLE_HUSH_INTERACTIVE 406#if ENABLE_HUSH_JOB
409static int checkjobs_and_fg_shell(struct pipe* fg_pipe); 407static int checkjobs_and_fg_shell(struct pipe* fg_pipe);
410static void insert_bg_job(struct pipe *pi); 408static void insert_bg_job(struct pipe *pi);
411static void remove_bg_job(struct pipe *pi); 409static void remove_bg_job(struct pipe *pi);
@@ -427,7 +425,7 @@ static void unset_local_var(const char *name);
427 * For example, 'unset foo | whatever' will parse and run, but foo will 425 * For example, 'unset foo | whatever' will parse and run, but foo will
428 * still be set at the end. */ 426 * still be set at the end. */
429static const struct built_in_command bltins[] = { 427static const struct built_in_command bltins[] = {
430#if ENABLE_HUSH_INTERACTIVE 428#if ENABLE_HUSH_JOB
431 { "bg", "Resume a job in the background", builtin_fg_bg }, 429 { "bg", "Resume a job in the background", builtin_fg_bg },
432#endif 430#endif
433 { "break", "Exit for, while or until loop", builtin_not_written }, 431 { "break", "Exit for, while or until loop", builtin_not_written },
@@ -439,7 +437,7 @@ static const struct built_in_command bltins[] = {
439 builtin_exec }, 437 builtin_exec },
440 { "exit", "Exit from shell()", builtin_exit }, 438 { "exit", "Exit from shell()", builtin_exit },
441 { "export", "Set environment variable", builtin_export }, 439 { "export", "Set environment variable", builtin_export },
442#if ENABLE_HUSH_INTERACTIVE 440#if ENABLE_HUSH_JOB
443 { "fg", "Bring job into the foreground", builtin_fg_bg }, 441 { "fg", "Bring job into the foreground", builtin_fg_bg },
444 { "jobs", "Lists the active jobs", builtin_jobs }, 442 { "jobs", "Lists the active jobs", builtin_jobs },
445#endif 443#endif
@@ -457,7 +455,7 @@ static const struct built_in_command bltins[] = {
457 { NULL, NULL, NULL } 455 { NULL, NULL, NULL }
458}; 456};
459 457
460#if ENABLE_HUSH_INTERACTIVE 458#if ENABLE_HUSH_JOB
461 459
462#if ENABLE_FEATURE_SH_STANDALONE 460#if ENABLE_FEATURE_SH_STANDALONE
463/* move to libbb? */ 461/* move to libbb? */
@@ -727,7 +725,7 @@ static int builtin_export(char **argv)
727 return res; 725 return res;
728} 726}
729 727
730#if ENABLE_HUSH_INTERACTIVE 728#if ENABLE_HUSH_JOB
731/* built-in 'fg' and 'bg' handler */ 729/* built-in 'fg' and 'bg' handler */
732static int builtin_fg_bg(char **argv) 730static int builtin_fg_bg(char **argv)
733{ 731{
@@ -807,7 +805,7 @@ static int builtin_help(char **argv ATTRIBUTE_UNUSED)
807 return EXIT_SUCCESS; 805 return EXIT_SUCCESS;
808} 806}
809 807
810#if ENABLE_HUSH_INTERACTIVE 808#if ENABLE_HUSH_JOB
811/* built-in 'jobs' handler */ 809/* built-in 'jobs' handler */
812static int builtin_jobs(char **argv ATTRIBUTE_UNUSED) 810static int builtin_jobs(char **argv ATTRIBUTE_UNUSED)
813{ 811{
@@ -1032,6 +1030,7 @@ static int static_peek(struct in_str *i)
1032 return *i->p; 1030 return *i->p;
1033} 1031}
1034 1032
1033#if ENABLE_HUSH_INTERACTIVE
1035static void cmdedit_set_initial_prompt(void) 1034static void cmdedit_set_initial_prompt(void)
1036{ 1035{
1037#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT 1036#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
@@ -1065,17 +1064,19 @@ static const char* setup_prompt_string(int promptmode)
1065 debug_printf("result %s\n", prompt_str); 1064 debug_printf("result %s\n", prompt_str);
1066 return prompt_str; 1065 return prompt_str;
1067} 1066}
1067#endif
1068 1068
1069#if ENABLE_FEATURE_EDITING 1069#if ENABLE_FEATURE_EDITING
1070static line_input_t *line_input_state; 1070static line_input_t *line_input_state;
1071#endif 1071#endif
1072 1072
1073#if ENABLE_HUSH_INTERACTIVE
1073static int get_user_input(struct in_str *i) 1074static int get_user_input(struct in_str *i)
1074{ 1075{
1076 static char the_command[ENABLE_FEATURE_EDITING ? BUFSIZ : 2];
1077
1075 int r; 1078 int r;
1076 const char *prompt_str; 1079 const char *prompt_str;
1077 static char the_command[BUFSIZ];
1078
1079 prompt_str = setup_prompt_string(i->promptmode); 1080 prompt_str = setup_prompt_string(i->promptmode);
1080#if ENABLE_FEATURE_EDITING 1081#if ENABLE_FEATURE_EDITING
1081 /* 1082 /*
@@ -1095,6 +1096,7 @@ static int get_user_input(struct in_str *i)
1095 i->p = the_command; 1096 i->p = the_command;
1096 return r; /* < 0 == EOF. Not meaningful otherwise */ 1097 return r; /* < 0 == EOF. Not meaningful otherwise */
1097} 1098}
1099#endif
1098 1100
1099/* This is the magic location that prints prompts 1101/* This is the magic location that prints prompts
1100 * and gets data back from the user */ 1102 * and gets data back from the user */
@@ -1109,7 +1111,8 @@ static int file_get(struct in_str *i)
1109 } else { 1111 } else {
1110 /* need to double check i->file because we might be doing something 1112 /* need to double check i->file because we might be doing something
1111 * more complicated by now, like sourcing or substituting. */ 1113 * more complicated by now, like sourcing or substituting. */
1112 if (i->__promptme && interactive_fd && i->file == stdin) { 1114#if ENABLE_HUSH_INTERACTIVE
1115 if (interactive_fd && i->__promptme && i->file == stdin) {
1113 while (!i->p || !(interactive_fd && i->p[0])) { 1116 while (!i->p || !(interactive_fd && i->p[0])) {
1114 if (get_user_input(i) < 0) 1117 if (get_user_input(i) < 0)
1115 return EOF; 1118 return EOF;
@@ -1119,14 +1122,17 @@ static int file_get(struct in_str *i)
1119 if (i->p && *i->p) { 1122 if (i->p && *i->p) {
1120 ch = *i->p++; 1123 ch = *i->p++;
1121 } 1124 }
1122 } else { 1125 } else
1126#endif
1127 {
1123 ch = fgetc(i->file); 1128 ch = fgetc(i->file);
1124 } 1129 }
1125
1126 debug_printf("b_getch: got a %d\n", ch); 1130 debug_printf("b_getch: got a %d\n", ch);
1127 } 1131 }
1132#if ENABLE_HUSH_INTERACTIVE
1128 if (ch == '\n') 1133 if (ch == '\n')
1129 i->__promptme = 1; 1134 i->__promptme = 1;
1135#endif
1130 return ch; 1136 return ch;
1131} 1137}
1132 1138
@@ -1149,8 +1155,10 @@ static void setup_file_in_str(struct in_str *i, FILE *f)
1149{ 1155{
1150 i->peek = file_peek; 1156 i->peek = file_peek;
1151 i->get = file_get; 1157 i->get = file_get;
1158#if ENABLE_HUSH_INTERACTIVE
1152 i->__promptme = 1; 1159 i->__promptme = 1;
1153 i->promptmode = 1; 1160 i->promptmode = 1;
1161#endif
1154 i->file = f; 1162 i->file = f;
1155 i->p = NULL; 1163 i->p = NULL;
1156} 1164}
@@ -1159,8 +1167,10 @@ static void setup_string_in_str(struct in_str *i, const char *s)
1159{ 1167{
1160 i->peek = static_peek; 1168 i->peek = static_peek;
1161 i->get = static_get; 1169 i->get = static_get;
1170#if ENABLE_HUSH_INTERACTIVE
1162 i->__promptme = 1; 1171 i->__promptme = 1;
1163 i->promptmode = 1; 1172 i->promptmode = 1;
1173#endif
1164 i->p = s; 1174 i->p = s;
1165} 1175}
1166 1176
@@ -1333,7 +1343,7 @@ static void pseudo_exec(struct child_prog *child)
1333 _exit(EXIT_SUCCESS); 1343 _exit(EXIT_SUCCESS);
1334} 1344}
1335 1345
1336#if ENABLE_HUSH_INTERACTIVE 1346#if ENABLE_HUSH_JOB
1337static const char *get_cmdtext(struct pipe *pi) 1347static const char *get_cmdtext(struct pipe *pi)
1338{ 1348{
1339 char **argv; 1349 char **argv;
@@ -1364,7 +1374,7 @@ static const char *get_cmdtext(struct pipe *pi)
1364} 1374}
1365#endif 1375#endif
1366 1376
1367#if ENABLE_HUSH_INTERACTIVE 1377#if ENABLE_HUSH_JOB
1368static void insert_bg_job(struct pipe *pi) 1378static void insert_bg_job(struct pipe *pi)
1369{ 1379{
1370 struct pipe *thejob; 1380 struct pipe *thejob;
@@ -1436,7 +1446,7 @@ static int checkjobs(struct pipe* fg_pipe)
1436{ 1446{
1437 int attributes; 1447 int attributes;
1438 int status; 1448 int status;
1439#if ENABLE_HUSH_INTERACTIVE 1449#if ENABLE_HUSH_JOB
1440 int prognum = 0; 1450 int prognum = 0;
1441 struct pipe *pi; 1451 struct pipe *pi;
1442#endif 1452#endif
@@ -1496,7 +1506,7 @@ static int checkjobs(struct pipe* fg_pipe)
1496 fg_pipe->running_progs, fg_pipe->stopped_progs); 1506 fg_pipe->running_progs, fg_pipe->stopped_progs);
1497 if (fg_pipe->running_progs - fg_pipe->stopped_progs <= 0) { 1507 if (fg_pipe->running_progs - fg_pipe->stopped_progs <= 0) {
1498 /* All processes in fg pipe have exited/stopped */ 1508 /* All processes in fg pipe have exited/stopped */
1499#if ENABLE_HUSH_INTERACTIVE 1509#if ENABLE_HUSH_JOB
1500 if (fg_pipe->running_progs) 1510 if (fg_pipe->running_progs)
1501 insert_bg_job(fg_pipe); 1511 insert_bg_job(fg_pipe);
1502#endif 1512#endif
@@ -1509,7 +1519,7 @@ static int checkjobs(struct pipe* fg_pipe)
1509 /* fall through to searching process in bg pipes */ 1519 /* fall through to searching process in bg pipes */
1510 } 1520 }
1511 1521
1512#if ENABLE_HUSH_INTERACTIVE 1522#if ENABLE_HUSH_JOB
1513 /* We asked to wait for bg or orphaned children */ 1523 /* We asked to wait for bg or orphaned children */
1514 /* No need to remember exitcode in this case */ 1524 /* No need to remember exitcode in this case */
1515 for (pi = job_list; pi; pi = pi->next) { 1525 for (pi = job_list; pi; pi = pi->next) {
@@ -1526,7 +1536,7 @@ static int checkjobs(struct pipe* fg_pipe)
1526 debug_printf("checkjobs: pid %d was not in our list!\n", childpid); 1536 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1527 goto wait_more; 1537 goto wait_more;
1528 1538
1529#if ENABLE_HUSH_INTERACTIVE 1539#if ENABLE_HUSH_JOB
1530 found_pi_and_prognum: 1540 found_pi_and_prognum:
1531 if (dead) { 1541 if (dead) {
1532 /* child exited */ 1542 /* child exited */
@@ -1556,7 +1566,7 @@ static int checkjobs(struct pipe* fg_pipe)
1556 return rcode; 1566 return rcode;
1557} 1567}
1558 1568
1559#if ENABLE_HUSH_INTERACTIVE 1569#if ENABLE_HUSH_JOB
1560static int checkjobs_and_fg_shell(struct pipe* fg_pipe) 1570static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
1561{ 1571{
1562 pid_t p; 1572 pid_t p;
@@ -1575,7 +1585,7 @@ static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
1575static int run_single_fg_nofork(struct pipe *pi, const struct bb_applet *a, 1585static int run_single_fg_nofork(struct pipe *pi, const struct bb_applet *a,
1576 char **argv) 1586 char **argv)
1577{ 1587{
1578#if ENABLE_HUSH_INTERACTIVE 1588#if ENABLE_HUSH_JOB
1579 int rcode; 1589 int rcode;
1580 /* TSTP handler will store pid etc in pi */ 1590 /* TSTP handler will store pid etc in pi */
1581 nofork_pipe = pi; 1591 nofork_pipe = pi;
@@ -1637,7 +1647,7 @@ static int run_pipe_real(struct pipe *pi)
1637 const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG); 1647 const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG);
1638 1648
1639 nextin = 0; 1649 nextin = 0;
1640#if ENABLE_HUSH_INTERACTIVE 1650#if ENABLE_HUSH_JOB
1641 pi->pgrp = -1; 1651 pi->pgrp = -1;
1642#endif 1652#endif
1643 pi->running_progs = 0; 1653 pi->running_progs = 0;
@@ -1766,7 +1776,7 @@ static int run_pipe_real(struct pipe *pi)
1766 if (!child->pid) { /* child */ 1776 if (!child->pid) { /* child */
1767 /* Every child adds itself to new process group 1777 /* Every child adds itself to new process group
1768 * with pgid == pid of first child in pipe */ 1778 * with pgid == pid of first child in pipe */
1769#if ENABLE_HUSH_INTERACTIVE 1779#if ENABLE_HUSH_JOB
1770 if (interactive_fd) { 1780 if (interactive_fd) {
1771 /* Don't do pgrp restore anymore on fatal signals */ 1781 /* Don't do pgrp restore anymore on fatal signals */
1772 set_fatal_sighandler(SIG_DFL); 1782 set_fatal_sighandler(SIG_DFL);
@@ -1805,7 +1815,7 @@ static int run_pipe_real(struct pipe *pi)
1805 1815
1806 pi->running_progs++; 1816 pi->running_progs++;
1807 1817
1808#if ENABLE_HUSH_INTERACTIVE 1818#if ENABLE_HUSH_JOB
1809 /* Second and next children need to know pid of first one */ 1819 /* Second and next children need to know pid of first one */
1810 if (pi->pgrp < 0) 1820 if (pi->pgrp < 0)
1811 pi->pgrp = child->pid; 1821 pi->pgrp = child->pid;
@@ -1937,14 +1947,17 @@ static int run_list_real(struct pipe *pi)
1937 /* XXX check bash's behavior with nontrivial pipes */ 1947 /* XXX check bash's behavior with nontrivial pipes */
1938 /* XXX compute jobid */ 1948 /* XXX compute jobid */
1939 /* XXX what does bash do with attempts to background builtins? */ 1949 /* XXX what does bash do with attempts to background builtins? */
1940#if ENABLE_HUSH_INTERACTIVE 1950#if ENABLE_HUSH_JOB
1941 insert_bg_job(pi); 1951 insert_bg_job(pi);
1942#endif 1952#endif
1943 rcode = EXIT_SUCCESS; 1953 rcode = EXIT_SUCCESS;
1944 } else { 1954 } else {
1955#if ENABLE_HUSH_JOB
1945 if (interactive_fd) { 1956 if (interactive_fd) {
1946 rcode = checkjobs_and_fg_shell(pi); 1957 rcode = checkjobs_and_fg_shell(pi);
1947 } else { 1958 } else
1959#endif
1960 {
1948 rcode = checkjobs(pi); 1961 rcode = checkjobs(pi);
1949 } 1962 }
1950 debug_printf("checkjobs returned %d\n", rcode); 1963 debug_printf("checkjobs returned %d\n", rcode);
@@ -2012,7 +2025,7 @@ static int free_pipe(struct pipe *pi, int indent)
2012 } 2025 }
2013 free(pi->progs); /* children are an array, they get freed all at once */ 2026 free(pi->progs); /* children are an array, they get freed all at once */
2014 pi->progs = NULL; 2027 pi->progs = NULL;
2015#if ENABLE_HUSH_INTERACTIVE 2028#if ENABLE_HUSH_JOB
2016 free(pi->cmdtext); 2029 free(pi->cmdtext);
2017 pi->cmdtext = NULL; 2030 pi->cmdtext = NULL;
2018#endif 2031#endif
@@ -3084,7 +3097,9 @@ static int parse_stream_outer(struct in_str *inp, int flag)
3084 update_ifs_map(); 3097 update_ifs_map();
3085 if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) 3098 if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING))
3086 mapset(";$&|", 0); 3099 mapset(";$&|", 0);
3100#if ENABLE_HUSH_INTERACTIVE
3087 inp->promptmode = 1; 3101 inp->promptmode = 1;
3102#endif
3088 rcode = parse_stream(&temp, &ctx, inp, '\n'); 3103 rcode = parse_stream(&temp, &ctx, inp, '\n');
3089 if (rcode != 1 && ctx.old_flag != 0) { 3104 if (rcode != 1 && ctx.old_flag != 0) {
3090 syntax(); 3105 syntax();
@@ -3124,7 +3139,7 @@ static int parse_file_outer(FILE *f)
3124 return rcode; 3139 return rcode;
3125} 3140}
3126 3141
3127#if ENABLE_HUSH_INTERACTIVE 3142#if ENABLE_HUSH_JOB
3128/* Make sure we have a controlling tty. If we get started under a job 3143/* Make sure we have a controlling tty. If we get started under a job
3129 * aware app (like bash for example), make sure we are now in charge so 3144 * aware app (like bash for example), make sure we are now in charge so
3130 * we don't fight over who gets the foreground */ 3145 * we don't fight over who gets the foreground */
@@ -3183,6 +3198,8 @@ int hush_main(int argc, char **argv)
3183 close_me_head = NULL; 3198 close_me_head = NULL;
3184#if ENABLE_HUSH_INTERACTIVE 3199#if ENABLE_HUSH_INTERACTIVE
3185 interactive_fd = 0; 3200 interactive_fd = 0;
3201#endif
3202#if ENABLE_HUSH_JOB
3186 last_bg_pid = 0; 3203 last_bg_pid = 0;
3187 job_list = NULL; 3204 job_list = NULL;
3188 last_jobid = 0; 3205 last_jobid = 0;
@@ -3190,11 +3207,14 @@ int hush_main(int argc, char **argv)
3190 3207
3191 /* Initialize some more globals to non-zero values */ 3208 /* Initialize some more globals to non-zero values */
3192 set_cwd(); 3209 set_cwd();
3193 if (ENABLE_FEATURE_EDITING) 3210#if ENABLE_HUSH_INTERACTIVE
3194 cmdedit_set_initial_prompt(); 3211#if ENABLE_FEATURE_EDITING
3195 else PS1 = NULL; 3212 cmdedit_set_initial_prompt();
3213#else
3214 PS1 = NULL;
3215#endif
3196 PS2 = "> "; 3216 PS2 = "> ";
3197 3217#endif
3198 /* initialize our shell local variables with the values 3218 /* initialize our shell local variables with the values
3199 * currently living in the environment */ 3219 * currently living in the environment */
3200 e = environ; 3220 e = environ;
@@ -3241,7 +3261,7 @@ int hush_main(int argc, char **argv)
3241#endif 3261#endif
3242 } 3262 }
3243 } 3263 }
3244#if ENABLE_HUSH_INTERACTIVE 3264#if ENABLE_HUSH_JOB
3245 /* A shell is interactive if the '-i' flag was given, or if all of 3265 /* A shell is interactive if the '-i' flag was given, or if all of
3246 * the following conditions are met: 3266 * the following conditions are met:
3247 * no -c command 3267 * no -c command
@@ -3283,6 +3303,21 @@ int hush_main(int argc, char **argv)
3283 printf("Enter 'help' for a list of built-in commands.\n\n"); 3303 printf("Enter 'help' for a list of built-in commands.\n\n");
3284#endif 3304#endif
3285 } 3305 }
3306#elif ENABLE_HUSH_INTERACTIVE
3307/* no job control compiled, only prompt/line editing */
3308 if (argv[optind] == NULL && input == stdin
3309 && isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)
3310 ) {
3311 interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255);
3312 if (interactive_fd < 0) {
3313 /* try to dup to any fd */
3314 interactive_fd = dup(STDIN_FILENO);
3315 if (interactive_fd < 0)
3316 /* give up */
3317 interactive_fd = 0;
3318 }
3319 }
3320
3286#endif 3321#endif
3287 3322
3288 if (argv[optind] == NULL) { 3323 if (argv[optind] == NULL) {