From: Theodore Ts'o <tytso@athena.mit.edu> Subject: Patch to fix vhangup() Date: 15 Feb 1993 12:14:20 -0500
This patch fixes vhangup() so that it won't cause DTR to drop when it is
called. It should allow versions of getty which use the vhangup() call
to work correctly. (Previously, when DTR dropped it caused the modem to
drop the call, much to the disappointment to the person who was trying
to dial in over the modem. :-)
- Ted
===================================================================
RCS file: fs/RCS/open.c,v
retrieving revision 1.1
diff -c -r1.1 fs/open.c
*** 1.1 1993/02/13 21:50:59
--- fs/open.c 1993/02/13 22:25:18
***************
*** 474,496 ****
}
/*
! * This routine looks through all the process's and closes any
! * references to the current processes tty. To avoid problems with
! * process sleeping on an inode which has already been iput, anyprocess
! * which is sleeping on the tty is sent a sigkill (It's probably a rogue
! * process.) Also no process should ever have /dev/console as it's
! * controlling tty, or have it open for reading. So we don't have to
! * worry about messing with all the daemons abilities to write messages
! * to the console. (Besides they should be using syslog.)
*/
int sys_vhangup(void)
{
int j;
- struct task_struct ** process;
- struct file *filep;
- struct inode *inode;
struct tty_struct *tty;
- extern int kill_pg (int pgrp, int sig, int priv);
if (!suser())
return -EPERM;
--- 474,486 ----
}
/*
! * This routine simulates a hangup on the tty, to arrange that users
! * are given clean terminals at login time.
*/
int sys_vhangup(void)
{
int j;
struct tty_struct *tty;
if (!suser())
return -EPERM;
***************
*** 497,553 ****
/* See if there is a controlling tty. */
if (current->tty < 0)
return 0;
- /* send the SIGHUP signal. */
- tty = TTY_TABLE(current->tty);
- if (tty && tty->pgrp > 0)
- kill_pg(tty->pgrp, SIGHUP, 0);
-
- for (process = task + 0; process < task + NR_TASKS; process++) {
- for (j = 0; j < NR_OPEN; j++) {
- if (!*process)
- break;
- if (!(filep = (*process)->filp[j]))
- continue;
- if (!(inode = filep->f_inode))
- continue;
- if (!S_ISCHR(inode->i_mode))
- continue;
- if ((MAJOR(inode->i_rdev) == 5 ||
- MAJOR(inode->i_rdev) == 4 ) &&
- (MAJOR(filep->f_rdev) == 4 &&
- MINOR(filep->f_rdev) == MINOR (current->tty))) {
- /* so now we have found something to close. We
- need to kill every process waiting on the
- inode. */
- (*process)->filp[j] = NULL;
- kill_wait (&inode->i_wait, SIGKILL);
-
- /* now make sure they are awake before we close the
- file. */
-
- wake_up (&inode->i_wait);
-
- /* finally close the file. */
-
- FD_CLR(j, &(*process)->close_on_exec);
- close_fp (filep);
- }
- }
- /* can't let them keep a reference to it around.
- But we can't touch current->tty until after the
- loop is complete. */
-
- if (*process && (*process)->tty == current->tty && *process != current) {
- (*process)->tty = -1;
- }
- }
- /* need to do tty->session = 0 */
tty = TTY_TABLE(MINOR(current->tty));
! if (tty) {
! tty->session = 0;
! tty->pgrp = -1;
! current->tty = -1;
! }
return 0;
}
--- 487,494 ----
/* See if there is a controlling tty. */
if (current->tty < 0)
return 0;
tty = TTY_TABLE(MINOR(current->tty));
! tty_hangup(tty);
return 0;
}
===================================================================
RCS file: kernel/chr_drv/RCS/tty_io.c,v
retrieving revision 1.1
diff -c -r1.1 kernel/chr_drv/tty_io.c
*** 1.1 1993/02/13 22:09:48
--- kernel/chr_drv/tty_io.c 1993/02/14 17:37:04
***************
*** 213,218 ****
--- 213,219 ----
void tty_hangup(struct tty_struct * tty)
{
struct file * filp;
+ struct task_struct **p;
int dev;
if (!tty)
***************
*** 233,238 ****
--- 234,245 ----
wake_up_interruptible(&tty->write_q.proc_list);
if (tty->session > 0)
kill_sl(tty->session,SIGHUP,1);
+ tty->session = 0;
+ tty->pgrp = -1;
+ for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
+ if ((*p) && (*p)->tty == tty->line)
+ (*p)->tty = -1;
+ }
}
void tty_unhangup(struct file *filp)