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