Deleted Added
full compact
jobs.c (72086) jobs.c (90111)
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 25 unchanged lines hidden (view full) ---

34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95";
40#endif
41static const char rcsid[] =
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 25 unchanged lines hidden (view full) ---

34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95";
40#endif
41static const char rcsid[] =
42 "$FreeBSD: head/bin/sh/jobs.c 72086 2001-02-06 10:29:34Z cracauer $";
42 "$FreeBSD: head/bin/sh/jobs.c 90111 2002-02-02 06:50:57Z imp $";
43#endif /* not lint */
44
45#include <fcntl.h>
46#include <signal.h>
47#include <errno.h>
48#include <unistd.h>
49#include <stdlib.h>
50#include <sys/param.h>

--- 37 unchanged lines hidden (view full) ---

88int initialpgrp; /* pgrp of shell on invocation */
89int curjob; /* current job */
90#endif
91int in_waitcmd = 0; /* are we in waitcmd()? */
92int in_dowait = 0; /* are we in dowait()? */
93volatile sig_atomic_t breakwaitcmd = 0; /* should wait be terminated? */
94
95#if JOBS
43#endif /* not lint */
44
45#include <fcntl.h>
46#include <signal.h>
47#include <errno.h>
48#include <unistd.h>
49#include <stdlib.h>
50#include <sys/param.h>

--- 37 unchanged lines hidden (view full) ---

