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 --- |