Commit 7860b371 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] move job control fields from task_struct to signal_struct

From: Roland McGrath <roland@redhat.com>

This patch moves all the fields relating to job control from task_struct to
signal_struct, so that all this info is properly per-process rather than
being per-thread.
parent 0ab2d668
...@@ -1337,7 +1337,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) ...@@ -1337,7 +1337,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
* be holding locks... * be holding locks...
*/ */
if (user_mode(regs)) if (user_mode(regs))
tty_write_message(current->tty, buf); tty_write_message(current->signal->tty, buf);
buf[len-1] = '\0'; /* drop '\r' */ buf[len-1] = '\0'; /* drop '\r' */
printk(KERN_WARNING "%s", buf); /* watch for command names containing %s */ printk(KERN_WARNING "%s", buf); /* watch for command names containing %s */
} }
......
...@@ -402,7 +402,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) ...@@ -402,7 +402,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
Solaris setpgrp and setsid? */ Solaris setpgrp and setsid? */
ret = sys_setpgid(0, 0); ret = sys_setpgid(0, 0);
if (ret) return ret; if (ret) return ret;
current->tty = NULL; current->signal->tty = NULL;
return process_group(current); return process_group(current);
} }
case 2: /* getsid */ case 2: /* getsid */
......
...@@ -999,7 +999,8 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, ...@@ -999,7 +999,8 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
/* NOTE: not yet done after every sleep pending a thorough /* NOTE: not yet done after every sleep pending a thorough
check of the logic of this change. -- jlc */ check of the logic of this change. -- jlc */
/* don't stop on /dev/console */ /* don't stop on /dev/console */
if (file->f_op->write != redirected_tty_write && current->tty == tty) { if (file->f_op->write != redirected_tty_write &&
current->signal->tty == tty) {
if (tty->pgrp <= 0) if (tty->pgrp <= 0)
printk("read_chan: tty->pgrp <= 0!\n"); printk("read_chan: tty->pgrp <= 0!\n");
else if (process_group(current) != tty->pgrp) { else if (process_group(current) != tty->pgrp) {
......
...@@ -953,7 +953,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) ...@@ -953,7 +953,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
/* /*
* Info->count is now 1; so it's safe to sleep now. * Info->count is now 1; so it's safe to sleep now.
*/ */
info->session = current->session; info->session = current->signal->session;
info->pgrp = process_group(current); info->pgrp = process_group(current);
if ((info->flags & ROCKET_INITIALIZED) == 0) { if ((info->flags & ROCKET_INITIALIZED) == 0) {
......
...@@ -1420,7 +1420,7 @@ static int sx_open (struct tty_struct * tty, struct file * filp) ...@@ -1420,7 +1420,7 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
line = tty->index; line = tty->index;
sx_dprintk (SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, np=%d)\n", sx_dprintk (SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, np=%d)\n",
current->pid, line, tty, current->tty, sx_nports); current->pid, line, tty, current->signal->tty, sx_nports);
if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))
return -ENODEV; return -ENODEV;
......
...@@ -321,7 +321,7 @@ struct tty_driver *get_tty_driver(dev_t device, int *index) ...@@ -321,7 +321,7 @@ struct tty_driver *get_tty_driver(dev_t device, int *index)
*/ */
int tty_check_change(struct tty_struct * tty) int tty_check_change(struct tty_struct * tty)
{ {
if (current->tty != tty) if (current->signal->tty != tty)
return 0; return 0;
if (tty->pgrp <= 0) { if (tty->pgrp <= 0) {
printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n"); printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
...@@ -486,17 +486,14 @@ void do_tty_hangup(void *data) ...@@ -486,17 +486,14 @@ void do_tty_hangup(void *data)
if (tty->session > 0) { if (tty->session > 0) {
struct list_head *l; struct list_head *l;
for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) { for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) {
task_t *task = p; if (p->signal->tty == tty)
do { p->signal->tty = NULL;
if (task->tty == tty) if (!p->signal->leader)
task->tty = NULL; continue;
if (task->leader) { send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p);
send_group_sig_info(SIGHUP, SEND_SIG_PRIV, task); send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p);
send_group_sig_info(SIGCONT, SEND_SIG_PRIV, task);
}
} while_each_thread(p, task);
if (tty->pgrp > 0) if (tty->pgrp > 0)
p->tty_old_pgrp = tty->pgrp; p->signal->tty_old_pgrp = tty->pgrp;
} }
} }
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
...@@ -575,15 +572,15 @@ void disassociate_ctty(int on_exit) ...@@ -575,15 +572,15 @@ void disassociate_ctty(int on_exit)
lock_kernel(); lock_kernel();
tty = current->tty; tty = current->signal->tty;
if (tty) { if (tty) {
tty_pgrp = tty->pgrp; tty_pgrp = tty->pgrp;
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty); tty_vhangup(tty);
} else { } else {
if (current->tty_old_pgrp) { if (current->signal->tty_old_pgrp) {
kill_pg(current->tty_old_pgrp, SIGHUP, on_exit); kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
kill_pg(current->tty_old_pgrp, SIGCONT, on_exit); kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
} }
unlock_kernel(); unlock_kernel();
return; return;
...@@ -594,17 +591,13 @@ void disassociate_ctty(int on_exit) ...@@ -594,17 +591,13 @@ void disassociate_ctty(int on_exit)
kill_pg(tty_pgrp, SIGCONT, on_exit); kill_pg(tty_pgrp, SIGCONT, on_exit);
} }
current->tty_old_pgrp = 0; current->signal->tty_old_pgrp = 0;
tty->session = 0; tty->session = 0;
tty->pgrp = -1; tty->pgrp = -1;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(current->session, PIDTYPE_SID, p, l, pid) { for_each_task_pid(current->signal->session, PIDTYPE_SID, p, l, pid)
task_t *task = p; p->signal->tty = NULL;
do {
task->tty = NULL;
} while_each_thread(p, task);
}
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
unlock_kernel(); unlock_kernel();
} }
...@@ -1257,20 +1250,11 @@ static void release_dev(struct file * filp) ...@@ -1257,20 +1250,11 @@ static void release_dev(struct file * filp)
struct pid *pid; struct pid *pid;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) { for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid)
task_t *task = p; p->signal->tty = NULL;
do { if (o_tty)
task->tty = NULL; for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid)
} while_each_thread(p, task); p->signal->tty = NULL;
}
if (o_tty) {
for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid) {
task_t *task = p;
do {
task->tty = NULL;
} while_each_thread(p, task);
}
}
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} }
...@@ -1341,10 +1325,10 @@ static int tty_open(struct inode * inode, struct file * filp) ...@@ -1341,10 +1325,10 @@ static int tty_open(struct inode * inode, struct file * filp)
retry_open: retry_open:
noctty = filp->f_flags & O_NOCTTY; noctty = filp->f_flags & O_NOCTTY;
if (device == MKDEV(TTYAUX_MAJOR,0)) { if (device == MKDEV(TTYAUX_MAJOR,0)) {
if (!current->tty) if (!current->signal->tty)
return -ENXIO; return -ENXIO;
driver = current->tty->driver; driver = current->signal->tty->driver;
index = current->tty->index; index = current->signal->tty->index;
filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
/* noctty = 1; */ /* noctty = 1; */
goto got_driver; goto got_driver;
...@@ -1445,14 +1429,14 @@ static int tty_open(struct inode * inode, struct file * filp) ...@@ -1445,14 +1429,14 @@ static int tty_open(struct inode * inode, struct file * filp)
goto retry_open; goto retry_open;
} }
if (!noctty && if (!noctty &&
current->leader && current->signal->leader &&
!current->tty && !current->signal->tty &&
tty->session == 0) { tty->session == 0) {
task_lock(current); task_lock(current);
current->tty = tty; current->signal->tty = tty;
task_unlock(current); task_unlock(current);
current->tty_old_pgrp = 0; current->signal->tty_old_pgrp = 0;
tty->session = current->session; tty->session = current->signal->session;
tty->pgrp = process_group(current); tty->pgrp = process_group(current);
} }
return 0; return 0;
...@@ -1510,7 +1494,7 @@ static int tiocsti(struct tty_struct *tty, char * arg) ...@@ -1510,7 +1494,7 @@ static int tiocsti(struct tty_struct *tty, char * arg)
{ {
char ch, mbz = 0; char ch, mbz = 0;
if ((current->tty != tty) && !capable(CAP_SYS_ADMIN)) if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (get_user(ch, arg)) if (get_user(ch, arg))
return -EFAULT; return -EFAULT;
...@@ -1601,14 +1585,14 @@ static int tiocsctty(struct tty_struct *tty, int arg) ...@@ -1601,14 +1585,14 @@ static int tiocsctty(struct tty_struct *tty, int arg)
struct pid *pid; struct pid *pid;
task_t *p; task_t *p;
if (current->leader && if (current->signal->leader &&
(current->session == tty->session)) (current->signal->session == tty->session))
return 0; return 0;
/* /*
* The process must be a session leader and * The process must be a session leader and
* not have a controlling tty already. * not have a controlling tty already.
*/ */
if (!current->leader || current->tty) if (!current->signal->leader || current->signal->tty)
return -EPERM; return -EPERM;
if (tty->session > 0) { if (tty->session > 0) {
/* /*
...@@ -1621,21 +1605,17 @@ static int tiocsctty(struct tty_struct *tty, int arg) ...@@ -1621,21 +1605,17 @@ static int tiocsctty(struct tty_struct *tty, int arg)
*/ */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) { for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid)
task_t *task = p; p->signal->tty = NULL;
do {
task->tty = NULL;
} while_each_thread(p, task);
}
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} else } else
return -EPERM; return -EPERM;
} }
task_lock(current); task_lock(current);
current->tty = tty; current->signal->tty = tty;
task_unlock(current); task_unlock(current);
current->tty_old_pgrp = 0; current->signal->tty_old_pgrp = 0;
tty->session = current->session; tty->session = current->signal->session;
tty->pgrp = process_group(current); tty->pgrp = process_group(current);
return 0; return 0;
} }
...@@ -1646,7 +1626,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t ...@@ -1646,7 +1626,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
* (tty == real_tty) is a cheap way of * (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty. * testing if the tty is NOT a master pty.
*/ */
if (tty == real_tty && current->tty != real_tty) if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY; return -ENOTTY;
return put_user(real_tty->pgrp, arg); return put_user(real_tty->pgrp, arg);
} }
...@@ -1660,15 +1640,15 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t ...@@ -1660,15 +1640,15 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
return -ENOTTY; return -ENOTTY;
if (retval) if (retval)
return retval; return retval;
if (!current->tty || if (!current->signal->tty ||
(current->tty != real_tty) || (current->signal->tty != real_tty) ||
(real_tty->session != current->session)) (real_tty->session != current->signal->session))
return -ENOTTY; return -ENOTTY;
if (get_user(pgrp, (pid_t *) arg)) if (get_user(pgrp, (pid_t *) arg))
return -EFAULT; return -EFAULT;
if (pgrp < 0) if (pgrp < 0)
return -EINVAL; return -EINVAL;
if (session_of_pgrp(pgrp) != current->session) if (session_of_pgrp(pgrp) != current->signal->session)
return -EPERM; return -EPERM;
real_tty->pgrp = pgrp; real_tty->pgrp = pgrp;
return 0; return 0;
...@@ -1680,7 +1660,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t * ...@@ -1680,7 +1660,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t *
* (tty == real_tty) is a cheap way of * (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty. * testing if the tty is NOT a master pty.
*/ */
if (tty == real_tty && current->tty != real_tty) if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY; return -ENOTTY;
if (real_tty->session <= 0) if (real_tty->session <= 0)
return -ENOTTY; return -ENOTTY;
...@@ -1838,12 +1818,12 @@ int tty_ioctl(struct inode * inode, struct file * file, ...@@ -1838,12 +1818,12 @@ int tty_ioctl(struct inode * inode, struct file * file,
clear_bit(TTY_EXCLUSIVE, &tty->flags); clear_bit(TTY_EXCLUSIVE, &tty->flags);
return 0; return 0;
case TIOCNOTTY: case TIOCNOTTY:
if (current->tty != tty) if (current->signal->tty != tty)
return -ENOTTY; return -ENOTTY;
if (current->leader) if (current->signal->leader)
disassociate_ctty(0); disassociate_ctty(0);
task_lock(current); task_lock(current);
current->tty = NULL; current->signal->tty = NULL;
task_unlock(current); task_unlock(current);
return 0; return 0;
case TIOCSCTTY: case TIOCSCTTY:
...@@ -1947,9 +1927,9 @@ static void __do_SAK(void *arg) ...@@ -1947,9 +1927,9 @@ static void __do_SAK(void *arg)
tty->driver->flush_buffer(tty); tty->driver->flush_buffer(tty);
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(session, PIDTYPE_SID, p, l, pid) { for_each_task_pid(session, PIDTYPE_SID, p, l, pid) {
if (p->tty == tty || session > 0) { if (p->signal->tty == tty || session > 0) {
printk(KERN_NOTICE "SAK: killed process %d" printk(KERN_NOTICE "SAK: killed process %d"
" (%s): p->session==tty->session\n", " (%s): p->signal->session==tty->session\n",
p->pid, p->comm); p->pid, p->comm);
send_sig(SIGKILL, p, 1); send_sig(SIGKILL, p, 1);
continue; continue;
......
...@@ -2278,7 +2278,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) ...@@ -2278,7 +2278,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE)
return -EINVAL; return -EINVAL;
if (current->tty != tty && !capable(CAP_SYS_ADMIN)) if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (get_user(type, (char *)arg)) if (get_user(type, (char *)arg))
return -EFAULT; return -EFAULT;
......
...@@ -382,7 +382,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -382,7 +382,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
*/ */
perm = 0; perm = 0;
if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
perm = 1; perm = 1;
kbd = kbd_table + console; kbd = kbd_table + console;
...@@ -1221,4 +1221,3 @@ void change_console(unsigned int new_console) ...@@ -1221,4 +1221,3 @@ void change_console(unsigned int new_console)
complete_change_console(new_console); complete_change_console(new_console);
} }
...@@ -1307,7 +1307,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) ...@@ -1307,7 +1307,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
/* Resolve race condition, when ioctl'ing hanged up /* Resolve race condition, when ioctl'ing hanged up
and opened by another process device. and opened by another process device.
*/ */
if (sl->tty != current->tty && sl->pid != current->pid) { if (sl->tty != current->signal->tty && sl->pid != current->pid) {
spin_unlock_bh(&sl->lock); spin_unlock_bh(&sl->lock);
return -EPERM; return -EPERM;
} }
......
...@@ -471,7 +471,7 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, ...@@ -471,7 +471,7 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
* To have permissions to do most of the vt ioctls, we either have * To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
*/ */
perm = current->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG); perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
switch (cmd) { switch (cmd) {
case KDGKBTYPE: case KDGKBTYPE:
return put_user(KB_101, (char*) arg); return put_user(KB_101, (char*) arg);
......
...@@ -1129,7 +1129,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, ...@@ -1129,7 +1129,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
prstatus->pr_pid = p->pid; prstatus->pr_pid = p->pid;
prstatus->pr_ppid = p->parent->pid; prstatus->pr_ppid = p->parent->pid;
prstatus->pr_pgrp = process_group(p); prstatus->pr_pgrp = process_group(p);
prstatus->pr_sid = p->session; prstatus->pr_sid = p->signal->session;
jiffies_to_timeval(p->utime, &prstatus->pr_utime); jiffies_to_timeval(p->utime, &prstatus->pr_utime);
jiffies_to_timeval(p->stime, &prstatus->pr_stime); jiffies_to_timeval(p->stime, &prstatus->pr_stime);
jiffies_to_timeval(p->cutime, &prstatus->pr_cutime); jiffies_to_timeval(p->cutime, &prstatus->pr_cutime);
...@@ -1157,7 +1157,7 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, ...@@ -1157,7 +1157,7 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
psinfo->pr_pid = p->pid; psinfo->pr_pid = p->pid;
psinfo->pr_ppid = p->parent->pid; psinfo->pr_ppid = p->parent->pid;
psinfo->pr_pgrp = process_group(p); psinfo->pr_pgrp = process_group(p);
psinfo->pr_sid = p->session; psinfo->pr_sid = p->signal->session;
i = p->state ? ffz(~p->state) + 1 : 0; i = p->state ? ffz(~p->state) + 1 : 0;
psinfo->pr_state = i; psinfo->pr_state = i;
......
...@@ -1604,7 +1604,7 @@ static int vt_check(struct file *file) ...@@ -1604,7 +1604,7 @@ static int vt_check(struct file *file)
* To have permissions to do most of the vt ioctls, we either have * To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or super-user. * to be the owner of the tty, or super-user.
*/ */
if (current->tty == tty || capable(CAP_SYS_ADMIN)) if (current->signal->tty == tty || capable(CAP_SYS_ADMIN))
return 1; return 1;
return 0; return 0;
} }
......
...@@ -689,12 +689,12 @@ static void print_warning(struct dquot *dquot, const char warntype) ...@@ -689,12 +689,12 @@ static void print_warning(struct dquot *dquot, const char warntype)
if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
return; return;
tty_write_message(current->tty, dquot->dq_sb->s_id); tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
if (warntype == ISOFTWARN || warntype == BSOFTWARN) if (warntype == ISOFTWARN || warntype == BSOFTWARN)
tty_write_message(current->tty, ": warning, "); tty_write_message(current->signal->tty, ": warning, ");
else else
tty_write_message(current->tty, ": write failed, "); tty_write_message(current->signal->tty, ": write failed, ");
tty_write_message(current->tty, quotatypes[dquot->dq_type]); tty_write_message(current->signal->tty, quotatypes[dquot->dq_type]);
switch (warntype) { switch (warntype) {
case IHARDWARN: case IHARDWARN:
msg = " file limit reached.\n"; msg = " file limit reached.\n";
...@@ -715,7 +715,7 @@ static void print_warning(struct dquot *dquot, const char warntype) ...@@ -715,7 +715,7 @@ static void print_warning(struct dquot *dquot, const char warntype)
msg = " block quota exceeded.\n"; msg = " block quota exceeded.\n";
break; break;
} }
tty_write_message(current->tty, msg); tty_write_message(current->signal->tty, msg);
} }
static inline void flush_warnings(struct dquot **dquots, char *warntype) static inline void flush_warnings(struct dquot **dquots, char *warntype)
......
...@@ -601,6 +601,11 @@ static inline int de_thread(struct task_struct *tsk) ...@@ -601,6 +601,11 @@ static inline int de_thread(struct task_struct *tsk)
newsig->group_stop_count = 0; newsig->group_stop_count = 0;
newsig->curr_target = NULL; newsig->curr_target = NULL;
init_sigpending(&newsig->shared_pending); init_sigpending(&newsig->shared_pending);
newsig->pgrp = oldsig->pgrp;
newsig->session = oldsig->session;
newsig->leader = oldsig->leader;
newsig->tty_old_pgrp = oldsig->tty_old_pgrp;
} }
if (thread_group_empty(current)) if (thread_group_empty(current))
......
...@@ -1037,7 +1037,7 @@ EXPORT_SYMBOL(sys_close); ...@@ -1037,7 +1037,7 @@ EXPORT_SYMBOL(sys_close);
asmlinkage long sys_vhangup(void) asmlinkage long sys_vhangup(void)
{ {
if (capable(CAP_SYS_TTY_CONFIG)) { if (capable(CAP_SYS_TTY_CONFIG)) {
tty_vhangup(current->tty); tty_vhangup(current->signal->tty);
return 0; return 0;
} }
return -EPERM; return -EPERM;
......
...@@ -168,7 +168,7 @@ static inline char * task_state(struct task_struct *p, char *buffer) ...@@ -168,7 +168,7 @@ static inline char * task_state(struct task_struct *p, char *buffer)
p->pid && p->ptrace ? p->parent->pid : 0, p->pid && p->ptrace ? p->parent->pid : 0,
p->uid, p->euid, p->suid, p->fsuid, p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid); p->gid, p->egid, p->sgid, p->fsgid);
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
task_lock(p); task_lock(p);
buffer += sprintf(buffer, buffer += sprintf(buffer,
"FDSize:\t%d\n" "FDSize:\t%d\n"
...@@ -301,7 +301,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -301,7 +301,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
sigset_t sigign, sigcatch; sigset_t sigign, sigcatch;
char state; char state;
int res; int res;
pid_t ppid; pid_t ppid, pgid = -1, sid = -1;
int num_threads = 0; int num_threads = 0;
struct mm_struct *mm; struct mm_struct *mm;
...@@ -311,10 +311,6 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -311,10 +311,6 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
mm = task->mm; mm = task->mm;
if(mm) if(mm)
mm = mmgrab(mm); mm = mmgrab(mm);
if (task->tty) {
tty_pgrp = task->tty->pgrp;
tty_nr = new_encode_dev(tty_devnum(task->tty));
}
task_unlock(task); task_unlock(task);
if (mm) { if (mm) {
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
...@@ -335,7 +331,15 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -335,7 +331,15 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
collect_sigign_sigcatch(task, &sigign, &sigcatch); collect_sigign_sigcatch(task, &sigign, &sigcatch);
spin_unlock_irq(&task->sighand->siglock); spin_unlock_irq(&task->sighand->siglock);
} }
read_unlock(&tasklist_lock); if (task->signal) {
if (task->signal->tty) {
tty_pgrp = task->signal->tty->pgrp;
tty_nr = new_encode_dev(tty_devnum(task->signal->tty));
}
pgid = process_group(task);
sid = task->signal->session;
}
read_unlock(&tasklist_lock);
/* scale priority and nice values from timeslices to -20..20 */ /* scale priority and nice values from timeslices to -20..20 */
/* to make it look like a "normal" Unix priority/nice value */ /* to make it look like a "normal" Unix priority/nice value */
...@@ -352,8 +356,8 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -352,8 +356,8 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
task->comm, task->comm,
state, state,
ppid, ppid,
process_group(task), pgid,
task->session, sid,
tty_nr, tty_nr,
tty_pgrp, tty_pgrp,
task->flags, task->flags,
......
...@@ -269,6 +269,15 @@ struct signal_struct { ...@@ -269,6 +269,15 @@ struct signal_struct {
/* thread group stop support, overloads group_exit_code too */ /* thread group stop support, overloads group_exit_code too */
int group_stop_count; int group_stop_count;
/* job control IDs */
pid_t pgrp;
pid_t tty_old_pgrp;
pid_t session;
/* boolean value for session group leader */
int leader;
struct tty_struct *tty; /* NULL if no tty */
}; };
/* /*
...@@ -398,12 +407,7 @@ struct task_struct { ...@@ -398,12 +407,7 @@ struct task_struct {
unsigned long personality; unsigned long personality;
int did_exec:1; int did_exec:1;
pid_t pid; pid_t pid;
pid_t __pgrp; /* Accessed via process_group() */
pid_t tty_old_pgrp;
pid_t session;
pid_t tgid; pid_t tgid;
/* boolean value for session group leader */
int leader;
/* /*
* pointers to (original) parent process, youngest child, younger sibling, * pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with * older sibling, respectively. (p->father can be replaced with
...@@ -446,7 +450,6 @@ struct task_struct { ...@@ -446,7 +450,6 @@ struct task_struct {
char comm[16]; char comm[16];
/* file system info */ /* file system info */
int link_count, total_link_count; int link_count, total_link_count;
struct tty_struct *tty; /* NULL if no tty */
/* ipc stuff */ /* ipc stuff */
struct sysv_sem sysvsem; struct sysv_sem sysvsem;
/* CPU-specific state of this task */ /* CPU-specific state of this task */
...@@ -499,7 +502,7 @@ struct task_struct { ...@@ -499,7 +502,7 @@ struct task_struct {
static inline pid_t process_group(struct task_struct *tsk) static inline pid_t process_group(struct task_struct *tsk)
{ {
return tsk->group_leader->__pgrp; return tsk->signal->pgrp;
} }
extern void __put_task_struct(struct task_struct *tsk); extern void __put_task_struct(struct task_struct *tsk);
......
...@@ -347,7 +347,7 @@ static void do_acct_process(long exitcode, struct file *file) ...@@ -347,7 +347,7 @@ static void do_acct_process(long exitcode, struct file *file)
/* we really need to bite the bullet and change layout */ /* we really need to bite the bullet and change layout */
ac.ac_uid = current->uid; ac.ac_uid = current->uid;
ac.ac_gid = current->gid; ac.ac_gid = current->gid;
ac.ac_tty = current->tty ? old_encode_dev(tty_devnum(current->tty)) : 0; ac.ac_tty = current->signal->tty ? old_encode_dev(tty_devnum(current->signal->tty)) : 0;
ac.ac_flag = 0; ac.ac_flag = 0;
if (current->flags & PF_FORKNOEXEC) if (current->flags & PF_FORKNOEXEC)
......
...@@ -136,13 +136,13 @@ int session_of_pgrp(int pgrp) ...@@ -136,13 +136,13 @@ int session_of_pgrp(int pgrp)
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid)
if (p->session > 0) { if (p->signal->session > 0) {
sid = p->session; sid = p->signal->session;
goto out; goto out;
} }
p = find_task_by_pid(pgrp); p = find_task_by_pid(pgrp);
if (p) if (p)
sid = p->session; sid = p->signal->session;
out: out:
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
...@@ -170,7 +170,7 @@ static int will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) ...@@ -170,7 +170,7 @@ static int will_become_orphaned_pgrp(int pgrp, task_t *ignored_task)
|| p->real_parent->pid == 1) || p->real_parent->pid == 1)
continue; continue;
if (process_group(p->real_parent) != pgrp if (process_group(p->real_parent) != pgrp
&& p->real_parent->session == p->session) { && p->real_parent->signal->session == p->signal->session) {
ret = 0; ret = 0;
break; break;
} }
...@@ -259,14 +259,14 @@ void __set_special_pids(pid_t session, pid_t pgrp) ...@@ -259,14 +259,14 @@ void __set_special_pids(pid_t session, pid_t pgrp)
{ {
struct task_struct *curr = current; struct task_struct *curr = current;
if (curr->session != session) { if (curr->signal->session != session) {
detach_pid(curr, PIDTYPE_SID); detach_pid(curr, PIDTYPE_SID);
curr->session = session; curr->signal->session = session;
attach_pid(curr, PIDTYPE_SID, session); attach_pid(curr, PIDTYPE_SID, session);
} }
if (process_group(curr) != pgrp) { if (process_group(curr) != pgrp) {
detach_pid(curr, PIDTYPE_PGID); detach_pid(curr, PIDTYPE_PGID);
curr->group_leader->__pgrp = pgrp; curr->signal->pgrp = pgrp;
attach_pid(curr, PIDTYPE_PGID, pgrp); attach_pid(curr, PIDTYPE_PGID, pgrp);
} }
} }
...@@ -341,7 +341,7 @@ void daemonize(const char *name, ...) ...@@ -341,7 +341,7 @@ void daemonize(const char *name, ...)
exit_mm(current); exit_mm(current);
set_special_pids(1, 1); set_special_pids(1, 1);
current->tty = NULL; current->signal->tty = NULL;
/* Block and flush all signals */ /* Block and flush all signals */
sigfillset(&blocked); sigfillset(&blocked);
...@@ -564,7 +564,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) ...@@ -564,7 +564,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
* outside, so the child pgrp is now orphaned. * outside, so the child pgrp is now orphaned.
*/ */
if ((process_group(p) != process_group(father)) && if ((process_group(p) != process_group(father)) &&
(p->session == father->session)) { (p->signal->session == father->signal->session)) {
int pgrp = process_group(p); int pgrp = process_group(p);
if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
...@@ -675,7 +675,7 @@ static void exit_notify(struct task_struct *tsk) ...@@ -675,7 +675,7 @@ static void exit_notify(struct task_struct *tsk)
t = tsk->real_parent; t = tsk->real_parent;
if ((process_group(t) != process_group(tsk)) && if ((process_group(t) != process_group(tsk)) &&
(t->session == tsk->session) && (t->signal->session == tsk->signal->session) &&
will_become_orphaned_pgrp(process_group(tsk), tsk) && will_become_orphaned_pgrp(process_group(tsk), tsk) &&
has_stopped_jobs(process_group(tsk))) { has_stopped_jobs(process_group(tsk))) {
__kill_pg_info(SIGHUP, (void *)1, process_group(tsk)); __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
...@@ -780,7 +780,7 @@ asmlinkage NORET_TYPE void do_exit(long code) ...@@ -780,7 +780,7 @@ asmlinkage NORET_TYPE void do_exit(long code)
exit_itimers(tsk); exit_itimers(tsk);
exit_thread(); exit_thread();
if (tsk->leader) if (tsk->signal->leader)
disassociate_ctty(1); disassociate_ctty(1);
module_put(tsk->thread_info->exec_domain->module); module_put(tsk->thread_info->exec_domain->module);
......
...@@ -811,6 +811,12 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts ...@@ -811,6 +811,12 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
sig->curr_target = NULL; sig->curr_target = NULL;
init_sigpending(&sig->shared_pending); init_sigpending(&sig->shared_pending);
sig->tty = current->signal->tty;
sig->pgrp = process_group(current);
sig->session = current->signal->session;
sig->leader = 0; /* session leadership doesn't inherit */
sig->tty_old_pgrp = 0;
return 0; return 0;
} }
...@@ -935,8 +941,6 @@ struct task_struct *copy_process(unsigned long clone_flags, ...@@ -935,8 +941,6 @@ struct task_struct *copy_process(unsigned long clone_flags,
init_timer(&p->real_timer); init_timer(&p->real_timer);
p->real_timer.data = (unsigned long) p; p->real_timer.data = (unsigned long) p;
p->leader = 0; /* session leadership doesn't inherit */
p->tty_old_pgrp = 0;
p->utime = p->stime = 0; p->utime = p->stime = 0;
p->cutime = p->cstime = 0; p->cutime = p->cstime = 0;
p->lock_depth = -1; /* -1 = no lock */ p->lock_depth = -1; /* -1 = no lock */
...@@ -1055,7 +1059,7 @@ struct task_struct *copy_process(unsigned long clone_flags, ...@@ -1055,7 +1059,7 @@ struct task_struct *copy_process(unsigned long clone_flags,
if (thread_group_leader(p)) { if (thread_group_leader(p)) {
attach_pid(p, PIDTYPE_TGID, p->tgid); attach_pid(p, PIDTYPE_TGID, p->tgid);
attach_pid(p, PIDTYPE_PGID, process_group(p)); attach_pid(p, PIDTYPE_PGID, process_group(p));
attach_pid(p, PIDTYPE_SID, p->session); attach_pid(p, PIDTYPE_SID, p->signal->session);
if (p->pid) if (p->pid)
__get_cpu_var(process_counts)++; __get_cpu_var(process_counts)++;
} else } else
......
...@@ -253,14 +253,14 @@ void switch_exec_pids(task_t *leader, task_t *thread) ...@@ -253,14 +253,14 @@ void switch_exec_pids(task_t *leader, task_t *thread)
attach_pid(thread, PIDTYPE_PID, thread->pid); attach_pid(thread, PIDTYPE_PID, thread->pid);
attach_pid(thread, PIDTYPE_TGID, thread->tgid); attach_pid(thread, PIDTYPE_TGID, thread->tgid);
attach_pid(thread, PIDTYPE_PGID, leader->__pgrp); attach_pid(thread, PIDTYPE_PGID, thread->signal->pgrp);
attach_pid(thread, PIDTYPE_SID, thread->session); attach_pid(thread, PIDTYPE_SID, thread->signal->session);
list_add_tail(&thread->tasks, &init_task.tasks); list_add_tail(&thread->tasks, &init_task.tasks);
attach_pid(leader, PIDTYPE_PID, leader->pid); attach_pid(leader, PIDTYPE_PID, leader->pid);
attach_pid(leader, PIDTYPE_TGID, leader->tgid); attach_pid(leader, PIDTYPE_TGID, leader->tgid);
attach_pid(leader, PIDTYPE_PGID, leader->__pgrp); attach_pid(leader, PIDTYPE_PGID, leader->signal->pgrp);
attach_pid(leader, PIDTYPE_SID, leader->session); attach_pid(leader, PIDTYPE_SID, leader->signal->session);
} }
/* /*
......
...@@ -588,7 +588,8 @@ static int check_kill_permission(int sig, struct siginfo *info, ...@@ -588,7 +588,8 @@ static int check_kill_permission(int sig, struct siginfo *info,
error = -EPERM; error = -EPERM;
if ((!info || ((unsigned long)info != 1 && if ((!info || ((unsigned long)info != 1 &&
(unsigned long)info != 2 && SI_FROMUSER(info))) (unsigned long)info != 2 && SI_FROMUSER(info)))
&& ((sig != SIGCONT) || (current->session != t->session)) && ((sig != SIGCONT) ||
(current->signal->session != t->signal->session))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid) && (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid) && (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL)) && !capable(CAP_KILL))
...@@ -1103,7 +1104,7 @@ kill_sl_info(int sig, struct siginfo *info, pid_t sid) ...@@ -1103,7 +1104,7 @@ kill_sl_info(int sig, struct siginfo *info, pid_t sid)
retval = -ESRCH; retval = -ESRCH;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task_pid(sid, PIDTYPE_SID, p, l, pid) { for_each_task_pid(sid, PIDTYPE_SID, p, l, pid) {
if (!p->leader) if (!p->signal->leader)
continue; continue;
err = group_send_sig_info(sig, info, p); err = group_send_sig_info(sig, info, p);
if (retval) if (retval)
......
...@@ -990,7 +990,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -990,7 +990,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
if (p->parent == current || p->real_parent == current) { if (p->parent == current || p->real_parent == current) {
err = -EPERM; err = -EPERM;
if (p->session != current->session) if (p->signal->session != current->signal->session)
goto out; goto out;
err = -EACCES; err = -EACCES;
if (p->did_exec) if (p->did_exec)
...@@ -1002,7 +1002,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -1002,7 +1002,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
} }
err = -EPERM; err = -EPERM;
if (p->leader) if (p->signal->leader)
goto out; goto out;
if (pgid != pid) { if (pgid != pid) {
...@@ -1011,7 +1011,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -1011,7 +1011,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
struct list_head *l; struct list_head *l;
for_each_task_pid(pgid, PIDTYPE_PGID, p, l, pid) for_each_task_pid(pgid, PIDTYPE_PGID, p, l, pid)
if (p->session == current->session) if (p->signal->session == current->signal->session)
goto ok_pgid; goto ok_pgid;
goto out; goto out;
} }
...@@ -1023,7 +1023,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -1023,7 +1023,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
if (process_group(p) != pgid) { if (process_group(p) != pgid) {
detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_PGID);
p->group_leader->__pgrp = pgid; p->signal->pgrp = pgid;
attach_pid(p, PIDTYPE_PGID, pgid); attach_pid(p, PIDTYPE_PGID, pgid);
} }
...@@ -1065,7 +1065,7 @@ asmlinkage long sys_getpgrp(void) ...@@ -1065,7 +1065,7 @@ asmlinkage long sys_getpgrp(void)
asmlinkage long sys_getsid(pid_t pid) asmlinkage long sys_getsid(pid_t pid)
{ {
if (!pid) { if (!pid) {
return current->session; return current->signal->session;
} else { } else {
int retval; int retval;
struct task_struct *p; struct task_struct *p;
...@@ -1077,7 +1077,7 @@ asmlinkage long sys_getsid(pid_t pid) ...@@ -1077,7 +1077,7 @@ asmlinkage long sys_getsid(pid_t pid)
if(p) { if(p) {
retval = security_task_getsid(p); retval = security_task_getsid(p);
if (!retval) if (!retval)
retval = p->session; retval = p->signal->session;
} }
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
return retval; return retval;
...@@ -1098,10 +1098,10 @@ asmlinkage long sys_setsid(void) ...@@ -1098,10 +1098,10 @@ asmlinkage long sys_setsid(void)
if (pid) if (pid)
goto out; goto out;
current->leader = 1; current->signal->leader = 1;
__set_special_pids(current->pid, current->pid); __set_special_pids(current->pid, current->pid);
current->tty = NULL; current->signal->tty = NULL;
current->tty_old_pgrp = 0; current->signal->tty_old_pgrp = 0;
err = process_group(current); err = process_group(current);
out: out:
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
......
...@@ -46,7 +46,7 @@ static void print_string(char *str) ...@@ -46,7 +46,7 @@ static void print_string(char *str)
struct tty_struct *my_tty; struct tty_struct *my_tty;
/* The tty for the current task */ /* The tty for the current task */
my_tty = current->tty; my_tty = current->signal->tty;
if (my_tty != NULL) { if (my_tty != NULL) {
my_tty->driver->write(my_tty, 0, str, strlen(str)); my_tty->driver->write(my_tty, 0, str, strlen(str));
my_tty->driver->write(my_tty, 0, "\015\012", 2); my_tty->driver->write(my_tty, 0, "\015\012", 2);
......
...@@ -95,7 +95,7 @@ match_sid(const struct sk_buff *skb, pid_t sid) ...@@ -95,7 +95,7 @@ match_sid(const struct sk_buff *skb, pid_t sid)
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
do_each_thread(g, p) { do_each_thread(g, p) {
struct files_struct *files; struct files_struct *files;
if (p->session != sid) if (p->signal->session != sid)
continue; continue;
task_lock(p); task_lock(p);
......
...@@ -61,7 +61,7 @@ match_sid(const struct sk_buff *skb, pid_t sid) ...@@ -61,7 +61,7 @@ match_sid(const struct sk_buff *skb, pid_t sid)
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
do_each_thread(g, p) { do_each_thread(g, p) {
struct files_struct *files; struct files_struct *files;
if (p->session != sid) if (p->signal->session != sid)
continue; continue;
task_lock(p); task_lock(p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment