summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-06-25 17:11:54 +0000
committerEric Andersen <andersen@codepoet.org>2001-06-25 17:11:54 +0000
commit2d848a476ac212046bcda453c8bc3da5fcaff5d3 (patch)
tree10d660a6497b2854c1846de302a2cef05d621d9c
parent2e6d3cfa82eb64fffe53ccb5669aa7146228cf8f (diff)
downloadbusybox-w32-2d848a476ac212046bcda453c8bc3da5fcaff5d3.tar.gz
busybox-w32-2d848a476ac212046bcda453c8bc3da5fcaff5d3.tar.bz2
busybox-w32-2d848a476ac212046bcda453c8bc3da5fcaff5d3.zip
This should finish off the job control issues with lash. Make certain
we have a controlling terminal... -Erik
-rw-r--r--lash.c61
-rw-r--r--shell/lash.c61
2 files changed, 92 insertions, 30 deletions
diff --git a/lash.c b/lash.c
index 689c720f6..68f673539 100644
--- a/lash.c
+++ b/lash.c
@@ -44,6 +44,7 @@
44#include <sys/wait.h> 44#include <sys/wait.h>
45#include <unistd.h> 45#include <unistd.h>
46#include <getopt.h> 46#include <getopt.h>
47#include <termios.h>
47#include "busybox.h" 48#include "busybox.h"
48#include "cmdedit.h" 49#include "cmdedit.h"
49 50
@@ -181,7 +182,8 @@ static int argc;
181static char **argv; 182static char **argv;
182static struct close_me *close_me_head; 183static struct close_me *close_me_head;
183static unsigned int last_jobid; 184static unsigned int last_jobid;
184 185static int shell_terminal;
186static pid_t shell_pgrp;
185static char *PS1; 187static char *PS1;
186static char *PS2 = "> "; 188static char *PS2 = "> ";
187 189
@@ -299,10 +301,9 @@ static int builtin_fg_bg(struct child_prog *child)
299 } 301 }
300 302
301 if (*child->argv[0] == 'f') { 303 if (*child->argv[0] == 'f') {
302 /* Make this job the foreground job */ 304 /* Put the job into the foreground. */
303 /* suppress messages when run from /linuxrc mag@sysgo.de */ 305 tcsetpgrp(shell_terminal, job->pgrp);
304 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) 306
305 perror_msg("tcsetpgrp");
306 child->family->job_list->fg = job; 307 child->family->job_list->fg = job;
307 } 308 }
308 309
@@ -310,10 +311,11 @@ static int builtin_fg_bg(struct child_prog *child)
310 for (i = 0; i < job->num_progs; i++) 311 for (i = 0; i < job->num_progs; i++)
311 job->progs[i].is_stopped = 0; 312 job->progs[i].is_stopped = 0;
312 313
313 kill(-job->pgrp, SIGCONT);
314
315 job->stopped_progs = 0; 314 job->stopped_progs = 0;
316 315
316 if (kill(- job->pgrp, SIGCONT) < 0)
317 perror_msg("kill (SIGCONT)");
318
317 return EXIT_SUCCESS; 319 return EXIT_SUCCESS;
318} 320}
319 321
@@ -1081,7 +1083,7 @@ static void insert_job(struct job *newjob, int inbg)
1081 1083
1082 /* move the new process group into the foreground */ 1084 /* move the new process group into the foreground */
1083 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1085 /* suppress messages when run from /linuxrc mag@sysgo.de */
1084 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY) 1086 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
1085 perror_msg("tcsetpgrp"); 1087 perror_msg("tcsetpgrp");
1086 } 1088 }
1087} 1089}
@@ -1131,7 +1133,13 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1131 } 1133 }
1132 1134
1133 if (!(child->pid = fork())) { 1135 if (!(child->pid = fork())) {
1136 /* Set the handling for job control signals back to the default. */
1137 signal(SIGINT, SIG_DFL);
1138 signal(SIGQUIT, SIG_DFL);
1139 signal(SIGTSTP, SIG_DFL);
1140 signal(SIGTTIN, SIG_DFL);
1134 signal(SIGTTOU, SIG_DFL); 1141 signal(SIGTTOU, SIG_DFL);
1142 signal(SIGCHLD, SIG_DFL);
1135 1143
1136 close_all(); 1144 close_all();
1137 1145
@@ -1192,14 +1200,10 @@ static int busy_loop(FILE * input)
1192 newjob.job_context = DEFAULT_CONTEXT; 1200 newjob.job_context = DEFAULT_CONTEXT;
1193 1201
1194 /* save current owner of TTY so we can restore it on exit */ 1202 /* save current owner of TTY so we can restore it on exit */
1195 parent_pgrp = tcgetpgrp(0); 1203 parent_pgrp = tcgetpgrp(shell_terminal);
1196 1204
1197 command = (char *) xcalloc(BUFSIZ, sizeof(char)); 1205 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1198 1206
1199 /* don't pay any attention to this signal; it just confuses
1200 things and isn't really meant for shells anyway */
1201 signal(SIGTTOU, SIG_IGN);
1202
1203 while (1) { 1207 while (1) {
1204 if (!job_list.fg) { 1208 if (!job_list.fg) {
1205 /* no job is in the foreground */ 1209 /* no job is in the foreground */
@@ -1266,7 +1270,7 @@ static int busy_loop(FILE * input)
1266 if (!job_list.fg) { 1270 if (!job_list.fg) {
1267 /* move the shell to the foreground */ 1271 /* move the shell to the foreground */
1268 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1272 /* suppress messages when run from /linuxrc mag@sysgo.de */
1269 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) 1273 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1270 perror_msg("tcsetpgrp"); 1274 perror_msg("tcsetpgrp");
1271 } 1275 }
1272 } 1276 }
@@ -1274,7 +1278,7 @@ static int busy_loop(FILE * input)
1274 free(command); 1278 free(command);
1275 1279
1276 /* return controlling TTY back to parent process group before exiting */ 1280 /* return controlling TTY back to parent process group before exiting */
1277 if (tcsetpgrp(0, parent_pgrp)) 1281 if (tcsetpgrp(shell_terminal, parent_pgrp))
1278 perror_msg("tcsetpgrp"); 1282 perror_msg("tcsetpgrp");
1279 1283
1280 /* return exit status if called with "-c" */ 1284 /* return exit status if called with "-c" */
@@ -1300,6 +1304,32 @@ void free_memory(void)
1300} 1304}
1301#endif 1305#endif
1302 1306
1307/* Make sure we have a controlling tty. If we get started under a job
1308 * aware app (like bash for example), make sure we are now in charge so
1309 * we don't fight over who gets the foreground */
1310static void setup_job_control()
1311{
1312 /* Loop until we are in the foreground. */
1313 while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
1314 kill (- shell_pgrp, SIGTTIN);
1315
1316 /* Ignore interactive and job-control signals. */
1317 signal(SIGINT, SIG_IGN);
1318 signal(SIGQUIT, SIG_IGN);
1319 signal(SIGTSTP, SIG_IGN);
1320 signal(SIGTTIN, SIG_IGN);
1321 signal(SIGTTOU, SIG_IGN);
1322 signal(SIGCHLD, SIG_IGN);
1323
1324 /* Put ourselves in our own process group. */
1325 shell_pgrp = getpid ();
1326 if (setpgid (shell_pgrp, shell_pgrp) < 0) {
1327 perror_msg_and_die("Couldn't put the shell in its own process group");
1328 }
1329
1330 /* Grab control of the terminal. */
1331 tcsetpgrp(shell_terminal, shell_pgrp);
1332}
1303 1333
1304int shell_main(int argc_l, char **argv_l) 1334int shell_main(int argc_l, char **argv_l)
1305{ 1335{
@@ -1359,6 +1389,7 @@ int shell_main(int argc_l, char **argv_l)
1359 isatty(fileno(stdin)) && isatty(fileno(stdout))) { 1389 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1360 interactive=TRUE; 1390 interactive=TRUE;
1361 } 1391 }
1392 setup_job_control();
1362 if (interactive==TRUE) { 1393 if (interactive==TRUE) {
1363 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]); 1394 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1364 /* Looks like they want an interactive shell */ 1395 /* Looks like they want an interactive shell */
diff --git a/shell/lash.c b/shell/lash.c
index 689c720f6..68f673539 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -44,6 +44,7 @@
44#include <sys/wait.h> 44#include <sys/wait.h>
45#include <unistd.h> 45#include <unistd.h>
46#include <getopt.h> 46#include <getopt.h>
47#include <termios.h>
47#include "busybox.h" 48#include "busybox.h"
48#include "cmdedit.h" 49#include "cmdedit.h"
49 50
@@ -181,7 +182,8 @@ static int argc;
181static char **argv; 182static char **argv;
182static struct close_me *close_me_head; 183static struct close_me *close_me_head;
183static unsigned int last_jobid; 184static unsigned int last_jobid;
184 185static int shell_terminal;
186static pid_t shell_pgrp;
185static char *PS1; 187static char *PS1;
186static char *PS2 = "> "; 188static char *PS2 = "> ";
187 189
@@ -299,10 +301,9 @@ static int builtin_fg_bg(struct child_prog *child)
299 } 301 }
300 302
301 if (*child->argv[0] == 'f') { 303 if (*child->argv[0] == 'f') {
302 /* Make this job the foreground job */ 304 /* Put the job into the foreground. */
303 /* suppress messages when run from /linuxrc mag@sysgo.de */ 305 tcsetpgrp(shell_terminal, job->pgrp);
304 if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) 306
305 perror_msg("tcsetpgrp");
306 child->family->job_list->fg = job; 307 child->family->job_list->fg = job;
307 } 308 }
308 309
@@ -310,10 +311,11 @@ static int builtin_fg_bg(struct child_prog *child)
310 for (i = 0; i < job->num_progs; i++) 311 for (i = 0; i < job->num_progs; i++)
311 job->progs[i].is_stopped = 0; 312 job->progs[i].is_stopped = 0;
312 313
313 kill(-job->pgrp, SIGCONT);
314
315 job->stopped_progs = 0; 314 job->stopped_progs = 0;
316 315
316 if (kill(- job->pgrp, SIGCONT) < 0)
317 perror_msg("kill (SIGCONT)");
318
317 return EXIT_SUCCESS; 319 return EXIT_SUCCESS;
318} 320}
319 321
@@ -1081,7 +1083,7 @@ static void insert_job(struct job *newjob, int inbg)
1081 1083
1082 /* move the new process group into the foreground */ 1084 /* move the new process group into the foreground */
1083 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1085 /* suppress messages when run from /linuxrc mag@sysgo.de */
1084 if (tcsetpgrp(0, newjob->pgrp) && errno != ENOTTY) 1086 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
1085 perror_msg("tcsetpgrp"); 1087 perror_msg("tcsetpgrp");
1086 } 1088 }
1087} 1089}
@@ -1131,7 +1133,13 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1131 } 1133 }
1132 1134
1133 if (!(child->pid = fork())) { 1135 if (!(child->pid = fork())) {
1136 /* Set the handling for job control signals back to the default. */
1137 signal(SIGINT, SIG_DFL);
1138 signal(SIGQUIT, SIG_DFL);
1139 signal(SIGTSTP, SIG_DFL);
1140 signal(SIGTTIN, SIG_DFL);
1134 signal(SIGTTOU, SIG_DFL); 1141 signal(SIGTTOU, SIG_DFL);
1142 signal(SIGCHLD, SIG_DFL);
1135 1143
1136 close_all(); 1144 close_all();
1137 1145
@@ -1192,14 +1200,10 @@ static int busy_loop(FILE * input)
1192 newjob.job_context = DEFAULT_CONTEXT; 1200 newjob.job_context = DEFAULT_CONTEXT;
1193 1201
1194 /* save current owner of TTY so we can restore it on exit */ 1202 /* save current owner of TTY so we can restore it on exit */
1195 parent_pgrp = tcgetpgrp(0); 1203 parent_pgrp = tcgetpgrp(shell_terminal);
1196 1204
1197 command = (char *) xcalloc(BUFSIZ, sizeof(char)); 1205 command = (char *) xcalloc(BUFSIZ, sizeof(char));
1198 1206
1199 /* don't pay any attention to this signal; it just confuses
1200 things and isn't really meant for shells anyway */
1201 signal(SIGTTOU, SIG_IGN);
1202
1203 while (1) { 1207 while (1) {
1204 if (!job_list.fg) { 1208 if (!job_list.fg) {
1205 /* no job is in the foreground */ 1209 /* no job is in the foreground */
@@ -1266,7 +1270,7 @@ static int busy_loop(FILE * input)
1266 if (!job_list.fg) { 1270 if (!job_list.fg) {
1267 /* move the shell to the foreground */ 1271 /* move the shell to the foreground */
1268 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1272 /* suppress messages when run from /linuxrc mag@sysgo.de */
1269 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) 1273 if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
1270 perror_msg("tcsetpgrp"); 1274 perror_msg("tcsetpgrp");
1271 } 1275 }
1272 } 1276 }
@@ -1274,7 +1278,7 @@ static int busy_loop(FILE * input)
1274 free(command); 1278 free(command);
1275 1279
1276 /* return controlling TTY back to parent process group before exiting */ 1280 /* return controlling TTY back to parent process group before exiting */
1277 if (tcsetpgrp(0, parent_pgrp)) 1281 if (tcsetpgrp(shell_terminal, parent_pgrp))
1278 perror_msg("tcsetpgrp"); 1282 perror_msg("tcsetpgrp");
1279 1283
1280 /* return exit status if called with "-c" */ 1284 /* return exit status if called with "-c" */
@@ -1300,6 +1304,32 @@ void free_memory(void)
1300} 1304}
1301#endif 1305#endif
1302 1306
1307/* Make sure we have a controlling tty. If we get started under a job
1308 * aware app (like bash for example), make sure we are now in charge so
1309 * we don't fight over who gets the foreground */
1310static void setup_job_control()
1311{
1312 /* Loop until we are in the foreground. */
1313 while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
1314 kill (- shell_pgrp, SIGTTIN);
1315
1316 /* Ignore interactive and job-control signals. */
1317 signal(SIGINT, SIG_IGN);
1318 signal(SIGQUIT, SIG_IGN);
1319 signal(SIGTSTP, SIG_IGN);
1320 signal(SIGTTIN, SIG_IGN);
1321 signal(SIGTTOU, SIG_IGN);
1322 signal(SIGCHLD, SIG_IGN);
1323
1324 /* Put ourselves in our own process group. */
1325 shell_pgrp = getpid ();
1326 if (setpgid (shell_pgrp, shell_pgrp) < 0) {
1327 perror_msg_and_die("Couldn't put the shell in its own process group");
1328 }
1329
1330 /* Grab control of the terminal. */
1331 tcsetpgrp(shell_terminal, shell_pgrp);
1332}
1303 1333
1304int shell_main(int argc_l, char **argv_l) 1334int shell_main(int argc_l, char **argv_l)
1305{ 1335{
@@ -1359,6 +1389,7 @@ int shell_main(int argc_l, char **argv_l)
1359 isatty(fileno(stdin)) && isatty(fileno(stdout))) { 1389 isatty(fileno(stdin)) && isatty(fileno(stdout))) {
1360 interactive=TRUE; 1390 interactive=TRUE;
1361 } 1391 }
1392 setup_job_control();
1362 if (interactive==TRUE) { 1393 if (interactive==TRUE) {
1363 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]); 1394 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1364 /* Looks like they want an interactive shell */ 1395 /* Looks like they want an interactive shell */