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