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