switch_uid(INIT_USER);
}
-void __set_special_pids(pid_t session, pid_t pgrp)
+void __set_special_pids(struct pid *pid)
{
struct task_struct *curr = current->group_leader;
+ pid_t nr = pid_nr(pid);
- if (task_session_nr(curr) != session) {
+ if (task_session(curr) != pid) {
detach_pid(curr, PIDTYPE_SID);
- set_task_session(curr, session);
- attach_pid(curr, PIDTYPE_SID, find_pid(session));
+ attach_pid(curr, PIDTYPE_SID, pid);
+ set_task_session(curr, nr);
}
- if (task_pgrp_nr(curr) != pgrp) {
+ if (task_pgrp(curr) != pid) {
detach_pid(curr, PIDTYPE_PGID);
- set_task_pgrp(curr, pgrp);
- attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp));
+ attach_pid(curr, PIDTYPE_PGID, pid);
+ set_task_pgrp(curr, nr);
}
}
-static void set_special_pids(pid_t session, pid_t pgrp)
+static void set_special_pids(struct pid *pid)
{
write_lock_irq(&tasklist_lock);
- __set_special_pids(session, pgrp);
+ __set_special_pids(pid);
write_unlock_irq(&tasklist_lock);
}
*/
current->flags |= PF_NOFREEZE;
- set_special_pids(1, 1);
+ if (current->nsproxy != &init_nsproxy) {
+ get_nsproxy(&init_nsproxy);
+ switch_task_namespaces(current, &init_nsproxy);
+ }
+ set_special_pids(&init_struct_pid);
proc_clear_tty(current);
/* Block and flush all signals */
current->fs = fs;
atomic_inc(&fs->count);
- if (current->nsproxy != init_task.nsproxy) {
- get_nsproxy(init_task.nsproxy);
- switch_task_namespaces(current, init_task.nsproxy);
- }
-
exit_files(current);
current->files = init_task.files;
atomic_inc(¤t->files->count);
return files;
}
-void fastcall put_files_struct(struct files_struct *files)
+void put_files_struct(struct files_struct *files)
{
struct fdtable *fdt;
{
/* No need to hold fs->lock if we are killing it */
if (atomic_dec_and_test(&fs->count)) {
- dput(fs->root);
- mntput(fs->rootmnt);
- dput(fs->pwd);
- mntput(fs->pwdmnt);
- if (fs->altroot) {
- dput(fs->altroot);
- mntput(fs->altrootmnt);
- }
+ path_put(&fs->root);
+ path_put(&fs->pwd);
+ if (fs->altroot.dentry)
+ path_put(&fs->altroot);
kmem_cache_free(fs_cachep, fs);
}
}
struct task_struct *t;
struct pid *pgrp;
- if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
- && !thread_group_empty(tsk)) {
- /*
- * This occurs when there was a race between our exit
- * syscall and a group signal choosing us as the one to
- * wake up. It could be that we are the only thread
- * alerted to check for pending signals, but another thread
- * should be woken now to take the signal since we will not.
- * Now we'll wake all the threads in the group just to make
- * sure someone gets all the pending signals.
- */
- spin_lock_irq(&tsk->sighand->siglock);
- for (t = next_thread(tsk); t != tsk; t = next_thread(t))
- if (!signal_pending(t) && !(t->flags & PF_EXITING))
- recalc_sigpending_and_wake(t);
- spin_unlock_irq(&tsk->sighand->siglock);
- }
-
/*
* This does two things:
*
zap_pid_ns_processes(tsk->nsproxy->pid_ns);
}
-fastcall NORET_TYPE void do_exit(long code)
+NORET_TYPE void do_exit(long code)
{
struct task_struct *tsk = current;
int group_dead;
schedule();
}
- tsk->flags |= PF_EXITING;
+ exit_signals(tsk); /* sets PF_EXITING */
/*
* tsk->flags are checked in the futex code to protect against
* an exiting task cleaning up the robust pi futexes.
do_group_exit((error_code & 0xff) << 8);
}
-static int eligible_child(pid_t pid, int options, struct task_struct *p)
+static struct pid *task_pid_type(struct task_struct *task, enum pid_type type)
+{
+ struct pid *pid = NULL;
+ if (type == PIDTYPE_PID)
+ pid = task->pids[type].pid;
+ else if (type < PIDTYPE_MAX)
+ pid = task->group_leader->pids[type].pid;
+ return pid;
+}
+
+static int eligible_child(enum pid_type type, struct pid *pid, int options,
+ struct task_struct *p)
{
int err;
- struct pid_namespace *ns;
- ns = current->nsproxy->pid_ns;
- if (pid > 0) {
- if (task_pid_nr_ns(p, ns) != pid)
- return 0;
- } else if (!pid) {
- if (task_pgrp_nr_ns(p, ns) != task_pgrp_vnr(current))
- return 0;
- } else if (pid != -1) {
- if (task_pgrp_nr_ns(p, ns) != -pid)
+ if (type < PIDTYPE_MAX) {
+ if (task_pid_type(p, type) != pid)
return 0;
}
if (likely(!err))
return 1;
- if (pid <= 0)
+ if (type != PIDTYPE_PID)
return 0;
/* This child was explicitly requested, abort */
read_unlock(&tasklist_lock);
{
unsigned long state;
int retval, status, traced;
- struct pid_namespace *ns;
-
- ns = current->nsproxy->pid_ns;
+ pid_t pid = task_pid_vnr(p);
if (unlikely(noreap)) {
- pid_t pid = task_pid_nr_ns(p, ns);
uid_t uid = p->uid;
int exit_code = p->exit_code;
int why, status;
- if (unlikely(p->exit_state != EXIT_ZOMBIE))
- return 0;
- if (unlikely(p->exit_signal == -1 && p->ptrace == 0))
- return 0;
get_task_struct(p);
read_unlock(&tasklist_lock);
if ((exit_code & 0x7f) == 0) {
retval = put_user(status, &infop->si_status);
}
if (!retval && infop)
- retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
+ retval = put_user(pid, &infop->si_pid);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
if (!retval)
- retval = task_pid_nr_ns(p, ns);
+ retval = pid;
if (traced) {
write_lock_irq(&tasklist_lock);
* possibly take page faults for user memory.
*/
get_task_struct(p);
- pid = task_pid_nr_ns(p, current->nsproxy->pid_ns);
+ pid = task_pid_vnr(p);
why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
read_unlock(&tasklist_lock);
int retval;
pid_t pid;
uid_t uid;
- struct pid_namespace *ns;
if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
return 0;
p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
spin_unlock_irq(&p->sighand->siglock);
- ns = current->nsproxy->pid_ns;
- pid = task_pid_nr_ns(p, ns);
+ pid = task_pid_vnr(p);
uid = p->uid;
get_task_struct(p);
read_unlock(&tasklist_lock);
if (!retval && stat_addr)
retval = put_user(0xffff, stat_addr);
if (!retval)
- retval = task_pid_nr_ns(p, ns);
+ retval = pid;
} else {
retval = wait_noreap_copyout(p, pid, uid,
CLD_CONTINUED, SIGCONT,
return retval;
}
-static long do_wait(pid_t pid, int options, struct siginfo __user *infop,
- int __user *stat_addr, struct rusage __user *ru)
+static long do_wait(enum pid_type type, struct pid *pid, int options,
+ struct siginfo __user *infop, int __user *stat_addr,
+ struct rusage __user *ru)
{
DECLARE_WAITQUEUE(wait, current);
struct task_struct *tsk;
add_wait_queue(¤t->signal->wait_chldexit,&wait);
repeat:
+ /* If there is nothing that can match our critier just get out */
+ retval = -ECHILD;
+ if ((type < PIDTYPE_MAX) && (!pid || hlist_empty(&pid->tasks[type])))
+ goto end;
+
/*
* We will set this flag if we see any child that might later
* match our criteria, even if we are not able to reap it yet.
struct task_struct *p;
list_for_each_entry(p, &tsk->children, sibling) {
- int ret = eligible_child(pid, options, p);
+ int ret = eligible_child(type, pid, options, p);
if (!ret)
continue;
if (!flag) {
list_for_each_entry(p, &tsk->ptrace_children,
ptrace_list) {
- flag = eligible_child(pid, options, p);
+ flag = eligible_child(type, pid, options, p);
if (!flag)
continue;
if (likely(flag > 0))
return retval;
}
-asmlinkage long sys_waitid(int which, pid_t pid,
+asmlinkage long sys_waitid(int which, pid_t upid,
struct siginfo __user *infop, int options,
struct rusage __user *ru)
{
+ struct pid *pid = NULL;
+ enum pid_type type;
long ret;
if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED))
switch (which) {
case P_ALL:
- pid = -1;
+ type = PIDTYPE_MAX;
break;
case P_PID:
- if (pid <= 0)
+ type = PIDTYPE_PID;
+ if (upid <= 0)
return -EINVAL;
break;
case P_PGID:
- if (pid <= 0)
+ type = PIDTYPE_PGID;
+ if (upid <= 0)
return -EINVAL;
- pid = -pid;
break;
default:
return -EINVAL;
}
- ret = do_wait(pid, options, infop, NULL, ru);
+ if (type < PIDTYPE_MAX)
+ pid = find_get_pid(upid);
+ ret = do_wait(type, pid, options, infop, NULL, ru);
+ put_pid(pid);
/* avoid REGPARM breakage on x86: */
prevent_tail_call(ret);
return ret;
}
-asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr,
+asmlinkage long sys_wait4(pid_t upid, int __user *stat_addr,
int options, struct rusage __user *ru)
{
+ struct pid *pid = NULL;
+ enum pid_type type;
long ret;
if (options & ~(WNOHANG|WUNTRACED|WCONTINUED|
__WNOTHREAD|__WCLONE|__WALL))
return -EINVAL;
- ret = do_wait(pid, options | WEXITED, NULL, stat_addr, ru);
+
+ if (upid == -1)
+ type = PIDTYPE_MAX;
+ else if (upid < 0) {
+ type = PIDTYPE_PGID;
+ pid = find_get_pid(-upid);
+ } else if (upid == 0) {
+ type = PIDTYPE_PGID;
+ pid = get_pid(task_pgrp(current));
+ } else /* upid > 0 */ {
+ type = PIDTYPE_PID;
+ pid = find_get_pid(upid);
+ }
+
+ ret = do_wait(type, pid, options | WEXITED, NULL, stat_addr, ru);
+ put_pid(pid);
/* avoid REGPARM breakage on x86: */
prevent_tail_call(ret);