summaryrefslogtreecommitdiff
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 00:53:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 08:29:40 -0700
commit5d0fdf1e01899805b6c2c0b789a707dcb731b1ea (patch)
tree19827c7b3cf365c0b403741ead6c7bc317cad51b /drivers/char/tty_io.c
parent575537b3248ee9b7578a3bb3df33fcdda2bfc4d5 (diff)
tty_io: fix remaining pid struct locking
This fixes the last couple of pid struct locking failures I know about. [oleg@tv-sign.ru: clean up do_task_stat()] Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index c8aa318eaa18..2460c4c76161 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -3174,6 +3174,27 @@ unlock:
}
/**
+ * tty_get_pgrp - return a ref counted pgrp pid
+ * @tty: tty to read
+ *
+ * Returns a refcounted instance of the pid struct for the process
+ * group controlling the tty.
+ */
+
+struct pid *tty_get_pgrp(struct tty_struct *tty)
+{
+ unsigned long flags;
+ struct pid *pgrp;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ pgrp = get_pid(tty->pgrp);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+ return pgrp;
+}
+EXPORT_SYMBOL_GPL(tty_get_pgrp);
+
+/**
* tiocgpgrp - get process group
* @tty: tty passed by user
* @real_tty: tty side of the tty pased by the user if a pty else the tty
@@ -3187,13 +3208,18 @@ unlock:
static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ struct pid *pid;
+ int ret;
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- return put_user(pid_vnr(real_tty->pgrp), p);
+ pid = tty_get_pgrp(real_tty);
+ ret = put_user(pid_vnr(pid), p);
+ put_pid(pid);
+ return ret;
}
/**