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 && (p->signal & ~p->blocked))
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 }
354 }
355 read_unlock(&tasklist_lock);
356}
357
358static inline void close_files(struct files_struct * files)
359{
360 int i, j;
361
362 j = 0;
363 for (;;) {
364 unsigned long set = files->open_fds.fds_bits[j];
365 i = j * __NFDBITS;
366 j++;
367 if (i >= NR_OPEN)
368 break;
369 while (set) {
370 if (set & 1) {
371 struct file * file = files->fd[i];
372 if (file) {
373 files->fd[i] = NULL;
374 close_fp(file);
375 }
376 }
377 i++;
378 set >>= 1;
379 }
380 }
381}
382
383extern kmem_cache_t *files_cachep;
384
385static inline void __exit_files(struct task_struct *tsk)
386{
387 struct files_struct * files = tsk->files;
388
389 if (files) {
390 tsk->files = NULL;
391 if (!--files->count) {
392 close_files(files);
393 kmem_cache_free(files_cachep, files);
394 }
395 }
396}
397
398void exit_files(struct task_struct *tsk)
399{
400 __exit_files(tsk);
401}
402
403static inline void __exit_fs(struct task_struct *tsk)
404{
405 struct fs_struct * fs = tsk->fs;
406
407 if (fs) {
408 tsk->fs = NULL;
409 if (!--fs->count) {
410 dput(fs->root);
411 dput(fs->pwd);
412 kfree(fs);
413 }
414 }
415}
416
417void exit_fs(struct task_struct *tsk)
418{
419 __exit_fs(tsk);
420}
421
422static inline void __exit_sighand(struct task_struct *tsk)
423{
424 struct signal_struct * sig = tsk->sig;
425
426 if (sig) {
427 tsk->sig = NULL;
428 if (atomic_dec_and_test(&sig->count))
429 kfree(sig);
430 }
431}
432
433void exit_sighand(struct task_struct *tsk)
434{
435 __exit_sighand(tsk);
436}
437
438static inline void __exit_mm(struct task_struct * tsk)
439{
440 struct mm_struct * mm = tsk->mm;
441
442
443 if (mm != &init_mm) {
444 flush_cache_mm(mm);
445 flush_tlb_mm(mm);
446 destroy_context(mm);
447 tsk->mm = &init_mm;
448 tsk->swappable = 0;
449 SET_PAGE_DIR(tsk, swapper_pg_dir);
450 mmput(mm);
451 }
452}
453
454void exit_mm(struct task_struct *tsk)
455{
456 __exit_mm(tsk);
457}
458
459
460
461
462
463static void exit_notify(void)
464{
465 struct task_struct * p;
466
467 forget_original_parent(current);
468
469
470
471
472
473
474
475
476
477 if ((current->p_pptr->pgrp != current->pgrp) &&
478 (current->p_pptr->session == current->session) &&
479 will_become_orphaned_pgrp(current->pgrp, current) &&
480 has_stopped_jobs(current->pgrp)) {
481 kill_pg(current->pgrp,SIGHUP,1);
482 kill_pg(current->pgrp,SIGCONT,1);
483 }
484
485 notify_parent(current, current->exit_signal);
486
487
488
489
490
491
492
493
494
495 while ((p = current->p_cptr) != NULL) {
496 current->p_cptr = p->p_osptr;
497 p->p_ysptr = NULL;
498 p->flags &= ~(PF_PTRACED|PF_TRACESYS);
499
500 p->p_pptr = p->p_opptr;
501 p->p_osptr = p->p_pptr->p_cptr;
502 if (p->p_osptr)
503 p->p_osptr->p_ysptr = p;
504 p->p_pptr->p_cptr = p;
505 if (p->state == TASK_ZOMBIE)
506 notify_parent(p, p->exit_signal);
507
508
509
510
511
512
513 if ((p->pgrp != current->pgrp) &&
514 (p->session == current->session) &&
515 is_orphaned_pgrp(p->pgrp) &&
516 has_stopped_jobs(p->pgrp)) {
517 kill_pg(p->pgrp,SIGHUP,1);
518 kill_pg(p->pgrp,SIGCONT,1);
519 }
520 }
521 if (current->leader)
522 disassociate_ctty(1);
523}
524
525NORET_TYPE void do_exit(long code)
526{
527 if (in_interrupt())
528 printk("Aiee, killing interrupt handler\n");
529fake_volatile:
530 acct_process(code);
531 current->flags |= PF_EXITING;
532 del_timer(¤t->real_timer);
533 sem_exit();
534 kerneld_exit();
535 __exit_mm(current);
536#if CONFIG_AP1000
537 exit_msc(current);
538#endif
539 __exit_files(current);
540 __exit_fs(current);
541 __exit_sighand(current);
542 exit_thread();
543 current->state = TASK_ZOMBIE;
544 current->exit_code = code;
545 exit_notify();
546#ifdef DEBUG_PROC_TREE
547 audit_ptree();
548#endif
549 if (current->exec_domain && current->exec_domain->module)
550 __MOD_DEC_USE_COUNT(current->exec_domain->module);
551 if (current->binfmt && current->binfmt->module)
552 __MOD_DEC_USE_COUNT(current->binfmt->module);
553 schedule();
554
555
556
557
558
559
560
561
562
563
564
565
566
567 goto fake_volatile;
568}
569
570asmlinkage int sys_exit(int error_code)
571{
572 lock_kernel();
573 do_exit((error_code&0xff)<<8);
574 unlock_kernel();
575}
576
577asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
578{
579 int flag, retval;
580 struct wait_queue wait = { current, NULL };
581 struct task_struct *p;
582
583 if (stat_addr) {
584 if(verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr)))
585 return -EFAULT;
586 }
587 if (ru) {
588 if(verify_area(VERIFY_WRITE, ru, sizeof(*ru)))
589 return -EFAULT;
590 }
591
592 if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
593 return -EINVAL;
594
595 add_wait_queue(¤t->wait_chldexit,&wait);
596repeat:
597 flag = 0;
598 read_lock(&tasklist_lock);
599 for (p = current->p_cptr ; p ; p = p->p_osptr) {
600 if (pid>0) {
601 if (p->pid != pid)
602 continue;
603 } else if (!pid) {
604 if (p->pgrp != current->pgrp)
605 continue;
606 } else if (pid != -1) {
607 if (p->pgrp != -pid)
608 continue;
609 }
610
611 if ((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))
612 continue;
613 flag = 1;
614 switch (p->state) {
615 case TASK_STOPPED:
616 if (!p->exit_code)
617 continue;
618 if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED))
619 continue;
620 read_unlock(&tasklist_lock);
621 if (ru != NULL)
622 getrusage(p, RUSAGE_BOTH, ru);
623 if (stat_addr)
624 __put_user((p->exit_code << 8) | 0x7f,
625 stat_addr);
626 p->exit_code = 0;
627 retval = p->pid;
628 goto end_wait4;
629 case TASK_ZOMBIE:
630 current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
631 current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
632 read_unlock(&tasklist_lock);
633 if (ru != NULL)
634 getrusage(p, RUSAGE_BOTH, ru);
635 if (stat_addr)
636 __put_user(p->exit_code, stat_addr);
637 retval = p->pid;
638 if (p->p_opptr != p->p_pptr) {
639
640
641
642 REMOVE_LINKS(p);
643 p->p_pptr = p->p_opptr;
644 SET_LINKS(p);
645 notify_parent(p, SIGCHLD);
646 } else
647 release(p);
648#ifdef DEBUG_PROC_TREE
649 audit_ptree();
650#endif
651 goto end_wait4;
652 default:
653 continue;
654 }
655 }
656 read_unlock(&tasklist_lock);
657 if (flag) {
658 retval = 0;
659 if (options & WNOHANG)
660 goto end_wait4;
661 retval = -ERESTARTSYS;
662 if (current->signal & ~current->blocked)
663 goto end_wait4;
664 current->state=TASK_INTERRUPTIBLE;
665 schedule();
666 goto repeat;
667 }
668 retval = -ECHILD;
669end_wait4:
670 remove_wait_queue(¤t->wait_chldexit,&wait);
671 return retval;
672}
673
674#ifndef __alpha__
675
676
677
678
679
680asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options)
681{
682 return sys_wait4(pid, stat_addr, options, NULL);
683}
684
685#endif
686