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