diff options
Diffstat (limited to 'usr')
-rw-r--r-- | usr/src/cmd/ttymon/tmchild.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/ttymon/tmexpress.c | 46 | ||||
-rw-r--r-- | usr/src/cmd/ttymon/tmextern.h | 2 | ||||
-rw-r--r-- | usr/src/cmd/ttymon/tmstruct.h | 1 | ||||
-rw-r--r-- | usr/src/cmd/ttymon/tmterm.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/ttymon/ttymon.c | 88 |
6 files changed, 134 insertions, 7 deletions
diff --git a/usr/src/cmd/ttymon/tmchild.c b/usr/src/cmd/ttymon/tmchild.c index a58099974b..960a9a816c 100644 --- a/usr/src/cmd/ttymon/tmchild.c +++ b/usr/src/cmd/ttymon/tmchild.c @@ -99,7 +99,7 @@ tmchild(struct pmtab *pmtab) */ (void) setsid(); } - speedef = get_speed(pmtab->p_ttylabel); + speedef = get_speed(pmtab); openline(pmtab, speedef); if (pmtab->p_ttyflags & (C_FLAG|B_FLAG)) { if (pmtab->p_fd >= 0) { diff --git a/usr/src/cmd/ttymon/tmexpress.c b/usr/src/cmd/ttymon/tmexpress.c index 345fdd1529..2a3f91d147 100644 --- a/usr/src/cmd/ttymon/tmexpress.c +++ b/usr/src/cmd/ttymon/tmexpress.c @@ -34,7 +34,6 @@ #include <ctype.h> #include <string.h> #include <signal.h> -#include <sys/stat.h> #include <utmpx.h> #include <pwd.h> #include <dirent.h> @@ -42,6 +41,7 @@ #include <sys/acl.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/mkdev.h> #include <sys/console.h> #include <libdevinfo.h> #include "ttymon.h" @@ -143,6 +143,44 @@ ttymon_express(int argc, char **argv) } /* + * For serial device, return ttyX-mode property value. + */ +static char * +get_ttymode_prop(dev_t rconsdev) +{ + char *rootpath = "/"; + char path[MAXPATHLEN]; + di_node_t root; + char *propname, *v; + struct stat st; + + (void) snprintf(path, sizeof (path), "/dev/tty%c", + 'a' + minor(rconsdev)); + if (stat(path, &st) < 0) + return (NULL); + + if (st.st_rdev != rconsdev) + return (NULL); + + if (asprintf(&propname, "%s-mode", path + 5) <= 0) + return (NULL); + + root = di_init(rootpath, DINFOPROP); + if (root == DI_NODE_NIL) { + free(propname); + return (NULL); + } + + v = NULL; + if (di_prop_lookup_strings(DDI_DEV_T_ANY, root, propname, &v) > 0) + v = strdup(v); + + di_fini(root); + free(propname); + return (v); +} + +/* * parse_arg - parse cmd line arguments */ static int @@ -172,11 +210,13 @@ parse_args(int argc, char **argv, struct pmtab *pmtab) pmtab->p_termtype = ""; pmtab->p_device = ""; pmtab->p_status = GETTY; + pmtab->p_ttymode = NULL; if (strcmp(lastname(argv[0]), "getty") == 0) { pmtab->p_ttylabel = "300"; getty_options(argc, argv, pmtab); } else { int cn_fd; + struct cons_getdev cnd; pmtab->p_ttylabel = "9600"; ttymon_options(argc, argv, pmtab); @@ -200,6 +240,10 @@ parse_args(int argc, char **argv, struct pmtab *pmtab) if (ioctl(cn_fd, CONS_GETTERM, &cnterm) != -1) pmtab->p_termtype = cnterm.cn_term_type; + + if (ioctl(cn_fd, CONS_GETDEV, &cnd) != -1) + pmtab->p_ttymode = + get_ttymode_prop(cnd.cnd_rconsdev); (void) close(cn_fd); } } diff --git a/usr/src/cmd/ttymon/tmextern.h b/usr/src/cmd/ttymon/tmextern.h index b08c59f04d..955e5773ff 100644 --- a/usr/src/cmd/ttymon/tmextern.h +++ b/usr/src/cmd/ttymon/tmextern.h @@ -222,7 +222,7 @@ extern "C" { extern int Splflag; /* ttymon.c */ - extern struct Gdef *get_speed(char *); + extern struct Gdef *get_speed(struct pmtab *); extern void open_device(struct pmtab *); extern void set_softcar(struct pmtab *); extern void setup_PCpipe(void); diff --git a/usr/src/cmd/ttymon/tmstruct.h b/usr/src/cmd/ttymon/tmstruct.h index 288c1ec122..8c4582896a 100644 --- a/usr/src/cmd/ttymon/tmstruct.h +++ b/usr/src/cmd/ttymon/tmstruct.h @@ -74,6 +74,7 @@ struct pmtab { uid_t p_uid; /* uid of p_identity */ gid_t p_gid; /* gid of p_identity */ char *p_dir; /* home dir of p_identity */ + char *p_ttymode; /* mode line for serial device */ struct pmtab *p_next; }; diff --git a/usr/src/cmd/ttymon/tmterm.c b/usr/src/cmd/ttymon/tmterm.c index 96e63af2d3..613cf2597d 100644 --- a/usr/src/cmd/ttymon/tmterm.c +++ b/usr/src/cmd/ttymon/tmterm.c @@ -244,7 +244,7 @@ initial_termio(int fd, struct pmtab *pmptr) int ret; struct Gdef *speedef; - speedef = get_speed(pmptr->p_ttylabel); + speedef = get_speed(pmptr); if (speedef->g_autobaud & A_FLAG) { pmptr->p_ttyflags |= A_FLAG; if (auto_termio(fd) == -1) { diff --git a/usr/src/cmd/ttymon/ttymon.c b/usr/src/cmd/ttymon/ttymon.c index 03ff520059..0c061a9c8c 100644 --- a/usr/src/cmd/ttymon/ttymon.c +++ b/usr/src/cmd/ttymon/ttymon.c @@ -26,6 +26,7 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ +#include <ctype.h> #include <stdio_ext.h> #include <stdlib.h> #include <fcntl.h> @@ -597,25 +598,106 @@ free_defs(void) } /* + * rebuild flags entry using speed from ttymode. + */ +static char * +merge_flags(char *src, char *ttymode) +{ + char *data, *ptr, *flags; + + /* copy speed entry */ + data = strsave(src); + flags = strsave(ttymode); + ptr = strchr(flags, ','); + if (ptr == NULL) { /* ttymode is corrupted */ + free(flags); + return (data); + } + *ptr = '\0'; + ptr = flags; + flags = strsave(flags); + free(ptr); + + /* + * The flags line is supposed to have stty keywords separated by space. + * We need to split up the keywords, replace the speed and + * reconstruct the flags line. + */ + + ptr = strtok(data, " \t"); + if (ptr == NULL) { + free(data); + return (flags); + } + + do { + char *tmp; + + /* skip speed */ + if (isdigit(*ptr)) + continue; + + if (asprintf(&tmp, "%s %s", flags, ptr) <= 0) { + /* should we complain? */ + break; + } + free(flags); + flags = tmp; + } while ((ptr = strtok(NULL, " \t")) != NULL); + + free(data); + return (flags); +} + +/* * struct Gdef *get_speed(ttylabel) * - search "/etc/ttydefs" for speed and term. specification * using "ttylabel". If "ttylabel" is NULL, default * to DEFAULT + * - for /dev/console, if we are in fact using serial console, + * use ttyX-mode value to get speed. This allows us to use + * the value set for serial console either from firmware (or BMC sol), + * or boot loader default. * arg: ttylabel - label/id of speed settings. */ struct Gdef * -get_speed(char *ttylabel) +get_speed(struct pmtab *pmptr) { + static struct Gdef serial = { 0 }; struct Gdef *sp; + char *ttylabel = pmptr->p_ttylabel; if ((ttylabel != NULL) && (*ttylabel != '\0')) { if ((sp = find_def(ttylabel)) == NULL) { log("unable to find <%s> in \"%s\"", ttylabel, TTYDEFS); sp = &DEFAULT; /* use default */ } - } else sp = &DEFAULT; /* use default */ - return (sp); + } else { + sp = &DEFAULT; /* use default */ + } + + /* + * if this is not /dev/console or /dev/console is not using serial, + * we are done. + */ + if (pmptr->p_ttymode == NULL || + strcmp(pmptr->p_device, "/dev/console") != 0) + return (sp); + + /* is entry for serial set up? */ + if (serial.g_id == NULL) { + /* + * Copy data from sp, except we need to update inital and + * final flags. + */ + serial.g_id = strsave(sp->g_id); + serial.g_iflags = merge_flags(sp->g_iflags, pmptr->p_ttymode); + serial.g_fflags = merge_flags(sp->g_fflags, pmptr->p_ttymode); + serial.g_autobaud = sp->g_autobaud; + serial.g_nextid = strsave(sp->g_nextid); + } + return (&serial); } /* |