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