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