88int initialpgrp; /* pgrp of shell on invocation */
89int curjob; /* current job */
90#endif
91int in_waitcmd = 0; /* are we in waitcmd()? */
92int in_dowait = 0; /* are we in dowait()? */
93volatile sig_atomic_t breakwaitcmd = 0; /* should wait be terminated? */
94
95#if JOBS
96STATIC void restartjob __P((struct job *));
96STATIC void restartjob(struct job *);
97#endif
97#endif
98STATIC void freejob __P((struct job *));
99STATIC struct job *getjob __P((char *));
100STATIC int dowait __P((int, struct job *));
98STATIC void freejob(struct job *);
99STATIC struct job *getjob(char *);
100STATIC int dowait(int, struct job *);
101#if SYSV
101#if SYSV
102STATIC int onsigchild __P((void));
102STATIC int onsigchild(void);
103#endif
103#endif
104STATIC int waitproc __P((int, int *));
105STATIC void cmdtxt __P((union node *));
106STATIC void cmdputs __P((char *));
104STATIC int waitproc(int, int *);
105STATIC void cmdtxt(union node *);
106STATIC void cmdputs(char *);
107
108
109/*
110 * Turn job control on and off.
111 *
112 * Note: This code assumes that the third arg to ioctl is a character
113 * pointer, which is true on Berkeley systems but not System V. Since
114 * System V doesn't have job control yet, this isn't a problem now.
115 */
116
117MKINIT int jobctl;
118
119#if JOBS
120void
107
108
109/*
110 * Turn job control on and off.
111 *
112 * Note: This code assumes that the third arg to ioctl is a character
113 * pointer, which is true on Berkeley systems but not System V. Since
114 * System V doesn't have job control yet, this isn't a problem now.
115 */
116
117MKINIT int jobctl;
118
119#if JOBS
120void
121setjobctl(on)
122 int on;
121setjobctl(int on)
123{
124#ifdef OLD_TTY_DRIVER
125 int ldisc;
126#endif
127
128 if (on == jobctl || rootshell == 0)
129 return;
130 if (on) {

--- 59 unchanged lines hidden (view full) ---

190}
191
192#endif
193
194
195
196#if JOBS
197int
122{
123#ifdef OLD_TTY_DRIVER
124 int ldisc;
125#endif
126
127 if (on == jobctl || rootshell == 0)
128 return;
129 if (on) {

--- 59 unchanged lines hidden (view full) ---

189}
190
191#endif
192
193
194
195#if JOBS
196int
198fgcmd(argc, argv)
199 int argc __unused;
200 char **argv;
197fgcmd(int argc __unused, char **argv)
201{
202 struct job *jp;
203 int pgrp;
204 int status;
205
206 jp = getjob(argv[1]);
207 if (jp->jobctl == 0)
208 error("job not created under job control");

--- 7 unchanged lines hidden (view full) ---

216 INTOFF;
217 status = waitforjob(jp, (int *)NULL);
218 INTON;
219 return status;
220}
221
222
223int
198{
199 struct job *jp;
200 int pgrp;
201 int status;
202
203 jp = getjob(argv[1]);
204 if (jp->jobctl == 0)
205 error("job not created under job control");

--- 7 unchanged lines hidden (view full) ---

213 INTOFF;
214 status = waitforjob(jp, (int *)NULL);
215 INTON;
216 return status;
217}
218
219
220int
224bgcmd(argc, argv)
225 int argc;
226 char **argv;
221bgcmd(int argc, char **argv)
227{
228 struct job *jp;
229
230 do {
231 jp = getjob(*++argv);
232 if (jp->jobctl == 0)
233 error("job not created under job control");
234 restartjob(jp);
235 } while (--argc > 1);
236 return 0;
237}
238
239
240STATIC void
222{
223 struct job *jp;
224
225 do {
226 jp = getjob(*++argv);
227 if (jp->jobctl == 0)
228 error("job not created under job control");
229 restartjob(jp);
230 } while (--argc > 1);
231 return 0;
232}
233
234
235STATIC void
241restartjob(jp)
242 struct job *jp;
236restartjob(struct job *jp)
243{
244 struct procstat *ps;
245 int i;
246
247 if (jp->state == JOBDONE)
248 return;
249 INTOFF;
250 killpg(jp->ps[0].pid, SIGCONT);

--- 4 unchanged lines hidden (view full) ---

255 }
256 }
257 INTON;
258}
259#endif
260
261
262int
237{
238 struct procstat *ps;
239 int i;
240
241 if (jp->state == JOBDONE)
242 return;
243 INTOFF;
244 killpg(jp->ps[0].pid, SIGCONT);

--- 4 unchanged lines hidden (view full) ---

249 }
250 }
251 INTON;
252}
253#endif
254
255
256int
263jobscmd(argc, argv)
264 int argc __unused;
265 char **argv __unused;
257jobscmd(int argc __unused, char **argv __unused)
266{
267 showjobs(0);
268 return 0;
269}
270
271
272/*
273 * Print a list of jobs. If "change" is nonzero, only print jobs whose
274 * statuses have changed since the last call to showjobs.
275 *
276 * If the shell is interrupted in the process of creating a job, the
277 * result may be a job structure containing zero processes. Such structures
278 * will be freed here.
279 */
280
281void
258{
259 showjobs(0);
260 return 0;
261}
262
263
264/*
265 * Print a list of jobs. If "change" is nonzero, only print jobs whose
266 * statuses have changed since the last call to showjobs.
267 *
268 * If the shell is interrupted in the process of creating a job, the
269 * result may be a job structure containing zero processes. Such structures
270 * will be freed here.
271 */
272
273void
282showjobs(change)
283 int change;
274showjobs(int change)
284{
285 int jobno;
286 int procno;
287 int i;
288 struct job *jp;
289 struct procstat *ps;
290 int col;
291 char s[64];

--- 55 unchanged lines hidden (view full) ---

347}
348
349
350/*
351 * Mark a job structure as unused.
352 */
353
354STATIC void
275{
276 int jobno;
277 int procno;
278 int i;
279 struct job *jp;
280 struct procstat *ps;
281 int col;
282 char s[64];

--- 55 unchanged lines hidden (view full) ---

338}
339
340
341/*
342 * Mark a job structure as unused.
343 */
344
345STATIC void
355freejob(jp)
356 struct job *jp;
357 {
346freejob(struct job *jp)
347{
358 struct procstat *ps;
359 int i;
360
361 INTOFF;
362 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
363 if (ps->cmd != nullstr)
364 ckfree(ps->cmd);
365 }

--- 5 unchanged lines hidden (view full) ---

371 curjob = 0;
372#endif
373 INTON;
374}
375
376
377
378int
348 struct procstat *ps;
349 int i;
350
351 INTOFF;
352 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
353 if (ps->cmd != nullstr)
354 ckfree(ps->cmd);
355 }

--- 5 unchanged lines hidden (view full) ---

