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