1/*********************************************************************** 2* * 3* This software is part of the ast package * 4* Copyright (c) 1990-2011 AT&T Intellectual Property * 5* and is licensed under the * 6* Eclipse Public License, Version 1.0 * 7* by AT&T Intellectual Property * 8* * 9* A copy of the License is available at * 10* http://www.eclipse.org/org/documents/epl-v10.html * 11* (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12* * 13* Information and Software Systems Research * 14* AT&T Research * 15* Florham Park NJ * 16* * 17* Glenn Fowler <gsf@research.att.com> * 18* * 19***********************************************************************/ 20#pragma prototyped 21/* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * if co==0 then kill all coshell jobs with sig 26 * elif cj==0 then kill co jobs with sig 27 * else kill cj with sig 28 * 29 * if sig==0 then cause all CO_SERVICE jobs to fail 30 */ 31 32#include "colib.h" 33 34/* 35 * kill job cj in shell co with signal sig 36 */ 37 38static int 39cokilljob(register Coshell_t* co, register Cojob_t* cj, int sig) 40{ 41 int n; 42 43 if (co->flags & CO_DEBUG) 44 errormsg(state.lib, 2, "coshell %d kill co=%d cj=%d sig=%d", co->index, co->pid, cj->pid, sig); 45 if (cj->pid < 0) 46 return 0; 47 if (cj->pid == 0) 48 { 49 if (cj->service) 50 co->svc_running--; 51 else 52 co->running--; 53 cj->pid = CO_PID_ZOMBIE; 54 cj->status = EXIT_TERM(sig); 55 return 0; 56 } 57 if (sig == SIGKILL) 58 { 59 co->running--; 60 cj->pid = CO_PID_ZOMBIE; 61 cj->status = EXIT_TERM(sig); 62 } 63 n = kill(cj->pid, sig); 64 killpg(cj->pid, sig); 65 return n; 66} 67 68/* 69 * kill cj (or all jobs if cj==0) in shell co with sig 70 */ 71 72static int 73cokillshell(register Coshell_t* co, register Cojob_t* cj, int sig) 74{ 75 int n; 76 77 if (sig && (co->flags & CO_SERVER)) 78 { 79 char buf[CO_BUFSIZ]; 80 81 n = sfsprintf(buf, sizeof(buf), "#%05d\nk %d %d\n", 0, cj ? cj->id : 0, sig); 82 sfsprintf(buf, 7, "#%05d\n", n - 7); 83 return write(co->cmdfd, buf, n) == n ? 0 : -1; 84 } 85 if (cj) 86 return cokilljob(co, cj, sig); 87 n = 0; 88 for (cj = co->jobs; cj; cj = cj->next) 89 if (cj->pid > 0) 90 n |= cokilljob(co, cj, sig); 91 return n; 92} 93 94int 95cokill(register Coshell_t* co, register Cojob_t* cj, int sig) 96{ 97 int any; 98 int n; 99 100 if (cj) 101 { 102 if (!co) 103 co = cj->coshell; 104 else if (co != cj->coshell) 105 return -1; 106 any = 0; 107 } 108 else if (co) 109 any = 0; 110 else if (!(co = state.coshells)) 111 return -1; 112 else 113 any = 1; 114 if (co->flags & CO_DEBUG) 115 errormsg(state.lib, 2, "coshell %d kill co=%d cj=%d sig=%d", co->index, co ? co->pid : 0, cj ? cj->pid : 0, sig); 116 switch (sig) 117 { 118 case SIGINT: 119 sig = SIGTERM; 120 break; 121#if defined(SIGSTOP) && defined(SIGTSTP) 122 case SIGTSTP: 123 sig = SIGSTOP; 124 break; 125#endif 126 } 127 n = 0; 128 do 129 { 130 cowait(co, (Cojob_t*)co, 0); 131 n |= cokillshell(co, cj, sig); 132 } while (any && (co = co->next)); 133 return n; 134} 135