diff options
| -rw-r--r-- | hush.c | 120 | ||||
| -rw-r--r-- | shell/hush.c | 120 |
2 files changed, 148 insertions, 92 deletions
| @@ -470,48 +470,53 @@ static int builtin_export(struct child_prog *child) | |||
| 470 | /* built-in 'fg' and 'bg' handler */ | 470 | /* built-in 'fg' and 'bg' handler */ |
| 471 | static int builtin_fg_bg(struct child_prog *child) | 471 | static int builtin_fg_bg(struct child_prog *child) |
| 472 | { | 472 | { |
| 473 | int i, jobNum; | 473 | int i, jobnum; |
| 474 | struct pipe *job=NULL; | 474 | struct pipe *pi=NULL; |
| 475 | |||
| 476 | if (!child->argv[1] || child->argv[2]) { | ||
| 477 | error_msg("%s: exactly one argument is expected\n", | ||
| 478 | child->argv[0]); | ||
| 479 | return EXIT_FAILURE; | ||
| 480 | } | ||
| 481 | |||
| 482 | if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) { | ||
| 483 | error_msg("%s: bad argument '%s'\n", | ||
| 484 | child->argv[0], child->argv[1]); | ||
| 485 | return EXIT_FAILURE; | ||
| 486 | } | ||
| 487 | 475 | ||
| 488 | for (job = job_list->head; job; job = job->next) { | 476 | /* If they gave us no args, assume they want the last backgrounded task */ |
| 489 | if (job->jobid == jobNum) { | 477 | if (!child->argv[1]) { |
| 490 | break; | 478 | for (pi = job_list->head; pi; pi = pi->next) { |
| 479 | if (pi->progs && pi->progs->pid == last_bg_pid) { | ||
| 480 | break; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | if (!pi) { | ||
| 484 | error_msg("%s: no current job", child->argv[0]); | ||
| 485 | return EXIT_FAILURE; | ||
| 486 | } | ||
| 487 | } else { | ||
| 488 | if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { | ||
| 489 | error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); | ||
| 490 | return EXIT_FAILURE; | ||
| 491 | } | 491 | } |
| 492 | } | ||
| 493 | 492 | ||
| 494 | if (!job) { | 493 | for (pi = job_list->head; pi; pi = pi->next) { |
| 495 | error_msg("%s: unknown job %d\n", | 494 | if (pi->jobid == jobnum) { |
| 496 | child->argv[0], jobNum); | 495 | break; |
| 497 | return EXIT_FAILURE; | 496 | } |
| 497 | } | ||
| 498 | if (!pi) { | ||
| 499 | error_msg("%s: %d: no such job", child->argv[0], jobnum); | ||
| 500 | return EXIT_FAILURE; | ||
| 501 | } | ||
| 498 | } | 502 | } |
| 499 | |||
| 500 | if (*child->argv[0] == 'f') { | 503 | if (*child->argv[0] == 'f') { |
| 501 | /* Make this job the foreground job */ | 504 | /* Make this job the foreground job */ |
| 505 | signal(SIGTTOU, SIG_IGN); | ||
| 502 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 506 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 503 | if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) | 507 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) |
| 504 | perror_msg("tcsetpgrp"); | 508 | perror_msg("tcsetpgrp"); |
| 505 | job_list->fg = job; | 509 | signal(SIGTTOU, SIG_DFL); |
| 510 | job_list->fg = pi; | ||
| 506 | } | 511 | } |
| 507 | 512 | ||
| 508 | /* Restart the processes in the job */ | 513 | /* Restart the processes in the job */ |
| 509 | for (i = 0; i < job->num_progs; i++) | 514 | for (i = 0; i < pi->num_progs; i++) |
| 510 | job->progs[i].is_stopped = 0; | 515 | pi->progs[i].is_stopped = 0; |
| 511 | 516 | ||
| 512 | kill(-job->pgrp, SIGCONT); | 517 | kill(-pi->pgrp, SIGCONT); |
| 513 | 518 | ||
| 514 | job->stopped_progs = 0; | 519 | pi->stopped_progs = 0; |
| 515 | return EXIT_SUCCESS; | 520 | return EXIT_SUCCESS; |
| 516 | } | 521 | } |
| 517 | 522 | ||
| @@ -1055,7 +1060,7 @@ static void insert_bg_job(struct pipe *pi) | |||
| 1055 | } | 1060 | } |
| 1056 | 1061 | ||
| 1057 | /* physically copy the struct job */ | 1062 | /* physically copy the struct job */ |
| 1058 | *thejob = *pi; | 1063 | memcpy(thejob, pi, sizeof(struct pipe)); |
| 1059 | thejob->next = NULL; | 1064 | thejob->next = NULL; |
| 1060 | thejob->running_progs = thejob->num_progs; | 1065 | thejob->running_progs = thejob->num_progs; |
| 1061 | thejob->stopped_progs = 0; | 1066 | thejob->stopped_progs = 0; |
| @@ -1103,6 +1108,7 @@ static void free_pipe(struct pipe *pi) | |||
| 1103 | memset(pi, 0, sizeof(struct pipe)); | 1108 | memset(pi, 0, sizeof(struct pipe)); |
| 1104 | } | 1109 | } |
| 1105 | 1110 | ||
| 1111 | |||
| 1106 | /* Checks to see if any background processes have exited -- if they | 1112 | /* Checks to see if any background processes have exited -- if they |
| 1107 | have, figure out why and see if a job has completed */ | 1113 | have, figure out why and see if a job has completed */ |
| 1108 | static void checkjobs() | 1114 | static void checkjobs() |
| @@ -1169,14 +1175,27 @@ static void checkjobs() | |||
| 1169 | static int run_pipe_real(struct pipe *pi) | 1175 | static int run_pipe_real(struct pipe *pi) |
| 1170 | { | 1176 | { |
| 1171 | int i; | 1177 | int i; |
| 1178 | int ctty; | ||
| 1172 | int nextin, nextout; | 1179 | int nextin, nextout; |
| 1173 | int pipefds[2]; /* pipefds[0] is for reading */ | 1180 | int pipefds[2]; /* pipefds[0] is for reading */ |
| 1174 | struct child_prog *child; | 1181 | struct child_prog *child; |
| 1175 | struct built_in_command *x; | 1182 | struct built_in_command *x; |
| 1176 | 1183 | ||
| 1184 | ctty = -1; | ||
| 1177 | nextin = 0; | 1185 | nextin = 0; |
| 1178 | pi->pgrp = 0; | 1186 | pi->pgrp = 0; |
| 1179 | 1187 | ||
| 1188 | /* Check if we are supposed to run in the foreground */ | ||
| 1189 | if (pi->followup!=PIPE_BG) { | ||
| 1190 | if ((pi->pgrp = tcgetpgrp(ctty = 2)) < 0 | ||
| 1191 | && (pi->pgrp = tcgetpgrp(ctty = 0)) < 0 | ||
| 1192 | && (pi->pgrp = tcgetpgrp(ctty = 1)) < 0) | ||
| 1193 | return errno = ENOTTY, -1; | ||
| 1194 | |||
| 1195 | if (pi->pgrp < 0 && pi->pgrp != getpgrp()) | ||
| 1196 | return errno = EPERM, -1; | ||
| 1197 | } | ||
| 1198 | |||
| 1180 | /* Check if this is a simple builtin (not part of a pipe). | 1199 | /* Check if this is a simple builtin (not part of a pipe). |
| 1181 | * Builtins within pipes have to fork anyway, and are handled in | 1200 | * Builtins within pipes have to fork anyway, and are handled in |
| 1182 | * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. | 1201 | * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. |
| @@ -1225,6 +1244,7 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1225 | 1244 | ||
| 1226 | /* XXX test for failed fork()? */ | 1245 | /* XXX test for failed fork()? */ |
| 1227 | if (!(child->pid = fork())) { | 1246 | if (!(child->pid = fork())) { |
| 1247 | |||
| 1228 | signal(SIGTTOU, SIG_DFL); | 1248 | signal(SIGTTOU, SIG_DFL); |
| 1229 | 1249 | ||
| 1230 | close_all(); | 1250 | close_all(); |
| @@ -1244,22 +1264,33 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1244 | /* Like bash, explicit redirects override pipes, | 1264 | /* Like bash, explicit redirects override pipes, |
| 1245 | * and the pipe fd is available for dup'ing. */ | 1265 | * and the pipe fd is available for dup'ing. */ |
| 1246 | setup_redirects(child,NULL); | 1266 | setup_redirects(child,NULL); |
| 1267 | |||
| 1268 | if (pi->followup!=PIPE_BG) { | ||
| 1269 | /* Put our child in the process group whose leader is the | ||
| 1270 | * first process in this pipe. */ | ||
| 1271 | if (pi->pgrp < 0) { | ||
| 1272 | pi->pgrp = child->pid; | ||
| 1273 | } | ||
| 1274 | /* Don't check for errors. The child may be dead already, | ||
| 1275 | * in which case setpgid returns error code EACCES. */ | ||
| 1276 | if (setpgid(0, pi->pgrp) == 0) { | ||
| 1277 | signal(SIGTTOU, SIG_IGN); | ||
| 1278 | tcsetpgrp(ctty, pi->pgrp); | ||
| 1279 | signal(SIGTTOU, SIG_DFL); | ||
| 1280 | } | ||
| 1281 | } | ||
| 1247 | 1282 | ||
| 1248 | pseudo_exec(child); | 1283 | pseudo_exec(child); |
| 1249 | } | 1284 | } |
| 1250 | if (interactive) { | 1285 | /* Put our child in the process group whose leader is the |
| 1251 | /* Put our child in the process group whose leader is the | 1286 | * first process in this pipe. */ |
| 1252 | * first process in this pipe. */ | 1287 | if (pi->pgrp < 0) { |
| 1253 | if (pi->pgrp==0) { | 1288 | pi->pgrp = child->pid; |
| 1254 | pi->pgrp = child->pid; | ||
| 1255 | } | ||
| 1256 | /* Don't check for errors. The child may be dead already, | ||
| 1257 | * in which case setpgid returns error code EACCES. */ | ||
| 1258 | setpgid(child->pid, pi->pgrp); | ||
| 1259 | } | 1289 | } |
| 1260 | /* In the non-interactive case, do nothing. Leave the children | 1290 | /* Don't check for errors. The child may be dead already, |
| 1261 | * with the process group that they inherited from us. */ | 1291 | * in which case setpgid returns error code EACCES. */ |
| 1262 | 1292 | setpgid(child->pid, pi->pgrp); | |
| 1293 | |||
| 1263 | if (nextin != 0) | 1294 | if (nextin != 0) |
| 1264 | close(nextin); | 1295 | close(nextin); |
| 1265 | if (nextout != 1) | 1296 | if (nextout != 1) |
| @@ -1295,13 +1326,10 @@ static int run_list_real(struct pipe *pi) | |||
| 1295 | /* XXX check bash's behavior with nontrivial pipes */ | 1326 | /* XXX check bash's behavior with nontrivial pipes */ |
| 1296 | /* XXX compute jobid */ | 1327 | /* XXX compute jobid */ |
| 1297 | /* XXX what does bash do with attempts to background builtins? */ | 1328 | /* XXX what does bash do with attempts to background builtins? */ |
| 1298 | #if 0 | ||
| 1299 | printf("[%d] %d\n", pi->jobid, pi->pgrp); | ||
| 1300 | last_bg_pid = pi->pgrp; | ||
| 1301 | #endif | ||
| 1302 | insert_bg_job(pi); | 1329 | insert_bg_job(pi); |
| 1303 | rcode = EXIT_SUCCESS; | 1330 | rcode = EXIT_SUCCESS; |
| 1304 | } else { | 1331 | } else { |
| 1332 | |||
| 1305 | if (interactive) { | 1333 | if (interactive) { |
| 1306 | /* move the new process group into the foreground */ | 1334 | /* move the new process group into the foreground */ |
| 1307 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 1335 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
diff --git a/shell/hush.c b/shell/hush.c index 01fd33486..4a16a3fa6 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -470,48 +470,53 @@ static int builtin_export(struct child_prog *child) | |||
| 470 | /* built-in 'fg' and 'bg' handler */ | 470 | /* built-in 'fg' and 'bg' handler */ |
| 471 | static int builtin_fg_bg(struct child_prog *child) | 471 | static int builtin_fg_bg(struct child_prog *child) |
| 472 | { | 472 | { |
| 473 | int i, jobNum; | 473 | int i, jobnum; |
| 474 | struct pipe *job=NULL; | 474 | struct pipe *pi=NULL; |
| 475 | |||
| 476 | if (!child->argv[1] || child->argv[2]) { | ||
| 477 | error_msg("%s: exactly one argument is expected\n", | ||
| 478 | child->argv[0]); | ||
| 479 | return EXIT_FAILURE; | ||
| 480 | } | ||
| 481 | |||
| 482 | if (sscanf(child->argv[1], "%%%d", &jobNum) != 1) { | ||
| 483 | error_msg("%s: bad argument '%s'\n", | ||
| 484 | child->argv[0], child->argv[1]); | ||
| 485 | return EXIT_FAILURE; | ||
| 486 | } | ||
| 487 | 475 | ||
| 488 | for (job = job_list->head; job; job = job->next) { | 476 | /* If they gave us no args, assume they want the last backgrounded task */ |
| 489 | if (job->jobid == jobNum) { | 477 | if (!child->argv[1]) { |
| 490 | break; | 478 | for (pi = job_list->head; pi; pi = pi->next) { |
| 479 | if (pi->progs && pi->progs->pid == last_bg_pid) { | ||
| 480 | break; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | if (!pi) { | ||
| 484 | error_msg("%s: no current job", child->argv[0]); | ||
| 485 | return EXIT_FAILURE; | ||
| 486 | } | ||
| 487 | } else { | ||
| 488 | if (sscanf(child->argv[1], "%%%d", &jobnum) != 1) { | ||
| 489 | error_msg("%s: bad argument '%s'", child->argv[0], child->argv[1]); | ||
| 490 | return EXIT_FAILURE; | ||
| 491 | } | 491 | } |
| 492 | } | ||
| 493 | 492 | ||
| 494 | if (!job) { | 493 | for (pi = job_list->head; pi; pi = pi->next) { |
| 495 | error_msg("%s: unknown job %d\n", | 494 | if (pi->jobid == jobnum) { |
| 496 | child->argv[0], jobNum); | 495 | break; |
| 497 | return EXIT_FAILURE; | 496 | } |
| 497 | } | ||
| 498 | if (!pi) { | ||
| 499 | error_msg("%s: %d: no such job", child->argv[0], jobnum); | ||
| 500 | return EXIT_FAILURE; | ||
| 501 | } | ||
| 498 | } | 502 | } |
| 499 | |||
| 500 | if (*child->argv[0] == 'f') { | 503 | if (*child->argv[0] == 'f') { |
| 501 | /* Make this job the foreground job */ | 504 | /* Make this job the foreground job */ |
| 505 | signal(SIGTTOU, SIG_IGN); | ||
| 502 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 506 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 503 | if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY) | 507 | if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) |
| 504 | perror_msg("tcsetpgrp"); | 508 | perror_msg("tcsetpgrp"); |
| 505 | job_list->fg = job; | 509 | signal(SIGTTOU, SIG_DFL); |
| 510 | job_list->fg = pi; | ||
| 506 | } | 511 | } |
| 507 | 512 | ||
| 508 | /* Restart the processes in the job */ | 513 | /* Restart the processes in the job */ |
| 509 | for (i = 0; i < job->num_progs; i++) | 514 | for (i = 0; i < pi->num_progs; i++) |
| 510 | job->progs[i].is_stopped = 0; | 515 | pi->progs[i].is_stopped = 0; |
| 511 | 516 | ||
| 512 | kill(-job->pgrp, SIGCONT); | 517 | kill(-pi->pgrp, SIGCONT); |
| 513 | 518 | ||
| 514 | job->stopped_progs = 0; | 519 | pi->stopped_progs = 0; |
| 515 | return EXIT_SUCCESS; | 520 | return EXIT_SUCCESS; |
| 516 | } | 521 | } |
| 517 | 522 | ||
| @@ -1055,7 +1060,7 @@ static void insert_bg_job(struct pipe *pi) | |||
| 1055 | } | 1060 | } |
| 1056 | 1061 | ||
| 1057 | /* physically copy the struct job */ | 1062 | /* physically copy the struct job */ |
| 1058 | *thejob = *pi; | 1063 | memcpy(thejob, pi, sizeof(struct pipe)); |
| 1059 | thejob->next = NULL; | 1064 | thejob->next = NULL; |
| 1060 | thejob->running_progs = thejob->num_progs; | 1065 | thejob->running_progs = thejob->num_progs; |
| 1061 | thejob->stopped_progs = 0; | 1066 | thejob->stopped_progs = 0; |
| @@ -1103,6 +1108,7 @@ static void free_pipe(struct pipe *pi) | |||
| 1103 | memset(pi, 0, sizeof(struct pipe)); | 1108 | memset(pi, 0, sizeof(struct pipe)); |
| 1104 | } | 1109 | } |
| 1105 | 1110 | ||
| 1111 | |||
| 1106 | /* Checks to see if any background processes have exited -- if they | 1112 | /* Checks to see if any background processes have exited -- if they |
| 1107 | have, figure out why and see if a job has completed */ | 1113 | have, figure out why and see if a job has completed */ |
| 1108 | static void checkjobs() | 1114 | static void checkjobs() |
| @@ -1169,14 +1175,27 @@ static void checkjobs() | |||
| 1169 | static int run_pipe_real(struct pipe *pi) | 1175 | static int run_pipe_real(struct pipe *pi) |
| 1170 | { | 1176 | { |
| 1171 | int i; | 1177 | int i; |
| 1178 | int ctty; | ||
| 1172 | int nextin, nextout; | 1179 | int nextin, nextout; |
| 1173 | int pipefds[2]; /* pipefds[0] is for reading */ | 1180 | int pipefds[2]; /* pipefds[0] is for reading */ |
| 1174 | struct child_prog *child; | 1181 | struct child_prog *child; |
| 1175 | struct built_in_command *x; | 1182 | struct built_in_command *x; |
| 1176 | 1183 | ||
| 1184 | ctty = -1; | ||
| 1177 | nextin = 0; | 1185 | nextin = 0; |
| 1178 | pi->pgrp = 0; | 1186 | pi->pgrp = 0; |
| 1179 | 1187 | ||
| 1188 | /* Check if we are supposed to run in the foreground */ | ||
| 1189 | if (pi->followup!=PIPE_BG) { | ||
| 1190 | if ((pi->pgrp = tcgetpgrp(ctty = 2)) < 0 | ||
| 1191 | && (pi->pgrp = tcgetpgrp(ctty = 0)) < 0 | ||
| 1192 | && (pi->pgrp = tcgetpgrp(ctty = 1)) < 0) | ||
| 1193 | return errno = ENOTTY, -1; | ||
| 1194 | |||
| 1195 | if (pi->pgrp < 0 && pi->pgrp != getpgrp()) | ||
| 1196 | return errno = EPERM, -1; | ||
| 1197 | } | ||
| 1198 | |||
| 1180 | /* Check if this is a simple builtin (not part of a pipe). | 1199 | /* Check if this is a simple builtin (not part of a pipe). |
| 1181 | * Builtins within pipes have to fork anyway, and are handled in | 1200 | * Builtins within pipes have to fork anyway, and are handled in |
| 1182 | * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. | 1201 | * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. |
| @@ -1225,6 +1244,7 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1225 | 1244 | ||
| 1226 | /* XXX test for failed fork()? */ | 1245 | /* XXX test for failed fork()? */ |
| 1227 | if (!(child->pid = fork())) { | 1246 | if (!(child->pid = fork())) { |
| 1247 | |||
| 1228 | signal(SIGTTOU, SIG_DFL); | 1248 | signal(SIGTTOU, SIG_DFL); |
| 1229 | 1249 | ||
| 1230 | close_all(); | 1250 | close_all(); |
| @@ -1244,22 +1264,33 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1244 | /* Like bash, explicit redirects override pipes, | 1264 | /* Like bash, explicit redirects override pipes, |
| 1245 | * and the pipe fd is available for dup'ing. */ | 1265 | * and the pipe fd is available for dup'ing. */ |
| 1246 | setup_redirects(child,NULL); | 1266 | setup_redirects(child,NULL); |
| 1267 | |||
| 1268 | if (pi->followup!=PIPE_BG) { | ||
| 1269 | /* Put our child in the process group whose leader is the | ||
| 1270 | * first process in this pipe. */ | ||
| 1271 | if (pi->pgrp < 0) { | ||
| 1272 | pi->pgrp = child->pid; | ||
| 1273 | } | ||
| 1274 | /* Don't check for errors. The child may be dead already, | ||
| 1275 | * in which case setpgid returns error code EACCES. */ | ||
| 1276 | if (setpgid(0, pi->pgrp) == 0) { | ||
| 1277 | signal(SIGTTOU, SIG_IGN); | ||
| 1278 | tcsetpgrp(ctty, pi->pgrp); | ||
| 1279 | signal(SIGTTOU, SIG_DFL); | ||
| 1280 | } | ||
| 1281 | } | ||
| 1247 | 1282 | ||
| 1248 | pseudo_exec(child); | 1283 | pseudo_exec(child); |
| 1249 | } | 1284 | } |
| 1250 | if (interactive) { | 1285 | /* Put our child in the process group whose leader is the |
| 1251 | /* Put our child in the process group whose leader is the | 1286 | * first process in this pipe. */ |
| 1252 | * first process in this pipe. */ | 1287 | if (pi->pgrp < 0) { |
| 1253 | if (pi->pgrp==0) { | 1288 | pi->pgrp = child->pid; |
| 1254 | pi->pgrp = child->pid; | ||
| 1255 | } | ||
| 1256 | /* Don't check for errors. The child may be dead already, | ||
| 1257 | * in which case setpgid returns error code EACCES. */ | ||
| 1258 | setpgid(child->pid, pi->pgrp); | ||
| 1259 | } | 1289 | } |
| 1260 | /* In the non-interactive case, do nothing. Leave the children | 1290 | /* Don't check for errors. The child may be dead already, |
| 1261 | * with the process group that they inherited from us. */ | 1291 | * in which case setpgid returns error code EACCES. */ |
| 1262 | 1292 | setpgid(child->pid, pi->pgrp); | |
| 1293 | |||
| 1263 | if (nextin != 0) | 1294 | if (nextin != 0) |
| 1264 | close(nextin); | 1295 | close(nextin); |
| 1265 | if (nextout != 1) | 1296 | if (nextout != 1) |
| @@ -1295,13 +1326,10 @@ static int run_list_real(struct pipe *pi) | |||
| 1295 | /* XXX check bash's behavior with nontrivial pipes */ | 1326 | /* XXX check bash's behavior with nontrivial pipes */ |
| 1296 | /* XXX compute jobid */ | 1327 | /* XXX compute jobid */ |
| 1297 | /* XXX what does bash do with attempts to background builtins? */ | 1328 | /* XXX what does bash do with attempts to background builtins? */ |
| 1298 | #if 0 | ||
| 1299 | printf("[%d] %d\n", pi->jobid, pi->pgrp); | ||
| 1300 | last_bg_pid = pi->pgrp; | ||
| 1301 | #endif | ||
| 1302 | insert_bg_job(pi); | 1329 | insert_bg_job(pi); |
| 1303 | rcode = EXIT_SUCCESS; | 1330 | rcode = EXIT_SUCCESS; |
| 1304 | } else { | 1331 | } else { |
| 1332 | |||
| 1305 | if (interactive) { | 1333 | if (interactive) { |
| 1306 | /* move the new process group into the foreground */ | 1334 | /* move the new process group into the foreground */ |
| 1307 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 1335 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
