unsigned int cmd, unsigned long arg);
static int tty_fasync(int fd, struct file * filp, int on);
static void release_tty(struct tty_struct *tty, int idx);
-static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+static struct pid *__proc_set_tty(struct task_struct *tsk,
+ struct tty_struct *tty);
/**
* alloc_tty_struct - allocate a tty object
{
if (current->signal->tty != tty)
return 0;
- if (tty->pgrp <= 0) {
- printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
+ if (!tty->pgrp) {
+ printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
return 0;
}
- if (process_group(current) == tty->pgrp)
+ if (task_pgrp(current) == tty->pgrp)
return 0;
if (is_ignored(SIGTTOU))
return 0;
- if (is_orphaned_pgrp(process_group(current)))
+ if (is_current_pgrp_orphaned())
return -EIO;
- (void) kill_pg(process_group(current), SIGTTOU, 1);
+ (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
return -ERESTARTSYS;
}
tty_release is called */
read_lock(&tasklist_lock);
- if (tty->session > 0) {
- do_each_task_pid(tty->session, PIDTYPE_SID, p) {
+ if (tty->session) {
+ do_each_pid_task(tty->session, PIDTYPE_SID, p) {
spin_lock_irq(&p->sighand->siglock);
if (p->signal->tty == tty)
p->signal->tty = NULL;
}
__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
- if (tty->pgrp > 0)
- p->signal->tty_old_pgrp = tty->pgrp;
+ put_pid(p->signal->tty_old_pgrp); /* A noop */
+ if (tty->pgrp)
+ p->signal->tty_old_pgrp = get_pid(tty->pgrp);
spin_unlock_irq(&p->sighand->siglock);
- } while_each_task_pid(tty->session, PIDTYPE_SID, p);
+ } while_each_pid_task(tty->session, PIDTYPE_SID, p);
}
read_unlock(&tasklist_lock);
tty->flags = 0;
- tty->session = 0;
- tty->pgrp = -1;
+ put_pid(tty->session);
+ put_pid(tty->pgrp);
+ tty->session = NULL;
+ tty->pgrp = NULL;
tty->ctrl_status = 0;
/*
* If one of the devices matches a console pointer, we
EXPORT_SYMBOL(tty_hung_up_p);
-static void session_clear_tty(pid_t session)
+static void session_clear_tty(struct pid *session)
{
struct task_struct *p;
- do_each_task_pid(session, PIDTYPE_SID, p) {
+ do_each_pid_task(session, PIDTYPE_SID, p) {
proc_clear_tty(p);
- } while_each_task_pid(session, PIDTYPE_SID, p);
+ } while_each_pid_task(session, PIDTYPE_SID, p);
}
/**
void disassociate_ctty(int on_exit)
{
struct tty_struct *tty;
- int tty_pgrp = -1;
+ struct pid *tty_pgrp = NULL;
lock_kernel();
mutex_lock(&tty_mutex);
tty = get_current_tty();
if (tty) {
- tty_pgrp = tty->pgrp;
+ tty_pgrp = get_pid(tty->pgrp);
mutex_unlock(&tty_mutex);
/* XXX: here we race, there is nothing protecting tty */
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
} else if (on_exit) {
- pid_t old_pgrp;
+ struct pid *old_pgrp;
spin_lock_irq(¤t->sighand->siglock);
old_pgrp = current->signal->tty_old_pgrp;
- current->signal->tty_old_pgrp = 0;
+ current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(¤t->sighand->siglock);
if (old_pgrp) {
- kill_pg(old_pgrp, SIGHUP, on_exit);
- kill_pg(old_pgrp, SIGCONT, on_exit);
+ kill_pgrp(old_pgrp, SIGHUP, on_exit);
+ kill_pgrp(old_pgrp, SIGCONT, on_exit);
+ put_pid(old_pgrp);
}
mutex_unlock(&tty_mutex);
unlock_kernel();
return;
}
- if (tty_pgrp > 0) {
- kill_pg(tty_pgrp, SIGHUP, on_exit);
+ if (tty_pgrp) {
+ kill_pgrp(tty_pgrp, SIGHUP, on_exit);
if (!on_exit)
- kill_pg(tty_pgrp, SIGCONT, on_exit);
+ kill_pgrp(tty_pgrp, SIGCONT, on_exit);
+ put_pid(tty_pgrp);
}
spin_lock_irq(¤t->sighand->siglock);
- current->signal->tty_old_pgrp = 0;
+ tty_pgrp = current->signal->tty_old_pgrp;
+ current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(¤t->sighand->siglock);
+ put_pid(tty_pgrp);
mutex_lock(&tty_mutex);
/* It is possible that do_tty_hangup has free'd this tty */
tty = get_current_tty();
if (tty) {
- tty->session = 0;
- tty->pgrp = 0;
+ put_pid(tty->session);
+ put_pid(tty->pgrp);
+ tty->session = NULL;
+ tty->pgrp = NULL;
} else {
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
- session_clear_tty(process_session(current));
+ session_clear_tty(task_session(current));
read_unlock(&tasklist_lock);
unlock_kernel();
}
/* check whether we're reopening an existing tty */
if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
tty = devpts_get_tty(idx);
+ /*
+ * If we don't have a tty here on a slave open, it's because
+ * the master already started the close process and there's
+ * no relation between devpts file and tty anymore.
+ */
+ if (!tty && driver->subtype == PTY_TYPE_SLAVE) {
+ retval = -EIO;
+ goto end_init;
+ }
+ /*
+ * It's safe from now on because init_dev() is called with
+ * tty_mutex held and release_dev() won't change tty->count
+ * or tty->flags without having to grab tty_mutex
+ */
if (tty && driver->subtype == PTY_TYPE_MASTER)
tty = tty->link;
} else {
int index;
dev_t device = inode->i_rdev;
unsigned short saved_flags = filp->f_flags;
+ struct pid *old_pgrp;
nonseekable_open(inode, filp);
goto retry_open;
}
+ old_pgrp = NULL;
mutex_lock(&tty_mutex);
spin_lock_irq(¤t->sighand->siglock);
if (!noctty &&
current->signal->leader &&
!current->signal->tty &&
- tty->session == 0)
- __proc_set_tty(current, tty);
+ tty->session == NULL)
+ old_pgrp = __proc_set_tty(current, tty);
spin_unlock_irq(¤t->sighand->siglock);
mutex_unlock(&tty_mutex);
+ put_pid(old_pgrp);
return 0;
}
return retval;
if (on) {
+ enum pid_type type;
+ struct pid *pid;
if (!waitqueue_active(&tty->read_wait))
tty->minimum_to_wake = 1;
- retval = f_setown(filp, (-tty->pgrp) ? : current->pid, 0);
+ if (tty->pgrp) {
+ pid = tty->pgrp;
+ type = PIDTYPE_PGID;
+ } else {
+ pid = task_pid(current);
+ type = PIDTYPE_PID;
+ }
+ retval = __f_setown(filp, pid, type, 0);
if (retval)
return retval;
} else {
}
}
#endif
- if (tty->pgrp > 0)
- kill_pg(tty->pgrp, SIGWINCH, 1);
- if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
- kill_pg(real_tty->pgrp, SIGWINCH, 1);
+ if (tty->pgrp)
+ kill_pgrp(tty->pgrp, SIGWINCH, 1);
+ if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp)
+ kill_pgrp(real_tty->pgrp, SIGWINCH, 1);
tty->winsize = tmp_ws;
real_tty->winsize = tmp_ws;
done:
static int tiocsctty(struct tty_struct *tty, int arg)
{
int ret = 0;
- if (current->signal->leader &&
- (process_session(current) == tty->session))
+ if (current->signal->leader && (task_session(current) == tty->session))
return ret;
mutex_lock(&tty_mutex);
goto unlock;
}
- if (tty->session > 0) {
+ if (tty->session) {
/*
* This tty is already the controlling
* tty for another session group!
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- return put_user(real_tty->pgrp, p);
+ return put_user(pid_nr(real_tty->pgrp), p);
}
/**
return retval;
if (!current->signal->tty ||
(current->signal->tty != real_tty) ||
- (real_tty->session != process_session(current)))
+ (real_tty->session != task_session(current)))
return -ENOTTY;
if (get_user(pgrp_nr, p))
return -EFAULT;
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
- real_tty->pgrp = pgrp_nr;
+ put_pid(real_tty->pgrp);
+ real_tty->pgrp = get_pid(pgrp);
out_unlock:
rcu_read_unlock();
return retval;
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- if (real_tty->session <= 0)
+ if (!real_tty->session)
return -ENOTTY;
- return put_user(real_tty->session, p);
+ return put_user(pid_nr(real_tty->session), p);
}
/**
tty_hangup(tty);
#else
struct task_struct *g, *p;
- int session;
+ struct pid *session;
int i;
struct file *filp;
struct fdtable *fdt;
read_lock(&tasklist_lock);
/* Kill the entire session */
- do_each_task_pid(session, PIDTYPE_SID, p) {
+ do_each_pid_task(session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): process_session(p)==tty->session\n",
p->pid, p->comm);
send_sig(SIGKILL, p, 1);
- } while_each_task_pid(session, PIDTYPE_SID, p);
+ } while_each_pid_task(session, PIDTYPE_SID, p);
/* Now kill any processes that happen to have the
* tty open.
*/
{
if (!tty)
return;
- PREPARE_WORK(&tty->SAK_work, do_SAK_work);
schedule_work(&tty->SAK_work);
}
memset(tty, 0, sizeof(struct tty_struct));
tty->magic = TTY_MAGIC;
tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
- tty->pgrp = -1;
+ tty->session = NULL;
+ tty->pgrp = NULL;
tty->overrun_time = jiffies;
tty->buf.head = tty->buf.tail = NULL;
tty_buffer_init(tty);
mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->read_lock);
INIT_LIST_HEAD(&tty->tty_files);
- INIT_WORK(&tty->SAK_work, NULL);
+ INIT_WORK(&tty->SAK_work, do_SAK_work);
}
/*
if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
- if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
- p = kmalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
+ if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
+ p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
if (!p)
return -ENOMEM;
- memset(p, 0, driver->num * 3 * sizeof(void *));
}
if (!driver->major) {
error = alloc_chrdev_region(&dev, driver->minor_start, driver->num,
- (char*)driver->name);
+ driver->name);
if (!error) {
driver->major = MAJOR(dev);
driver->minor_start = MINOR(dev);
}
} else {
dev = MKDEV(driver->major, driver->minor_start);
- error = register_chrdev_region(dev, driver->num,
- (char*)driver->name);
+ error = register_chrdev_region(dev, driver->num, driver->name);
}
if (error < 0) {
kfree(p);
}
EXPORT_SYMBOL(proc_clear_tty);
-static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
+ struct pid *old_pgrp;
if (tty) {
- tty->session = process_session(tsk);
- tty->pgrp = process_group(tsk);
+ /* We should not have a session or pgrp to here but.... */
+ put_pid(tty->session);
+ put_pid(tty->pgrp);
+ tty->session = get_pid(task_session(tsk));
+ tty->pgrp = get_pid(task_pgrp(tsk));
}
+ old_pgrp = tsk->signal->tty_old_pgrp;
tsk->signal->tty = tty;
- tsk->signal->tty_old_pgrp = 0;
+ tsk->signal->tty_old_pgrp = NULL;
+ return old_pgrp;
}
void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
+ struct pid *old_pgrp;
+
spin_lock_irq(&tsk->sighand->siglock);
- __proc_set_tty(tsk, tty);
+ old_pgrp = __proc_set_tty(tsk, tty);
spin_unlock_irq(&tsk->sighand->siglock);
+
+ put_pid(old_pgrp);
}
struct tty_struct *get_current_tty(void)