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/kern/kern_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 /*-
    2  * Copyright (c) 1988 University of Utah.
    3  * Copyright (c) 1991 The Regents of the University of California.
    4  * Copyright (c) 1999 Michael Smith
    5  * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
    6  *
    7  * 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  * 4. 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: @(#)cons.c        7.2 (Berkeley) 5/9/91
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD: releng/10.1/sys/kern/kern_cons.c 270988 2014-09-02 22:01:14Z emaste $");
   42 
   43 #include "opt_ddb.h"
   44 #include "opt_syscons.h"
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/lock.h>
   49 #include <sys/mutex.h>
   50 #include <sys/conf.h>
   51 #include <sys/cons.h>
   52 #include <sys/fcntl.h>
   53 #include <sys/kdb.h>
   54 #include <sys/kernel.h>
   55 #include <sys/malloc.h>
   56 #include <sys/msgbuf.h>
   57 #include <sys/namei.h>
   58 #include <sys/priv.h>
   59 #include <sys/proc.h>
   60 #include <sys/queue.h>
   61 #include <sys/reboot.h>
   62 #include <sys/sysctl.h>
   63 #include <sys/sbuf.h>
   64 #include <sys/tty.h>
   65 #include <sys/uio.h>
   66 #include <sys/vnode.h>
   67 
   68 #include <ddb/ddb.h>
   69 
   70 #include <machine/cpu.h>
   71 #include <machine/clock.h>
   72 
   73 static MALLOC_DEFINE(M_TTYCONS, "tty console", "tty console handling");
   74 
   75 struct cn_device {
   76         STAILQ_ENTRY(cn_device) cnd_next;
   77         struct          consdev *cnd_cn;
   78 };
   79 
   80 #define CNDEVPATHMAX    32
   81 #define CNDEVTAB_SIZE   4
   82 static struct cn_device cn_devtab[CNDEVTAB_SIZE];
   83 static STAILQ_HEAD(, cn_device) cn_devlist =
   84     STAILQ_HEAD_INITIALIZER(cn_devlist);
   85 
   86 int     cons_avail_mask = 0;    /* Bit mask. Each registered low level console
   87                                  * which is currently unavailable for inpit
   88                                  * (i.e., if it is in graphics mode) will have
   89                                  * this bit cleared.
   90                                  */
   91 static int cn_mute;
   92 static char *consbuf;                   /* buffer used by `consmsgbuf' */
   93 static struct callout conscallout;      /* callout for outputting to constty */
   94 struct msgbuf consmsgbuf;               /* message buffer for console tty */
   95 static u_char console_pausing;          /* pause after each line during probe */
   96 static char *console_pausestr=
   97 "<pause; press any key to proceed to next line or '.' to end pause mode>";
   98 struct tty *constty;                    /* pointer to console "window" tty */
   99 static struct mtx cnputs_mtx;           /* Mutex for cnputs(). */
  100 static int use_cnputs_mtx = 0;          /* != 0 if cnputs_mtx locking reqd. */
  101 
  102 static void constty_timeout(void *arg);
  103 
  104 static struct consdev cons_consdev;
  105 DATA_SET(cons_set, cons_consdev);
  106 SET_DECLARE(cons_set, struct consdev);
  107 
  108 void
  109 cninit(void)
  110 {
  111         struct consdev *best_cn, *cn, **list;
  112 
  113         /*
  114          * Check if we should mute the console (for security reasons perhaps)
  115          * It can be changes dynamically using sysctl kern.consmute
  116          * once we are up and going.
  117          * 
  118          */
  119         cn_mute = ((boothowto & (RB_MUTE
  120                         |RB_SINGLE
  121                         |RB_VERBOSE
  122                         |RB_ASKNAME)) == RB_MUTE);
  123 
  124         /*
  125          * Find the first console with the highest priority.
  126          */
  127         best_cn = NULL;
  128         SET_FOREACH(list, cons_set) {
  129                 cn = *list;
  130                 cnremove(cn);
  131                 /* Skip cons_consdev. */
  132                 if (cn->cn_ops == NULL)
  133                         continue;
  134                 cn->cn_ops->cn_probe(cn);
  135                 if (cn->cn_pri == CN_DEAD)
  136                         continue;
  137                 if (best_cn == NULL || cn->cn_pri > best_cn->cn_pri)
  138                         best_cn = cn;
  139                 if (boothowto & RB_MULTIPLE) {
  140                         /*
  141                          * Initialize console, and attach to it.
  142                          */
  143                         cn->cn_ops->cn_init(cn);
  144                         cnadd(cn);
  145                 }
  146         }
  147         if (best_cn == NULL)
  148                 return;
  149         if ((boothowto & RB_MULTIPLE) == 0) {
  150                 best_cn->cn_ops->cn_init(best_cn);
  151                 cnadd(best_cn);
  152         }
  153         if (boothowto & RB_PAUSE)
  154                 console_pausing = 1;
  155         /*
  156          * Make the best console the preferred console.
  157          */
  158         cnselect(best_cn);
  159 }
  160 
  161 void
  162 cninit_finish()
  163 {
  164         console_pausing = 0;
  165 } 
  166 
  167 /* add a new physical console to back the virtual console */
  168 int
  169 cnadd(struct consdev *cn)
  170 {
  171         struct cn_device *cnd;
  172         int i;
  173 
  174         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next)
  175                 if (cnd->cnd_cn == cn)
  176                         return (0);
  177         for (i = 0; i < CNDEVTAB_SIZE; i++) {
  178                 cnd = &cn_devtab[i];
  179                 if (cnd->cnd_cn == NULL)
  180                         break;
  181         }
  182         if (cnd->cnd_cn != NULL)
  183                 return (ENOMEM);
  184         cnd->cnd_cn = cn;
  185         if (cn->cn_name[0] == '\0') {
  186                 /* XXX: it is unclear if/where this print might output */
  187                 printf("WARNING: console at %p has no name\n", cn);
  188         }
  189         STAILQ_INSERT_TAIL(&cn_devlist, cnd, cnd_next);
  190         if (STAILQ_FIRST(&cn_devlist) == cnd)
  191                 ttyconsdev_select(cnd->cnd_cn->cn_name);
  192 
  193         /* Add device to the active mask. */
  194         cnavailable(cn, (cn->cn_flags & CN_FLAG_NOAVAIL) == 0);
  195 
  196         return (0);
  197 }
  198 
  199 void
  200 cnremove(struct consdev *cn)
  201 {
  202         struct cn_device *cnd;
  203         int i;
  204 
  205         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
  206                 if (cnd->cnd_cn != cn)
  207                         continue;
  208                 if (STAILQ_FIRST(&cn_devlist) == cnd)
  209                         ttyconsdev_select(NULL);
  210                 STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next);
  211                 cnd->cnd_cn = NULL;
  212 
  213                 /* Remove this device from available mask. */
  214                 for (i = 0; i < CNDEVTAB_SIZE; i++) 
  215                         if (cnd == &cn_devtab[i]) {
  216                                 cons_avail_mask &= ~(1 << i);
  217                                 break;
  218                         }
  219 #if 0
  220                 /*
  221                  * XXX
  222                  * syscons gets really confused if console resources are
  223                  * freed after the system has initialized.
  224                  */
  225                 if (cn->cn_term != NULL)
  226                         cn->cn_ops->cn_term(cn);
  227 #endif
  228                 return;
  229         }
  230 }
  231 
  232 void
  233 cnselect(struct consdev *cn)
  234 {
  235         struct cn_device *cnd;
  236 
  237         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
  238                 if (cnd->cnd_cn != cn)
  239                         continue;
  240                 if (cnd == STAILQ_FIRST(&cn_devlist))
  241                         return;
  242                 STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next);
  243                 STAILQ_INSERT_HEAD(&cn_devlist, cnd, cnd_next);
  244                 ttyconsdev_select(cnd->cnd_cn->cn_name);
  245                 return;
  246         }
  247 }
  248 
  249 void
  250 cnavailable(struct consdev *cn, int available)
  251 {
  252         int i;
  253 
  254         for (i = 0; i < CNDEVTAB_SIZE; i++) {
  255                 if (cn_devtab[i].cnd_cn == cn)
  256                         break;
  257         }
  258         if (available) {
  259                 if (i < CNDEVTAB_SIZE)
  260                         cons_avail_mask |= (1 << i); 
  261                 cn->cn_flags &= ~CN_FLAG_NOAVAIL;
  262         } else {
  263                 if (i < CNDEVTAB_SIZE)
  264                         cons_avail_mask &= ~(1 << i);
  265                 cn->cn_flags |= CN_FLAG_NOAVAIL;
  266         }
  267 }
  268 
  269 int
  270 cnunavailable(void)
  271 {
  272 
  273         return (cons_avail_mask == 0);
  274 }
  275 
  276 /*
  277  * sysctl_kern_console() provides output parseable in conscontrol(1).
  278  */
  279 static int
  280 sysctl_kern_console(SYSCTL_HANDLER_ARGS)
  281 {
  282         struct cn_device *cnd;
  283         struct consdev *cp, **list;
  284         char *p;
  285         int delete, error;
  286         struct sbuf *sb;
  287 
  288         sb = sbuf_new(NULL, NULL, CNDEVPATHMAX * 2, SBUF_AUTOEXTEND);
  289         if (sb == NULL)
  290                 return (ENOMEM);
  291         sbuf_clear(sb);
  292         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next)
  293                 sbuf_printf(sb, "%s,", cnd->cnd_cn->cn_name);
  294         sbuf_printf(sb, "/");
  295         SET_FOREACH(list, cons_set) {
  296                 cp = *list;
  297                 if (cp->cn_name[0] != '\0')
  298                         sbuf_printf(sb, "%s,", cp->cn_name);
  299         }
  300         sbuf_finish(sb);
  301         error = sysctl_handle_string(oidp, sbuf_data(sb), sbuf_len(sb), req);
  302         if (error == 0 && req->newptr != NULL) {
  303                 p = sbuf_data(sb);
  304                 error = ENXIO;
  305                 delete = 0;
  306                 if (*p == '-') {
  307                         delete = 1;
  308                         p++;
  309                 }
  310                 SET_FOREACH(list, cons_set) {
  311                         cp = *list;
  312                         if (strcmp(p, cp->cn_name) != 0)
  313                                 continue;
  314                         if (delete) {
  315                                 cnremove(cp);
  316                                 error = 0;
  317                         } else {
  318                                 error = cnadd(cp);
  319                                 if (error == 0)
  320                                         cnselect(cp);
  321                         }
  322                         break;
  323                 }
  324         }
  325         sbuf_delete(sb);
  326         return (error);
  327 }
  328 
  329 SYSCTL_PROC(_kern, OID_AUTO, console, CTLTYPE_STRING|CTLFLAG_RW,
  330         0, 0, sysctl_kern_console, "A", "Console device control");
  331 
  332 /*
  333  * User has changed the state of the console muting.
  334  * This may require us to open or close the device in question.
  335  */
  336 static int
  337 sysctl_kern_consmute(SYSCTL_HANDLER_ARGS)
  338 {
  339         int error;
  340 
  341         error = sysctl_handle_int(oidp, &cn_mute, 0, req);
  342         if (error != 0 || req->newptr == NULL)
  343                 return (error);
  344         return (error);
  345 }
  346 
  347 SYSCTL_PROC(_kern, OID_AUTO, consmute, CTLTYPE_INT|CTLFLAG_RW,
  348         0, sizeof(cn_mute), sysctl_kern_consmute, "I",
  349         "State of the console muting");
  350 
  351 void
  352 cngrab()
  353 {
  354         struct cn_device *cnd;
  355         struct consdev *cn;
  356 
  357         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
  358                 cn = cnd->cnd_cn;
  359                 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG))
  360                         cn->cn_ops->cn_grab(cn);
  361         }
  362 }
  363 
  364 void
  365 cnungrab()
  366 {
  367         struct cn_device *cnd;
  368         struct consdev *cn;
  369 
  370         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
  371                 cn = cnd->cnd_cn;
  372                 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG))
  373                         cn->cn_ops->cn_ungrab(cn);
  374         }
  375 }
  376 
  377 /*
  378  * Low level console routines.
  379  */
  380 int
  381 cngetc(void)
  382 {
  383         int c;
  384 
  385         if (cn_mute)
  386                 return (-1);
  387         while ((c = cncheckc()) == -1)
  388                 cpu_spinwait();
  389         if (c == '\r')
  390                 c = '\n';               /* console input is always ICRNL */
  391         return (c);
  392 }
  393 
  394 int
  395 cncheckc(void)
  396 {
  397         struct cn_device *cnd;
  398         struct consdev *cn;
  399         int c;
  400 
  401         if (cn_mute)
  402                 return (-1);
  403         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
  404                 cn = cnd->cnd_cn;
  405                 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) {
  406                         c = cn->cn_ops->cn_getc(cn);
  407                         if (c != -1)
  408                                 return (c);
  409                 }
  410         }
  411         return (-1);
  412 }
  413 
  414 void
  415 cngets(char *cp, size_t size, int visible)
  416 {
  417         char *lp, *end;
  418         int c;
  419 
  420         cngrab();
  421 
  422         lp = cp;
  423         end = cp + size - 1;
  424         for (;;) {
  425                 c = cngetc() & 0177;
  426                 switch (c) {
  427                 case '\n':
  428                 case '\r':
  429                         cnputc(c);
  430                         *lp = '\0';
  431                         cnungrab();
  432                         return;
  433                 case '\b':
  434                 case '\177':
  435                         if (lp > cp) {
  436                                 if (visible)
  437                                         cnputs("\b \b");
  438                                 lp--;
  439                         }
  440                         continue;
  441                 case '\0':
  442                         continue;
  443                 default:
  444                         if (lp < end) {
  445                                 switch (visible) {
  446                                 case GETS_NOECHO:
  447                                         break;
  448                                 case GETS_ECHOPASS:
  449                                         cnputc('*');
  450                                         break;
  451                                 default:
  452                                         cnputc(c);
  453                                         break;
  454                                 }
  455                                 *lp++ = c;
  456                         }
  457                 }
  458         }
  459 }
  460 
  461 void
  462 cnputc(int c)
  463 {
  464         struct cn_device *cnd;
  465         struct consdev *cn;
  466         char *cp;
  467 
  468 #ifdef EARLY_PRINTF
  469         if (early_putc != NULL) {
  470                 if (c == '\n')
  471                         early_putc('\r');
  472                 early_putc(c);
  473                 return;
  474         }
  475 #endif
  476 
  477         if (cn_mute || c == '\0')
  478                 return;
  479         STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
  480                 cn = cnd->cnd_cn;
  481                 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) {
  482                         if (c == '\n')
  483                                 cn->cn_ops->cn_putc(cn, '\r');
  484                         cn->cn_ops->cn_putc(cn, c);
  485                 }
  486         }
  487         if (console_pausing && c == '\n' && !kdb_active) {
  488                 for (cp = console_pausestr; *cp != '\0'; cp++)
  489                         cnputc(*cp);
  490                 cngrab();
  491                 if (cngetc() == '.')
  492                         console_pausing = 0;
  493                 cnungrab();
  494                 cnputc('\r');
  495                 for (cp = console_pausestr; *cp != '\0'; cp++)
  496                         cnputc(' ');
  497                 cnputc('\r');
  498         }
  499 }
  500 
  501 void
  502 cnputs(char *p)
  503 {
  504         int c;
  505         int unlock_reqd = 0;
  506 
  507         if (use_cnputs_mtx) {
  508                 mtx_lock_spin(&cnputs_mtx);
  509                 unlock_reqd = 1;
  510         }
  511 
  512         while ((c = *p++) != '\0')
  513                 cnputc(c);
  514 
  515         if (unlock_reqd)
  516                 mtx_unlock_spin(&cnputs_mtx);
  517 }
  518 
  519 static int consmsgbuf_size = 8192;
  520 SYSCTL_INT(_kern, OID_AUTO, consmsgbuf_size, CTLFLAG_RW, &consmsgbuf_size, 0,
  521     "Console tty buffer size");
  522 
  523 /*
  524  * Redirect console output to a tty.
  525  */
  526 void
  527 constty_set(struct tty *tp)
  528 {
  529         int size;
  530 
  531         KASSERT(tp != NULL, ("constty_set: NULL tp"));
  532         if (consbuf == NULL) {
  533                 size = consmsgbuf_size;
  534                 consbuf = malloc(size, M_TTYCONS, M_WAITOK);
  535                 msgbuf_init(&consmsgbuf, consbuf, size);
  536                 callout_init(&conscallout, 0);
  537         }
  538         constty = tp;
  539         constty_timeout(NULL);
  540 }
  541 
  542 /*
  543  * Disable console redirection to a tty.
  544  */
  545 void
  546 constty_clear(void)
  547 {
  548         int c;
  549 
  550         constty = NULL;
  551         if (consbuf == NULL)
  552                 return;
  553         callout_stop(&conscallout);
  554         while ((c = msgbuf_getchar(&consmsgbuf)) != -1)
  555                 cnputc(c);
  556         free(consbuf, M_TTYCONS);
  557         consbuf = NULL;
  558 }
  559 
  560 /* Times per second to check for pending console tty messages. */
  561 static int constty_wakeups_per_second = 5;
  562 SYSCTL_INT(_kern, OID_AUTO, constty_wakeups_per_second, CTLFLAG_RW,
  563     &constty_wakeups_per_second, 0,
  564     "Times per second to check for pending console tty messages");
  565 
  566 static void
  567 constty_timeout(void *arg)
  568 {
  569         int c;
  570 
  571         if (constty != NULL) {
  572                 tty_lock(constty);
  573                 while ((c = msgbuf_getchar(&consmsgbuf)) != -1) {
  574                         if (tty_putchar(constty, c) < 0) {
  575                                 tty_unlock(constty);
  576                                 constty = NULL;
  577                                 break;
  578                         }
  579                 }
  580 
  581                 if (constty != NULL)
  582                         tty_unlock(constty);
  583         }
  584         if (constty != NULL) {
  585                 callout_reset(&conscallout, hz / constty_wakeups_per_second,
  586                     constty_timeout, NULL);
  587         } else {
  588                 /* Deallocate the constty buffer memory. */
  589                 constty_clear();
  590         }
  591 }
  592 
  593 static void
  594 cn_drvinit(void *unused)
  595 {
  596 
  597         mtx_init(&cnputs_mtx, "cnputs_mtx", NULL, MTX_SPIN | MTX_NOWITNESS);
  598         use_cnputs_mtx = 1;
  599 }
  600 
  601 SYSINIT(cndev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, cn_drvinit, NULL);
  602 
  603 /*
  604  * Sysbeep(), if we have hardware for it
  605  */
  606 
  607 #ifdef HAS_TIMER_SPKR
  608 
  609 static int beeping;
  610 
  611 static void
  612 sysbeepstop(void *chan)
  613 {
  614 
  615         timer_spkr_release();
  616         beeping = 0;
  617 }
  618 
  619 int
  620 sysbeep(int pitch, int period)
  621 {
  622 
  623         if (timer_spkr_acquire()) {
  624                 if (!beeping) {
  625                         /* Something else owns it. */
  626                         return (EBUSY);
  627                 }
  628         }
  629         timer_spkr_setfreq(pitch);
  630         if (!beeping) {
  631                 beeping = period;
  632                 timeout(sysbeepstop, (void *)NULL, period);
  633         }
  634         return (0);
  635 }
  636 
  637 #else
  638 
  639 /*
  640  * No hardware, no sound
  641  */
  642 
  643 int
  644 sysbeep(int pitch __unused, int period __unused)
  645 {
  646 
  647         return (ENODEV);
  648 }
  649 
  650 #endif
  651 
  652 /*
  653  * Temporary support for sc(4) to vt(4) transition.
  654  */
  655 static unsigned vty_prefer;
  656 static char vty_name[16];
  657 SYSCTL_STRING(_kern, OID_AUTO, vty, CTLFLAG_RDTUN, vty_name, 0,
  658     "Console vty driver");
  659 
  660 int
  661 vty_enabled(unsigned vty)
  662 {
  663         static unsigned vty_selected = 0;
  664 
  665         if (vty_selected == 0) {
  666                 TUNABLE_STR_FETCH("kern.vty", vty_name, sizeof(vty_name));
  667                 do {
  668 #if defined(DEV_SC)
  669                         if (strcmp(vty_name, "sc") == 0) {
  670                                 vty_selected = VTY_SC;
  671                                 break;
  672                         }
  673 #endif
  674 #if defined(DEV_VT)
  675                         if (strcmp(vty_name, "vt") == 0) {
  676                                 vty_selected = VTY_VT;
  677                                 break;
  678                         }
  679 #endif
  680                         if (vty_prefer != 0) {
  681                                 vty_selected = vty_prefer;
  682                                 break;
  683                         }
  684 #if defined(DEV_SC)
  685                         vty_selected = VTY_SC;
  686 #elif defined(DEV_VT)
  687                         vty_selected = VTY_VT;
  688 #endif
  689                 } while (0);
  690 
  691                 if (vty_selected == VTY_VT)
  692                         strcpy(vty_name, "vt");
  693                 else if (vty_selected == VTY_SC)
  694                         strcpy(vty_name, "sc");
  695         }
  696         return ((vty_selected & vty) != 0);
  697 }
  698 
  699 void
  700 vty_set_preferred(unsigned vty)
  701 {
  702 
  703         vty_prefer = vty;
  704 #if !defined(DEV_SC)
  705         vty_prefer &= ~VTY_SC;
  706 #endif
  707 #if !defined(DEV_VT)
  708         vty_prefer &= ~VTY_VT;
  709 #endif
  710 }
  711 

Cache object: 703a8347fb5fed6931c4f938946d091b


[ 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.