10 date 91.12.01.09.21.46; author tytso; state Exp;
15 date 91.11.20.00.10.00; author tytso; state Exp;
20 date 91.11.16.21.02.17; author tytso; state Exp;
31 @Patches sent to Linus
37 * (C) 1991 Linus Torvalds
44 #include <linux/sched.h>
45 #include <linux/kernel.h>
46 #include <linux/tty.h>
47 #include <asm/segment.h>
50 int sys_close(int fd);
52 void release(struct task_struct * p)
58 for (i=1 ; i<NR_TASKS ; i++)
65 panic("trying to release non-existent task");
68 static inline int send_sig(long sig,struct task_struct * p,int priv)
70 if (!p || sig<1 || sig>32)
72 if (priv || (current->euid==p->euid) || suser())
73 p->signal |= (1<<(sig-1));
79 static void kill_session(void)
81 struct task_struct **p = NR_TASKS + task;
83 while (--p > &FIRST_TASK) {
84 if (*p && (*p)->session == current->session)
85 (*p)->signal |= 1<<(SIGHUP-1);
90 * XXX need to check permissions needed to send signals to process
91 * groups, etc. etc. kill() permissions semantics are tricky!
93 int sys_kill(int pid,int sig)
95 struct task_struct **p = NR_TASKS + task;
98 if (!pid) while (--p > &FIRST_TASK) {
99 if (*p && (*p)->pgrp == current->pid)
100 if (err=send_sig(sig,*p,1))
102 } else if (pid>0) while (--p > &FIRST_TASK) {
103 if (*p && (*p)->pid == pid)
104 if (err=send_sig(sig,*p,0))
106 } else if (pid == -1) while (--p > &FIRST_TASK)
107 if (err = send_sig(sig,*p,0))
109 else while (--p > &FIRST_TASK)
110 if (*p && (*p)->pgrp == -pid)
111 if (err = send_sig(sig,*p,0))
116 static void tell_father(int pid)
121 for (i=0;i<NR_TASKS;i++) {
124 if (task[i]->pid != pid)
126 task[i]->signal |= (1<<(SIGCHLD-1));
129 /* if we don't find any fathers, we just release ourselves */
133 int do_exit(long code)
137 free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
138 free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
139 for (i=0 ; i<NR_TASKS ; i++)
140 if (task[i] && task[i]->father == current->pid)
142 for (i=0 ; i<NR_OPEN ; i++)
143 if (current->filp[i])
149 if (current->leader && current->tty >= 0)
150 tty_table[current->tty].pgrp = 0;
151 if (last_task_used_math == current)
152 last_task_used_math = NULL;
155 current->state = TASK_ZOMBIE;
156 current->exit_code = code;
157 tell_father(current->father);
159 return (-1); /* just to suppress warnings */
162 int sys_exit(int error_code)
164 return do_exit((error_code&0xff)<<8);
167 int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
170 struct task_struct ** p;
172 verify_area(stat_addr,4);
175 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
176 if (!*p || *p == current)
178 if ((*p)->father != current->pid)
181 if ((*p)->pid != pid)
184 if ((*p)->pgrp != current->pgrp)
186 } else if (pid != -1) {
187 if ((*p)->pgrp != -pid)
190 switch ((*p)->state) {
192 if (!(options & WUNTRACED))
194 put_fs_long(0x7f,stat_addr);
197 current->cutime += (*p)->utime;
198 current->cstime += (*p)->stime;
200 put_fs_long((*p)->exit_code,stat_addr);
209 if (options & WNOHANG)
211 current->state=TASK_INTERRUPTIBLE;
213 if (!(current->signal &= ~(1<<(SIGCHLD-1))))
227 @Fixed bug in waitpid() so that the proper exit code would be returned.
232 static inline void send_sig(long sig,struct task_struct * p,int priv)
237 current->uid==p->uid ||
238 current->euid==p->uid ||
239 current->uid==p->euid ||
240 current->euid==p->euid)
247 void do_kill(long pid,long sig,int priv)
251 if (*p && (*p)->pgrp == current->pid)
252 send_sig(sig,*p,priv);
255 if (*p && (*p)->pid == pid)
256 send_sig(sig,*p,priv);
259 send_sig(sig,*p,priv);
262 send_sig(sig,*p,priv);
265 int sys_kill(int pid,int sig)
267 do_kill(pid,sig,!(current->uid || current->euid));
279 put_fs_long((*p)->exit_code,stat_addr);