summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty_cons.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1997-08-08 20:09:50 +0000
committerjulian <julian@FreeBSD.org>1997-08-08 20:09:50 +0000
commit0c0b422f311388aca08555dc82e39d9365b8049e (patch)
tree05fdb75c4505e1d32013c6ccfa2761af8cd96d87 /sys/kern/tty_cons.c
parentdc3ab858903e9fc74c4e541e16641a227d47cab7 (diff)
downloadFreeBSD-src-0c0b422f311388aca08555dc82e39d9365b8049e.zip
FreeBSD-src-0c0b422f311388aca08555dc82e39d9365b8049e.tar.gz
Clean up the console muting functionality.
this has been in production now for a long time with no known effects.
Diffstat (limited to 'sys/kern/tty_cons.c')
-rw-r--r--sys/kern/tty_cons.c122
1 files changed, 107 insertions, 15 deletions
diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c
index f39d319..a93eac5 100644
--- a/sys/kern/tty_cons.c
+++ b/sys/kern/tty_cons.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)cons.c 7.2 (Berkeley) 5/9/91
- * $Id: cons.c,v 1.51 1997/02/22 09:32:10 peter Exp $
+ * $Id: cons.c,v 1.52 1997/07/01 00:52:37 bde Exp $
*/
#include <sys/param.h>
@@ -84,25 +84,26 @@ static struct cdevsw cn_cdevsw =
cnioctl, nullstop, nullreset, nodevtotty,/* console */
cnselect, nommap, NULL, "console", NULL, -1 };
-static dev_t cn_dev_t;
+static dev_t cn_dev_t; /* seems to be never really used */
SYSCTL_OPAQUE(_machdep, CPU_CONSDEV, consdev, CTLTYPE_OPAQUE|CTLFLAG_RD,
&cn_dev_t, sizeof cn_dev_t, "T,dev_t", "");
+
static int cn_mute;
-SYSCTL_INT(_kern, OID_AUTO, consmute, CTLFLAG_RW, &cn_mute, 0, "");
int cons_unavail = 0; /* XXX:
* physical console not available for
* input (i.e., it is in graphics mode)
*/
-static u_char cn_is_open; /* nonzero if logical console is open */
-static u_char cn_phys_is_open; /* nonzero if physical console is open */
+static u_char cn_is_open; /* nonzero if logical console is open */
+static int openmode, openflag; /* how /dev/console was openned */
+static u_char cn_phys_is_open; /* nonzero if physical device is open */
static d_close_t *cn_phys_close; /* physical device close function */
-static d_open_t *cn_phys_open; /* physical device open function */
-static struct consdev *cn_tab; /* physical console device info */
-static struct tty *cn_tp; /* physical console tty struct */
+static d_open_t *cn_phys_open; /* physical device open function */
+static struct consdev *cn_tab; /* physical console device info */
+static struct tty *cn_tp; /* physical console tty struct */
#ifdef DEVFS
-void *cn_devfs_token; /* represents the devfs entry */
+static void *cn_devfs_token; /* represents the devfs entry */
#endif /* DEVFS */
void
@@ -156,7 +157,7 @@ cninit_finish()
{
struct cdevsw *cdp;
- if (cn_tab == NULL)
+ if ((cn_tab == NULL) || cn_mute)
return;
/*
@@ -171,6 +172,74 @@ cninit_finish()
cn_dev_t = cn_tp->t_dev;
}
+void
+cnuninit()
+{
+ struct cdevsw *cdp;
+
+ if (cn_tab == NULL)
+ return;
+
+ /*
+ * Unhook the open and close functions.
+ */
+ cdp = cdevsw[major(cn_tab->cn_dev)];
+ cdp->d_close = cn_phys_close;
+ cn_phys_close = NULL;
+ cdp->d_open = cn_phys_open;
+ cn_phys_open = NULL;
+ cn_tp = NULL;
+ cn_dev_t = 0;
+}
+
+/*
+ * User has changed the state of the console muting.
+ * This may require us to open or close the device in question.
+ */
+static int
+sysctl_kern_consmute SYSCTL_HANDLER_ARGS
+{
+ int error;
+ int ocn_mute;
+
+ ocn_mute = cn_mute;
+ error = sysctl_handle_int(oidp, &cn_mute, 0, req);
+ if((error == 0) && (cn_tab != NULL) && (req->newptr != NULL)) {
+ if(ocn_mute && !cn_mute) {
+ /*
+ * going from muted to unmuted.. open the physical dev
+ * if the console has been openned
+ */
+ cninit_finish();
+ if(cn_is_open)
+ /* XXX curproc is not what we want really */
+ error = cnopen(cn_dev_t, openflag,
+ openmode, curproc);
+ /* if it failed, back it out */
+ if ( error != 0) cnuninit();
+ } else if (!ocn_mute && cn_mute) {
+ /*
+ * going from unmuted to muted.. close the physical dev
+ * if it's only open via /dev/console
+ */
+ if(cn_is_open)
+ error = cnclose(cn_dev_t, openflag,
+ openmode, curproc);
+ if ( error == 0) cnuninit();
+ }
+ if (error != 0) {
+ /*
+ * back out the change if there was an error
+ */
+ cn_mute = ocn_mute;
+ }
+ }
+ return (error);
+}
+
+SYSCTL_PROC(_kern, OID_AUTO, consmute, CTLTYPE_INT|CTLFLAG_RW,
+ 0, sizeof cn_mute, sysctl_kern_consmute, "I", "");
+
static int
cnopen(dev, flag, mode, p)
dev_t dev;
@@ -178,18 +247,31 @@ cnopen(dev, flag, mode, p)
struct proc *p;
{
dev_t cndev, physdev;
- int retval;
+ int retval = 0;
if (cn_tab == NULL)
return (0);
cndev = cn_tab->cn_dev;
physdev = (major(dev) == major(cndev) ? dev : cndev);
- retval = (*cn_phys_open)(physdev, flag, mode, p);
+ /*
+ * If mute is active, then non console opens don't get here
+ * so we don't need to check for that. They
+ * bypass this and go straight to the device.
+ */
+ if(!cn_mute)
+ retval = (*cn_phys_open)(physdev, flag, mode, p);
if (retval == 0) {
+ /*
+ * check if we openned it via /dev/console or
+ * via the physical entry (e.g. /dev/sio0).
+ */
if (dev == cndev)
cn_phys_is_open = 1;
- else if (physdev == cndev)
+ else if (physdev == cndev) {
+ openmode = mode;
+ openflag = flag;
cn_is_open = 1;
+ }
}
return (retval);
}
@@ -205,6 +287,12 @@ cnclose(dev, flag, mode, p)
if (cn_tab == NULL)
return (0);
cndev = cn_tab->cn_dev;
+ /*
+ * act appropriatly depending on whether it's /dev/console
+ * or the pysical device (e.g. /dev/sio) that's being closed.
+ * in either case, don't actually close the device unless
+ * both are closed.
+ */
if (dev == cndev) {
/* the physical device is about to be closed */
cn_phys_is_open = 0;
@@ -224,7 +312,9 @@ cnclose(dev, flag, mode, p)
return (0);
dev = cndev;
}
- return ((*cn_phys_close)(dev, flag, mode, p));
+ if(cn_phys_close)
+ return ((*cn_phys_close)(dev, flag, mode, p));
+ return (0);
}
static int
@@ -245,8 +335,10 @@ cnwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
- if ((cn_tab == NULL) || cn_mute)
+ if ((cn_tab == NULL) || cn_mute) {
+ uio->uio_resid = 0; /* dump the data */
return (0);
+ }
if (constty)
dev = constty->t_dev;
else
OpenPOWER on IntegriCloud