1 /* $OpenBSD: proc.c,v 1.21 2009/10/27 23:59:21 deraadt Exp $ */ 2 /* $NetBSD: proc.c,v 1.9 1995/04/29 23:21:33 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1980, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/wait.h> 35 #include <errno.h> 36 #include <unistd.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <stdarg.h> 40 41 #include "csh.h" 42 #include "dir.h" 43 #include "proc.h" 44 #include "extern.h" 45 46 #define BIGINDEX 9 /* largest desirable job index */ 47 48 static struct rusage zru; 49 50 static void pflushall(void); 51 static void pflush(struct process *); 52 static void pclrcurr(struct process *); 53 static void padd(struct command *); 54 static int pprint(struct process *, int); 55 static void ptprint(struct process *); 56 static void pads(Char *); 57 static void pkill(Char **v, int); 58 static struct process 59 *pgetcurr(struct process *); 60 static void okpcntl(void); 61 62 /* 63 * pchild - called at interrupt level by the SIGCHLD signal 64 * indicating that at least one child has terminated or stopped 65 * thus at least one wait system call will definitely return a 66 * childs status. Top level routines (like pwait) must be sure 67 * to mask interrupts when playing with the proclist data structures! 68 */ 69 /* ARGUSED */ 70 void 71 pchild(int notused) 72 { 73 struct process *pp; 74 struct process *fp; 75 int pid; 76 extern int insource; 77 int save_errno = errno; 78 union wait w; 79 int jobflags; 80 struct rusage ru; 81 82 loop: 83 errno = 0; /* reset, just in case */ 84 pid = wait3(&w.w_status, 85 (setintr && (intty || insource) ? WNOHANG | WUNTRACED : WNOHANG), &ru); 86 87 if (pid <= 0) { 88 if (errno == EINTR) { 89 errno = 0; 90 goto loop; 91 } 92 pnoprocesses = pid == -1; 93 errno = save_errno; 94 return; 95 } 96 for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) 97 if (pid == pp->p_pid) 98 goto found; 99 goto loop; 100 found: 101 if (pid == atoi(short2str(value(STRchild)))) 102 unsetv(STRchild); 103 pp->p_flags &= ~(PRUNNING | PSTOPPED | PREPORTED); 104 if (WIFSTOPPED(w)) { 105 pp->p_flags |= PSTOPPED; 106 pp->p_reason = w.w_stopsig; 107 } 108 else { 109 if (pp->p_flags & (PTIME | PPTIME) || adrof(STRtime)) 110 (void) gettimeofday(&pp->p_etime, NULL); 111 112 pp->p_rusage = ru; 113 if (WIFSIGNALED(w)) { 114 if (w.w_termsig == SIGINT) 115 pp->p_flags |= PINTERRUPTED; 116 else 117 pp->p_flags |= PSIGNALED; 118 if (w.w_coredump) 119 pp->p_flags |= PDUMPED; 120 pp->p_reason = w.w_termsig; 121 } 122 else { 123 pp->p_reason = w.w_retcode; 124 if (pp->p_reason != 0) 125 pp->p_flags |= PAEXITED; 126 else 127 pp->p_flags |= PNEXITED; 128 } 129 } 130 jobflags = 0; 131 fp = pp; 132 do { 133 if ((fp->p_flags & (PPTIME | PRUNNING | PSTOPPED)) == 0 && 134 !child && adrof(STRtime) && 135 fp->p_rusage.ru_utime.tv_sec + fp->p_rusage.ru_stime.tv_sec 136 >= atoi(short2str(value(STRtime)))) 137 fp->p_flags |= PTIME; 138 jobflags |= fp->p_flags; 139 } while ((fp = fp->p_friends) != pp); 140 pp->p_flags &= ~PFOREGND; 141 if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { 142 pp->p_flags &= ~PPTIME; 143 pp->p_flags |= PTIME; 144 } 145 if ((jobflags & (PRUNNING | PREPORTED)) == 0) { 146 fp = pp; 147 do { 148 if (fp->p_flags & PSTOPPED) 149 fp->p_flags |= PREPORTED; 150 } while ((fp = fp->p_friends) != pp); 151 while (fp->p_pid != fp->p_jobid) 152 fp = fp->p_friends; 153 if (jobflags & PSTOPPED) { 154 if (pcurrent && pcurrent != fp) 155 pprevious = pcurrent; 156 pcurrent = fp; 157 } 158 else 159 pclrcurr(fp); 160 if (jobflags & PFOREGND) { 161 if (jobflags & (PSIGNALED | PSTOPPED | PPTIME) || 162 #ifdef IIASA 163 jobflags & PAEXITED || 164 #endif 165 !eq(dcwd->di_name, fp->p_cwd->di_name)) { 166 ; /* print in pjwait */ 167 } 168 /* PWP: print a newline after ^C */ 169 else if (jobflags & PINTERRUPTED) { 170 (void) vis_fputc('\r' | QUOTE, cshout); 171 (void) fputc('\n', cshout); 172 } 173 } 174 else { 175 if (jobflags & PNOTIFY || adrof(STRnotify)) { 176 (void) vis_fputc('\r' | QUOTE, cshout); 177 (void) fputc('\n', cshout); 178 (void) pprint(pp, NUMBER | NAME | REASON); 179 if ((jobflags & PSTOPPED) == 0) 180 pflush(pp); 181 } 182 else { 183 fp->p_flags |= PNEEDNOTE; 184 neednote++; 185 } 186 } 187 } 188 goto loop; 189 } 190 191 void 192 pnote(void) 193 { 194 struct process *pp; 195 int flags; 196 sigset_t sigset, osigset; 197 198 neednote = 0; 199 sigemptyset(&sigset); 200 sigaddset(&sigset, SIGCHLD); 201 for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) { 202 if (pp->p_flags & PNEEDNOTE) { 203 sigprocmask(SIG_BLOCK, &sigset, &osigset); 204 pp->p_flags &= ~PNEEDNOTE; 205 flags = pprint(pp, NUMBER | NAME | REASON); 206 if ((flags & (PRUNNING | PSTOPPED)) == 0) 207 pflush(pp); 208 sigprocmask(SIG_SETMASK, &osigset, NULL); 209 } 210 } 211 } 212 213 /* 214 * pwait - wait for current job to terminate, maintaining integrity 215 * of current and previous job indicators. 216 */ 217 void 218 pwait(void) 219 { 220 struct process *fp, *pp; 221 sigset_t sigset, osigset; 222 223 /* 224 * Here's where dead procs get flushed. 225 */ 226 sigemptyset(&sigset); 227 sigaddset(&sigset, SIGCHLD); 228 sigprocmask(SIG_BLOCK, &sigset, &osigset); 229 for (pp = (fp = &proclist)->p_next; pp != NULL; pp = (fp = pp)->p_next) 230 if (pp->p_pid == 0) { 231 fp->p_next = pp->p_next; 232 xfree((ptr_t) pp->p_command); 233 if (pp->p_cwd && --pp->p_cwd->di_count == 0) 234 if (pp->p_cwd->di_next == 0) 235 dfree(pp->p_cwd); 236 xfree((ptr_t) pp); 237 pp = fp; 238 } 239 sigprocmask(SIG_SETMASK, &osigset, NULL); 240 pjwait(pcurrjob); 241 } 242 243 244 /* 245 * pjwait - wait for a job to finish or become stopped 246 * It is assumed to be in the foreground state (PFOREGND) 247 */ 248 void 249 pjwait(struct process *pp) 250 { 251 struct process *fp; 252 int jobflags, reason; 253 sigset_t sigset, osigset; 254 255 while (pp->p_pid != pp->p_jobid) 256 pp = pp->p_friends; 257 fp = pp; 258 259 do { 260 if ((fp->p_flags & (PFOREGND | PRUNNING)) == PRUNNING) 261 (void) fprintf(csherr, "BUG: waiting for background job!\n"); 262 } while ((fp = fp->p_friends) != pp); 263 /* 264 * Now keep pausing as long as we are not interrupted (SIGINT), and the 265 * target process, or any of its friends, are running 266 */ 267 fp = pp; 268 sigemptyset(&sigset); 269 sigaddset(&sigset, SIGCHLD); 270 sigprocmask(SIG_BLOCK, &sigset, &osigset); 271 for (;;) { 272 sigemptyset(&sigset); 273 sigaddset(&sigset, SIGCHLD); 274 sigprocmask(SIG_BLOCK, &sigset, NULL); 275 jobflags = 0; 276 do 277 jobflags |= fp->p_flags; 278 while ((fp = (fp->p_friends)) != pp); 279 if ((jobflags & PRUNNING) == 0) 280 break; 281 #ifdef JOBDEBUG 282 (void) fprintf(csherr, "starting to sigsuspend for SIGCHLD on %d\n", 283 fp->p_pid); 284 #endif /* JOBDEBUG */ 285 sigset = osigset; 286 sigdelset(&sigset, SIGCHLD); 287 sigsuspend(&sigset); 288 } 289 sigprocmask(SIG_SETMASK, &osigset, NULL); 290 if (tpgrp > 0) /* get tty back */ 291 (void) tcsetpgrp(FSHTTY, tpgrp); 292 if ((jobflags & (PSIGNALED | PSTOPPED | PTIME)) || 293 !eq(dcwd->di_name, fp->p_cwd->di_name)) { 294 if (jobflags & PSTOPPED) { 295 (void) fputc('\n', cshout); 296 if (adrof(STRlistjobs)) { 297 Char *jobcommand[3]; 298 299 jobcommand[0] = STRjobs; 300 if (eq(value(STRlistjobs), STRlong)) 301 jobcommand[1] = STRml; 302 else 303 jobcommand[1] = NULL; 304 jobcommand[2] = NULL; 305 306 dojobs(jobcommand, NULL); 307 (void) pprint(pp, SHELLDIR); 308 } 309 else 310 (void) pprint(pp, AREASON | SHELLDIR); 311 } 312 else 313 (void) pprint(pp, AREASON | SHELLDIR); 314 } 315 if ((jobflags & (PINTERRUPTED | PSTOPPED)) && setintr && 316 (!gointr || !eq(gointr, STRminus))) { 317 if ((jobflags & PSTOPPED) == 0) 318 pflush(pp); 319 pintr1(0); 320 /* NOTREACHED */ 321 } 322 reason = 0; 323 fp = pp; 324 do { 325 if (fp->p_reason) 326 reason = fp->p_flags & (PSIGNALED | PINTERRUPTED) ? 327 fp->p_reason | META : fp->p_reason; 328 } while ((fp = fp->p_friends) != pp); 329 if ((reason != 0) && (adrof(STRprintexitvalue))) { 330 (void) fprintf(cshout, "Exit %d\n", reason); 331 } 332 set(STRstatus, putn(reason)); 333 if (reason && exiterr) 334 exitstat(); 335 pflush(pp); 336 } 337 338 /* 339 * dowait - wait for all processes to finish 340 */ 341 void 342 /*ARGSUSED*/ 343 dowait(Char **v, struct command *t) 344 { 345 struct process *pp; 346 sigset_t sigset, osigset; 347 348 pjobs++; 349 sigemptyset(&sigset); 350 sigaddset(&sigset, SIGCHLD); 351 sigprocmask(SIG_BLOCK, &sigset, &osigset); 352 loop: 353 for (pp = proclist.p_next; pp; pp = pp->p_next) 354 if (pp->p_pid && /* pp->p_pid == pp->p_jobid && */ 355 pp->p_flags & PRUNNING) { 356 sigemptyset(&sigset); 357 sigsuspend(&sigset); 358 goto loop; 359 } 360 sigprocmask(SIG_SETMASK, &osigset, NULL); 361 pjobs = 0; 362 } 363 364 /* 365 * pflushall - flush all jobs from list (e.g. at fork()) 366 */ 367 static void 368 pflushall(void) 369 { 370 struct process *pp; 371 372 for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) 373 if (pp->p_pid) 374 pflush(pp); 375 } 376 377 /* 378 * pflush - flag all process structures in the same job as the 379 * the argument process for deletion. The actual free of the 380 * space is not done here since pflush is called at interrupt level. 381 */ 382 static void 383 pflush(struct process *pp) 384 { 385 struct process *np; 386 int idx; 387 388 if (pp->p_pid == 0) { 389 (void) fprintf(csherr, "BUG: process flushed twice"); 390 return; 391 } 392 while (pp->p_pid != pp->p_jobid) 393 pp = pp->p_friends; 394 pclrcurr(pp); 395 if (pp == pcurrjob) 396 pcurrjob = 0; 397 idx = pp->p_index; 398 np = pp; 399 do { 400 np->p_index = np->p_pid = 0; 401 np->p_flags &= ~PNEEDNOTE; 402 } while ((np = np->p_friends) != pp); 403 if (idx == pmaxindex) { 404 for (np = proclist.p_next, idx = 0; np; np = np->p_next) 405 if (np->p_index > idx) 406 idx = np->p_index; 407 pmaxindex = idx; 408 } 409 } 410 411 /* 412 * pclrcurr - make sure the given job is not the current or previous job; 413 * pp MUST be the job leader 414 */ 415 static void 416 pclrcurr(struct process *pp) 417 { 418 419 if (pp == pcurrent) 420 if (pprevious != NULL) { 421 pcurrent = pprevious; 422 pprevious = pgetcurr(pp); 423 } 424 else { 425 pcurrent = pgetcurr(pp); 426 pprevious = pgetcurr(pp); 427 } 428 else if (pp == pprevious) 429 pprevious = pgetcurr(pp); 430 } 431 432 /* +4 here is 1 for '\0', 1 ea for << >& >> */ 433 static Char command[PMAXLEN + 4]; 434 static int cmdlen; 435 static Char *cmdp; 436 437 /* 438 * palloc - allocate a process structure and fill it up. 439 * an important assumption is made that the process is running. 440 */ 441 void 442 palloc(int pid, struct command *t) 443 { 444 struct process *pp; 445 int i; 446 447 pp = (struct process *) xcalloc(1, (size_t) sizeof(struct process)); 448 pp->p_pid = pid; 449 pp->p_flags = t->t_dflg & F_AMPERSAND ? PRUNNING : PRUNNING | PFOREGND; 450 if (t->t_dflg & F_TIME) 451 pp->p_flags |= PPTIME; 452 cmdp = command; 453 cmdlen = 0; 454 padd(t); 455 *cmdp++ = 0; 456 if (t->t_dflg & F_PIPEOUT) { 457 pp->p_flags |= PPOU; 458 if (t->t_dflg & F_STDERR) 459 pp->p_flags |= PERR; 460 } 461 pp->p_command = Strsave(command); 462 if (pcurrjob) { 463 struct process *fp; 464 465 /* careful here with interrupt level */ 466 pp->p_cwd = 0; 467 pp->p_index = pcurrjob->p_index; 468 pp->p_friends = pcurrjob; 469 pp->p_jobid = pcurrjob->p_pid; 470 for (fp = pcurrjob; fp->p_friends != pcurrjob; fp = fp->p_friends) 471 continue; 472 fp->p_friends = pp; 473 } 474 else { 475 pcurrjob = pp; 476 pp->p_jobid = pid; 477 pp->p_friends = pp; 478 pp->p_cwd = dcwd; 479 dcwd->di_count++; 480 if (pmaxindex < BIGINDEX) 481 pp->p_index = ++pmaxindex; 482 else { 483 struct process *np; 484 485 for (i = 1;; i++) { 486 for (np = proclist.p_next; np; np = np->p_next) 487 if (np->p_index == i) 488 goto tryagain; 489 pp->p_index = i; 490 if (i > pmaxindex) 491 pmaxindex = i; 492 break; 493 tryagain:; 494 } 495 } 496 if (pcurrent == NULL) 497 pcurrent = pp; 498 else if (pprevious == NULL) 499 pprevious = pp; 500 } 501 pp->p_next = proclist.p_next; 502 proclist.p_next = pp; 503 (void) gettimeofday(&pp->p_btime, NULL); 504 } 505 506 static void 507 padd(struct command *t) 508 { 509 Char **argp; 510 511 if (t == 0) 512 return; 513 switch (t->t_dtyp) { 514 515 case NODE_PAREN: 516 pads(STRLparensp); 517 padd(t->t_dspr); 518 pads(STRspRparen); 519 break; 520 521 case NODE_COMMAND: 522 for (argp = t->t_dcom; *argp; argp++) { 523 pads(*argp); 524 if (argp[1]) 525 pads(STRspace); 526 } 527 break; 528 529 case NODE_OR: 530 case NODE_AND: 531 case NODE_PIPE: 532 case NODE_LIST: 533 padd(t->t_dcar); 534 switch (t->t_dtyp) { 535 case NODE_OR: 536 pads(STRspor2sp); 537 break; 538 case NODE_AND: 539 pads(STRspand2sp); 540 break; 541 case NODE_PIPE: 542 pads(STRsporsp); 543 break; 544 case NODE_LIST: 545 pads(STRsemisp); 546 break; 547 } 548 padd(t->t_dcdr); 549 return; 550 } 551 if ((t->t_dflg & F_PIPEIN) == 0 && t->t_dlef) { 552 pads((t->t_dflg & F_READ) ? STRspLarrow2sp : STRspLarrowsp); 553 pads(t->t_dlef); 554 } 555 if ((t->t_dflg & F_PIPEOUT) == 0 && t->t_drit) { 556 pads((t->t_dflg & F_APPEND) ? STRspRarrow2 : STRspRarrow); 557 if (t->t_dflg & F_STDERR) 558 pads(STRand); 559 pads(STRspace); 560 pads(t->t_drit); 561 } 562 } 563 564 static void 565 pads(Char *cp) 566 { 567 int i; 568 569 /* 570 * Avoid the Quoted Space alias hack! Reported by: 571 * sam@john-bigboote.ICS.UCI.EDU (Sam Horrocks) 572 */ 573 if (cp[0] == STRQNULL[0]) 574 cp++; 575 576 i = Strlen(cp); 577 578 if (cmdlen >= PMAXLEN) 579 return; 580 if (cmdlen + i >= PMAXLEN) { 581 (void) Strlcpy(cmdp, STRsp3dots, PMAXLEN - cmdlen); 582 cmdlen = PMAXLEN; 583 cmdp += 4; 584 return; 585 } 586 (void) Strlcpy(cmdp, cp, PMAXLEN - cmdlen); 587 cmdp += i; 588 cmdlen += i; 589 } 590 591 /* 592 * psavejob - temporarily save the current job on a one level stack 593 * so another job can be created. Used for { } in exp6 594 * and `` in globbing. 595 */ 596 void 597 psavejob(void) 598 { 599 600 pholdjob = pcurrjob; 601 pcurrjob = NULL; 602 } 603 604 /* 605 * prestjob - opposite of psavejob. This may be missed if we are interrupted 606 * somewhere, but pendjob cleans up anyway. 607 */ 608 void 609 prestjob(void) 610 { 611 612 pcurrjob = pholdjob; 613 pholdjob = NULL; 614 } 615 616 /* 617 * pendjob - indicate that a job (set of commands) has been completed 618 * or is about to begin. 619 */ 620 void 621 pendjob(void) 622 { 623 struct process *pp, *tp; 624 625 if (pcurrjob && (pcurrjob->p_flags & (PFOREGND | PSTOPPED)) == 0) { 626 pp = pcurrjob; 627 while (pp->p_pid != pp->p_jobid) 628 pp = pp->p_friends; 629 (void) fprintf(cshout, "[%d]", pp->p_index); 630 tp = pp; 631 do { 632 (void) fprintf(cshout, " %d", pp->p_pid); 633 pp = pp->p_friends; 634 } while (pp != tp); 635 (void) fputc('\n', cshout); 636 } 637 pholdjob = pcurrjob = 0; 638 } 639 640 /* 641 * pprint - print a job 642 */ 643 static int 644 pprint(struct process *pp, bool flag) 645 { 646 int status, reason; 647 struct process *tp; 648 int jobflags, pstatus; 649 bool hadnl = 1; /* did we just have a newline */ 650 char *format; 651 652 (void) fpurge(cshout); 653 654 while (pp->p_pid != pp->p_jobid) 655 pp = pp->p_friends; 656 if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { 657 pp->p_flags &= ~PPTIME; 658 pp->p_flags |= PTIME; 659 } 660 tp = pp; 661 status = reason = -1; 662 jobflags = 0; 663 do { 664 jobflags |= pp->p_flags; 665 pstatus = pp->p_flags & PALLSTATES; 666 if (tp != pp && !hadnl && !(flag & FANCY) && 667 ((pstatus == status && pp->p_reason == reason) || 668 !(flag & REASON))) { 669 (void) fputc(' ', cshout); 670 hadnl = 0; 671 } 672 else { 673 if (tp != pp && !hadnl) { 674 (void) fputc('\n', cshout); 675 hadnl = 1; 676 } 677 if (flag & NUMBER) { 678 if (pp == tp) 679 (void) fprintf(cshout, "[%d]%s %c ", pp->p_index, 680 pp->p_index < 10 ? " " : "", 681 pp == pcurrent ? '+' : 682 (pp == pprevious ? '-' : ' ')); 683 else 684 (void) fprintf(cshout, " "); 685 hadnl = 0; 686 } 687 if (flag & FANCY) { 688 (void) fprintf(cshout, "%5d ", pp->p_pid); 689 hadnl = 0; 690 } 691 if (flag & (REASON | AREASON)) { 692 if (flag & NAME) 693 format = "%-23s"; 694 else 695 format = "%s"; 696 if (pstatus == status) 697 if (pp->p_reason == reason) { 698 (void) fprintf(cshout, format, ""); 699 hadnl = 0; 700 goto prcomd; 701 } 702 else 703 reason = pp->p_reason; 704 else { 705 status = pstatus; 706 reason = pp->p_reason; 707 } 708 switch (status) { 709 710 case PRUNNING: 711 (void) fprintf(cshout, format, "Running "); 712 hadnl = 0; 713 break; 714 715 case PINTERRUPTED: 716 case PSTOPPED: 717 case PSIGNALED: 718 /* 719 * tell what happened to the background job 720 * From: Michael Schroeder 721 * <mlschroe@immd4.informatik.uni-erlangen.de> 722 */ 723 if ((flag & REASON) 724 || ((flag & AREASON) 725 && reason != SIGINT 726 && (reason != SIGPIPE 727 || (pp->p_flags & PPOU) == 0))) { 728 (void) fprintf(cshout, format, 729 sys_siglist[(unsigned char) 730 pp->p_reason]); 731 hadnl = 0; 732 } 733 break; 734 735 case PNEXITED: 736 case PAEXITED: 737 if (flag & REASON) { 738 if (pp->p_reason) 739 (void) fprintf(cshout, "Exit %-18d", pp->p_reason); 740 else 741 (void) fprintf(cshout, format, "Done"); 742 hadnl = 0; 743 } 744 break; 745 746 default: 747 (void) fprintf(csherr, "BUG: status=%-9o", status); 748 } 749 } 750 } 751 prcomd: 752 if (flag & NAME) { 753 (void) fprintf(cshout, "%s", vis_str(pp->p_command)); 754 if (pp->p_flags & PPOU) 755 (void) fprintf(cshout, " |"); 756 if (pp->p_flags & PERR) 757 (void) fputc('&', cshout); 758 hadnl = 0; 759 } 760 if (flag & (REASON | AREASON) && pp->p_flags & PDUMPED) { 761 (void) fprintf(cshout, " (core dumped)"); 762 hadnl = 0; 763 } 764 if (tp == pp->p_friends) { 765 if (flag & AMPERSAND) { 766 (void) fprintf(cshout, " &"); 767 hadnl = 0; 768 } 769 if (flag & JOBDIR && 770 !eq(tp->p_cwd->di_name, dcwd->di_name)) { 771 (void) fprintf(cshout, " (wd: "); 772 dtildepr(value(STRhome), tp->p_cwd->di_name); 773 (void) fputc(')', cshout); 774 hadnl = 0; 775 } 776 } 777 if (pp->p_flags & PPTIME && !(status & (PSTOPPED | PRUNNING))) { 778 if (!hadnl) 779 (void) fprintf(cshout, "\n\t"); 780 prusage(&zru, &pp->p_rusage, &pp->p_etime, 781 &pp->p_btime); 782 hadnl = 1; 783 } 784 if (tp == pp->p_friends) { 785 if (!hadnl) { 786 (void) fputc('\n', cshout); 787 hadnl = 1; 788 } 789 if (flag & SHELLDIR && !eq(tp->p_cwd->di_name, dcwd->di_name)) { 790 (void) fprintf(cshout, "(wd now: "); 791 dtildepr(value(STRhome), dcwd->di_name); 792 (void) fprintf(cshout, ")\n"); 793 hadnl = 1; 794 } 795 } 796 } while ((pp = pp->p_friends) != tp); 797 if (jobflags & PTIME && (jobflags & (PSTOPPED | PRUNNING)) == 0) { 798 if (jobflags & NUMBER) 799 (void) fprintf(cshout, " "); 800 ptprint(tp); 801 hadnl = 1; 802 } 803 (void) fflush(cshout); 804 return (jobflags); 805 } 806 807 static void 808 ptprint(struct process *tp) 809 { 810 struct timeval tetime, diff; 811 static struct timeval ztime; 812 struct rusage ru; 813 static struct rusage zru; 814 struct process *pp = tp; 815 816 ru = zru; 817 tetime = ztime; 818 do { 819 ruadd(&ru, &pp->p_rusage); 820 timersub(&pp->p_etime, &pp->p_btime, &diff); 821 if (timercmp(&diff, &tetime, >)) 822 tetime = diff; 823 } while ((pp = pp->p_friends) != tp); 824 prusage(&zru, &ru, &tetime, &ztime); 825 } 826 827 /* 828 * dojobs - print all jobs 829 */ 830 void 831 /*ARGSUSED*/ 832 dojobs(Char **v, struct command *t) 833 { 834 struct process *pp; 835 int flag = NUMBER | NAME | REASON; 836 int i; 837 838 if (chkstop) 839 chkstop = 2; 840 if (*++v) { 841 if (v[1] || !eq(*v, STRml)) 842 stderror(ERR_JOBS); 843 flag |= FANCY | JOBDIR; 844 } 845 for (i = 1; i <= pmaxindex; i++) 846 for (pp = proclist.p_next; pp; pp = pp->p_next) 847 if (pp->p_index == i && pp->p_pid == pp->p_jobid) { 848 pp->p_flags &= ~PNEEDNOTE; 849 if (!(pprint(pp, flag) & (PRUNNING | PSTOPPED))) 850 pflush(pp); 851 break; 852 } 853 } 854 855 /* 856 * dofg - builtin - put the job into the foreground 857 */ 858 void 859 /*ARGSUSED*/ 860 dofg(Char **v, struct command *t) 861 { 862 struct process *pp; 863 864 okpcntl(); 865 ++v; 866 do { 867 pp = pfind(*v); 868 pstart(pp, 1); 869 pjwait(pp); 870 } while (*v && *++v); 871 } 872 873 /* 874 * %... - builtin - put the job into the foreground 875 */ 876 void 877 /*ARGSUSED*/ 878 dofg1(Char **v, struct command *t) 879 { 880 struct process *pp; 881 882 okpcntl(); 883 pp = pfind(v[0]); 884 pstart(pp, 1); 885 pjwait(pp); 886 } 887 888 /* 889 * dobg - builtin - put the job into the background 890 */ 891 void 892 /*ARGSUSED*/ 893 dobg(Char **v, struct command *t) 894 { 895 struct process *pp; 896 897 okpcntl(); 898 ++v; 899 do { 900 pp = pfind(*v); 901 pstart(pp, 0); 902 } while (*v && *++v); 903 } 904 905 /* 906 * %... & - builtin - put the job into the background 907 */ 908 void 909 /*ARGSUSED*/ 910 dobg1(Char **v, struct command *t) 911 { 912 struct process *pp; 913 914 pp = pfind(v[0]); 915 pstart(pp, 0); 916 } 917 918 /* 919 * dostop - builtin - stop the job 920 */ 921 void 922 /*ARGSUSED*/ 923 dostop(Char **v, struct command *t) 924 { 925 pkill(++v, SIGSTOP); 926 } 927 928 /* 929 * dokill - builtin - superset of kill (1) 930 */ 931 void 932 /*ARGSUSED*/ 933 dokill(Char **v, struct command *t) 934 { 935 int signum = SIGTERM; 936 char *name; 937 938 v++; 939 if (v[0] && v[0][0] == '-') { 940 if (v[0][1] == 'l') { 941 if (v[1]) { 942 if (!Isdigit(v[1][0])) 943 stderror(ERR_NAME | ERR_BADSIG); 944 945 signum = atoi(short2str(v[1])); 946 if (signum < 0 || signum >= NSIG) 947 stderror(ERR_NAME | ERR_BADSIG); 948 else if (signum == 0) 949 (void) fputc('0', cshout); /* 0's symbolic name is '0' */ 950 else 951 (void) fprintf(cshout, "%s ", sys_signame[signum]); 952 } else { 953 for (signum = 1; signum < NSIG; signum++) { 954 (void) fprintf(cshout, "%s ", sys_signame[signum]); 955 if (signum == NSIG / 2) 956 (void) fputc('\n', cshout); 957 } 958 } 959 (void) fputc('\n', cshout); 960 return; 961 } 962 if (Isdigit(v[0][1])) { 963 signum = atoi(short2str(v[0] + 1)); 964 if (signum < 0 || signum >= NSIG) 965 stderror(ERR_NAME | ERR_BADSIG); 966 } 967 else { 968 if (v[0][1] == 's' && (Isspace(v[0][2]) || v[0][2] == '\0')) { 969 v++; 970 name = short2str(&v[0][0]); 971 } else { 972 name = short2str(&v[0][1]); 973 } 974 975 if (v[0] == NULL || v[1] == NULL) { 976 stderror(ERR_NAME | ERR_TOOFEW); 977 return; 978 } 979 980 for (signum = 1; signum < NSIG; signum++) 981 if (!strcasecmp(sys_signame[signum], name) || 982 (strlen(name) > 3 && !strncasecmp("SIG", name, 3) && 983 !strcasecmp(sys_signame[signum], name + 3))) 984 break; 985 986 if (signum == NSIG) { 987 if (name[0] == '0') 988 signum = 0; 989 else { 990 setname(vis_str(&v[0][0])); 991 stderror(ERR_NAME | ERR_UNKSIG); 992 } 993 } 994 } 995 v++; 996 } 997 pkill(v, signum); 998 } 999 1000 static void 1001 pkill(Char **v, int signum) 1002 { 1003 struct process *pp, *np; 1004 int jobflags = 0; 1005 int pid, err1 = 0; 1006 sigset_t sigset; 1007 Char *cp; 1008 1009 sigemptyset(&sigset); 1010 sigaddset(&sigset, SIGCHLD); 1011 if (setintr) 1012 sigaddset(&sigset, SIGINT); 1013 sigprocmask(SIG_BLOCK, &sigset, NULL); 1014 gflag = 0, tglob(v); 1015 if (gflag) { 1016 v = globall(v); 1017 if (v == 0) 1018 stderror(ERR_NAME | ERR_NOMATCH); 1019 } 1020 else { 1021 v = gargv = saveblk(v); 1022 trim(v); 1023 } 1024 1025 while (v && (cp = *v)) { 1026 if (*cp == '%') { 1027 np = pp = pfind(cp); 1028 do 1029 jobflags |= np->p_flags; 1030 while ((np = np->p_friends) != pp); 1031 switch (signum) { 1032 1033 case SIGSTOP: 1034 case SIGTSTP: 1035 case SIGTTIN: 1036 case SIGTTOU: 1037 if ((jobflags & PRUNNING) == 0) { 1038 (void) fprintf(csherr, "%s: Already suspended\n", 1039 vis_str(cp)); 1040 err1++; 1041 goto cont; 1042 } 1043 break; 1044 /* 1045 * suspend a process, kill -CONT %, then type jobs; the shell 1046 * says it is suspended, but it is running; thanks jaap.. 1047 */ 1048 case SIGCONT: 1049 pstart(pp, 0); 1050 goto cont; 1051 } 1052 if (kill(-pp->p_jobid, signum) < 0) { 1053 (void) fprintf(csherr, "%s: %s\n", vis_str(cp), 1054 strerror(errno)); 1055 err1++; 1056 } 1057 if (signum == SIGTERM || signum == SIGHUP) 1058 (void) kill(-pp->p_jobid, SIGCONT); 1059 } 1060 else if (!(Isdigit(*cp) || *cp == '-')) 1061 stderror(ERR_NAME | ERR_JOBARGS); 1062 else { 1063 char *ep; 1064 char *pidnam = short2str(cp); 1065 1066 pid = strtol(pidnam, &ep, 10); 1067 if (!*pidnam || *ep) { 1068 (void) fprintf(csherr, "%s: illegal process id\n", pidnam); 1069 err1++; 1070 goto cont; 1071 } 1072 if (kill((pid_t) pid, signum) < 0) { 1073 (void) fprintf(csherr, "%d: %s\n", pid, strerror(errno)); 1074 err1++; 1075 goto cont; 1076 } 1077 if (signum == SIGTERM || signum == SIGHUP) 1078 (void) kill((pid_t) pid, SIGCONT); 1079 } 1080 cont: 1081 v++; 1082 } 1083 if (gargv) 1084 blkfree(gargv), gargv = 0; 1085 sigprocmask(SIG_UNBLOCK, &sigset, NULL); 1086 if (err1) 1087 stderror(ERR_SILENT); 1088 } 1089 1090 /* 1091 * pstart - start the job in foreground/background 1092 */ 1093 void 1094 pstart(struct process *pp, int foregnd) 1095 { 1096 struct process *np; 1097 sigset_t sigset, osigset; 1098 long jobflags = 0; 1099 1100 sigemptyset(&sigset); 1101 sigaddset(&sigset, SIGCHLD); 1102 sigprocmask(SIG_BLOCK, &sigset, &osigset); 1103 np = pp; 1104 do { 1105 jobflags |= np->p_flags; 1106 if (np->p_flags & (PRUNNING | PSTOPPED)) { 1107 np->p_flags |= PRUNNING; 1108 np->p_flags &= ~PSTOPPED; 1109 if (foregnd) 1110 np->p_flags |= PFOREGND; 1111 else 1112 np->p_flags &= ~PFOREGND; 1113 } 1114 } while ((np = np->p_friends) != pp); 1115 if (!foregnd) 1116 pclrcurr(pp); 1117 (void) pprint(pp, foregnd ? NAME | JOBDIR : NUMBER | NAME | AMPERSAND); 1118 if (foregnd) 1119 (void) tcsetpgrp(FSHTTY, pp->p_jobid); 1120 if (jobflags & PSTOPPED) 1121 (void) kill(-pp->p_jobid, SIGCONT); 1122 sigprocmask(SIG_SETMASK, &osigset, NULL); 1123 } 1124 1125 void 1126 panystop(bool neednl) 1127 { 1128 struct process *pp; 1129 1130 chkstop = 2; 1131 for (pp = proclist.p_next; pp; pp = pp->p_next) 1132 if (pp->p_flags & PSTOPPED) 1133 stderror(ERR_STOPPED, neednl ? "\n" : ""); 1134 } 1135 1136 struct process * 1137 pfind(Char *cp) 1138 { 1139 struct process *pp, *np; 1140 1141 if (cp == 0 || cp[1] == 0 || eq(cp, STRcent2) || eq(cp, STRcentplus)) { 1142 if (pcurrent == NULL) 1143 stderror(ERR_NAME | ERR_JOBCUR); 1144 return (pcurrent); 1145 } 1146 if (eq(cp, STRcentminus) || eq(cp, STRcenthash)) { 1147 if (pprevious == NULL) 1148 stderror(ERR_NAME | ERR_JOBPREV); 1149 return (pprevious); 1150 } 1151 if (Isdigit(cp[1])) { 1152 int idx = atoi(short2str(cp + 1)); 1153 1154 for (pp = proclist.p_next; pp; pp = pp->p_next) 1155 if (pp->p_index == idx && pp->p_pid == pp->p_jobid) 1156 return (pp); 1157 stderror(ERR_NAME | ERR_NOSUCHJOB); 1158 } 1159 np = NULL; 1160 for (pp = proclist.p_next; pp; pp = pp->p_next) 1161 if (pp->p_pid == pp->p_jobid) { 1162 if (cp[1] == '?') { 1163 Char *dp; 1164 1165 for (dp = pp->p_command; *dp; dp++) { 1166 if (*dp != cp[2]) 1167 continue; 1168 if (prefix(cp + 2, dp)) 1169 goto match; 1170 } 1171 } 1172 else if (prefix(cp + 1, pp->p_command)) { 1173 match: 1174 if (np) 1175 stderror(ERR_NAME | ERR_AMBIG); 1176 np = pp; 1177 } 1178 } 1179 if (np) 1180 return (np); 1181 stderror(ERR_NAME | (cp[1] == '?' ? ERR_JOBPAT : ERR_NOSUCHJOB)); 1182 /* NOTREACHED */ 1183 return (0); 1184 } 1185 1186 1187 /* 1188 * pgetcurr - find most recent job that is not pp, preferably stopped 1189 */ 1190 static struct process * 1191 pgetcurr(struct process *pp) 1192 { 1193 struct process *np; 1194 struct process *xp = NULL; 1195 1196 for (np = proclist.p_next; np; np = np->p_next) 1197 if (np != pcurrent && np != pp && np->p_pid && 1198 np->p_pid == np->p_jobid) { 1199 if (np->p_flags & PSTOPPED) 1200 return (np); 1201 if (xp == NULL) 1202 xp = np; 1203 } 1204 return (xp); 1205 } 1206 1207 /* 1208 * donotify - flag the job so as to report termination asynchronously 1209 */ 1210 void 1211 /*ARGSUSED*/ 1212 donotify(Char **v, struct command *t) 1213 { 1214 struct process *pp; 1215 1216 pp = pfind(*++v); 1217 pp->p_flags |= PNOTIFY; 1218 } 1219 1220 /* 1221 * Do the fork and whatever should be done in the child side that 1222 * should not be done if we are not forking at all (like for simple builtin's) 1223 * Also do everything that needs any signals fiddled with in the parent side 1224 * 1225 * Wanttty tells whether process and/or tty pgrps are to be manipulated: 1226 * -1: leave tty alone; inherit pgrp from parent 1227 * 0: already have tty; manipulate process pgrps only 1228 * 1: want to claim tty; manipulate process and tty pgrps 1229 * It is usually just the value of tpgrp. 1230 */ 1231 1232 int 1233 pfork(struct command *t, int wanttty) 1234 { 1235 int pid; 1236 bool ignint = 0; 1237 int pgrp; 1238 sigset_t sigset, osigset; 1239 1240 /* 1241 * A child will be uninterruptible only under very special conditions. 1242 * Remember that the semantics of '&' is implemented by disconnecting the 1243 * process from the tty so signals do not need to ignored just for '&'. 1244 * Thus signals are set to default action for children unless: we have had 1245 * an "onintr -" (then specifically ignored) we are not playing with 1246 * signals (inherit action) 1247 */ 1248 if (setintr) 1249 ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) 1250 || (gointr && eq(gointr, STRminus)); 1251 /* 1252 * Check for maximum nesting of 16 processes to avoid Forking loops 1253 */ 1254 if (child == 16) 1255 stderror(ERR_NESTING, 16); 1256 /* 1257 * Hold SIGCHLD until we have the process installed in our table. 1258 */ 1259 sigemptyset(&sigset); 1260 sigaddset(&sigset, SIGCHLD); 1261 sigprocmask(SIG_BLOCK, &sigset, &osigset); 1262 while ((pid = fork()) < 0) 1263 if (setintr == 0) 1264 (void) sleep(FORKSLEEP); 1265 else { 1266 sigprocmask(SIG_SETMASK, &osigset, NULL); 1267 stderror(ERR_NOPROC); 1268 } 1269 if (pid == 0) { 1270 settimes(); 1271 pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); 1272 pflushall(); 1273 pcurrjob = NULL; 1274 child++; 1275 if (setintr) { 1276 setintr = 0; /* until I think otherwise */ 1277 /* 1278 * Children just get blown away on SIGINT, SIGQUIT unless "onintr 1279 * -" seen. 1280 */ 1281 (void) signal(SIGINT, ignint ? SIG_IGN : SIG_DFL); 1282 (void) signal(SIGQUIT, ignint ? SIG_IGN : SIG_DFL); 1283 if (wanttty >= 0) { 1284 /* make stoppable */ 1285 (void) signal(SIGTSTP, SIG_DFL); 1286 (void) signal(SIGTTIN, SIG_DFL); 1287 (void) signal(SIGTTOU, SIG_DFL); 1288 } 1289 (void) signal(SIGTERM, parterm); 1290 } 1291 else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { 1292 (void) signal(SIGINT, SIG_IGN); 1293 (void) signal(SIGQUIT, SIG_IGN); 1294 } 1295 pgetty(wanttty, pgrp); 1296 /* 1297 * Nohup and nice apply only to NODE_COMMAND's but it would be nice 1298 * (?!?) if you could say "nohup (foo;bar)" Then the parser would have 1299 * to know about nice/nohup/time 1300 */ 1301 if (t->t_dflg & F_NOHUP) 1302 (void) signal(SIGHUP, SIG_IGN); 1303 if (t->t_dflg & F_NICE) 1304 (void) setpriority(PRIO_PROCESS, 0, t->t_nice); 1305 } 1306 else { 1307 if (wanttty >= 0) 1308 (void) setpgid(pid, pcurrjob ? pcurrjob->p_jobid : pid); 1309 palloc(pid, t); 1310 sigprocmask(SIG_SETMASK, &osigset, NULL); 1311 } 1312 1313 return (pid); 1314 } 1315 1316 static void 1317 okpcntl(void) 1318 { 1319 if (tpgrp == -1) 1320 stderror(ERR_JOBCONTROL); 1321 if (tpgrp == 0) 1322 stderror(ERR_JOBCTRLSUB); 1323 } 1324 1325 /* 1326 * if we don't have vfork(), things can still go in the wrong order 1327 * resulting in the famous 'Stopped (tty output)'. But some systems 1328 * don't permit the setpgid() call, (these are more recent secure 1329 * systems such as ibm's aix). Then we'd rather print an error message 1330 * than hang the shell! 1331 * I am open to suggestions how to fix that. 1332 */ 1333 void 1334 pgetty(int wanttty, int pgrp) 1335 { 1336 sigset_t sigset, osigset; 1337 1338 /* 1339 * christos: I am blocking the tty signals till I've set things 1340 * correctly.... 1341 */ 1342 if (wanttty > 0) { 1343 sigemptyset(&sigset); 1344 sigaddset(&sigset, SIGTSTP); 1345 sigaddset(&sigset, SIGTTIN); 1346 sigaddset(&sigset, SIGTTOU); 1347 sigprocmask(SIG_BLOCK, &sigset, &osigset); 1348 } 1349 /* 1350 * From: Michael Schroeder <mlschroe@immd4.informatik.uni-erlangen.de> 1351 * Don't check for tpgrp >= 0 so even non-interactive shells give 1352 * background jobs process groups Same for the comparison in the other part 1353 * of the #ifdef 1354 */ 1355 if (wanttty >= 0) 1356 if (setpgid(0, pgrp) == -1) { 1357 (void) fprintf(csherr, "csh: setpgid error.\n"); 1358 xexit(0); 1359 } 1360 1361 if (wanttty > 0) { 1362 (void) tcsetpgrp(FSHTTY, pgrp); 1363 sigprocmask(SIG_SETMASK, &osigset, NULL); 1364 } 1365 1366 if (tpgrp > 0) 1367 tpgrp = 0; /* gave tty away */ 1368 } 1369