root/dev/cons.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cnopen
  2. cnclose
  3. cnread
  4. cnwrite
  5. cnstop
  6. cnioctl
  7. cnpoll
  8. cnkqfilter
  9. cngetc
  10. cnputc
  11. cnpollc
  12. nullcnpollc
  13. cnbell

    1 /*      $OpenBSD: cons.c,v 1.18 2007/06/17 18:50:58 jasper Exp $        */
    2 /*      $NetBSD: cons.c,v 1.30 1996/04/08 19:57:30 jonathan Exp $       */
    3 
    4 /*
    5  * Copyright (c) 1988 University of Utah.
    6  * Copyright (c) 1990, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  *
    9  * This code is derived from software contributed to Berkeley by
   10  * the Systems Programming Group of the University of Utah Computer
   11  * Science Department.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  * from: Utah $Hdr: cons.c 1.7 92/01/21$
   38  *
   39  *      @(#)cons.c      8.2 (Berkeley) 1/12/94
   40  */
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/proc.h>
   45 #include <sys/user.h>
   46 #include <sys/buf.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/tty.h>
   49 #include <sys/file.h>
   50 #include <sys/conf.h>
   51 #include <sys/vnode.h>
   52 #include <sys/poll.h>
   53 
   54 #include <dev/cons.h>
   55 
   56 struct  tty *constty = NULL;    /* virtual console output device */
   57 struct  consdev *cn_tab;        /* physical console device info */
   58 struct  vnode *cn_devvp;        /* vnode for underlying device. */
   59 
   60 int
   61 cnopen(dev_t dev, int flag, int mode, struct proc *p)
   62 {
   63         dev_t cndev;
   64 
   65         if (cn_tab == NULL)
   66                 return (0);
   67 
   68         /*
   69          * always open the 'real' console device, so we don't get nailed
   70          * later.  This follows normal device semantics; they always get
   71          * open() calls.
   72          */
   73         cndev = cn_tab->cn_dev;
   74         if (cndev == NODEV)
   75                 return (ENXIO);
   76 #ifdef DIAGNOSTIC
   77         if (cndev == dev)
   78                 panic("cnopen: recursive");
   79 #endif
   80         if (cn_devvp == NULLVP) {
   81                 /* try to get a reference on its vnode, but fail silently */
   82                 cdevvp(cndev, &cn_devvp);
   83         }
   84         return ((*cdevsw[major(cndev)].d_open)(cndev, flag, mode, p));
   85 }
   86  
   87 int
   88 cnclose(dev_t dev, int flag, int mode, struct proc *p)
   89 {
   90         struct vnode *vp;
   91 
   92         if (cn_tab == NULL)
   93                 return (0);
   94 
   95         /*
   96          * If the real console isn't otherwise open, close it.
   97          * If it's otherwise open, don't close it, because that'll
   98          * screw up others who have it open.
   99          */
  100         dev = cn_tab->cn_dev;
  101         if (cn_devvp != NULLVP) {
  102                 /* release our reference to real dev's vnode */
  103                 vrele(cn_devvp);
  104                 cn_devvp = NULLVP;
  105         }
  106         if (vfinddev(dev, VCHR, &vp) && vcount(vp))
  107                 return (0);
  108         return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
  109 }
  110  
  111 int
  112 cnread(dev_t dev, struct uio *uio, int flag)
  113 {
  114 
  115         /*
  116          * If we would redirect input, punt.  This will keep strange
  117          * things from happening to people who are using the real
  118          * console.  Nothing should be using /dev/console for
  119          * input (except a shell in single-user mode, but then,
  120          * one wouldn't TIOCCONS then).
  121          */
  122         if (constty != NULL)
  123                 return 0;
  124         else if (cn_tab == NULL)
  125                 return ENXIO;
  126 
  127         dev = cn_tab->cn_dev;
  128         return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
  129 }
  130  
  131 int
  132 cnwrite(dev_t dev, struct uio *uio, int flag)
  133 {
  134 
  135         /*
  136          * Redirect output, if that's appropriate.
  137          * If there's no real console, return ENXIO.
  138          */
  139         if (constty != NULL)
  140                 dev = constty->t_dev;
  141         else if (cn_tab == NULL)
  142                 return ENXIO;
  143         else
  144                 dev = cn_tab->cn_dev;
  145         return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
  146 }
  147 
  148 int
  149 cnstop(struct tty *tp, int flag)
  150 {
  151         return (0);
  152 }
  153  
  154 int
  155 cnioctl(dev_t dev, u_long cmd, caddr_t data, int flag,
  156     struct proc *p)
  157 {
  158         int error;
  159 
  160         /*
  161          * Superuser can always use this to wrest control of console
  162          * output from the "virtual" console.
  163          */
  164         if (cmd == TIOCCONS && constty != NULL) {
  165                 error = suser(p, SUSER_NOACCT);
  166                 if (error)
  167                         return (error);
  168                 constty = NULL;
  169                 return (0);
  170         }
  171 
  172         /*
  173          * Redirect the ioctl, if that's appropriate.
  174          * Note that strange things can happen, if a program does
  175          * ioctls on /dev/console, then the console is redirected
  176          * out from under it.
  177          */
  178         if (constty != NULL)
  179                 dev = constty->t_dev;
  180         else if (cn_tab == NULL)
  181                 return ENXIO;
  182         else
  183                 dev = cn_tab->cn_dev;
  184         return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
  185 }
  186 
  187 /*ARGSUSED*/
  188 int
  189 cnpoll(dev_t dev, int rw, struct proc *p)
  190 {
  191 
  192         /*
  193          * Redirect the poll, if that's appropriate.
  194          * I don't want to think of the possible side effects
  195          * of console redirection here.
  196          */
  197         if (constty != NULL)
  198                 dev = constty->t_dev;
  199         else if (cn_tab == NULL)
  200                 return POLLERR;
  201         else
  202                 dev = cn_tab->cn_dev;
  203         return (ttpoll(cn_tab->cn_dev, rw, p));
  204 }
  205 
  206 
  207 int
  208 cnkqfilter(dev_t dev, struct knote *kn)
  209 {
  210 
  211         /*
  212          * Redirect output, if that's appropriate.
  213          * If there's no real console, return 1.
  214          */
  215         if (constty != NULL)
  216                 dev = constty->t_dev;
  217         else if (cn_tab == NULL)
  218                 return (1);
  219         else
  220                 dev = cn_tab->cn_dev;
  221         if (cdevsw[major(dev)].d_flags & D_KQFILTER)
  222                 return ((*cdevsw[major(dev)].d_kqfilter)(dev, kn));
  223         return (1);
  224 }
  225 
  226 int
  227 cngetc(void)
  228 {
  229 
  230         if (cn_tab == NULL)
  231                 return (0);
  232         return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
  233 }
  234 
  235 void
  236 cnputc(int c)
  237 {
  238 
  239         if (cn_tab == NULL)
  240                 return;                 
  241 
  242         if (c) {
  243                 (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
  244                 if (c == '\n')
  245                         (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
  246         }
  247 }
  248 
  249 void
  250 cnpollc(int on)
  251 {
  252         static int refcount = 0;
  253 
  254         if (cn_tab == NULL)
  255                 return;
  256         if (!on)
  257                 --refcount;
  258         if (refcount == 0)
  259                 (*cn_tab->cn_pollc)(cn_tab->cn_dev, on);
  260         if (on)
  261                 ++refcount;
  262 }
  263 
  264 void
  265 nullcnpollc(dev_t dev, int on)
  266 {
  267 
  268 }
  269 
  270 void
  271 cnbell(u_int pitch, u_int period, u_int volume)
  272 {
  273         if (cn_tab == NULL || cn_tab->cn_bell == NULL)
  274                 return;
  275 
  276         (*cn_tab->cn_bell)(cn_tab->cn_dev, pitch, period, volume);
  277 }

/* [<][>][^][v][top][bottom][index][help] */