The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/cons.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: cons.c,v 1.30 2022/07/02 08:50:41 visa 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/ioctl.h>
   45 #include <sys/tty.h>
   46 #include <sys/conf.h>
   47 #include <sys/vnode.h>
   48 
   49 #include <dev/cons.h>
   50 
   51 struct  tty *constty = NULL;            /* virtual console output device */
   52 struct  vnode *cn_devvp = NULLVP;       /* vnode for underlying device. */
   53 
   54 int
   55 cnopen(dev_t dev, int flag, int mode, struct proc *p)
   56 {
   57         dev_t cndev;
   58 
   59         if (cn_tab == NULL)
   60                 return (0);
   61 
   62         /*
   63          * always open the 'real' console device, so we don't get nailed
   64          * later.  This follows normal device semantics; they always get
   65          * open() calls.
   66          */
   67         cndev = cn_tab->cn_dev;
   68         if (cndev == NODEV)
   69                 return (ENXIO);
   70 #ifdef DIAGNOSTIC
   71         if (cndev == dev)
   72                 panic("cnopen: recursive");
   73 #endif
   74         if (cn_devvp == NULLVP) {
   75                 /* try to get a reference on its vnode, but fail silently */
   76                 cdevvp(cndev, &cn_devvp);
   77         }
   78         return ((*cdevsw[major(cndev)].d_open)(cndev, flag, mode, p));
   79 }
   80  
   81 int
   82 cnclose(dev_t dev, int flag, int mode, struct proc *p)
   83 {
   84         struct vnode *vp;
   85 
   86         if (cn_tab == NULL)
   87                 return (0);
   88 
   89         /*
   90          * If the real console isn't otherwise open, close it.
   91          * If it's otherwise open, don't close it, because that'll
   92          * screw up others who have it open.
   93          */
   94         dev = cn_tab->cn_dev;
   95         if (cn_devvp != NULLVP) {
   96                 /* release our reference to real dev's vnode */
   97                 vrele(cn_devvp);
   98                 cn_devvp = NULLVP;
   99         }
  100         if (vfinddev(dev, VCHR, &vp) && vcount(vp))
  101                 return (0);
  102         return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
  103 }
  104  
  105 int
  106 cnread(dev_t dev, struct uio *uio, int flag)
  107 {
  108 
  109         /*
  110          * If we would redirect input, punt.  This will keep strange
  111          * things from happening to people who are using the real
  112          * console.  Nothing should be using /dev/console for
  113          * input (except a shell in single-user mode, but then,
  114          * one wouldn't TIOCCONS then).
  115          */
  116         if (constty != NULL)
  117                 return 0;
  118         else if (cn_tab == NULL)
  119                 return ENXIO;
  120 
  121         dev = cn_tab->cn_dev;
  122         return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
  123 }
  124  
  125 int
  126 cnwrite(dev_t dev, struct uio *uio, int flag)
  127 {
  128 
  129         /*
  130          * Redirect output, if that's appropriate.
  131          * If there's no real console, return ENXIO.
  132          */
  133         if (constty != NULL)
  134                 dev = constty->t_dev;
  135         else if (cn_tab == NULL)
  136                 return ENXIO;
  137         else
  138                 dev = cn_tab->cn_dev;
  139         return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
  140 }
  141 
  142 int
  143 cnstop(struct tty *tp, int flag)
  144 {
  145         return (0);
  146 }
  147  
  148 int
  149 cnioctl(dev_t dev, u_long cmd, caddr_t data, int flag,
  150     struct proc *p)
  151 {
  152         int error;
  153 
  154         /*
  155          * Superuser can always use this to wrest control of console
  156          * output from the "virtual" console.
  157          */
  158         if (cmd == TIOCCONS && constty != NULL) {
  159                 error = suser(p);
  160                 if (error)
  161                         return (error);
  162                 constty = NULL;
  163                 return (0);
  164         }
  165 
  166         /*
  167          * Redirect the ioctl, if that's appropriate.
  168          * Note that strange things can happen, if a program does
  169          * ioctls on /dev/console, then the console is redirected
  170          * out from under it.
  171          */
  172         if (constty != NULL)
  173                 dev = constty->t_dev;
  174         else if (cn_tab == NULL)
  175                 return ENXIO;
  176         else
  177                 dev = cn_tab->cn_dev;
  178         return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
  179 }
  180 
  181 int
  182 cnkqfilter(dev_t dev, struct knote *kn)
  183 {
  184 
  185         /*
  186          * Redirect output, if that's appropriate.
  187          * If there's no real console, return 1.
  188          */
  189         if (constty != NULL)
  190                 dev = constty->t_dev;
  191         else if (cn_tab == NULL)
  192                 return (ENXIO);
  193         else
  194                 dev = cn_tab->cn_dev;
  195         if (cdevsw[major(dev)].d_kqfilter)
  196                 return ((*cdevsw[major(dev)].d_kqfilter)(dev, kn));
  197         return (EOPNOTSUPP);
  198 }
  199 
  200 int
  201 cngetc(void)
  202 {
  203 
  204         if (cn_tab == NULL)
  205                 return (0);
  206         return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
  207 }
  208 
  209 void
  210 cnputc(int c)
  211 {
  212 
  213         if (cn_tab == NULL)
  214                 return;                 
  215 
  216         if (c) {
  217                 (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
  218                 if (c == '\n')
  219                         (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
  220         }
  221 }
  222 
  223 void
  224 cnpollc(int on)
  225 {
  226         static int refcount = 0;
  227 
  228         if (cn_tab == NULL)
  229                 return;
  230         if (!on)
  231                 --refcount;
  232         if (refcount == 0)
  233                 (*cn_tab->cn_pollc)(cn_tab->cn_dev, on);
  234         if (on)
  235                 ++refcount;
  236 }
  237 
  238 void
  239 nullcnpollc(dev_t dev, int on)
  240 {
  241 
  242 }
  243 
  244 void
  245 cnbell(u_int pitch, u_int period, u_int volume)
  246 {
  247         if (cn_tab == NULL || cn_tab->cn_bell == NULL)
  248                 return;
  249 
  250         (*cn_tab->cn_bell)(cn_tab->cn_dev, pitch, period, volume);
  251 }

Cache object: d0fc1c42d01c22103aae1f9d339f05dd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.