From: Roland McGrath 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. drivers/char/n_tty.c | 3 - drivers/char/rocket.c | 2 drivers/char/tty_io.c | 88 +++++++++++++++++++--------------------- drivers/char/vt.c | 2 drivers/char/vt_ioctl.c | 3 - drivers/net/slip.c | 2 fs/binfmt_elf.c | 4 - fs/dquot.c | 10 ++-- fs/exec.c | 5 ++ fs/open.c | 2 fs/proc/array.c | 8 +-- include/linux/sched.h | 32 +++++++++++--- kernel/acct.c | 2 kernel/exit.c | 22 +++++----- kernel/fork.c | 14 ++++-- kernel/pid.c | 8 +-- kernel/signal.c | 5 +- kernel/sys.c | 18 ++++---- net/ipv4/netfilter/ipt_owner.c | 2 net/ipv6/netfilter/ip6t_owner.c | 2 20 files changed, 131 insertions(+), 103 deletions(-) diff -puN drivers/char/n_tty.c~move-job-control-fields drivers/char/n_tty.c --- 25/drivers/char/n_tty.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/drivers/char/n_tty.c 2003-10-05 00:36:15.000000000 -0700 @@ -974,7 +974,8 @@ do_it_again: /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* 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) printk("read_chan: tty->pgrp <= 0!\n"); else if (process_group(current) != tty->pgrp) { diff -puN drivers/char/rocket.c~move-job-control-fields drivers/char/rocket.c --- 25/drivers/char/rocket.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/drivers/char/rocket.c 2003-10-05 00:36:15.000000000 -0700 @@ -953,7 +953,7 @@ static int rp_open(struct tty_struct *tt /* * 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); if ((info->flags & ROCKET_INITIALIZED) == 0) { diff -puN drivers/char/tty_io.c~move-job-control-fields drivers/char/tty_io.c --- 25/drivers/char/tty_io.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/drivers/char/tty_io.c 2003-10-05 00:36:15.000000000 -0700 @@ -314,7 +314,7 @@ struct tty_driver *get_tty_driver(dev_t */ int tty_check_change(struct tty_struct * tty) { - if (current->tty != tty) + if (process_tty(current) != tty) return 0; if (tty->pgrp <= 0) { printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n"); @@ -481,14 +481,14 @@ void do_tty_hangup(void *data) if (tty->session > 0) { struct list_head *l; for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) { - if (p->tty == tty) - p->tty = NULL; - if (!p->leader) + if (process_tty(p) == tty) + p->signal->tty = NULL; + if (!process_session_leader(p)) continue; send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); if (tty->pgrp > 0) - p->tty_old_pgrp = tty->pgrp; + p->signal->tty_old_pgrp = tty->pgrp; } } read_unlock(&tasklist_lock); @@ -565,15 +565,15 @@ void disassociate_ctty(int on_exit) lock_kernel(); - tty = current->tty; + tty = process_tty(current); if (tty) { tty_pgrp = tty->pgrp; if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) tty_vhangup(tty); } else { - if (current->tty_old_pgrp) { - kill_pg(current->tty_old_pgrp, SIGHUP, on_exit); - kill_pg(current->tty_old_pgrp, SIGCONT, on_exit); + if (current->signal->tty_old_pgrp) { + kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); + kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); } unlock_kernel(); return; @@ -584,13 +584,13 @@ void disassociate_ctty(int on_exit) kill_pg(tty_pgrp, SIGCONT, on_exit); } - current->tty_old_pgrp = 0; + current->signal->tty_old_pgrp = 0; tty->session = 0; tty->pgrp = -1; read_lock(&tasklist_lock); - for_each_task_pid(current->session, PIDTYPE_SID, p, l, pid) - p->tty = NULL; + for_each_task_pid(process_session(current), PIDTYPE_SID, p, l, pid) + p->signal->tty = NULL; read_unlock(&tasklist_lock); unlock_kernel(); } @@ -1218,10 +1218,10 @@ static void release_dev(struct file * fi read_lock(&tasklist_lock); for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) - p->tty = NULL; + p->signal->tty = NULL; if (o_tty) for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid) - p->tty = NULL; + p->signal->tty = NULL; read_unlock(&tasklist_lock); } @@ -1292,10 +1292,10 @@ static int tty_open(struct inode * inode retry_open: noctty = filp->f_flags & O_NOCTTY; if (device == MKDEV(TTYAUX_MAJOR,0)) { - if (!current->tty) + if (!process_tty(current)) return -ENXIO; - driver = current->tty->driver; - index = current->tty->index; + driver = process_tty(current)->driver; + index = process_tty(current)->index; filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ /* noctty = 1; */ goto got_driver; @@ -1389,15 +1389,13 @@ got_driver: filp->f_op = &tty_fops; goto retry_open; } - if (!noctty && - current->leader && - !current->tty && - tty->session == 0) { + if (!noctty && process_session_leader(current) && + !process_tty(current) && tty->session == 0) { task_lock(current); - current->tty = tty; + current->signal->tty = tty; task_unlock(current); - current->tty_old_pgrp = 0; - tty->session = current->session; + current->signal->tty_old_pgrp = 0; + tty->session = process_session(current); tty->pgrp = process_group(current); } return 0; @@ -1455,7 +1453,7 @@ static int tiocsti(struct tty_struct *tt { char ch, mbz = 0; - if ((current->tty != tty) && !capable(CAP_SYS_ADMIN)) + if ((process_tty(current) != tty) && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ch, arg)) return -EFAULT; @@ -1541,14 +1539,14 @@ static int tiocsctty(struct tty_struct * struct pid *pid; task_t *p; - if (current->leader && - (current->session == tty->session)) + if (process_session_leader(current) && + (process_session(current) == tty->session)) return 0; /* * The process must be a session leader and * not have a controlling tty already. */ - if (!current->leader || current->tty) + if (!process_session_leader(current) || process_tty(current)) return -EPERM; if (tty->session > 0) { /* @@ -1562,16 +1560,16 @@ static int tiocsctty(struct tty_struct * read_lock(&tasklist_lock); for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) - p->tty = NULL; + p->signal->tty = NULL; read_unlock(&tasklist_lock); } else return -EPERM; } task_lock(current); - current->tty = tty; + current->signal->tty = tty; task_unlock(current); - current->tty_old_pgrp = 0; - tty->session = current->session; + current->signal->tty_old_pgrp = 0; + tty->session = process_session(current); tty->pgrp = process_group(current); return 0; } @@ -1582,12 +1580,13 @@ static int tiocgpgrp(struct tty_struct * * (tty == real_tty) is a cheap way of * 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 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; int retval = tty_check_change(real_tty); @@ -1596,15 +1595,14 @@ static int tiocspgrp(struct tty_struct * return -ENOTTY; if (retval) return retval; - if (!current->tty || - (current->tty != real_tty) || - (real_tty->session != current->session)) + if (!process_tty(current) || (process_tty(current) != real_tty) || + (real_tty->session != process_session(current))) return -ENOTTY; if (get_user(pgrp, (pid_t *) arg)) return -EFAULT; if (pgrp < 0) return -EINVAL; - if (session_of_pgrp(pgrp) != current->session) + if (session_of_pgrp(pgrp) != process_session(current)) return -EPERM; real_tty->pgrp = pgrp; return 0; @@ -1616,7 +1614,7 @@ static int tiocgsid(struct tty_struct *t * (tty == real_tty) is a cheap way of * 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; if (real_tty->session <= 0) return -ENOTTY; @@ -1774,12 +1772,12 @@ int tty_ioctl(struct inode * inode, stru clear_bit(TTY_EXCLUSIVE, &tty->flags); return 0; case TIOCNOTTY: - if (current->tty != tty) + if (process_tty(current) != tty) return -ENOTTY; - if (current->leader) + if (process_session_leader(current)) disassociate_ctty(0); task_lock(current); - current->tty = NULL; + current->signal->tty = NULL; task_unlock(current); return 0; case TIOCSCTTY: @@ -1883,10 +1881,10 @@ static void __do_SAK(void *arg) tty->driver->flush_buffer(tty); read_lock(&tasklist_lock); 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" - " (%s): p->session==tty->session\n", - p->pid, p->comm); + " (%s): process_session(p)==tty->session\n", + p->pid, p->comm); send_sig(SIGKILL, p, 1); continue; } diff -puN drivers/char/vt.c~move-job-control-fields drivers/char/vt.c --- 25/drivers/char/vt.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/drivers/char/vt.c 2003-10-05 00:36:15.000000000 -0700 @@ -2226,7 +2226,7 @@ int tioclinux(struct tty_struct *tty, un if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) return -EINVAL; - if (current->tty != tty && !capable(CAP_SYS_ADMIN)) + if (process_tty(current) != tty && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(type, (char *)arg)) return -EFAULT; diff -puN drivers/char/vt_ioctl.c~move-job-control-fields drivers/char/vt_ioctl.c --- 25/drivers/char/vt_ioctl.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/drivers/char/vt_ioctl.c 2003-10-05 00:36:15.000000000 -0700 @@ -380,7 +380,7 @@ int vt_ioctl(struct tty_struct *tty, str * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. */ perm = 0; - if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) + if (process_tty(current) == tty || capable(CAP_SYS_TTY_CONFIG)) perm = 1; kbd = kbd_table + console; @@ -1188,4 +1188,3 @@ void change_console(unsigned int new_con complete_change_console(new_console); } - diff -puN drivers/net/slip.c~move-job-control-fields drivers/net/slip.c --- 25/drivers/net/slip.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/drivers/net/slip.c 2003-10-05 00:36:15.000000000 -0700 @@ -1307,7 +1307,7 @@ static int sl_ioctl(struct net_device *d /* Resolve race condition, when ioctl'ing hanged up 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); return -EPERM; } diff -puN fs/binfmt_elf.c~move-job-control-fields fs/binfmt_elf.c --- 25/fs/binfmt_elf.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/fs/binfmt_elf.c 2003-10-05 00:36:15.000000000 -0700 @@ -1084,7 +1084,7 @@ static void fill_prstatus(struct elf_prs prstatus->pr_pid = p->pid; prstatus->pr_ppid = p->parent->pid; 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->stime, &prstatus->pr_stime); jiffies_to_timeval(p->cutime, &prstatus->pr_cutime); @@ -1112,7 +1112,7 @@ static void fill_psinfo(struct elf_prpsi psinfo->pr_pid = p->pid; psinfo->pr_ppid = p->parent->pid; 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; psinfo->pr_state = i; diff -puN fs/dquot.c~move-job-control-fields fs/dquot.c --- 25/fs/dquot.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/fs/dquot.c 2003-10-05 00:36:15.000000000 -0700 @@ -668,12 +668,12 @@ static void print_warning(struct dquot * if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) 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) - tty_write_message(current->tty, ": warning, "); + tty_write_message(process_tty(current), ": warning, "); else - tty_write_message(current->tty, ": write failed, "); - tty_write_message(current->tty, quotatypes[dquot->dq_type]); + tty_write_message(process_tty(current), ": write failed, "); + tty_write_message(process_tty(current), quotatypes[dquot->dq_type]); switch (warntype) { case IHARDWARN: msg = " file limit reached.\n"; @@ -694,7 +694,7 @@ static void print_warning(struct dquot * msg = " block quota exceeded.\n"; break; } - tty_write_message(current->tty, msg); + tty_write_message(process_tty(current), msg); } static inline void flush_warnings(struct dquot **dquots, char *warntype) diff -puN fs/exec.c~move-job-control-fields fs/exec.c --- 25/fs/exec.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/fs/exec.c 2003-10-05 00:36:15.000000000 -0700 @@ -596,6 +596,11 @@ static inline int de_thread(struct task_ newsig->group_stop_count = 0; newsig->curr_target = NULL; 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)) diff -puN fs/open.c~move-job-control-fields fs/open.c --- 25/fs/open.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/fs/open.c 2003-10-05 00:36:15.000000000 -0700 @@ -1020,7 +1020,7 @@ out_unlock: asmlinkage long sys_vhangup(void) { if (capable(CAP_SYS_TTY_CONFIG)) { - tty_vhangup(current->tty); + tty_vhangup(process_tty(current)); return 0; } return -EPERM; diff -puN fs/proc/array.c~move-job-control-fields fs/proc/array.c --- 25/fs/proc/array.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/fs/proc/array.c 2003-10-05 00:36:15.000000000 -0700 @@ -304,9 +304,9 @@ int proc_pid_stat(struct task_struct *ta mm = task->mm; if(mm) mm = mmgrab(mm); - if (task->tty) { - tty_pgrp = task->tty->pgrp; - tty_nr = new_encode_dev(tty_devnum(task->tty)); + if (process_tty(task)) { + tty_pgrp = process_tty(task)->pgrp; + tty_nr = new_encode_dev(tty_devnum(process_tty(task))); } task_unlock(task); if (mm) { @@ -345,7 +345,7 @@ int proc_pid_stat(struct task_struct *ta state, ppid, process_group(task), - task->session, + process_session(task), tty_nr, tty_pgrp, task->flags, diff -puN include/linux/sched.h~move-job-control-fields include/linux/sched.h --- 25/include/linux/sched.h~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/include/linux/sched.h 2003-10-05 00:36:15.000000000 -0700 @@ -264,6 +264,15 @@ struct signal_struct { /* thread group stop support, overloads group_exit_code too */ 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 { unsigned long personality; int did_exec:1; pid_t pid; - pid_t __pgrp; /* Accessed via process_group() */ - pid_t tty_old_pgrp; - pid_t session; pid_t tgid; - /* boolean value for session group leader */ - int leader; /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with @@ -415,7 +419,6 @@ struct task_struct { char comm[16]; /* file system info */ int link_count, total_link_count; - struct tty_struct *tty; /* NULL if no tty */ unsigned int locks; /* How many file locks are being held */ /* ipc stuff */ struct sysv_sem sysvsem; @@ -469,7 +472,22 @@ struct task_struct { 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); diff -puN kernel/acct.c~move-job-control-fields kernel/acct.c --- 25/kernel/acct.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/kernel/acct.c 2003-10-05 00:36:15.000000000 -0700 @@ -343,7 +343,7 @@ static void do_acct_process(long exitcod /* we really need to bite the bullet and change layout */ ac.ac_uid = current->uid; 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; if (current->flags & PF_FORKNOEXEC) diff -puN kernel/exit.c~move-job-control-fields kernel/exit.c --- 25/kernel/exit.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/kernel/exit.c 2003-10-05 00:36:15.000000000 -0700 @@ -119,13 +119,13 @@ int session_of_pgrp(int pgrp) read_lock(&tasklist_lock); for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) - if (p->session > 0) { - sid = p->session; + if (process_session(p) > 0) { + sid = process_session(p); goto out; } p = find_task_by_pid(pgrp); if (p) - sid = p->session; + sid = process_session(p); out: read_unlock(&tasklist_lock); @@ -153,7 +153,7 @@ static int will_become_orphaned_pgrp(int || p->real_parent->pid == 1) continue; if (process_group(p->real_parent) != pgrp - && p->real_parent->session == p->session) { + && process_session(p->real_parent) == process_session(p)) { ret = 0; break; } @@ -242,14 +242,14 @@ void __set_special_pids(pid_t session, p { struct task_struct *curr = current; - if (curr->session != session) { + if (process_session(curr) != session) { detach_pid(curr, PIDTYPE_SID); - curr->session = session; + curr->signal->session = session; attach_pid(curr, PIDTYPE_SID, session); } if (process_group(curr) != pgrp) { detach_pid(curr, PIDTYPE_PGID); - curr->group_leader->__pgrp = pgrp; + curr->signal->pgrp = pgrp; attach_pid(curr, PIDTYPE_PGID, pgrp); } } @@ -303,7 +303,7 @@ void daemonize(const char *name, ...) exit_mm(current); set_special_pids(1, 1); - current->tty = NULL; + current->signal->tty = NULL; /* Block and flush all signals */ sigfillset(&blocked); @@ -509,7 +509,7 @@ static inline void reparent_thread(task_ * outside, so the child pgrp is now orphaned. */ if ((process_group(p) != process_group(father)) && - (p->session == father->session)) { + (process_session(p) == process_session(father))) { int pgrp = process_group(p); if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { @@ -619,7 +619,7 @@ static void exit_notify(struct task_stru t = tsk->real_parent; 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) && has_stopped_jobs(process_group(tsk))) { __kill_pg_info(SIGHUP, (void *)1, process_group(tsk)); @@ -714,7 +714,7 @@ NORET_TYPE void do_exit(long code) exit_itimers(tsk); exit_thread(); - if (tsk->leader) + if (process_session_leader(tsk)) disassociate_ctty(1); module_put(tsk->thread_info->exec_domain->module); diff -puN kernel/fork.c~move-job-control-fields kernel/fork.c --- 25/kernel/fork.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/kernel/fork.c 2003-10-05 00:36:15.000000000 -0700 @@ -725,6 +725,12 @@ static inline int copy_signal(unsigned l sig->curr_target = NULL; 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; } @@ -771,7 +777,9 @@ struct task_struct *copy_process(unsigne * Thread groups must share signals as well, and detached threads * 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); /* @@ -876,8 +884,6 @@ struct task_struct *copy_process(unsigne init_timer(&p->real_timer); 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->cutime = p->cstime = 0; p->array = NULL; @@ -1022,7 +1028,7 @@ struct task_struct *copy_process(unsigne if (thread_group_leader(p)) { attach_pid(p, PIDTYPE_TGID, p->tgid); 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) __get_cpu_var(process_counts)++; } else diff -puN kernel/pid.c~move-job-control-fields kernel/pid.c --- 25/kernel/pid.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/kernel/pid.c 2003-10-05 00:36:15.000000000 -0700 @@ -250,14 +250,14 @@ void switch_exec_pids(task_t *leader, ta attach_pid(thread, PIDTYPE_PID, thread->pid); attach_pid(thread, PIDTYPE_TGID, thread->tgid); - attach_pid(thread, PIDTYPE_PGID, leader->__pgrp); - attach_pid(thread, PIDTYPE_SID, thread->session); + attach_pid(thread, PIDTYPE_PGID, thread->signal->pgrp); + attach_pid(thread, PIDTYPE_SID, thread->signal->session); list_add_tail(&thread->tasks, &init_task.tasks); attach_pid(leader, PIDTYPE_PID, leader->pid); attach_pid(leader, PIDTYPE_TGID, leader->tgid); - attach_pid(leader, PIDTYPE_PGID, leader->__pgrp); - attach_pid(leader, PIDTYPE_SID, leader->session); + attach_pid(leader, PIDTYPE_PGID, leader->signal->pgrp); + attach_pid(leader, PIDTYPE_SID, leader->signal->session); } /* diff -puN kernel/signal.c~move-job-control-fields kernel/signal.c --- 25/kernel/signal.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/kernel/signal.c 2003-10-05 00:36:15.000000000 -0700 @@ -593,7 +593,8 @@ static int check_kill_permission(int sig error = -EPERM; if ((!info || ((unsigned long)info != 1 && (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->uid ^ t->suid) && (current->uid ^ t->uid) && !capable(CAP_KILL)) @@ -1102,7 +1103,7 @@ kill_sl_info(int sig, struct siginfo *in retval = -ESRCH; read_lock(&tasklist_lock); for_each_task_pid(sid, PIDTYPE_SID, p, l, pid) { - if (!p->leader) + if (!process_session_leader(p)) continue; err = group_send_sig_info(sig, info, p); if (retval) diff -puN kernel/sys.c~move-job-control-fields kernel/sys.c --- 25/kernel/sys.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/kernel/sys.c 2003-10-05 00:36:15.000000000 -0700 @@ -951,7 +951,7 @@ asmlinkage long sys_setpgid(pid_t pid, p if (p->parent == current || p->real_parent == current) { err = -EPERM; - if (p->session != current->session) + if (process_session(p) != process_session(current)) goto out; err = -EACCES; if (p->did_exec) @@ -963,7 +963,7 @@ asmlinkage long sys_setpgid(pid_t pid, p } err = -EPERM; - if (p->leader) + if (process_session_leader(p)) goto out; if (pgid != pid) { @@ -972,7 +972,7 @@ asmlinkage long sys_setpgid(pid_t pid, p struct list_head *l; 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 out; } @@ -984,7 +984,7 @@ ok_pgid: if (process_group(p) != pgid) { detach_pid(p, PIDTYPE_PGID); - p->group_leader->__pgrp = pgid; + p->signal->pgrp = pgid; attach_pid(p, PIDTYPE_PGID, pgid); } @@ -1026,7 +1026,7 @@ asmlinkage long sys_getpgrp(void) asmlinkage long sys_getsid(pid_t pid) { if (!pid) { - return current->session; + return process_session(current); } else { int retval; struct task_struct *p; @@ -1038,7 +1038,7 @@ asmlinkage long sys_getsid(pid_t pid) if(p) { retval = security_task_getsid(p); if (!retval) - retval = p->session; + retval = process_session(p); } read_unlock(&tasklist_lock); return retval; @@ -1059,10 +1059,10 @@ asmlinkage long sys_setsid(void) if (pid) goto out; - current->leader = 1; + current->signal->leader = 1; __set_special_pids(current->pid, current->pid); - current->tty = NULL; - current->tty_old_pgrp = 0; + current->signal->tty = NULL; + current->signal->tty_old_pgrp = 0; err = process_group(current); out: write_unlock_irq(&tasklist_lock); diff -puN net/ipv4/netfilter/ipt_owner.c~move-job-control-fields net/ipv4/netfilter/ipt_owner.c --- 25/net/ipv4/netfilter/ipt_owner.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/net/ipv4/netfilter/ipt_owner.c 2003-10-05 00:36:15.000000000 -0700 @@ -90,7 +90,7 @@ match_sid(const struct sk_buff *skb, pid read_lock(&tasklist_lock); do_each_thread(g, p) { struct files_struct *files; - if (p->session != sid) + if (process_session(p) != sid) continue; task_lock(p); diff -puN net/ipv6/netfilter/ip6t_owner.c~move-job-control-fields net/ipv6/netfilter/ip6t_owner.c --- 25/net/ipv6/netfilter/ip6t_owner.c~move-job-control-fields 2003-10-05 00:36:15.000000000 -0700 +++ 25-akpm/net/ipv6/netfilter/ip6t_owner.c 2003-10-05 00:36:15.000000000 -0700 @@ -56,7 +56,7 @@ match_sid(const struct sk_buff *skb, pid read_lock(&tasklist_lock); do_each_thread(g, p) { struct files_struct *files; - if (p->session != sid) + if (process_session(p) != sid) continue; task_lock(p); _