This source file includes following definitions.
- generate
- send_sig
- notify_parent
- release
- bad_task_ptr
- audit_ptree
- session_of_pgrp
- kill_pg
- kill_sl
- kill_proc
- sys_kill
- is_orphaned_pgrp
- has_stopped_jobs
- forget_original_parent
- do_exit
- sys_exit
- sys_wait4
- sys_waitpid
1
2
3
4
5
6
7 #define DEBUG_PROC_TREE
8
9 #include <linux/wait.h>
10 #include <linux/errno.h>
11 #include <linux/signal.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/resource.h>
15 #include <linux/mm.h>
16 #include <linux/tty.h>
17 #include <linux/malloc.h>
18
19 #include <asm/segment.h>
20 extern void shm_exit (void);
21 extern void sem_exit (void);
22
23 int getrusage(struct task_struct *, int, struct rusage *);
24
25 static int generate(unsigned long sig, struct task_struct * p)
26 {
27 unsigned long mask = 1 << (sig-1);
28 struct sigaction * sa = sig + p->sigaction - 1;
29
30
31 if (p->flags & PF_PTRACED) {
32 p->signal |= mask;
33 return 1;
34 }
35
36 if (sa->sa_handler == SIG_IGN && sig != SIGCHLD)
37 return 0;
38
39 if ((sa->sa_handler == SIG_DFL) &&
40 (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH))
41 return 0;
42 p->signal |= mask;
43 return 1;
44 }
45
46 int send_sig(unsigned long sig,struct task_struct * p,int priv)
47 {
48 if (!p || sig > 32)
49 return -EINVAL;
50 if (!priv && ((sig != SIGCONT) || (current->session != p->session)) &&
51 (current->euid != p->euid) && (current->uid != p->uid) && !suser())
52 return -EPERM;
53 if (!sig)
54 return 0;
55 if ((sig == SIGKILL) || (sig == SIGCONT)) {
56 if (p->state == TASK_STOPPED)
57 p->state = TASK_RUNNING;
58 p->exit_code = 0;
59 p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |
60 (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );
61 }
62
63 if ((sig >= SIGSTOP) && (sig <= SIGTTOU))
64 p->signal &= ~(1<<(SIGCONT-1));
65
66 generate(sig,p);
67 return 0;
68 }
69
70 void notify_parent(struct task_struct * tsk)
71 {
72 if (tsk->p_pptr == task[1])
73 tsk->exit_signal = SIGCHLD;
74 send_sig(tsk->exit_signal, tsk->p_pptr, 1);
75 wake_up_interruptible(&tsk->p_pptr->wait_chldexit);
76 }
77
78 void release(struct task_struct * p)
79 {
80 int i;
81
82 if (!p)
83 return;
84 if (p == current) {
85 printk("task releasing itself\n");
86 return;
87 }
88 for (i=1 ; i<NR_TASKS ; i++)
89 if (task[i] == p) {
90 task[i] = NULL;
91 REMOVE_LINKS(p);
92 if (STACK_MAGIC != *(unsigned long *)p->kernel_stack_page)
93 printk(KERN_ALERT "release: %s kernel stack corruption. Aiee\n", p->comm);
94 free_page(p->kernel_stack_page);
95 free_page((long) p);
96 return;
97 }
98 panic("trying to release non-existent task");
99 }
100
101 #ifdef DEBUG_PROC_TREE
102
103
104
105
106 int bad_task_ptr(struct task_struct *p)
107 {
108 int i;
109
110 if (!p)
111 return 0;
112 for (i=0 ; i<NR_TASKS ; i++)
113 if (task[i] == p)
114 return 0;
115 return 1;
116 }
117
118
119
120
121
122
123
124
125
126
127 void audit_ptree(void)
128 {
129 int i;
130
131 for (i=1 ; i<NR_TASKS ; i++) {
132 if (!task[i])
133 continue;
134 if (bad_task_ptr(task[i]->p_pptr))
135 printk("Warning, pid %d's parent link is bad\n",
136 task[i]->pid);
137 if (bad_task_ptr(task[i]->p_cptr))
138 printk("Warning, pid %d's child link is bad\n",
139 task[i]->pid);
140 if (bad_task_ptr(task[i]->p_ysptr))
141 printk("Warning, pid %d's ys link is bad\n",
142 task[i]->pid);
143 if (bad_task_ptr(task[i]->p_osptr))
144 printk("Warning, pid %d's os link is bad\n",
145 task[i]->pid);
146 if (task[i]->p_pptr == task[i])
147 printk("Warning, pid %d parent link points to self\n",
148 task[i]->pid);
149 if (task[i]->p_cptr == task[i])
150 printk("Warning, pid %d child link points to self\n",
151 task[i]->pid);
152 if (task[i]->p_ysptr == task[i])
153 printk("Warning, pid %d ys link points to self\n",
154 task[i]->pid);
155 if (task[i]->p_osptr == task[i])
156 printk("Warning, pid %d os link points to self\n",
157 task[i]->pid);
158 if (task[i]->p_osptr) {
159 if (task[i]->p_pptr != task[i]->p_osptr->p_pptr)
160 printk(
161 "Warning, pid %d older sibling %d parent is %d\n",
162 task[i]->pid, task[i]->p_osptr->pid,
163 task[i]->p_osptr->p_pptr->pid);
164 if (task[i]->p_osptr->p_ysptr != task[i])
165 printk(
166 "Warning, pid %d older sibling %d has mismatched ys link\n",
167 task[i]->pid, task[i]->p_osptr->pid);
168 }
169 if (task[i]->p_ysptr) {
170 if (task[i]->p_pptr != task[i]->p_ysptr->p_pptr)
171 printk(
172 "Warning, pid %d younger sibling %d parent is %d\n",
173 task[i]->pid, task[i]->p_osptr->pid,
174 task[i]->p_osptr->p_pptr->pid);
175 if (task[i]->p_ysptr->p_osptr != task[i])
176 printk(
177 "Warning, pid %d younger sibling %d has mismatched os link\n",
178 task[i]->pid, task[i]->p_ysptr->pid);
179 }
180 if (task[i]->p_cptr) {
181 if (task[i]->p_cptr->p_pptr != task[i])
182 printk(
183 "Warning, pid %d youngest child %d has mismatched parent link\n",
184 task[i]->pid, task[i]->p_cptr->pid);
185 if (task[i]->p_cptr->p_ysptr)
186 printk(
187 "Warning, pid %d youngest child %d has non-NULL ys link\n",
188 task[i]->pid, task[i]->p_cptr->pid);
189 }
190 }
191 }
192 #endif
193
194
195
196
197
198
199 int session_of_pgrp(int pgrp)
200 {
201 struct task_struct *p;
202 int fallback;
203
204 fallback = -1;
205 for_each_task(p) {
206 if (p->session <= 0)
207 continue;
208 if (p->pgrp == pgrp)
209 return p->session;
210 if (p->pid == pgrp)
211 fallback = p->session;
212 }
213 return fallback;
214 }
215
216
217
218
219
220 int kill_pg(int pgrp, int sig, int priv)
221 {
222 struct task_struct *p;
223 int err,retval = -ESRCH;
224 int found = 0;
225
226 if (sig<0 || sig>32 || pgrp<=0)
227 return -EINVAL;
228 for_each_task(p) {
229 if (p->pgrp == pgrp) {
230 if ((err = send_sig(sig,p,priv)) != 0)
231 retval = err;
232 else
233 found++;
234 }
235 }
236 return(found ? 0 : retval);
237 }
238
239
240
241
242
243
244 int kill_sl(int sess, int sig, int priv)
245 {
246 struct task_struct *p;
247 int err,retval = -ESRCH;
248 int found = 0;
249
250 if (sig<0 || sig>32 || sess<=0)
251 return -EINVAL;
252 for_each_task(p) {
253 if (p->session == sess && p->leader) {
254 if ((err = send_sig(sig,p,priv)) != 0)
255 retval = err;
256 else
257 found++;
258 }
259 }
260 return(found ? 0 : retval);
261 }
262
263 int kill_proc(int pid, int sig, int priv)
264 {
265 struct task_struct *p;
266
267 if (sig<0 || sig>32)
268 return -EINVAL;
269 for_each_task(p) {
270 if (p && p->pid == pid)
271 return send_sig(sig,p,priv);
272 }
273 return(-ESRCH);
274 }
275
276
277
278
279
280 asmlinkage int sys_kill(int pid,int sig)
281 {
282 int err, retval = 0, count = 0;
283
284 if (!pid)
285 return(kill_pg(current->pgrp,sig,0));
286 if (pid == -1) {
287 struct task_struct * p;
288 for_each_task(p) {
289 if (p->pid > 1 && p != current) {
290 ++count;
291 if ((err = send_sig(sig,p,0)) != -EPERM)
292 retval = err;
293 }
294 }
295 return(count ? retval : -ESRCH);
296 }
297 if (pid < 0)
298 return(kill_pg(-pid,sig,0));
299
300 return(kill_proc(pid,sig,0));
301 }
302
303
304
305
306
307
308
309
310
311 int is_orphaned_pgrp(int pgrp)
312 {
313 struct task_struct *p;
314
315 for_each_task(p) {
316 if ((p->pgrp != pgrp) ||
317 (p->state == TASK_ZOMBIE) ||
318 (p->p_pptr->pid == 1))
319 continue;
320 if ((p->p_pptr->pgrp != pgrp) &&
321 (p->p_pptr->session == p->session))
322 return 0;
323 }
324 return(1);
325 }
326
327 static int has_stopped_jobs(int pgrp)
328 {
329 struct task_struct * p;
330
331 for_each_task(p) {
332 if (p->pgrp != pgrp)
333 continue;
334 if (p->state == TASK_STOPPED)
335 return(1);
336 }
337 return(0);
338 }
339
340 static void forget_original_parent(struct task_struct * father)
341 {
342 struct task_struct * p;
343
344 for_each_task(p) {
345 if (p->p_opptr == father)
346 if (task[1])
347 p->p_opptr = task[1];
348 else
349 p->p_opptr = task[0];
350 }
351 }
352
353 NORET_TYPE void do_exit(long code)
354 {
355 struct task_struct *p;
356 int i;
357
358 fake_volatile:
359 if (current->semun)
360 sem_exit();
361 if (current->shm)
362 shm_exit();
363 free_page_tables(current);
364 for (i=0 ; i<NR_OPEN ; i++)
365 if (current->filp[i])
366 sys_close(i);
367 forget_original_parent(current);
368 iput(current->pwd);
369 current->pwd = NULL;
370 iput(current->root);
371 current->root = NULL;
372 iput(current->executable);
373 current->executable = NULL;
374
375
376 {
377 struct vm_area_struct * mpnt, *mpnt1;
378 mpnt = current->mmap;
379 current->mmap = NULL;
380 while (mpnt) {
381 mpnt1 = mpnt->vm_next;
382 if (mpnt->vm_ops && mpnt->vm_ops->close)
383 mpnt->vm_ops->close(mpnt);
384 kfree(mpnt);
385 mpnt = mpnt1;
386 }
387 }
388
389 if (current->ldt) {
390 vfree(current->ldt);
391 current->ldt = NULL;
392 for (i=1 ; i<NR_TASKS ; i++) {
393 if (task[i] == current) {
394 set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, &default_ldt, 1);
395 load_ldt(i);
396 }
397 }
398 }
399
400
401
402
403
404
405
406
407
408
409 if ((current->p_pptr->pgrp != current->pgrp) &&
410 (current->p_pptr->session == current->session) &&
411 is_orphaned_pgrp(current->pgrp) &&
412 has_stopped_jobs(current->pgrp)) {
413 kill_pg(current->pgrp,SIGHUP,1);
414 kill_pg(current->pgrp,SIGCONT,1);
415 }
416
417 notify_parent(current);
418
419
420
421
422
423
424
425
426
427 while ((p = current->p_cptr) != NULL) {
428 current->p_cptr = p->p_osptr;
429 p->p_ysptr = NULL;
430 p->flags &= ~(PF_PTRACED|PF_TRACESYS);
431 if (task[1] && task[1] != current)
432 p->p_pptr = task[1];
433 else
434 p->p_pptr = task[0];
435 p->p_osptr = p->p_pptr->p_cptr;
436 p->p_osptr->p_ysptr = p;
437 p->p_pptr->p_cptr = p;
438 if (p->state == TASK_ZOMBIE)
439 notify_parent(p);
440
441
442
443
444
445
446 if ((p->pgrp != current->pgrp) &&
447 (p->session == current->session) &&
448 is_orphaned_pgrp(p->pgrp) &&
449 has_stopped_jobs(p->pgrp)) {
450 kill_pg(p->pgrp,SIGHUP,1);
451 kill_pg(p->pgrp,SIGCONT,1);
452 }
453 }
454 if (current->leader)
455 disassociate_ctty(1);
456 if (last_task_used_math == current)
457 last_task_used_math = NULL;
458 current->state = TASK_ZOMBIE;
459 current->exit_code = code;
460 current->rss = 0;
461 #ifdef DEBUG_PROC_TREE
462 audit_ptree();
463 #endif
464 schedule();
465
466
467
468
469
470
471
472
473
474
475
476
477
478 goto fake_volatile;
479 }
480
481 asmlinkage int sys_exit(int error_code)
482 {
483 do_exit((error_code&0xff)<<8);
484 }
485
486 asmlinkage int sys_wait4(pid_t pid,unsigned long * stat_addr, int options, struct rusage * ru)
487 {
488 int flag, retval;
489 struct wait_queue wait = { current, NULL };
490 struct task_struct *p;
491
492 if (stat_addr) {
493 flag = verify_area(VERIFY_WRITE, stat_addr, 4);
494 if (flag)
495 return flag;
496 }
497 add_wait_queue(¤t->wait_chldexit,&wait);
498 repeat:
499 flag=0;
500 for (p = current->p_cptr ; p ; p = p->p_osptr) {
501 if (pid>0) {
502 if (p->pid != pid)
503 continue;
504 } else if (!pid) {
505 if (p->pgrp != current->pgrp)
506 continue;
507 } else if (pid != -1) {
508 if (p->pgrp != -pid)
509 continue;
510 }
511
512 if ((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
513 continue;
514 flag = 1;
515 switch (p->state) {
516 case TASK_STOPPED:
517 if (!p->exit_code)
518 continue;
519 if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED))
520 continue;
521 if (stat_addr)
522 put_fs_long((p->exit_code << 8) | 0x7f,
523 stat_addr);
524 p->exit_code = 0;
525 if (ru != NULL)
526 getrusage(p, RUSAGE_BOTH, ru);
527 retval = p->pid;
528 goto end_wait4;
529 case TASK_ZOMBIE:
530 current->cutime += p->utime + p->cutime;
531 current->cstime += p->stime + p->cstime;
532 current->cmin_flt += p->min_flt + p->cmin_flt;
533 current->cmaj_flt += p->maj_flt + p->cmaj_flt;
534 if (ru != NULL)
535 getrusage(p, RUSAGE_BOTH, ru);
536 flag = p->pid;
537 if (stat_addr)
538 put_fs_long(p->exit_code, stat_addr);
539 if (p->p_opptr != p->p_pptr) {
540 REMOVE_LINKS(p);
541 p->p_pptr = p->p_opptr;
542 SET_LINKS(p);
543 notify_parent(p);
544 } else
545 release(p);
546 #ifdef DEBUG_PROC_TREE
547 audit_ptree();
548 #endif
549 retval = flag;
550 goto end_wait4;
551 default:
552 continue;
553 }
554 }
555 if (flag) {
556 retval = 0;
557 if (options & WNOHANG)
558 goto end_wait4;
559 current->state=TASK_INTERRUPTIBLE;
560 schedule();
561 current->signal &= ~(1<<(SIGCHLD-1));
562 retval = -ERESTARTSYS;
563 if (current->signal & ~current->blocked)
564 goto end_wait4;
565 goto repeat;
566 }
567 retval = -ECHILD;
568 end_wait4:
569 remove_wait_queue(¤t->wait_chldexit,&wait);
570 return retval;
571 }
572
573
574
575
576
577 asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
578 {
579 return sys_wait4(pid, stat_addr, options, NULL);
580 }