Commit 1bd563fd authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] move job control fields from task_struct to

From: Roland McGrath <roland@redhat.com>

This patch completes what was started with the `process_group' accessor
function, moving all the job control-related fields from task_struct into
signal_struct and using process_foo accessor functions to read them.  All
these things are per-process in POSIX, none per-thread.  Off hand it's hard
to come up with the hairy MT scenarios in which the existing code would do
insane things, but trust me, they're there.  At any rate, all the uses
being done via inline accessor functions now has got to be all good.

I did a "make allyesconfig" build and caught the few random drivers and
whatnot that referred to these fields.  I was surprised to find how few
references to ->tty there really were to fix up.  I'm sure there will be a
few more fixups needed in non-x86 code.  The only actual testing of a
running kernel with these patches I've done is on my normal minimal x86
config.  Everything works fine as it did before as far as I can tell.

One issue that may be of concern is the lack of any locking on multiple
threads diddling these fields.  I don't think it really matters, though
there might be some obscure races that could produce inconsistent job
control results.  Nothing shattering, I'm sure; probably only something
like a multi-threaded program calling setsid while its other threads do tty
i/o, which never happens in reality.  This is the same situation we get by
using ->group_leader->foo without other synchronization, which seemed to be
the trend and noone was worried about it.
parent 9697ce4c
...@@ -1347,7 +1347,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) ...@@ -1347,7 +1347,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(process_tty(current), 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 */
} }
......
...@@ -974,7 +974,8 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, ...@@ -974,7 +974,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 &&
process_tty(current) == 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 = process_session(current);
info->pgrp = process_group(current); info->pgrp = process_group(current);
if ((info->flags & ROCKET_INITIALIZED) == 0) { if ((info->flags & ROCKET_INITIALIZED) == 0) {
......
...@@ -314,7 +314,7 @@ struct tty_driver *get_tty_driver(dev_t device, int *index) ...@@ -314,7 +314,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 (process_tty(current) != 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");
...@@ -481,14 +481,14 @@ void do_tty_hangup(void *data) ...@@ -481,14 +481,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) {
if (p->tty == tty) if (process_tty(p) == tty)
p->tty = NULL; p->signal->tty = NULL;
if (!p->leader) if (!process_session_leader(p))
continue; continue;
send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p);
send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p);
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);
...@@ -565,15 +565,15 @@ void disassociate_ctty(int on_exit) ...@@ -565,15 +565,15 @@ void disassociate_ctty(int on_exit)
lock_kernel(); lock_kernel();
tty = current->tty; tty = process_tty(current);
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;
...@@ -584,13 +584,13 @@ void disassociate_ctty(int on_exit) ...@@ -584,13 +584,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(process_session(current), PIDTYPE_SID, p, l, pid)
p->tty = NULL; p->signal->tty = NULL;
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
unlock_kernel(); unlock_kernel();
} }
...@@ -1218,10 +1218,10 @@ static void release_dev(struct file * filp) ...@@ -1218,10 +1218,10 @@ static void release_dev(struct file * filp)
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)
p->tty = NULL; p->signal->tty = NULL;
if (o_tty) if (o_tty)
for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid) for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid)
p->tty = NULL; p->signal->tty = NULL;
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} }
...@@ -1292,10 +1292,10 @@ static int tty_open(struct inode * inode, struct file * filp) ...@@ -1292,10 +1292,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 (!process_tty(current))
return -ENXIO; return -ENXIO;
driver = current->tty->driver; driver = process_tty(current)->driver;
index = current->tty->index; index = process_tty(current)->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;
...@@ -1389,15 +1389,13 @@ static int tty_open(struct inode * inode, struct file * filp) ...@@ -1389,15 +1389,13 @@ static int tty_open(struct inode * inode, struct file * filp)
filp->f_op = &tty_fops; filp->f_op = &tty_fops;
goto retry_open; goto retry_open;
} }
if (!noctty && if (!noctty && process_session_leader(current) &&
current->leader && !process_tty(current) && tty->session == 0) {
!current->tty &&
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 = process_session(current);
tty->pgrp = process_group(current); tty->pgrp = process_group(current);
} }
return 0; return 0;
...@@ -1455,7 +1453,7 @@ static int tiocsti(struct tty_struct *tty, char * arg) ...@@ -1455,7 +1453,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 ((process_tty(current) != tty) && !capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (get_user(ch, arg)) if (get_user(ch, arg))
return -EFAULT; return -EFAULT;
...@@ -1541,14 +1539,14 @@ static int tiocsctty(struct tty_struct *tty, int arg) ...@@ -1541,14 +1539,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 (process_session_leader(current) &&
(current->session == tty->session)) (process_session(current) == 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 (!process_session_leader(current) || process_tty(current))
return -EPERM; return -EPERM;
if (tty->session > 0) { if (tty->session > 0) {
/* /*
...@@ -1562,16 +1560,16 @@ static int tiocsctty(struct tty_struct *tty, int arg) ...@@ -1562,16 +1560,16 @@ 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)
p->tty = NULL; p->signal->tty = NULL;
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 = process_session(current);
tty->pgrp = process_group(current); tty->pgrp = process_group(current);
return 0; return 0;
} }
...@@ -1582,12 +1580,13 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t ...@@ -1582,12 +1580,13 @@ 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 && process_tty(current) != real_tty)
return -ENOTTY; return -ENOTTY;
return put_user(real_tty->pgrp, arg); return put_user(real_tty->pgrp, arg);
} }
static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t *arg) static int tiocspgrp(struct tty_struct *tty,
struct tty_struct *real_tty, pid_t *arg)
{ {
pid_t pgrp; pid_t pgrp;
int retval = tty_check_change(real_tty); int retval = tty_check_change(real_tty);
...@@ -1596,15 +1595,14 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t ...@@ -1596,15 +1595,14 @@ 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 (!process_tty(current) || (process_tty(current) != real_tty) ||
(current->tty != real_tty) || (real_tty->session != process_session(current)))
(real_tty->session != current->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) != process_session(current))
return -EPERM; return -EPERM;
real_tty->pgrp = pgrp; real_tty->pgrp = pgrp;
return 0; return 0;
...@@ -1616,7 +1614,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t * ...@@ -1616,7 +1614,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 && process_tty(current) != real_tty)
return -ENOTTY; return -ENOTTY;
if (real_tty->session <= 0) if (real_tty->session <= 0)
return -ENOTTY; return -ENOTTY;
...@@ -1774,12 +1772,12 @@ int tty_ioctl(struct inode * inode, struct file * file, ...@@ -1774,12 +1772,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 (process_tty(current) != tty)
return -ENOTTY; return -ENOTTY;
if (current->leader) if (process_session_leader(current))
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:
...@@ -1883,9 +1881,9 @@ static void __do_SAK(void *arg) ...@@ -1883,9 +1881,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 (process_tty(p) == tty || session > 0) {
printk(KERN_NOTICE "SAK: killed process %d" printk(KERN_NOTICE "SAK: killed process %d"
" (%s): p->session==tty->session\n", " (%s): process_session(p)==tty->session\n",
p->pid, p->comm); p->pid, p->comm);
send_sig(SIGKILL, p, 1); send_sig(SIGKILL, p, 1);
continue; continue;
......
...@@ -2226,7 +2226,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) ...@@ -2226,7 +2226,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 (process_tty(current) != 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;
......
...@@ -380,7 +380,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -380,7 +380,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 (process_tty(current) == tty || capable(CAP_SYS_TTY_CONFIG))
perm = 1; perm = 1;
kbd = kbd_table + console; kbd = kbd_table + console;
...@@ -1188,4 +1188,3 @@ void change_console(unsigned int new_console) ...@@ -1188,4 +1188,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 != process_tty(current) && sl->pid != current->pid) {
spin_unlock_bh(&sl->lock); spin_unlock_bh(&sl->lock);
return -EPERM; return -EPERM;
} }
......
...@@ -1084,7 +1084,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, ...@@ -1084,7 +1084,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 = process_session(p);
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);
...@@ -1112,7 +1112,7 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, ...@@ -1112,7 +1112,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 = process_session(p);
i = p->state ? ffz(~p->state) + 1 : 0; i = p->state ? ffz(~p->state) + 1 : 0;
psinfo->pr_state = i; psinfo->pr_state = i;
......
...@@ -668,12 +668,12 @@ static void print_warning(struct dquot *dquot, const char warntype) ...@@ -668,12 +668,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(process_tty(current), dquot->dq_sb->s_id);
if (warntype == ISOFTWARN || warntype == BSOFTWARN) if (warntype == ISOFTWARN || warntype == BSOFTWARN)
tty_write_message(current->tty, ": warning, "); tty_write_message(process_tty(current), ": warning, ");
else else
tty_write_message(current->tty, ": write failed, "); tty_write_message(process_tty(current), ": write failed, ");
tty_write_message(current->tty, quotatypes[dquot->dq_type]); tty_write_message(process_tty(current), quotatypes[dquot->dq_type]);
switch (warntype) { switch (warntype) {
case IHARDWARN: case IHARDWARN:
msg = " file limit reached.\n"; msg = " file limit reached.\n";
...@@ -694,7 +694,7 @@ static void print_warning(struct dquot *dquot, const char warntype) ...@@ -694,7 +694,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(process_tty(current), msg);
} }
static inline void flush_warnings(struct dquot **dquots, char *warntype) static inline void flush_warnings(struct dquot **dquots, char *warntype)
......
...@@ -596,6 +596,11 @@ static inline int de_thread(struct task_struct *tsk) ...@@ -596,6 +596,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))
......
...@@ -1019,7 +1019,7 @@ asmlinkage long sys_close(unsigned int fd) ...@@ -1019,7 +1019,7 @@ asmlinkage long sys_close(unsigned int fd)
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(process_tty(current));
return 0; return 0;
} }
return -EPERM; return -EPERM;
......
...@@ -304,9 +304,9 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -304,9 +304,9 @@ 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) { if (process_tty(task)) {
tty_pgrp = task->tty->pgrp; tty_pgrp = process_tty(task)->pgrp;
tty_nr = new_encode_dev(tty_devnum(task->tty)); tty_nr = new_encode_dev(tty_devnum(process_tty(task)));
} }
task_unlock(task); task_unlock(task);
if (mm) { if (mm) {
...@@ -345,7 +345,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer) ...@@ -345,7 +345,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
state, state,
ppid, ppid,
process_group(task), process_group(task),
task->session, process_session(task),
tty_nr, tty_nr,
tty_pgrp, tty_pgrp,
task->flags, task->flags,
......
...@@ -264,6 +264,15 @@ struct signal_struct { ...@@ -264,6 +264,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 */
}; };
/* /*
...@@ -366,12 +375,7 @@ struct task_struct { ...@@ -366,12 +375,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
...@@ -415,7 +419,6 @@ struct task_struct { ...@@ -415,7 +419,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 */
unsigned int locks; /* How many file locks are being held */ unsigned int locks; /* How many file locks are being held */
/* ipc stuff */ /* ipc stuff */
struct sysv_sem sysvsem; struct sysv_sem sysvsem;
...@@ -469,7 +472,22 @@ struct task_struct { ...@@ -469,7 +472,22 @@ 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;
}
static inline pid_t process_session(struct task_struct *tsk)
{
return tsk->signal->session;
}
static inline int process_session_leader(struct task_struct *tsk)
{
return tsk->signal->leader;
}
static inline struct tty_struct *process_tty(struct task_struct *tsk)
{
return tsk->signal->tty;
} }
extern void __put_task_struct(struct task_struct *tsk); extern void __put_task_struct(struct task_struct *tsk);
......
...@@ -343,7 +343,7 @@ static void do_acct_process(long exitcode, struct file *file) ...@@ -343,7 +343,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 = process_tty(current) ? old_encode_dev(tty_devnum(process_tty(current))) : 0;
ac.ac_flag = 0; ac.ac_flag = 0;
if (current->flags & PF_FORKNOEXEC) if (current->flags & PF_FORKNOEXEC)
......
...@@ -119,13 +119,13 @@ int session_of_pgrp(int pgrp) ...@@ -119,13 +119,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 (process_session(p) > 0) {
sid = p->session; sid = process_session(p);
goto out; goto out;
} }
p = find_task_by_pid(pgrp); p = find_task_by_pid(pgrp);
if (p) if (p)
sid = p->session; sid = process_session(p);
out: out:
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
...@@ -153,7 +153,7 @@ static int will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) ...@@ -153,7 +153,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) { && process_session(p->real_parent) == process_session(p)) {
ret = 0; ret = 0;
break; break;
} }
...@@ -242,14 +242,14 @@ void __set_special_pids(pid_t session, pid_t pgrp) ...@@ -242,14 +242,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 (process_session(curr) != 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);
} }
} }
...@@ -303,7 +303,7 @@ void daemonize(const char *name, ...) ...@@ -303,7 +303,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);
...@@ -509,7 +509,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) ...@@ -509,7 +509,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)) { (process_session(p) == process_session(father))) {
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)) {
...@@ -619,7 +619,7 @@ static void exit_notify(struct task_struct *tsk) ...@@ -619,7 +619,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) && (process_session(t) == process_session(tsk)) &&
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));
...@@ -714,7 +714,7 @@ NORET_TYPE void do_exit(long code) ...@@ -714,7 +714,7 @@ NORET_TYPE void do_exit(long code)
exit_itimers(tsk); exit_itimers(tsk);
exit_thread(); exit_thread();
if (tsk->leader) if (process_session_leader(tsk))
disassociate_ctty(1); disassociate_ctty(1);
module_put(tsk->thread_info->exec_domain->module); module_put(tsk->thread_info->exec_domain->module);
......
...@@ -725,6 +725,12 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts ...@@ -725,6 +725,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 = process_tty(current);
sig->pgrp = process_group(current);
sig->session = process_session(current);
sig->leader = 0; /* session leadership doesn't inherit */
sig->tty_old_pgrp = 0;
return 0; return 0;
} }
...@@ -771,7 +777,9 @@ struct task_struct *copy_process(unsigned long clone_flags, ...@@ -771,7 +777,9 @@ struct task_struct *copy_process(unsigned long clone_flags,
* Thread groups must share signals as well, and detached threads * Thread groups must share signals as well, and detached threads
* can only be started up within the thread group. * can only be started up within the thread group.
*/ */
if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND)) if ((clone_flags & CLONE_THREAD) &&
(clone_flags & (CLONE_SIGHAND|CLONE_DETACHED)) !=
(CLONE_SIGHAND|CLONE_DETACHED))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/* /*
...@@ -876,8 +884,6 @@ struct task_struct *copy_process(unsigned long clone_flags, ...@@ -876,8 +884,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->array = NULL; p->array = NULL;
...@@ -1022,7 +1028,7 @@ struct task_struct *copy_process(unsigned long clone_flags, ...@@ -1022,7 +1028,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, process_session(p));
if (p->pid) if (p->pid)
__get_cpu_var(process_counts)++; __get_cpu_var(process_counts)++;
} else } else
......
...@@ -250,14 +250,14 @@ void switch_exec_pids(task_t *leader, task_t *thread) ...@@ -250,14 +250,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);
} }
/* /*
......
...@@ -593,7 +593,8 @@ static int check_kill_permission(int sig, struct siginfo *info, ...@@ -593,7 +593,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) ||
(process_session(current) != process_session(t)))
&& (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))
...@@ -1102,7 +1103,7 @@ kill_sl_info(int sig, struct siginfo *info, pid_t sid) ...@@ -1102,7 +1103,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 (!process_session_leader(p))
continue; continue;
err = group_send_sig_info(sig, info, p); err = group_send_sig_info(sig, info, p);
if (retval) if (retval)
......
...@@ -951,7 +951,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -951,7 +951,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 (process_session(p) != process_session(current))
goto out; goto out;
err = -EACCES; err = -EACCES;
if (p->did_exec) if (p->did_exec)
...@@ -963,7 +963,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -963,7 +963,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
} }
err = -EPERM; err = -EPERM;
if (p->leader) if (process_session_leader(p))
goto out; goto out;
if (pgid != pid) { if (pgid != pid) {
...@@ -972,7 +972,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -972,7 +972,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 (process_session(p) == process_session(current))
goto ok_pgid; goto ok_pgid;
goto out; goto out;
} }
...@@ -984,7 +984,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) ...@@ -984,7 +984,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);
} }
...@@ -1026,7 +1026,7 @@ asmlinkage long sys_getpgrp(void) ...@@ -1026,7 +1026,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 process_session(current);
} else { } else {
int retval; int retval;
struct task_struct *p; struct task_struct *p;
...@@ -1038,7 +1038,7 @@ asmlinkage long sys_getsid(pid_t pid) ...@@ -1038,7 +1038,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 = process_session(p);
} }
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
return retval; return retval;
...@@ -1059,10 +1059,10 @@ asmlinkage long sys_setsid(void) ...@@ -1059,10 +1059,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);
......
...@@ -90,7 +90,7 @@ match_sid(const struct sk_buff *skb, pid_t sid) ...@@ -90,7 +90,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 (process_session(p) != sid)
continue; continue;
task_lock(p); task_lock(p);
......
...@@ -56,7 +56,7 @@ match_sid(const struct sk_buff *skb, pid_t sid) ...@@ -56,7 +56,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 (process_session(p) != 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