Skip to content

Instantly share code, notes, and snippets.

@jclulow
Created May 7, 2020 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jclulow/f4d6a65f8dd0de7b3b60518df8c53cfe to your computer and use it in GitHub Desktop.
Save jclulow/f4d6a65f8dd0de7b3b60518df8c53cfe to your computer and use it in GitHub Desktop.
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