This source file includes following definitions.
- release
- send_sig
- kill_session
- sys_kill
- tell_father
- do_exit
- sys_exit
- sys_waitpid
1
2
3
4
5
6
7 #include <errno.h>
8 #include <signal.h>
9 #include <sys/wait.h>
10
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/tty.h>
14 #include <asm/segment.h>
15
16 int sys_pause(void);
17 int sys_close(int fd);
18
19 void release(struct task_struct * p)
20 {
21 int i;
22
23 if (!p)
24 return;
25 for (i=1 ; i<NR_TASKS ; i++)
26 if (task[i]==p) {
27 task[i]=NULL;
28 free_page((long)p);
29 schedule();
30 return;
31 }
32 panic("trying to release non-existent task");
33 }
34
35 static inline int send_sig(long sig,struct task_struct * p,int priv)
36 {
37 if (!p || sig<1 || sig>32)
38 return -EINVAL;
39 if (priv || (current->euid==p->euid) || suser())
40 p->signal |= (1<<(sig-1));
41 else
42 return -EPERM;
43 return 0;
44 }
45
46 static void kill_session(void)
47 {
48 struct task_struct **p = NR_TASKS + task;
49
50 while (--p > &FIRST_TASK) {
51 if (*p && (*p)->session == current->session)
52 (*p)->signal |= 1<<(SIGHUP-1);
53 }
54 }
55
56
57
58
59
60 int sys_kill(int pid,int sig)
61 {
62 struct task_struct **p = NR_TASKS + task;
63 int err, retval = 0;
64
65 if (!pid) while (--p > &FIRST_TASK) {
66 if (*p && (*p)->pgrp == current->pid)
67 if (err=send_sig(sig,*p,1))
68 retval = err;
69 } else if (pid>0) while (--p > &FIRST_TASK) {
70 if (*p && (*p)->pid == pid)
71 if (err=send_sig(sig,*p,0))
72 retval = err;
73 } else if (pid == -1) while (--p > &FIRST_TASK)
74 if (err = send_sig(sig,*p,0))
75 retval = err;
76 else while (--p > &FIRST_TASK)
77 if (*p && (*p)->pgrp == -pid)
78 if (err = send_sig(sig,*p,0))
79 retval = err;
80 return retval;
81 }
82
83 static void tell_father(int pid)
84 {
85 int i;
86
87 if (pid)
88 for (i=0;i<NR_TASKS;i++) {
89 if (!task[i])
90 continue;
91 if (task[i]->pid != pid)
92 continue;
93 task[i]->signal |= (1<<(SIGCHLD-1));
94 return;
95 }
96
97 release(current);
98 }
99
100 int do_exit(long code)
101 {
102 int i;
103
104 free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
105 free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
106 for (i=0 ; i<NR_TASKS ; i++)
107 if (task[i] && task[i]->father == current->pid)
108 task[i]->father = 0;
109 for (i=0 ; i<NR_OPEN ; i++)
110 if (current->filp[i])
111 sys_close(i);
112 iput(current->pwd);
113 current->pwd=NULL;
114 iput(current->root);
115 current->root=NULL;
116 if (current->leader && current->tty >= 0)
117 tty_table[current->tty].pgrp = 0;
118 if (last_task_used_math == current)
119 last_task_used_math = NULL;
120 if (current->leader)
121 kill_session();
122 current->state = TASK_ZOMBIE;
123 current->exit_code = code;
124 tell_father(current->father);
125 schedule();
126 return (-1);
127 }
128
129 int sys_exit(int error_code)
130 {
131 return do_exit((error_code&0xff)<<8);
132 }
133
134 int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
135 {
136 int flag;
137 struct task_struct ** p;
138
139 verify_area(stat_addr,4);
140 repeat:
141 flag=0;
142 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
143 if (!*p || *p == current)
144 continue;
145 if ((*p)->father != current->pid)
146 continue;
147 if (pid>0) {
148 if ((*p)->pid != pid)
149 continue;
150 } else if (!pid) {
151 if ((*p)->pgrp != current->pgrp)
152 continue;
153 } else if (pid != -1) {
154 if ((*p)->pgrp != -pid)
155 continue;
156 }
157 switch ((*p)->state) {
158 case TASK_STOPPED:
159 if (!(options & WUNTRACED))
160 continue;
161 put_fs_long(0x7f,stat_addr);
162 return (*p)->pid;
163 case TASK_ZOMBIE:
164 current->cutime += (*p)->utime;
165 current->cstime += (*p)->stime;
166 flag = (*p)->pid;
167 put_fs_long((*p)->exit_code,stat_addr);
168 release(*p);
169 return flag;
170 default:
171 flag=1;
172 continue;
173 }
174 }
175 if (flag) {
176 if (options & WNOHANG)
177 return 0;
178 current->state=TASK_INTERRUPTIBLE;
179 schedule();
180 if (!(current->signal &= ~(1<<(SIGCHLD-1))))
181 goto repeat;
182 else
183 return -EINTR;
184 }
185 return -ECHILD;
186 }
187
188