361 curjob = 0;
362#endif
363 INTON;
364}
365
366
367
368int
379waitcmd(argc, argv)
380 int argc;
381 char **argv;
369waitcmd(int argc, char **argv)
382{
383 struct job *job;
384 int status, retval;
385 struct job *jp;
386
387 if (argc > 1) {
388 job = getjob(argv[1]);
389 } else {

--- 37 unchanged lines hidden (view full) ---

427 in_waitcmd--;
428
429 return 0;
430}
431
432
433
434int
370{
371 struct job *job;
372 int status, retval;
373 struct job *jp;
374
375 if (argc > 1) {
376 job = getjob(argv[1]);
377 } else {

--- 37 unchanged lines hidden (view full) ---

415 in_waitcmd--;
416
417 return 0;
418}
419
420
421
422int
435jobidcmd(argc, argv)
436 int argc __unused;
437 char **argv;
423jobidcmd(int argc __unused, char **argv)
438{
439 struct job *jp;
440 int i;
441
442 jp = getjob(argv[1]);
443 for (i = 0 ; i < jp->nprocs ; ) {
444 out1fmt("%d", jp->ps[i].pid);
445 out1c(++i < jp->nprocs? ' ' : '\n');
446 }
447 return 0;
448}
449
450
451
452/*
453 * Convert a job name to a job structure.
454 */
455
456STATIC struct job *
424{
425 struct job *jp;
426 int i;
427
428 jp = getjob(argv[1]);
429 for (i = 0 ; i < jp->nprocs ; ) {
430 out1fmt("%d", jp->ps[i].pid);
431 out1c(++i < jp->nprocs? ' ' : '\n');
432 }
433 return 0;
434}
435
436
437
438/*
439 * Convert a job name to a job structure.
440 */
441
442STATIC struct job *
457getjob(name)
458 char *name;
459 {
443getjob(char *name)
444{
460 int jobno;
461 struct job *jp;
462 int pid;
463 int i;
464
465 if (name == NULL) {
466#if JOBS
467currentjob:

--- 41 unchanged lines hidden (view full) ---

509
510
511
512/*
513 * Return a new job structure,
514 */
515
516struct job *
445 int jobno;
446 struct job *jp;
447 int pid;
448 int i;
449
450 if (name == NULL) {
451#if JOBS
452currentjob:

--- 41 unchanged lines hidden (view full) ---

494
495
496
497/*
498 * Return a new job structure,
499 */
500
501struct job *
517makejob(node, nprocs)
518 union node *node __unused;
519 int nprocs;
502makejob(union node *node __unused, int nprocs)
520{
521 int i;
522 struct job *jp;
523
524 for (i = njobs, jp = jobtab ; ; jp++) {
525 if (--i < 0) {
526 INTOFF;
527 if (njobs == 0) {

--- 47 unchanged lines hidden (view full) ---

575 * process group even if job control is on.
576 *
577 * When job control is turned off, background processes have their standard
578 * input redirected to /dev/null (except for the second and later processes
579 * in a pipeline).
580 */
581
582int
503{
504 int i;
505 struct job *jp;
506
507 for (i = njobs, jp = jobtab ; ; jp++) {
508 if (--i < 0) {
509 INTOFF;
510 if (njobs == 0) {

--- 47 unchanged lines hidden (view full) ---

558 * process group even if job control is on.
559 *
560 * When job control is turned off, background processes have their standard
561 * input redirected to /dev/null (except for the second and later processes
562 * in a pipeline).
563 */
564
565int
583forkshell(jp, n, mode)
584 union node *n;
585 struct job *jp;
586 int mode;
566forkshell(struct job *jp, union node *n, int mode)
587{
588 int pid;
589 int pgrp;
590
591 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
592 mode));
593 INTOFF;
594 pid = fork();

--- 105 unchanged lines hidden (view full) ---

700 * signal if the child process was terminated by an interrupt signal.
701 * Unfortunately, some programs want to do a bit of cleanup and then
702 * exit on interrupt; unless these processes terminate themselves by
703 * sending a signal to themselves (instead of calling exit) they will
704 * confuse this approach.
705 */
706
707int
567{
568 int pid;
569 int pgrp;
570
571 TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n,
572 mode));
573 INTOFF;
574 pid = fork();

--- 105 unchanged lines hidden (view full) ---

680 * signal if the child process was terminated by an interrupt signal.
681 * Unfortunately, some programs want to do a bit of cleanup and then
682 * exit on interrupt; unless these processes terminate themselves by
683 * sending a signal to themselves (instead of calling exit) they will
684 * confuse this approach.
685 */
686
687int
708waitforjob(jp, origstatus)
709 struct job *jp;
710 int *origstatus;
688waitforjob(struct job *jp, int *origstatus)
711{
712#if JOBS
713 int mypgrp = getpgrp();
714#endif
715 int status;
716 int st;
717
718 INTOFF;

--- 40 unchanged lines hidden (view full) ---

759
760
761
762/*
763 * Wait for a process to terminate.
764 */
765
766STATIC int
689{
690#if JOBS
691 int mypgrp = getpgrp();
692#endif
693 int status;
694 int st;
695
696 INTOFF;

--- 40 unchanged lines hidden (view full) ---

737
738
739
740/*
741 * Wait for a process to terminate.
742 */
743
744STATIC int
767dowait(block, job)
768 int block;
769 struct job *job;
745dowait(int block, struct job *job)
770{
771 int pid;
772 int status;
773 struct procstat *sp;
774 struct job *jp;
775 struct job *thisjob;
776 int done;
777 int stopped;

--- 123 unchanged lines hidden (view full) ---

901
902STATIC int onsigchild() {
903 gotsigchild = 1;
904}
905#endif
906
907
908STATIC int
746{
747 int pid;
748 int status;
749 struct procstat *sp;
750 struct job *jp;
751 struct job *thisjob;
752 int done;
753 int stopped;

--- 123 unchanged lines hidden (view full) ---

877
878STATIC int onsigchild() {
879 gotsigchild = 1;
880}
881#endif
882
883
884STATIC int
909waitproc(block, status)
910 int block;
911 int *status;
885waitproc(int block, int *status)
912{
913#ifdef BSD
914 int flags;
915
916#if JOBS
917 flags = WUNTRACED;
918#else
919 flags = 0;

--- 21 unchanged lines hidden (view full) ---

941#endif
942}
943
944/*
945 * return 1 if there are stopped jobs, otherwise 0
946 */
947int job_warning = 0;
948int
886{
887#ifdef BSD
888 int flags;
889
890#if JOBS
891 flags = WUNTRACED;
892#else
893 flags = 0;

--- 21 unchanged lines hidden (view full) ---

915#endif
916}
917
918/*
919 * return 1 if there are stopped jobs, otherwise 0
920 */
921int job_warning = 0;
922int
949stoppedjobs()
923stoppedjobs(void)
950{
951 int jobno;
952 struct job *jp;
953
954 if (job_warning)
955 return (0);
956 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
957 if (jp->used == 0)

--- 13 unchanged lines hidden (view full) ---

971 * jobs command.
972 */
973
974STATIC char *cmdnextc;
975STATIC int cmdnleft;
976#define MAXCMDTEXT 200
977
978char *
924{
925 int jobno;
926 struct job *jp;
927
928 if (job_warning)
929 return (0);
930 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) {
931 if (jp->used == 0)

--- 13 unchanged lines hidden (view full) ---

945 * jobs command.
946 */
947
948STATIC char *cmdnextc;
949STATIC int cmdnleft;
950#define MAXCMDTEXT 200
951
952char *
979commandtext(n)
980 union node *n;
981 {
953commandtext(union node *n)
954{
982 char *name;
983
984 cmdnextc = name = ckmalloc(MAXCMDTEXT);
985 cmdnleft = MAXCMDTEXT - 4;
986 cmdtxt(n);
987 *cmdnextc = '\0';
988 return name;
989}
990
991
992STATIC void
955 char *name;
956
957 cmdnextc = name = ckmalloc(MAXCMDTEXT);
958 cmdnleft = MAXCMDTEXT - 4;
959 cmdtxt(n);
960 *cmdnextc = '\0';
961 return name;
962}
963
964
965STATIC void
993cmdtxt(n)
994 union node *n;
995 {
966cmdtxt(union node *n)
967{
996 union node *np;
997 struct nodelist *lp;
998 char *p;
999 int i;
1000 char s[2];
1001
1002 if (n == NULL)
1003 return;

--- 110 unchanged lines hidden (view full) ---

1114 cmdputs("???");
1115 break;
1116 }
1117}
1118
1119
1120
1121STATIC void
968 union node *np;
969 struct nodelist *lp;
970 char *p;
971 int i;
972 char s[2];
973
974 if (n == NULL)
975 return;

--- 110 unchanged lines hidden (view full) ---

1086 cmdputs("???");
1087 break;
1088 }
1089}
1090
1091
1092
1093STATIC void
1122cmdputs(s)
1123 char *s;
1124 {
1094cmdputs(char *s)
1095{
1125 char *p, *q;
1126 char c;
1127 int subtype = 0;
1128
1129 if (cmdnleft <= 0)
1130 return;
1131 p = s;
1132 q = cmdnextc;

--- 26 unchanged lines hidden ---
1096 char *p, *q;
1097 char c;
1098 int subtype = 0;
1099
1100 if (cmdnleft <= 0)
1101 return;
1102 p = s;
1103 q = cmdnextc;

--- 26 unchanged lines hidden ---