Created
May 7, 2020 22:40
-
-
Save jclulow/f4d6a65f8dd0de7b3b60518df8c53cfe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/usr/src/cmd/ttymon/Makefile b/usr/src/cmd/ttymon/Makefile | |
index ae70a2619c..fec4322a6a 100644 | |
--- a/usr/src/cmd/ttymon/Makefile | |
+++ b/usr/src/cmd/ttymon/Makefile | |
@@ -62,38 +62,30 @@ include ../Makefile.cmd | |
# fix for 1111333 - turn on SYS_NAME so /etc/issue will be read if it exists | |
CPPFLAGS += -DSYS_NAME | |
$(XPG4):= CPPFLAGS += -DXPG4 | |
sttydefs := LDLIBS += -lnsl | |
ttymon := LDLIBS += -lnsl -lsec -ldevinfo | |
# Only stty can be built with -DEUC. ttymon will dump core unless further | |
# changes are made to it. | |
$(STTYOBJ) := CPPFLAGS += -DEUC | |
$(XPG4STTYOBJ) := CPPFLAGS += -DEUC | |
LINTFLAGS = -b -x | |
CFLAGS += $(CCVERBOSE) | |
LDFLAGS += $(MAPFILE.NGB:%=-M%) | |
-CERRWARN += -_gcc=-Wno-parentheses | |
-CERRWARN += -_gcc=-Wno-unused-variable | |
-CERRWARN += $(CNOWARN_UNINIT) | |
-CERRWARN += -_gcc=-Wno-extra | |
- | |
-# not linted | |
-SMATCH=off | |
- | |
# | |
# Message catalog | |
# | |
POFILES= $(STTYOBJ:sttyobjs/%.o=%.po) | |
POFILE= ttymon.po | |
LIBSAFD= $(ROOTLIB)/saf | |
DIRS= $(LIBSAFD) | |
LIBSAF= ttymon | |
USRSBINF= sttydefs ttyadm | |
BINF= stty | |
ROOTLIBF= $(LIBSAF:%=$(LIBSAFD)/%) | |
ROOTUSRSBINF= $(USRSBINF:%=$(ROOTUSRSBIN)/%) | |
ROOTBINF= $(BINF:%=$(ROOTBIN)/%) | |
diff --git a/usr/src/cmd/ttymon/stty.c b/usr/src/cmd/ttymon/stty.c | |
index 8ae976fdbd..691fe70aa1 100644 | |
--- a/usr/src/cmd/ttymon/stty.c | |
+++ b/usr/src/cmd/ttymon/stty.c | |
@@ -95,31 +95,38 @@ main(int argc, char *argv[]) | |
char *s_arg, *sttyparse(); /* s_arg: ptr to mode to be set */ | |
#ifdef EUC | |
char *lc; | |
char tmps[PATH_MAX]; | |
#endif /* EUC */ | |
(void) setlocale(LC_ALL, ""); | |
#if !defined(TEXT_DOMAIN) | |
#define TEXT_DOMAIN "SYS_TEST" | |
#endif | |
(void) textdomain(TEXT_DOMAIN); | |
#ifdef EUC | |
lc = setlocale(LC_CTYPE, (const char *)NULL); | |
if (lc) { | |
- sprintf(tmps, _LDTERM_DAT_PATH, lc); | |
+ int r; | |
+ | |
+ if ((r = sprintf(tmps, _LDTERM_DAT_PATH, lc)) < 0 || | |
+ r >= sizeof (tmps)) { | |
+ (void) fprintf(stderr, gettext( | |
+ "cannot construct ldterm.dat path\n")); | |
+ exit(2); | |
+ } | |
fd = open(tmps, O_RDONLY, 0); | |
if (fd != -1) { | |
if (read(fd, (void *)&cswp, sizeof (cswp)) < | |
sizeof (cswp)) { | |
(void) fprintf(stderr, gettext( | |
"cannot read entire %s file\n"), tmps); | |
exit(2); | |
} | |
(void) close(fd); | |
/* | |
* If the ldterm.dat contains invalid data or | |
* the current locale name is too long, we clear | |
@@ -143,80 +150,87 @@ main(int argc, char *argv[]) | |
} | |
} | |
getwidth(&wp); | |
#endif /* EUC */ | |
if ((term = get_ttymode(0, &ocb, &cb, &stio, &termiox, &winsize | |
#ifdef EUC | |
/* */, &kwp, &kcswp | |
#endif /* EUC */ | |
/* */)) < 0) { | |
perror(STTY); | |
exit(2); | |
} | |
owinsize = winsize; | |
+ | |
if (argc == 1) { | |
prmodes(); | |
exit(0); | |
} | |
- if ((argc == 2) && (argv[1][0] == '-') && (argv[1][2] == '\0')) | |
- switch (argv[1][1]) { | |
+ | |
+ if ((argc == 2) && (argv[1][0] == '-') && (argv[1][2] == '\0')) { | |
+ switch (argv[1][1]) { | |
+ case 'a': | |
+ pramodes(); | |
+ return (0); | |
+ case 'g': | |
+ prencode(); | |
+ return (0); | |
+ case '-': | |
+ prmodes(); /* stty -- */ | |
+ return (0); | |
+ default: | |
+ (void) fprintf(stderr, gettext( | |
+ "usage: stty [-a| -g]\n")); | |
+ (void) fprintf(stderr, gettext( | |
+ " stty [modes]\n")); | |
+ return (2); | |
+ } | |
+ } | |
+ | |
+ if ((argc == 3) && (argv[1][0] == '-') && (argv[1][2] == '\0') && | |
+ (argv[2][0] == '-') && (argv[2][1] == '-') && | |
+ (argv[2][2] == '\0')) { | |
+ switch (argv[1][1]) { | |
case 'a': | |
pramodes(); | |
return (0); | |
case 'g': | |
prencode(); | |
return (0); | |
- case '-': | |
- prmodes(); /* stty -- */ | |
- return (0); | |
default: | |
(void) fprintf(stderr, gettext( | |
"usage: stty [-a| -g]\n")); | |
(void) fprintf(stderr, gettext( | |
" stty [modes]\n")); | |
return (2); | |
+ } | |
} | |
- if ((argc == 3) && (argv[1][0] == '-') && (argv[1][2] == '\0') && | |
- (argv[2][0] == '-') && (argv[2][1] == '-') && (argv[2][2] == '\0')) | |
- switch (argv[1][1]) { | |
- case 'a': | |
- pramodes(); | |
- return (0); | |
- case 'g': | |
- prencode(); | |
- return (0); | |
- default: | |
- (void) fprintf(stderr, gettext( | |
- "usage: stty [-a| -g]\n")); | |
- (void) fprintf(stderr, gettext( | |
- " stty [modes]\n")); | |
- return (2); | |
- } | |
if ((argc >= 3) && (argv[1][0] == '-') && (argv[1][1] == '-') && | |
(argv[1][2] == '\0')) { | |
/* ignore -- */ | |
--argc; | |
++argv; | |
} | |
- if (s_arg = sttyparse(argc, argv, term, &ocb, &cb, &termiox, &winsize | |
+ | |
+ if ((s_arg = sttyparse(argc, argv, term, &ocb, &cb, &termiox, &winsize | |
#ifdef EUC | |
/* */, &wp, &kwp, &cswp, &kcswp | |
#endif /* EUC */ | |
- /* */)) { | |
+ /* */)) != NULL) { | |
char *s = s_arg; | |
if (*s == '-') s++; | |
for (i = 0; not_supported[i]; i++) { | |
if (strcmp(not_supported[i], s) == 0) { | |
(void) fprintf(stderr, | |
gettext( | |
"mode not supported on this device: %s\n"), | |
s_arg); | |
exit(2); | |
} | |
} | |
(void) fprintf(stderr, gettext("unknown mode: %s\n"), s_arg); | |
return (2); | |
} | |
@@ -387,35 +401,36 @@ prmodes(void) /* print modes, no options, argc is 1 */ | |
(void) printf("imaxbel "); | |
m = cb.c_oflag; | |
if (!(m&OPOST)) | |
(void) printf("-opost "); | |
else { | |
if (m&OLCUC) | |
(void) printf("olcuc "); | |
if (m&ONLCR) | |
(void) printf("onlcr "); | |
if (m&OCRNL) | |
(void) printf("ocrnl "); | |
if (m&ONOCR) | |
(void) printf("onocr "); | |
if (m&ONLRET) | |
(void) printf("onlret "); | |
- if (m&OFILL) | |
+ if (m&OFILL) { | |
if (m&OFDEL) | |
(void) printf("del-fill "); | |
else | |
(void) printf("nul-fill "); | |
+ } | |
delay((m&CRDLY)/CR1, "cr"); | |
delay((m&NLDLY)/NL1, "nl"); | |
delay((m&TABDLY)/TAB1, "tab"); | |
delay((m&BSDLY)/BS1, "bs"); | |
delay((m&VTDLY)/VT1, "vt"); | |
delay((m&FFDLY)/FF1, "ff"); | |
} | |
(void) printf("\n"); | |
m = cb.c_lflag; | |
if (!(m&ISIG)) | |
(void) printf("-isig "); | |
if (!(m&ICANON)) | |
(void) printf("-icanon "); | |
if (m&XCASE) | |
(void) printf("xcase "); | |
@@ -689,32 +704,32 @@ pramodes(void) /* print all modes, -a option */ | |
case RSETCTSET: (void)printf("rsetctset "); | |
break; | |
case RSETCRSET: (void)printf("rsetcrset "); | |
} | |
(void) printf("\n"); | |
} | |
} | |
/* print function for prmodes() and pramodes() */ | |
void | |
pit(unsigned char what, char *itsname, char *sep) | |
{ | |
pitt++; | |
(void) printf("%s", itsname); | |
- if ((term & TERMIOS) && what == _POSIX_VDISABLE || | |
- !(term & TERMIOS) && what == 0200) { | |
+ if (((term & TERMIOS) && what == _POSIX_VDISABLE) || | |
+ (!(term & TERMIOS) && what == 0200)) { | |
(void) printf(" = <undef>%s", sep); | |
return; | |
} | |
(void) printf(" = "); | |
if (what & 0200 && !isprint(what)) { | |
(void) printf("-"); | |
what &= ~ 0200; | |
} | |
if (what == 0177) { | |
(void) printf("^?%s", sep); | |
return; | |
} else if (what < ' ') { | |
(void) printf("^"); | |
what += '`'; | |
if (what > 'z') | |
@@ -772,31 +787,31 @@ prencode(void) /* another stty cmd, used for -g option */ | |
#ifdef EUC | |
if (term & CSIW) { | |
for (i = 0; i < MAX_CC; i++) | |
(void) printf(":%x", (i >= last) ? 0 : cb.c_cc[i]); | |
/* | |
* Print out ldterm_cs_data_user_t data fields for | |
* PSARC/1999/140 TCR2. This change introduces additional | |
* 44 fields that come from the ldterm_cs_data_user_t data | |
* structure. | |
*/ | |
(void) printf(":%x:%x:%x:", kcswp.version, kcswp.codeset_type, | |
kcswp.csinfo_num); | |
if (*kcswp.locale_name == '\0') { | |
(void) printf("00"); | |
} else { | |
- for (i = 0; kcswp.locale_name[i] && i < MAXNAMELEN; i++) | |
+ for (i = 0; i < MAXNAMELEN && kcswp.locale_name[i]; i++) | |
(void) printf("%02x", kcswp.locale_name[i]); | |
} | |
for (i = 0; i < LDTERM_CS_MAX_CODESETS; i++) | |
(void) printf(":%x:%x:%x:%x", | |
kcswp.eucpc_data[i].byte_length, | |
kcswp.eucpc_data[i].screen_width, | |
kcswp.eucpc_data[i].msb_start, | |
kcswp.eucpc_data[i].msb_end); | |
} else { | |
#endif /* EUC */ | |
for (i = 0; i < last; i++) | |
(void) printf(":%x", cb.c_cc[i]); | |
#ifdef EUC | |
} | |
#endif /* EUC */ | |
diff --git a/usr/src/cmd/ttymon/tmexpress.c b/usr/src/cmd/ttymon/tmexpress.c | |
index c01a67142e..083dae6297 100644 | |
--- a/usr/src/cmd/ttymon/tmexpress.c | |
+++ b/usr/src/cmd/ttymon/tmexpress.c | |
@@ -16,30 +16,31 @@ | |
* fields enclosed by brackets "[]" replaced with your own identifying | |
* information: Portions Copyright [yyyy] [name of copyright owner] | |
* | |
* CDDL HEADER END | |
*/ | |
/* | |
* Copyright 2008 Sun Microsystems, Inc. All rights reserved. | |
* Use is subject to license terms. | |
*/ | |
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ | |
/* All Rights Reserved */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
+#include <stdbool.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <ctype.h> | |
#include <string.h> | |
#include <signal.h> | |
#include <sys/stat.h> | |
#include <utmpx.h> | |
#include <pwd.h> | |
#include <dirent.h> | |
#include <sys/param.h> | |
#include <sys/acl.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <sys/console.h> | |
@@ -51,30 +52,36 @@ static char devbuf[BUFSIZ]; | |
static char *devname; | |
static int parse_args(); | |
static void ttymon_options(); | |
static void getty_options(); | |
static void usage(); | |
static char *find_ttyname(); | |
extern void tmchild(); | |
extern int vml(); | |
void revokedevaccess(char *, uid_t, gid_t, mode_t); | |
/* cannot include libdevinfo.h */ | |
extern int di_devperm_logout(const char *); | |
+static bool | |
+empty(const char *check) | |
+{ | |
+ return (check == NULL || check[0] == '\0'); | |
+} | |
+ | |
/* | |
* ttymon_express - This is call when ttymon is invoked with args | |
* or invoked as getty | |
* - This special version of ttymon will monitor | |
* one port only | |
* - It is intended to be used when some process | |
* wants to have a login session on the fly | |
*/ | |
void | |
ttymon_express(int argc, char **argv) | |
{ | |
struct pmtab *pmtab; | |
struct sigaction sigact; | |
extern int Retry; | |
extern void open_device(); | |
@@ -94,62 +101,64 @@ ttymon_express(int argc, char **argv) | |
(void) sigemptyset(&sigact.sa_mask); | |
(void) sigaction(SIGINT, &sigact, NULL); | |
if ((pmtab = ALLOC_PMTAB) == PNULL) { | |
log("ttymon_express: ALLOC_PMTAB failed"); | |
exit(1); | |
} | |
if (parse_args(argc, argv, pmtab) != 0) { | |
log("ttymon_express: parse_args failed"); | |
exit(1); | |
} | |
read_ttydefs(NULL, FALSE); | |
- if ((pmtab->p_device != NULL) && (*(pmtab->p_device) != '\0')) | |
- while (checkut_line(pmtab->p_device)) | |
- sleep(15); | |
+ if (!empty(pmtab->p_device)) { | |
+ while (checkut_line(pmtab->p_device)) { | |
+ sleep(1); | |
+ } | |
+ } | |
- if ((pmtab->p_device == NULL) || (*(pmtab->p_device) == '\0')) { | |
+ if (empty(pmtab->p_device)) { | |
devname = find_ttyname(0); | |
- if ((devname == NULL) || (*devname == '\0')) { | |
+ if (empty(devname)) { | |
log("ttyname cannot find the device on fd 0"); | |
exit(1); | |
} | |
pmtab->p_device = devname; | |
#ifdef DEBUG | |
debug("ttymon_express: devname = %s", devname); | |
#endif | |
/* | |
* become session leader | |
* fd 0 is closed and reopened just to make sure | |
* controlling tty is set up right | |
*/ | |
(void) setsid(); | |
(void) close(0); | |
revokedevaccess(pmtab->p_device, 0, 0, 0); | |
if (open(pmtab->p_device, O_RDWR) < 0) { | |
log("open %s failed: %s", pmtab->p_device, | |
strerror(errno)); | |
exit(1); | |
} | |
- if ((pmtab->p_modules != NULL) && | |
- (*(pmtab->p_modules) != '\0')) { | |
+ if (!empty(pmtab->p_modules)) { | |
if (push_linedisc(0, pmtab->p_modules, | |
- pmtab->p_device) == -1) | |
+ pmtab->p_device) == -1) { | |
exit(1); | |
+ } | |
} | |
if (initial_termio(0, pmtab) == -1) | |
exit(1); | |
di_devperm_logout((const char *)pmtab->p_device); | |
} else { | |
(void) setsid(); | |
(void) close(0); | |
Retry = FALSE; | |
open_device(pmtab); | |
if (Retry) /* open failed */ | |
exit(1); | |
} | |
tmchild(pmtab); | |
exit(1); /*NOTREACHED*/ | |
} | |
@@ -206,32 +215,33 @@ parse_args(int argc, char **argv, struct pmtab *pmtab) | |
* If any of the tests, system calls, or ioctls fail | |
* then pmtab->p_termtype retains its default value | |
* of "". otherwise it is set to a term type value | |
* that was returned. | |
*/ | |
if ((strlen(pmtab->p_termtype) == 0) && | |
(strcmp(pmtab->p_device, "/dev/console") == 0) && | |
((cn_fd = open("/dev/console", O_RDONLY)) != -1)) { | |
if (ioctl(cn_fd, CONS_GETTERM, &cnterm) != -1) | |
pmtab->p_termtype = cnterm.cn_term_type; | |
(void) close(cn_fd); | |
} | |
} | |
- if ((pmtab->p_device != NULL) && (*(pmtab->p_device) != '\0')) | |
+ if (!empty(pmtab->p_device)) { | |
getty_account(pmtab->p_device); /* utmp accounting */ | |
+ } | |
return (0); | |
} | |
/* | |
* ttymon_options - scan and check args for ttymon express | |
*/ | |
static void | |
ttymon_options(int argc, char **argv, struct pmtab *pmtab) | |
{ | |
int c; /* option letter */ | |
char *timeout; | |
int gflag = 0; /* -g seen */ | |
int size = 0; | |
diff --git a/usr/src/cmd/ttymon/tmhandler.c b/usr/src/cmd/ttymon/tmhandler.c | |
index bd7932f7b6..3dfd274582 100644 | |
--- a/usr/src/cmd/ttymon/tmhandler.c | |
+++ b/usr/src/cmd/ttymon/tmhandler.c | |
@@ -44,30 +44,46 @@ | |
#include <sys/wait.h> | |
#include "ttymon.h" | |
#include "tmstruct.h" | |
#include "tmextern.h" | |
#include "sac.h" | |
extern int Retry; | |
static struct pmtab *find_pid(); | |
static void kill_children(); | |
static struct pmtab *find_fd(); | |
static void pcsync_close(); | |
extern void sigalarm(); | |
extern void tmchild(); | |
+static void | |
+safe_close(int fd) | |
+{ | |
+ for (;;) { | |
+ if (close(fd) == 0) { | |
+ return; | |
+ } | |
+ | |
+ if (errno == EINTR) { | |
+ continue; | |
+ } | |
+ | |
+ fatal("close(%d) failed: %s", fd, strerror(errno)); | |
+ } | |
+} | |
+ | |
/* | |
* fork_tmchild - fork child on the device | |
*/ | |
static void | |
fork_tmchild(pmptr) | |
struct pmtab *pmptr; | |
{ | |
pid_t pid; | |
sigset_t cset; | |
sigset_t tset; | |
int pcpipe0[2], pcpipe1[2]; | |
int p0; | |
#ifdef DEBUG | |
debug("in fork_tmchild"); | |
@@ -76,32 +92,32 @@ struct pmtab *pmptr; | |
/* | |
* initialize pipe. | |
* Child has pcpipe[0] pipe fd for reading and writing | |
* and closes pcpipe[1]. Parent has pcpipe[1] pipe fd for | |
* reading and writing and closes pcpipe[0]. | |
* | |
* This way if the child process exits the parent's block | |
* read on pipe will return immediately as the other end of | |
* the pipe has closed. Similarly if the parent process exits | |
* child's blocking read on the pipe will return immediately. | |
*/ | |
if (((p0 = pipe(pcpipe0)) == -1) || (pipe(pcpipe1) == -1)) { | |
if (p0 == 0) { | |
- close(pcpipe0[0]); | |
- close(pcpipe0[1]); | |
+ safe_close(pcpipe0[0]); | |
+ safe_close(pcpipe0[1]); | |
} | |
log("pipe() failed: %s", strerror(errno)); | |
pmptr->p_status = VALID; | |
pmptr->p_pid = 0; | |
Retry = TRUE; | |
} | |
/* protect following region from SIGCLD */ | |
(void)sigprocmask(SIG_SETMASK, NULL, &cset); | |
tset = cset; | |
(void)sigaddset(&tset, SIGCLD); | |
(void)sigprocmask(SIG_SETMASK, &tset, NULL); | |
if( (pid=fork()) == 0 ) { | |
/* | |
* Close all file descriptors except pmptr->p_fd | |
@@ -114,31 +130,31 @@ struct pmtab *pmptr; | |
fatal("tmchild for <%s> returns unexpected", pmptr->p_device); | |
} | |
else if (pid < 0) { | |
log("fork failed: %s", strerror(errno)); | |
pmptr->p_status = VALID; | |
pmptr->p_pid = 0; | |
Retry = TRUE; | |
} | |
else { | |
/* | |
* The PARENT - store pid of child and close the device | |
*/ | |
pmptr->p_pid = pid; | |
} | |
if (pmptr->p_fd > 0) { | |
- (void)close(pmptr->p_fd); | |
+ safe_close(pmptr->p_fd); | |
pmptr->p_fd = 0; | |
} | |
(void)sigprocmask(SIG_SETMASK, &cset, NULL); | |
/* | |
* Wait for child to close file descriptors | |
*/ | |
pcsync_close(pcpipe0, pcpipe1, pid, pmptr->p_fd); | |
} | |
/* | |
* got_carrier - carrier is detected on the stream | |
* - depends on the flags, different action is taken | |
* - R_FLAG - wait for data | |
* - C_FLAG - if port is not disabled, fork tmchild | |
* - A_FLAG - wait for data | |
@@ -174,55 +190,55 @@ struct pmtab *pmptr; | |
write_prompt(pmptr->p_fd,pmptr,TRUE,TRUE); | |
} | |
} | |
/* | |
* got_data - data is detected on the stream, fork tmchild | |
*/ | |
static void | |
got_data(pmptr) | |
struct pmtab *pmptr; | |
{ | |
struct sigaction sigact; | |
if (tm_checklock(pmptr->p_fd) != 0) { | |
pmptr->p_status = LOCKED; | |
- (void)close(pmptr->p_fd); | |
+ safe_close(pmptr->p_fd); | |
pmptr->p_fd = 0; | |
Nlocked++; | |
if (Nlocked == 1) { | |
sigact.sa_flags = 0; | |
sigact.sa_handler = sigalarm; | |
(void)sigemptyset(&sigact.sa_mask); | |
(void)sigaction(SIGALRM, &sigact, NULL); | |
(void)alarm(ALARMTIME); | |
} | |
} | |
else | |
fork_tmchild(pmptr); | |
} | |
/* | |
* got_hup - stream hangup is detected, close the device | |
*/ | |
static void | |
got_hup(pmptr) | |
struct pmtab *pmptr; | |
{ | |
#ifdef DEBUG | |
debug("in got hup"); | |
#endif | |
- (void)close(pmptr->p_fd); | |
+ safe_close(pmptr->p_fd); | |
pmptr->p_fd = 0; | |
pmptr->p_inservice = 0; | |
Retry = TRUE; | |
} | |
/* | |
* do_poll - poll device | |
* - if POLLHUP received, close the device | |
* - if POLLIN received, fork tmchild. | |
*/ | |
void | |
do_poll(fdp,nfds) | |
struct pollfd *fdp; | |
int nfds; | |
@@ -343,43 +359,43 @@ sigterm() | |
* its internal state between enabled and disabled | |
*/ | |
void | |
state_change() | |
{ | |
struct pmtab *pmptr; | |
#ifdef DEBUG | |
debug("in state_change"); | |
#endif | |
/* | |
* closing PCpipe will cause attached non-service children | |
* to get SIGPOLL and exit | |
*/ | |
- (void)close(PCpipe[0]); | |
- (void)close(PCpipe[1]); | |
+ safe_close(PCpipe[0]); | |
+ safe_close(PCpipe[1]); | |
/* reopen PCpipe */ | |
setup_PCpipe(); | |
/* | |
* also close all open ports so ttymon can start over | |
* with new internal state | |
*/ | |
for (pmptr = PMtab; pmptr; pmptr = pmptr->p_next) { | |
if ((pmptr->p_fd > 0) && (pmptr->p_pid == 0)) { | |
- (void)close(pmptr->p_fd); | |
+ safe_close(pmptr->p_fd); | |
pmptr->p_fd = 0; | |
} | |
} | |
Retry = TRUE; | |
} | |
/* | |
* re_read - reread pmtab | |
* - kill tmchild if entry changed | |
*/ | |
void | |
re_read() | |
{ | |
extern struct pollfd *Pollp; | |
@@ -451,31 +467,31 @@ int fd; | |
} | |
/* | |
* kill_children() - if the pmtab entry has been changed, | |
* kill tmchild if it is not in service. | |
* - close the device if there is no tmchild | |
*/ | |
static void | |
kill_children() | |
{ | |
struct pmtab *pmptr; | |
for (pmptr = PMtab; pmptr; pmptr = pmptr->p_next) { | |
if (pmptr->p_status == VALID) | |
continue; | |
if ((pmptr->p_fd > 0) && (pmptr->p_pid == 0)) { | |
- (void)close(pmptr->p_fd); | |
+ safe_close(pmptr->p_fd); | |
pmptr->p_fd = 0; | |
} | |
else if ((pmptr->p_fd == 0) && (pmptr->p_pid > 0) | |
&& (pmptr->p_inservice == FALSE)) { | |
(void)kill(pmptr->p_pid, SIGTERM); | |
} | |
} | |
} | |
static void | |
mark_service(pid) | |
pid_t pid; | |
{ | |
struct pmtab *pmptr; | |
#ifdef DEBUG | |
@@ -547,67 +563,65 @@ sigpoll_catch() | |
/*ARGSUSED*/ | |
void | |
sigalarm(signo) | |
int signo; | |
{ | |
struct pmtab *pmptr; | |
struct sigaction sigact; | |
int fd; | |
extern int check_session(); | |
#ifdef DEBUG | |
debug("in sigalarm, Nlocked = %d", Nlocked); | |
#endif | |
for (pmptr = PMtab; pmptr; pmptr = pmptr->p_next) { | |
- if ((pmptr->p_status == LOCKED) && (pmptr->p_fd == 0)) { | |
- if ((fd=open(pmptr->p_device,O_RDWR|O_NONBLOCK)) == -1){ | |
+ if (pmptr->p_status == LOCKED && pmptr->p_fd == 0) { | |
+ if ((fd = open(pmptr->p_device, | |
+ O_RDWR | O_NONBLOCK)) == -1) { | |
log("open (%s) failed: %s", pmptr->p_device, | |
strerror(errno)); | |
pmptr->p_status = VALID; | |
Nlocked--; | |
Retry = TRUE; | |
- } | |
- else { | |
+ } else { | |
if (tm_checklock(fd) == 0) { | |
Nlocked--; | |
pmptr->p_fd = fd; | |
Retry = TRUE; | |
+ } else { | |
+ safe_close(fd); | |
} | |
- else | |
- (void)close(fd); | |
} | |
- } | |
- else if ((pmptr->p_status == SESSION) && (pmptr->p_fd == 0)) { | |
- if ((fd=open(pmptr->p_device,O_RDWR|O_NONBLOCK)) == -1){ | |
+ } else if (pmptr->p_status == SESSION && pmptr->p_fd == 0) { | |
+ if ((fd = open(pmptr->p_device, | |
+ O_RDWR | O_NONBLOCK)) == -1) { | |
log("open (%s) failed: %s", pmptr->p_device, | |
strerror(errno)); | |
pmptr->p_status = VALID; | |
Nlocked--; | |
Retry = TRUE; | |
- } | |
- else { | |
+ } else { | |
if (check_session(fd) == 0) { | |
Nlocked--; | |
pmptr->p_fd = fd; | |
Retry = TRUE; | |
+ } else { | |
+ safe_close(fd); | |
} | |
- else | |
- (void)close(fd); | |
} | |
- } | |
- else if ((pmptr->p_status == UNACCESS) && (pmptr->p_fd == 0)) { | |
+ } else if (pmptr->p_status == UNACCESS && pmptr->p_fd == 0) { | |
if ((fd=open(pmptr->p_device,O_RDWR|O_NONBLOCK)) == -1){ | |
log("open (%s) failed: %s", pmptr->p_device, | |
strerror(errno)); | |
pmptr->p_status = VALID; | |
Nlocked--; | |
Retry = TRUE; | |
} | |
else { | |
Nlocked--; | |
pmptr->p_fd = fd; | |
Retry = TRUE; | |
} | |
} | |
} | |
if (Nlocked > 0) { | |
diff --git a/usr/src/cmd/ttymon/ttymon.c b/usr/src/cmd/ttymon/ttymon.c | |
index b0555612d3..a604cd195c 100644 | |
--- a/usr/src/cmd/ttymon/ttymon.c | |
+++ b/usr/src/cmd/ttymon/ttymon.c | |
@@ -349,35 +349,39 @@ struct pmtab *pmptr; | |
/* | |
* If soft carrier is not set one way or | |
* the other, leave it alone. | |
*/ | |
if (*pmptr->p_softcar == '\0') | |
return; | |
if (*pmptr->p_softcar == 'y') | |
val = 1; | |
if ((fd = open(pmptr->p_device, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) { | |
log("open (%s) failed: %s", pmptr->p_device, strerror(errno)); | |
return; | |
} | |
- if (ioctl(fd, TIOCSSOFTCAR, &val) < 0) | |
+ if (ioctl(fd, TIOCSSOFTCAR, &val) < 0) { | |
log("set soft-carrier (%s) failed: %s", pmptr->p_device, | |
strerror(errno)); | |
+ } | |
- close(fd); | |
+ if (close(fd) != 0) { | |
+ log("close (%d, %s) failed: %s", fd, pmptr->p_device, | |
+ strerror(errno)); | |
+ } | |
} | |
/* | |
* open_device(pmptr) - open the device | |
* - check device lock | |
* - change owner of device | |
* - push line disciplines | |
* - set termio | |
*/ | |
void | |
open_device(pmptr) | |
struct pmtab *pmptr; | |
{ | |
@@ -503,31 +507,31 @@ struct pmtab *pmptr; | |
if ((pmptr->p_modules != NULL)&&(*(pmptr->p_modules) != '\0')) { | |
if (push_linedisc(fd, pmptr->p_modules, pmptr->p_device) | |
== -1) { | |
Retry = TRUE; | |
(void) close(fd); | |
return; | |
} | |
} | |
if (initial_termio(fd, pmptr) == -1) { | |
Retry = TRUE; | |
(void) close(fd); | |
return; | |
} | |
- di_devperm_logout((const char *)pmptr->p_device); | |
+ (void) di_devperm_logout((const char *)pmptr->p_device); | |
pmptr->p_fd = fd; | |
} | |
/* | |
* set_poll(fdp) - put all fd's in a pollfd array | |
* - set poll event to POLLIN and POLLMSG | |
* - return number of fd to be polled | |
*/ | |
static int | |
set_poll(fdp) | |
struct pollfd *fdp; | |
{ | |
struct pmtab *tp; | |
int nfd = 0; | |
diff --git a/usr/src/uts/common/io/cons.c b/usr/src/uts/common/io/cons.c | |
index 8635023fe3..d799b20929 100644 | |
--- a/usr/src/uts/common/io/cons.c | |
+++ b/usr/src/uts/common/io/cons.c | |
@@ -435,30 +435,59 @@ cnwrite(dev_t dev, struct uio *uio, struct cred *cred) | |
if (iovlen != 0) | |
kmem_free(uiod.d_iov, iovlen); | |
} | |
if (rconsvp->v_stream != NULL) | |
return (strwrite(rconsvp, uio, cred)); | |
else | |
return (cdev_write(rconsdev, uio, cred)); | |
} | |
/* ARGSUSED */ | |
static int | |
cnprivateioc(dev_t dev, int cmd, intptr_t arg, int flag, struct cred *cred, | |
int *rvalp) | |
{ | |
+ if (cmd == CONS_GETDEV) { | |
+ /* | |
+ * The user has requested the device number of the redirection | |
+ * client. | |
+ */ | |
+ STRUCT_DECL(cons_getdev, cnd); | |
+ STRUCT_INIT(cnd, flag); | |
+ | |
+ bzero(STRUCT_BUF(cnd), STRUCT_SIZE(cnd)); | |
+ | |
+ if ((flag & DATAMODEL_MASK) == DATAMODEL_ILP32) { | |
+ dev32_t rconsdev32; | |
+ | |
+ if (cmpldev(&rconsdev32, rconsdev) != 1) { | |
+ return (EOVERFLOW); | |
+ } | |
+ | |
+ STRUCT_FSET(cnd, cnd_rconsdev, rconsdev32); | |
+ } else { | |
+ STRUCT_FSET(cnd, cnd_rconsdev, rconsdev); | |
+ } | |
+ | |
+ if (ddi_copyout(STRUCT_BUF(cnd), (void *)arg, | |
+ STRUCT_SIZE(cnd), flag) != 0) { | |
+ return (EFAULT); | |
+ } | |
+ | |
+ return (0); | |
+ } | |
/* currently we only support one ioctl */ | |
if (cmd != CONS_GETTERM) | |
return (EINVAL); | |
/* Confirm iwscn is immediate target of cn redirection */ | |
if (rconsvp != wsconsvp) | |
return (ENODEV); | |
/* | |
* If the redirection client is not wc, it should return | |
* error upon receiving the CONS_GETTERM ioctl. | |
* | |
* if it is wc, we know that the target supports the CONS_GETTERM | |
* ioctl, which very conviently has the exact same data | |
diff --git a/usr/src/uts/common/sys/console.h b/usr/src/uts/common/sys/console.h | |
index 9f60764092..892f7e5b34 100644 | |
--- a/usr/src/uts/common/sys/console.h | |
+++ b/usr/src/uts/common/sys/console.h | |
@@ -25,49 +25,58 @@ | |
*/ | |
#ifndef _SYS_CONSOLE_H | |
#define _SYS_CONSOLE_H | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/* | |
* Sun private interface for cn driver | |
*/ | |
#define _CNIOC (('C'<<24)|('N'<<16)) | |
#define _CNIOC_MASK (~0xffff) | |
#define CONS_GETTERM (_CNIOC | 0) | |
+#define CONS_GETDEV (_CNIOC | 1) | |
#define MAX_TERM_TYPE_LEN 10 | |
struct cons_getterm { | |
uint_t cn_term_len; | |
char *cn_term_type; | |
}; | |
+struct cons_getdev { | |
+ dev_t cnd_rconsdev; | |
+}; | |
+ | |
#ifdef _KERNEL | |
#include <sys/vnode.h> | |
#include <sys/taskq.h> | |
#include <sys/varargs.h> | |
#ifdef _SYSCALL32 | |
struct cons_getterm32 { | |
uint32_t cn_term_len; | |
caddr32_t cn_term_type; | |
}; | |
+ | |
+struct cons_getdev32 { | |
+ dev32_t cnd_rconsdev; | |
+}; | |
#endif /* _SYSCALL32 */ | |
extern void console_get_size(ushort_t *r, ushort_t *c, | |
ushort_t *x, ushort_t *y); | |
/*PRINTFLIKE1*/ | |
extern void console_printf(const char *, ...) __KPRINTFLIKE(1); | |
extern void console_vprintf(const char *, va_list) __KVPRINTFLIKE(1); | |
extern void console_puts(const char *, size_t); | |
extern void console_gets(char *, size_t); | |
extern int console_getc(void); | |
extern int console_enter(int); | |
extern void console_exit(int, int); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment