xref: /titanic_41/usr/src/cmd/ttymon/ttymon.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
35*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
36*7c478bd9Sstevel@tonic-gate #include <errno.h>
37*7c478bd9Sstevel@tonic-gate #include <poll.h>
38*7c478bd9Sstevel@tonic-gate #include <string.h>
39*7c478bd9Sstevel@tonic-gate #include <signal.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/resource.h>
44*7c478bd9Sstevel@tonic-gate #include <sys/termios.h>
45*7c478bd9Sstevel@tonic-gate #include <pwd.h>
46*7c478bd9Sstevel@tonic-gate #include <grp.h>
47*7c478bd9Sstevel@tonic-gate #include <unistd.h>
48*7c478bd9Sstevel@tonic-gate #include <ulimit.h>
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate #include "sac.h"
51*7c478bd9Sstevel@tonic-gate #include "ttymon.h"
52*7c478bd9Sstevel@tonic-gate #include "tmstruct.h"
53*7c478bd9Sstevel@tonic-gate #include "tmextern.h"
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate static	int	Initialized;
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate extern	int	Retry;
58*7c478bd9Sstevel@tonic-gate extern	struct	pollfd	*Pollp;
59*7c478bd9Sstevel@tonic-gate static	void	initialize();
60*7c478bd9Sstevel@tonic-gate static	void	open_all();
61*7c478bd9Sstevel@tonic-gate static	int	set_poll();
62*7c478bd9Sstevel@tonic-gate static	int	check_spawnlimit();
63*7c478bd9Sstevel@tonic-gate static	int	mod_ttydefs();
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate void	open_device();
66*7c478bd9Sstevel@tonic-gate void	set_softcar();
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate extern	int	check_session();
69*7c478bd9Sstevel@tonic-gate extern	void	sigalarm();
70*7c478bd9Sstevel@tonic-gate extern	void	revokedevaccess(char *, uid_t, gid_t, mode_t);
71*7c478bd9Sstevel@tonic-gate /* can't include libdevinfo.h */
72*7c478bd9Sstevel@tonic-gate extern int di_devperm_logout(const char *);
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate /*
75*7c478bd9Sstevel@tonic-gate  * 	ttymon	- a port monitor under SAC
76*7c478bd9Sstevel@tonic-gate  *		- monitor ports, set terminal modes, baud rate
77*7c478bd9Sstevel@tonic-gate  *		  and line discipline for the port
78*7c478bd9Sstevel@tonic-gate  *		- invoke service on port if connection request received
79*7c478bd9Sstevel@tonic-gate  *		- Usage: ttymon
80*7c478bd9Sstevel@tonic-gate  *			 ttymon -g [options]
81*7c478bd9Sstevel@tonic-gate  *			 Valid options are
82*7c478bd9Sstevel@tonic-gate  *			 -h
83*7c478bd9Sstevel@tonic-gate  *			 -d device
84*7c478bd9Sstevel@tonic-gate  *			 -l ttylabel
85*7c478bd9Sstevel@tonic-gate  *			 -t timeout
86*7c478bd9Sstevel@tonic-gate  *			 -m modules
87*7c478bd9Sstevel@tonic-gate  *			 -p prompt
88*7c478bd9Sstevel@tonic-gate  *
89*7c478bd9Sstevel@tonic-gate  *		- ttymon without args is invoked by SAC
90*7c478bd9Sstevel@tonic-gate  *		- ttymon -g is invoked by process that needs to
91*7c478bd9Sstevel@tonic-gate  *		  have login service on the fly
92*7c478bd9Sstevel@tonic-gate  */
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate main(argc, argv)
95*7c478bd9Sstevel@tonic-gate int	argc;
96*7c478bd9Sstevel@tonic-gate char	*argv[];
97*7c478bd9Sstevel@tonic-gate {
98*7c478bd9Sstevel@tonic-gate 	int	nfds;
99*7c478bd9Sstevel@tonic-gate 	extern	char	*lastname();
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate 	/*
102*7c478bd9Sstevel@tonic-gate 	 * Only the superuser should execute this command.
103*7c478bd9Sstevel@tonic-gate 	 */
104*7c478bd9Sstevel@tonic-gate 	if (getuid() != 0)
105*7c478bd9Sstevel@tonic-gate 		return (1);	/*NOTREACHED*/
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 	if ((argc > 1) || (strcmp(lastname(argv[0]), "getty") == 0)) {
108*7c478bd9Sstevel@tonic-gate 		ttymon_express(argc, argv);
109*7c478bd9Sstevel@tonic-gate 		return (1);	/*NOTREACHED*/
110*7c478bd9Sstevel@tonic-gate 	}
111*7c478bd9Sstevel@tonic-gate 	/* remember original signal mask and dispositions */
112*7c478bd9Sstevel@tonic-gate 	(void) sigprocmask(SIG_SETMASK, NULL, &Origmask);
113*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGINT, &Sigint, NULL);
114*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGALRM, &Sigalrm, NULL);
115*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGPOLL, &Sigpoll, NULL);
116*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGCLD, &Sigcld, NULL);
117*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGTERM, &Sigterm, NULL);
118*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
119*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGUSR1, &Sigusr1, NULL);
120*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGUSR2, &Sigusr2, NULL);
121*7c478bd9Sstevel@tonic-gate #endif
122*7c478bd9Sstevel@tonic-gate 	initialize();
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	for (;;) {
125*7c478bd9Sstevel@tonic-gate 		nfds = set_poll(Pollp);
126*7c478bd9Sstevel@tonic-gate 		if (!Reread_flag) {
127*7c478bd9Sstevel@tonic-gate 			if (nfds > 0)
128*7c478bd9Sstevel@tonic-gate 				do_poll(Pollp, nfds);
129*7c478bd9Sstevel@tonic-gate 			else
130*7c478bd9Sstevel@tonic-gate 				(void) pause();
131*7c478bd9Sstevel@tonic-gate 		}
132*7c478bd9Sstevel@tonic-gate 		/*
133*7c478bd9Sstevel@tonic-gate 		 * READDB messages may arrive during poll or pause.
134*7c478bd9Sstevel@tonic-gate 		 * So the flag needs to be checked again.
135*7c478bd9Sstevel@tonic-gate 		 */
136*7c478bd9Sstevel@tonic-gate 		if (Reread_flag) {
137*7c478bd9Sstevel@tonic-gate 			Reread_flag = FALSE;
138*7c478bd9Sstevel@tonic-gate 			re_read();
139*7c478bd9Sstevel@tonic-gate 		}
140*7c478bd9Sstevel@tonic-gate 		while (Retry) {
141*7c478bd9Sstevel@tonic-gate 			Retry = FALSE;
142*7c478bd9Sstevel@tonic-gate 			open_all();
143*7c478bd9Sstevel@tonic-gate 		}
144*7c478bd9Sstevel@tonic-gate 	}
145*7c478bd9Sstevel@tonic-gate }
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate static	void
148*7c478bd9Sstevel@tonic-gate initialize()
149*7c478bd9Sstevel@tonic-gate {
150*7c478bd9Sstevel@tonic-gate 	struct	pmtab	*tp;
151*7c478bd9Sstevel@tonic-gate 	register struct passwd *pwdp;
152*7c478bd9Sstevel@tonic-gate 	register struct	group	*gp;
153*7c478bd9Sstevel@tonic-gate 	struct	rlimit rlimit;
154*7c478bd9Sstevel@tonic-gate 	extern	struct	rlimit	Rlimit;
155*7c478bd9Sstevel@tonic-gate 	extern	 uid_t	Uucp_uid;
156*7c478bd9Sstevel@tonic-gate 	extern	 gid_t	Tty_gid;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate #ifdef 	DEBUG
159*7c478bd9Sstevel@tonic-gate 	extern	opendebug();
160*7c478bd9Sstevel@tonic-gate #endif
161*7c478bd9Sstevel@tonic-gate 	Initialized = FALSE;
162*7c478bd9Sstevel@tonic-gate 	/*
163*7c478bd9Sstevel@tonic-gate 	 * get_environ() must be called first,
164*7c478bd9Sstevel@tonic-gate 	 * otherwise we don't know where the log file is
165*7c478bd9Sstevel@tonic-gate 	 */
166*7c478bd9Sstevel@tonic-gate 	get_environ();
167*7c478bd9Sstevel@tonic-gate 	openttymonlog();
168*7c478bd9Sstevel@tonic-gate 	openpid();
169*7c478bd9Sstevel@tonic-gate 	openpipes();
170*7c478bd9Sstevel@tonic-gate 	setup_PCpipe();
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 	log("PMTAG: %s", Tag);
173*7c478bd9Sstevel@tonic-gate 	log("Starting state: %s",
174*7c478bd9Sstevel@tonic-gate 	    (State == PM_ENABLED) ? "enabled" : "disabled");
175*7c478bd9Sstevel@tonic-gate 
176*7c478bd9Sstevel@tonic-gate #ifdef 	DEBUG
177*7c478bd9Sstevel@tonic-gate 	opendebug(FALSE);
178*7c478bd9Sstevel@tonic-gate 	debug("***** ttymon in initialize *****");
179*7c478bd9Sstevel@tonic-gate 	log("debug mode is \t on");
180*7c478bd9Sstevel@tonic-gate #endif
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 	catch_signals();
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 	/* register to receive SIGPOLL when data comes to pmpipe */
185*7c478bd9Sstevel@tonic-gate 	if (ioctl(Pfd, I_SETSIG, S_INPUT) < 0)
186*7c478bd9Sstevel@tonic-gate 		fatal("I_SETSIG on pmpipe failed: %s", strerror(errno));
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 	sacpoll(); /* this is needed because there may be data already */
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 	Maxfiles = (int)ulimit(4, 0L);	/* get max number of open files */
191*7c478bd9Sstevel@tonic-gate 	if (Maxfiles < 0)
192*7c478bd9Sstevel@tonic-gate 		fatal("ulimit(4,0L) failed: %s", strerror(errno));
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 	if (getrlimit(RLIMIT_NOFILE, &Rlimit) == -1)
195*7c478bd9Sstevel@tonic-gate 		fatal("getrlimit failed: %s", strerror(errno));
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	rlimit.rlim_cur = rlimit.rlim_max = Rlimit.rlim_max;
198*7c478bd9Sstevel@tonic-gate 	if (setrlimit(RLIMIT_NOFILE, &rlimit) == -1)
199*7c478bd9Sstevel@tonic-gate 		fatal("setrlimit failed: %s", strerror(errno));
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	Maxfiles = rlimit.rlim_cur;
202*7c478bd9Sstevel@tonic-gate 	Maxfds = Maxfiles - FILE_RESERVED;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 	log("max open files = %d", Maxfiles);
205*7c478bd9Sstevel@tonic-gate 	log("max ports ttymon can monitor = %d", Maxfds);
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 	read_pmtab();
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 	/*
210*7c478bd9Sstevel@tonic-gate 	 * setup poll array
211*7c478bd9Sstevel@tonic-gate 	 * 	- we allocate 10 extra pollfd so that
212*7c478bd9Sstevel@tonic-gate 	 *	  we do not have to re-malloc when there is
213*7c478bd9Sstevel@tonic-gate 	 *	  minor fluctuation in Nentries
214*7c478bd9Sstevel@tonic-gate 	 */
215*7c478bd9Sstevel@tonic-gate 	Npollfd = Nentries + 10;
216*7c478bd9Sstevel@tonic-gate 	if (Npollfd > Maxfds)
217*7c478bd9Sstevel@tonic-gate 		Npollfd = Maxfds;
218*7c478bd9Sstevel@tonic-gate 	if ((Pollp = (struct pollfd *)
219*7c478bd9Sstevel@tonic-gate 	    malloc((unsigned)(Npollfd * sizeof (struct pollfd))))
220*7c478bd9Sstevel@tonic-gate 	    == (struct pollfd *)NULL)
221*7c478bd9Sstevel@tonic-gate 		fatal("malloc for Pollp failed");
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate 	(void) mod_ttydefs();	/* just to initialize Mtime */
224*7c478bd9Sstevel@tonic-gate 	if (check_version(TTYDEFS_VERS, TTYDEFS) != 0)
225*7c478bd9Sstevel@tonic-gate 		fatal("check /etc/ttydefs version failed");
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 	read_ttydefs(NULL, FALSE);
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	/* initialize global variables, Uucp_uid & Tty_gid */
230*7c478bd9Sstevel@tonic-gate 	if ((pwdp = getpwnam(UUCP)) != NULL)
231*7c478bd9Sstevel@tonic-gate 		Uucp_uid = pwdp->pw_uid;
232*7c478bd9Sstevel@tonic-gate 	if ((gp = getgrnam(TTY)) == NULL)
233*7c478bd9Sstevel@tonic-gate 		log("no group entry for <tty>, default is used");
234*7c478bd9Sstevel@tonic-gate 	else
235*7c478bd9Sstevel@tonic-gate 		Tty_gid = gp->gr_gid;
236*7c478bd9Sstevel@tonic-gate 	endgrent();
237*7c478bd9Sstevel@tonic-gate 	endpwent();
238*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
239*7c478bd9Sstevel@tonic-gate 	debug("Uucp_uid = %ld, Tty_gid = %ld", Uucp_uid, Tty_gid);
240*7c478bd9Sstevel@tonic-gate #endif
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	log("Initialization Completed");
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	/* open the devices ttymon monitors */
245*7c478bd9Sstevel@tonic-gate 	Retry = TRUE;
246*7c478bd9Sstevel@tonic-gate 	while (Retry) {
247*7c478bd9Sstevel@tonic-gate 		Retry = FALSE;
248*7c478bd9Sstevel@tonic-gate 		for (tp = PMtab; tp; tp = tp->p_next) {
249*7c478bd9Sstevel@tonic-gate 			if ((tp->p_status > 0) && (tp->p_fd == 0) &&
250*7c478bd9Sstevel@tonic-gate 			    (tp->p_pid == 0) && !(tp->p_ttyflags & I_FLAG) &&
251*7c478bd9Sstevel@tonic-gate 			    (!((State == PM_DISABLED) &&
252*7c478bd9Sstevel@tonic-gate 			    ((tp->p_dmsg == NULL)||(*(tp->p_dmsg) == '\0'))))) {
253*7c478bd9Sstevel@tonic-gate 				open_device(tp);
254*7c478bd9Sstevel@tonic-gate 				if (tp->p_fd > 0)
255*7c478bd9Sstevel@tonic-gate 					got_carrier(tp);
256*7c478bd9Sstevel@tonic-gate 			}
257*7c478bd9Sstevel@tonic-gate 		}
258*7c478bd9Sstevel@tonic-gate 	}
259*7c478bd9Sstevel@tonic-gate 	Initialized = TRUE;
260*7c478bd9Sstevel@tonic-gate }
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate /*
263*7c478bd9Sstevel@tonic-gate  *	open_all - open devices in pmtab if the entry is
264*7c478bd9Sstevel@tonic-gate  *	         - valid, fd = 0, and pid = 0
265*7c478bd9Sstevel@tonic-gate  */
266*7c478bd9Sstevel@tonic-gate static void
267*7c478bd9Sstevel@tonic-gate open_all()
268*7c478bd9Sstevel@tonic-gate {
269*7c478bd9Sstevel@tonic-gate 	struct	pmtab	*tp;
270*7c478bd9Sstevel@tonic-gate 	int	check_modtime;
271*7c478bd9Sstevel@tonic-gate 	static	void	free_defs();
272*7c478bd9Sstevel@tonic-gate 	sigset_t cset;
273*7c478bd9Sstevel@tonic-gate 	sigset_t tset;
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
276*7c478bd9Sstevel@tonic-gate 	debug("in open_all");
277*7c478bd9Sstevel@tonic-gate #endif
278*7c478bd9Sstevel@tonic-gate 	check_modtime = TRUE;
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate 	for (tp = PMtab; tp; tp = tp->p_next) {
281*7c478bd9Sstevel@tonic-gate 		if ((tp->p_status > 0) && (tp->p_fd == 0) &&
282*7c478bd9Sstevel@tonic-gate 		    (tp->p_pid == 0) &&
283*7c478bd9Sstevel@tonic-gate 		    !(tp->p_ttyflags & I_FLAG) && (!((State == PM_DISABLED) &&
284*7c478bd9Sstevel@tonic-gate 		    ((tp->p_dmsg == NULL)||(*(tp->p_dmsg) == '\0'))))) {
285*7c478bd9Sstevel@tonic-gate 			/*
286*7c478bd9Sstevel@tonic-gate 			 * if we have not check modification time and
287*7c478bd9Sstevel@tonic-gate 			 * /etc/ttydefs was modified, need to re-read it
288*7c478bd9Sstevel@tonic-gate 			 */
289*7c478bd9Sstevel@tonic-gate 			if (check_modtime && mod_ttydefs()) {
290*7c478bd9Sstevel@tonic-gate 				check_modtime = FALSE;
291*7c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, NULL, &cset);
292*7c478bd9Sstevel@tonic-gate 				tset = cset;
293*7c478bd9Sstevel@tonic-gate 				(void) sigaddset(&tset, SIGCLD);
294*7c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, &tset, NULL);
295*7c478bd9Sstevel@tonic-gate 				free_defs();
296*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
297*7c478bd9Sstevel@tonic-gate 				debug("/etc/ttydefs is modified, re-read it");
298*7c478bd9Sstevel@tonic-gate #endif
299*7c478bd9Sstevel@tonic-gate 				read_ttydefs(NULL, FALSE);
300*7c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, &cset, NULL);
301*7c478bd9Sstevel@tonic-gate 			}
302*7c478bd9Sstevel@tonic-gate 			open_device(tp);
303*7c478bd9Sstevel@tonic-gate 			if (tp->p_fd > 0)
304*7c478bd9Sstevel@tonic-gate 				got_carrier(tp);
305*7c478bd9Sstevel@tonic-gate 		} else if (((tp->p_status == LOCKED) ||
306*7c478bd9Sstevel@tonic-gate 		    (tp->p_status == SESSION) ||
307*7c478bd9Sstevel@tonic-gate 		    (tp->p_status == UNACCESS)) &&
308*7c478bd9Sstevel@tonic-gate 		    (tp->p_fd > 0) &&
309*7c478bd9Sstevel@tonic-gate 		    (!((State == PM_DISABLED) &&
310*7c478bd9Sstevel@tonic-gate 		    ((tp->p_dmsg == NULL)||(*(tp->p_dmsg) == '\0'))))) {
311*7c478bd9Sstevel@tonic-gate 			if (check_modtime && mod_ttydefs()) {
312*7c478bd9Sstevel@tonic-gate 				check_modtime = FALSE;
313*7c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, NULL, &cset);
314*7c478bd9Sstevel@tonic-gate 				tset = cset;
315*7c478bd9Sstevel@tonic-gate 				(void) sigaddset(&tset, SIGCLD);
316*7c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, &tset, NULL);
317*7c478bd9Sstevel@tonic-gate 				free_defs();
318*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
319*7c478bd9Sstevel@tonic-gate 				debug("/etc/ttydefs is modified, re-read it");
320*7c478bd9Sstevel@tonic-gate #endif
321*7c478bd9Sstevel@tonic-gate 				read_ttydefs(NULL, FALSE);
322*7c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, &cset, NULL);
323*7c478bd9Sstevel@tonic-gate 			}
324*7c478bd9Sstevel@tonic-gate 			tp->p_status = VALID;
325*7c478bd9Sstevel@tonic-gate 			open_device(tp);
326*7c478bd9Sstevel@tonic-gate 			if (tp->p_fd > 0)
327*7c478bd9Sstevel@tonic-gate 				got_carrier(tp);
328*7c478bd9Sstevel@tonic-gate 		}
329*7c478bd9Sstevel@tonic-gate 	}
330*7c478bd9Sstevel@tonic-gate }
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate void
333*7c478bd9Sstevel@tonic-gate set_softcar(pmptr)
334*7c478bd9Sstevel@tonic-gate struct	pmtab	*pmptr;
335*7c478bd9Sstevel@tonic-gate {
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 	int fd, val = 0;
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
340*7c478bd9Sstevel@tonic-gate 	debug("in set_softcar");
341*7c478bd9Sstevel@tonic-gate #endif
342*7c478bd9Sstevel@tonic-gate 	/*
343*7c478bd9Sstevel@tonic-gate 	 * If soft carrier is not set one way or
344*7c478bd9Sstevel@tonic-gate 	 * the other, leave it alone.
345*7c478bd9Sstevel@tonic-gate 	 */
346*7c478bd9Sstevel@tonic-gate 	if (*pmptr->p_softcar == '\0')
347*7c478bd9Sstevel@tonic-gate 		return;
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 	if (*pmptr->p_softcar == 'y')
350*7c478bd9Sstevel@tonic-gate 		val = 1;
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 	if ((fd = open(pmptr->p_device, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
353*7c478bd9Sstevel@tonic-gate 		log("open (%s) failed: %s", pmptr->p_device, strerror(errno));
354*7c478bd9Sstevel@tonic-gate 		return;
355*7c478bd9Sstevel@tonic-gate 	}
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 	if (ioctl(fd, TIOCSSOFTCAR, &val) < 0)
358*7c478bd9Sstevel@tonic-gate 		log("set soft-carrier (%s) failed: %s", pmptr->p_device,
359*7c478bd9Sstevel@tonic-gate 		    strerror(errno));
360*7c478bd9Sstevel@tonic-gate 
361*7c478bd9Sstevel@tonic-gate 	close(fd);
362*7c478bd9Sstevel@tonic-gate }
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate /*
366*7c478bd9Sstevel@tonic-gate  *	open_device(pmptr)	- open the device
367*7c478bd9Sstevel@tonic-gate  *				- check device lock
368*7c478bd9Sstevel@tonic-gate  *				- change owner of device
369*7c478bd9Sstevel@tonic-gate  *				- push line disciplines
370*7c478bd9Sstevel@tonic-gate  *				- set termio
371*7c478bd9Sstevel@tonic-gate  */
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate void
374*7c478bd9Sstevel@tonic-gate open_device(pmptr)
375*7c478bd9Sstevel@tonic-gate struct	pmtab	*pmptr;
376*7c478bd9Sstevel@tonic-gate {
377*7c478bd9Sstevel@tonic-gate 	int	fd, tmpfd;
378*7c478bd9Sstevel@tonic-gate 	struct	sigaction	sigact;
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
381*7c478bd9Sstevel@tonic-gate 	debug("in open_device");
382*7c478bd9Sstevel@tonic-gate #endif
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 	if (pmptr->p_status == GETTY) {
385*7c478bd9Sstevel@tonic-gate 		revokedevaccess(pmptr->p_device, 0, 0, 0);
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 		if ((fd = open(pmptr->p_device, O_RDWR)) == -1)
388*7c478bd9Sstevel@tonic-gate 			fatal("open (%s) failed: %s", pmptr->p_device,
389*7c478bd9Sstevel@tonic-gate 			    strerror(errno));
390*7c478bd9Sstevel@tonic-gate 
391*7c478bd9Sstevel@tonic-gate 	} else {
392*7c478bd9Sstevel@tonic-gate 		if (check_spawnlimit(pmptr) == -1) {
393*7c478bd9Sstevel@tonic-gate 			pmptr->p_status = NOTVALID;
394*7c478bd9Sstevel@tonic-gate 			log("service <%s> is respawning too rapidly",
395*7c478bd9Sstevel@tonic-gate 			    pmptr->p_tag);
396*7c478bd9Sstevel@tonic-gate 			return;
397*7c478bd9Sstevel@tonic-gate 		}
398*7c478bd9Sstevel@tonic-gate 		if (pmptr->p_fd > 0) { /* file already open */
399*7c478bd9Sstevel@tonic-gate 			fd = pmptr->p_fd;
400*7c478bd9Sstevel@tonic-gate 			pmptr->p_fd = 0;
401*7c478bd9Sstevel@tonic-gate 		} else if ((fd = open(pmptr->p_device, O_RDWR|O_NONBLOCK))
402*7c478bd9Sstevel@tonic-gate 		    == -1) {
403*7c478bd9Sstevel@tonic-gate 			log("open (%s) failed: %s", pmptr->p_device,
404*7c478bd9Sstevel@tonic-gate 			    strerror(errno));
405*7c478bd9Sstevel@tonic-gate 			if ((errno ==  ENODEV) || (errno == EBUSY)) {
406*7c478bd9Sstevel@tonic-gate 				pmptr->p_status = UNACCESS;
407*7c478bd9Sstevel@tonic-gate 				Nlocked++;
408*7c478bd9Sstevel@tonic-gate 				if (Nlocked == 1) {
409*7c478bd9Sstevel@tonic-gate 				    sigact.sa_flags = 0;
410*7c478bd9Sstevel@tonic-gate 				    sigact.sa_handler = sigalarm;
411*7c478bd9Sstevel@tonic-gate 				    (void) sigemptyset(&sigact.sa_mask);
412*7c478bd9Sstevel@tonic-gate 				    (void) sigaction(SIGALRM, &sigact, NULL);
413*7c478bd9Sstevel@tonic-gate 				    (void) alarm(ALARMTIME);
414*7c478bd9Sstevel@tonic-gate 				}
415*7c478bd9Sstevel@tonic-gate 			} else
416*7c478bd9Sstevel@tonic-gate 				Retry = TRUE;
417*7c478bd9Sstevel@tonic-gate 			return;
418*7c478bd9Sstevel@tonic-gate 		}
419*7c478bd9Sstevel@tonic-gate 		/* set close-on-exec flag */
420*7c478bd9Sstevel@tonic-gate 		if (fcntl(fd, F_SETFD, 1) == -1)
421*7c478bd9Sstevel@tonic-gate 			fatal("F_SETFD fcntl failed: %s", strerror(errno));
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 		if (tm_checklock(fd) != 0) {
424*7c478bd9Sstevel@tonic-gate 			pmptr->p_status = LOCKED;
425*7c478bd9Sstevel@tonic-gate 			(void) close(fd);
426*7c478bd9Sstevel@tonic-gate 			Nlocked++;
427*7c478bd9Sstevel@tonic-gate 			if (Nlocked == 1) {
428*7c478bd9Sstevel@tonic-gate 				sigact.sa_flags = 0;
429*7c478bd9Sstevel@tonic-gate 				sigact.sa_handler = sigalarm;
430*7c478bd9Sstevel@tonic-gate 				(void) sigemptyset(&sigact.sa_mask);
431*7c478bd9Sstevel@tonic-gate 				(void) sigaction(SIGALRM, &sigact, NULL);
432*7c478bd9Sstevel@tonic-gate 				(void) alarm(ALARMTIME);
433*7c478bd9Sstevel@tonic-gate 			}
434*7c478bd9Sstevel@tonic-gate 			return;
435*7c478bd9Sstevel@tonic-gate 		}
436*7c478bd9Sstevel@tonic-gate 		if (check_session(fd) != 0) {
437*7c478bd9Sstevel@tonic-gate 			if ((Initialized) && (pmptr->p_inservice != SESSION)) {
438*7c478bd9Sstevel@tonic-gate 				log("Warning -- active session exists on <%s>",
439*7c478bd9Sstevel@tonic-gate 				    pmptr->p_device);
440*7c478bd9Sstevel@tonic-gate 			} else {
441*7c478bd9Sstevel@tonic-gate 				/*
442*7c478bd9Sstevel@tonic-gate 				 * this may happen if a service is running
443*7c478bd9Sstevel@tonic-gate 				 * and ttymon dies and is restarted,
444*7c478bd9Sstevel@tonic-gate 				 * or another process is running on the
445*7c478bd9Sstevel@tonic-gate 				 * port.
446*7c478bd9Sstevel@tonic-gate 				 */
447*7c478bd9Sstevel@tonic-gate 				pmptr->p_status = SESSION;
448*7c478bd9Sstevel@tonic-gate 				pmptr->p_inservice = 0;
449*7c478bd9Sstevel@tonic-gate 				(void) close(fd);
450*7c478bd9Sstevel@tonic-gate 				Nlocked++;
451*7c478bd9Sstevel@tonic-gate 				if (Nlocked == 1) {
452*7c478bd9Sstevel@tonic-gate 					sigact.sa_flags = 0;
453*7c478bd9Sstevel@tonic-gate 					sigact.sa_handler = sigalarm;
454*7c478bd9Sstevel@tonic-gate 					(void) sigemptyset(&sigact.sa_mask);
455*7c478bd9Sstevel@tonic-gate 					(void) sigaction(SIGALRM, &sigact,
456*7c478bd9Sstevel@tonic-gate 					    NULL);
457*7c478bd9Sstevel@tonic-gate 					(void) alarm(ALARMTIME);
458*7c478bd9Sstevel@tonic-gate 				}
459*7c478bd9Sstevel@tonic-gate 				return;
460*7c478bd9Sstevel@tonic-gate 			}
461*7c478bd9Sstevel@tonic-gate 		}
462*7c478bd9Sstevel@tonic-gate 		pmptr->p_inservice = 0;
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 	if (pmptr->p_ttyflags & H_FLAG) {
466*7c478bd9Sstevel@tonic-gate 		/* drop DTR */
467*7c478bd9Sstevel@tonic-gate 		(void) hang_up_line(fd);
468*7c478bd9Sstevel@tonic-gate 		/*
469*7c478bd9Sstevel@tonic-gate 		 * After hang_up_line, the stream is in STRHUP state.
470*7c478bd9Sstevel@tonic-gate 		 * We need to do another open to reinitialize streams
471*7c478bd9Sstevel@tonic-gate 		 * then we can close one fd
472*7c478bd9Sstevel@tonic-gate 		 */
473*7c478bd9Sstevel@tonic-gate 		if ((tmpfd = open(pmptr->p_device, O_RDWR|O_NONBLOCK)) == -1) {
474*7c478bd9Sstevel@tonic-gate 			log("open (%s) failed: %s", pmptr->p_device,
475*7c478bd9Sstevel@tonic-gate 			    strerror(errno));
476*7c478bd9Sstevel@tonic-gate 			Retry = TRUE;
477*7c478bd9Sstevel@tonic-gate 			(void) close(fd);
478*7c478bd9Sstevel@tonic-gate 			return;
479*7c478bd9Sstevel@tonic-gate 		}
480*7c478bd9Sstevel@tonic-gate 		(void) close(tmpfd);
481*7c478bd9Sstevel@tonic-gate 	}
482*7c478bd9Sstevel@tonic-gate 
483*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
484*7c478bd9Sstevel@tonic-gate 	debug("open_device (%s), fd = %d", pmptr->p_device, fd);
485*7c478bd9Sstevel@tonic-gate #endif
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 	/* Change ownership of the tty line to root/uucp and */
488*7c478bd9Sstevel@tonic-gate 	/* set protections to only allow root/uucp to read the line. */
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate 	if (pmptr->p_ttyflags & (B_FLAG|C_FLAG))
491*7c478bd9Sstevel@tonic-gate 		(void) fchown(fd, Uucp_uid, Tty_gid);
492*7c478bd9Sstevel@tonic-gate 	else
493*7c478bd9Sstevel@tonic-gate 		(void) fchown(fd, ROOTUID, Tty_gid);
494*7c478bd9Sstevel@tonic-gate 	(void) fchmod(fd, 0620);
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate 	if ((pmptr->p_modules != NULL)&&(*(pmptr->p_modules) != '\0')) {
497*7c478bd9Sstevel@tonic-gate 		if (push_linedisc(fd, pmptr->p_modules, pmptr->p_device)
498*7c478bd9Sstevel@tonic-gate 		    == -1) {
499*7c478bd9Sstevel@tonic-gate 			Retry = TRUE;
500*7c478bd9Sstevel@tonic-gate 			(void) close(fd);
501*7c478bd9Sstevel@tonic-gate 			return;
502*7c478bd9Sstevel@tonic-gate 		}
503*7c478bd9Sstevel@tonic-gate 	}
504*7c478bd9Sstevel@tonic-gate 
505*7c478bd9Sstevel@tonic-gate 	if (initial_termio(fd, pmptr) == -1)  {
506*7c478bd9Sstevel@tonic-gate 		Retry = TRUE;
507*7c478bd9Sstevel@tonic-gate 		(void) close(fd);
508*7c478bd9Sstevel@tonic-gate 		return;
509*7c478bd9Sstevel@tonic-gate 	}
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate 	di_devperm_logout((const char *)pmptr->p_device);
512*7c478bd9Sstevel@tonic-gate 	pmptr->p_fd = fd;
513*7c478bd9Sstevel@tonic-gate }
514*7c478bd9Sstevel@tonic-gate 
515*7c478bd9Sstevel@tonic-gate /*
516*7c478bd9Sstevel@tonic-gate  *	set_poll(fdp)	- put all fd's in a pollfd array
517*7c478bd9Sstevel@tonic-gate  *			- set poll event to POLLIN and POLLMSG
518*7c478bd9Sstevel@tonic-gate  *			- return number of fd to be polled
519*7c478bd9Sstevel@tonic-gate  */
520*7c478bd9Sstevel@tonic-gate 
521*7c478bd9Sstevel@tonic-gate static	int
522*7c478bd9Sstevel@tonic-gate set_poll(fdp)
523*7c478bd9Sstevel@tonic-gate struct pollfd *fdp;
524*7c478bd9Sstevel@tonic-gate {
525*7c478bd9Sstevel@tonic-gate 	struct	pmtab	*tp;
526*7c478bd9Sstevel@tonic-gate 	int 	nfd = 0;
527*7c478bd9Sstevel@tonic-gate 
528*7c478bd9Sstevel@tonic-gate 	for (tp = PMtab; tp; tp = tp->p_next) {
529*7c478bd9Sstevel@tonic-gate 		if (tp->p_fd > 0)  {
530*7c478bd9Sstevel@tonic-gate 			fdp->fd = tp->p_fd;
531*7c478bd9Sstevel@tonic-gate 			fdp->events = POLLIN;
532*7c478bd9Sstevel@tonic-gate 			fdp++;
533*7c478bd9Sstevel@tonic-gate 			nfd++;
534*7c478bd9Sstevel@tonic-gate 		}
535*7c478bd9Sstevel@tonic-gate 	}
536*7c478bd9Sstevel@tonic-gate 	return (nfd);
537*7c478bd9Sstevel@tonic-gate }
538*7c478bd9Sstevel@tonic-gate 
539*7c478bd9Sstevel@tonic-gate /*
540*7c478bd9Sstevel@tonic-gate  *	check_spawnlimit	- return 0 if spawnlimit is not reached
541*7c478bd9Sstevel@tonic-gate  *				- otherwise return -1
542*7c478bd9Sstevel@tonic-gate  */
543*7c478bd9Sstevel@tonic-gate static	int
544*7c478bd9Sstevel@tonic-gate check_spawnlimit(pmptr)
545*7c478bd9Sstevel@tonic-gate struct	pmtab	*pmptr;
546*7c478bd9Sstevel@tonic-gate {
547*7c478bd9Sstevel@tonic-gate 	time_t	now;
548*7c478bd9Sstevel@tonic-gate 
549*7c478bd9Sstevel@tonic-gate 	(void) time(&now);
550*7c478bd9Sstevel@tonic-gate 	if (pmptr->p_time == 0L)
551*7c478bd9Sstevel@tonic-gate 		pmptr->p_time = now;
552*7c478bd9Sstevel@tonic-gate 	if (pmptr->p_respawn >= SPAWN_LIMIT) {
553*7c478bd9Sstevel@tonic-gate 		if ((now - pmptr->p_time) < SPAWN_INTERVAL) {
554*7c478bd9Sstevel@tonic-gate 			pmptr->p_time = now;
555*7c478bd9Sstevel@tonic-gate 			pmptr->p_respawn = 0;
556*7c478bd9Sstevel@tonic-gate 			return (-1);
557*7c478bd9Sstevel@tonic-gate 		}
558*7c478bd9Sstevel@tonic-gate 		pmptr->p_time = now;
559*7c478bd9Sstevel@tonic-gate 		pmptr->p_respawn = 0;
560*7c478bd9Sstevel@tonic-gate 	}
561*7c478bd9Sstevel@tonic-gate 	pmptr->p_respawn++;
562*7c478bd9Sstevel@tonic-gate 	return (0);
563*7c478bd9Sstevel@tonic-gate }
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate /*
566*7c478bd9Sstevel@tonic-gate  * mod_ttydefs	- to check if /etc/ttydefs has been modified
567*7c478bd9Sstevel@tonic-gate  *		- return TRUE if file modified
568*7c478bd9Sstevel@tonic-gate  *		- otherwise, return FALSE
569*7c478bd9Sstevel@tonic-gate  */
570*7c478bd9Sstevel@tonic-gate static	int
571*7c478bd9Sstevel@tonic-gate mod_ttydefs()
572*7c478bd9Sstevel@tonic-gate {
573*7c478bd9Sstevel@tonic-gate 	struct	stat	statbuf;
574*7c478bd9Sstevel@tonic-gate 	extern	long	Mtime;
575*7c478bd9Sstevel@tonic-gate 	if (stat(TTYDEFS, &statbuf) == -1) {
576*7c478bd9Sstevel@tonic-gate 		/* if stat failed, don't bother reread ttydefs */
577*7c478bd9Sstevel@tonic-gate 		return (FALSE);
578*7c478bd9Sstevel@tonic-gate 	}
579*7c478bd9Sstevel@tonic-gate 	if ((long)statbuf.st_mtime != Mtime) {
580*7c478bd9Sstevel@tonic-gate 		Mtime = (long)statbuf.st_mtime;
581*7c478bd9Sstevel@tonic-gate 		return (TRUE);
582*7c478bd9Sstevel@tonic-gate 	}
583*7c478bd9Sstevel@tonic-gate 	return (FALSE);
584*7c478bd9Sstevel@tonic-gate }
585*7c478bd9Sstevel@tonic-gate 
586*7c478bd9Sstevel@tonic-gate /*
587*7c478bd9Sstevel@tonic-gate  *	free_defs - free the Gdef table
588*7c478bd9Sstevel@tonic-gate  */
589*7c478bd9Sstevel@tonic-gate static	void
590*7c478bd9Sstevel@tonic-gate free_defs()
591*7c478bd9Sstevel@tonic-gate {
592*7c478bd9Sstevel@tonic-gate 	int	i;
593*7c478bd9Sstevel@tonic-gate 	struct	Gdef	*tp;
594*7c478bd9Sstevel@tonic-gate 	tp = &Gdef[0];
595*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < Ndefs; i++, tp++) {
596*7c478bd9Sstevel@tonic-gate 		free(tp->g_id);
597*7c478bd9Sstevel@tonic-gate 		free(tp->g_iflags);
598*7c478bd9Sstevel@tonic-gate 		free(tp->g_fflags);
599*7c478bd9Sstevel@tonic-gate 		free(tp->g_nextid);
600*7c478bd9Sstevel@tonic-gate 		tp->g_id = NULL;
601*7c478bd9Sstevel@tonic-gate 		tp->g_iflags = NULL;
602*7c478bd9Sstevel@tonic-gate 		tp->g_fflags = NULL;
603*7c478bd9Sstevel@tonic-gate 		tp->g_nextid = NULL;
604*7c478bd9Sstevel@tonic-gate 	}
605*7c478bd9Sstevel@tonic-gate 	Ndefs = 0;
606*7c478bd9Sstevel@tonic-gate }
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate /*
609*7c478bd9Sstevel@tonic-gate  * struct Gdef *get_speed(ttylabel)
610*7c478bd9Sstevel@tonic-gate  *	- search "/etc/ttydefs" for speed and term. specification
611*7c478bd9Sstevel@tonic-gate  *	  using "ttylabel". If "ttylabel" is NULL, default
612*7c478bd9Sstevel@tonic-gate  *	  to DEFAULT
613*7c478bd9Sstevel@tonic-gate  * arg:	  ttylabel - label/id of speed settings.
614*7c478bd9Sstevel@tonic-gate  */
615*7c478bd9Sstevel@tonic-gate 
616*7c478bd9Sstevel@tonic-gate struct Gdef *
617*7c478bd9Sstevel@tonic-gate get_speed(char *ttylabel)
618*7c478bd9Sstevel@tonic-gate {
619*7c478bd9Sstevel@tonic-gate 	register struct Gdef *sp;
620*7c478bd9Sstevel@tonic-gate 	extern   struct Gdef DEFAULT;
621*7c478bd9Sstevel@tonic-gate 
622*7c478bd9Sstevel@tonic-gate 	if ((ttylabel != NULL) && (*ttylabel != '\0')) {
623*7c478bd9Sstevel@tonic-gate 		if ((sp = find_def(ttylabel)) == NULL) {
624*7c478bd9Sstevel@tonic-gate 			log("unable to find <%s> in \"%s\"", ttylabel, TTYDEFS);
625*7c478bd9Sstevel@tonic-gate 			sp = &DEFAULT; /* use default */
626*7c478bd9Sstevel@tonic-gate 		}
627*7c478bd9Sstevel@tonic-gate 	} else sp = &DEFAULT; /* use default */
628*7c478bd9Sstevel@tonic-gate 	return (sp);
629*7c478bd9Sstevel@tonic-gate }
630*7c478bd9Sstevel@tonic-gate 
631*7c478bd9Sstevel@tonic-gate /*
632*7c478bd9Sstevel@tonic-gate  * setup_PCpipe()	- setup the pipe between Parent and Children
633*7c478bd9Sstevel@tonic-gate  *			- the pipe is used for a tmchild to send its
634*7c478bd9Sstevel@tonic-gate  *			  pid to inform ttymon that it is about to
635*7c478bd9Sstevel@tonic-gate  *			  invoke service
636*7c478bd9Sstevel@tonic-gate  *			- the pipe also serves as a mean for tmchild
637*7c478bd9Sstevel@tonic-gate  *			  to detect failure of ttymon
638*7c478bd9Sstevel@tonic-gate  */
639*7c478bd9Sstevel@tonic-gate void
640*7c478bd9Sstevel@tonic-gate setup_PCpipe()
641*7c478bd9Sstevel@tonic-gate {
642*7c478bd9Sstevel@tonic-gate 	int	flag = 0;
643*7c478bd9Sstevel@tonic-gate 
644*7c478bd9Sstevel@tonic-gate 	if (pipe(PCpipe) == -1)
645*7c478bd9Sstevel@tonic-gate 		fatal("pipe() failed: %s", strerror(errno));
646*7c478bd9Sstevel@tonic-gate 
647*7c478bd9Sstevel@tonic-gate 	/* set close-on-exec flag */
648*7c478bd9Sstevel@tonic-gate 	if (fcntl(PCpipe[0], F_SETFD, 1) == -1)
649*7c478bd9Sstevel@tonic-gate 		fatal("F_SETFD fcntl failed: %s", strerror(errno));
650*7c478bd9Sstevel@tonic-gate 
651*7c478bd9Sstevel@tonic-gate 	if (fcntl(PCpipe[1], F_SETFD, 1) == -1)
652*7c478bd9Sstevel@tonic-gate 		fatal("F_SETFD fcntl failed: %s", strerror(errno));
653*7c478bd9Sstevel@tonic-gate 
654*7c478bd9Sstevel@tonic-gate 	/* set O_NONBLOCK flag */
655*7c478bd9Sstevel@tonic-gate 	if (fcntl(PCpipe[0], F_GETFL, flag) == -1)
656*7c478bd9Sstevel@tonic-gate 		fatal("F_GETFL failed: %s", strerror(errno));
657*7c478bd9Sstevel@tonic-gate 
658*7c478bd9Sstevel@tonic-gate 	flag |= O_NONBLOCK;
659*7c478bd9Sstevel@tonic-gate 	if (fcntl(PCpipe[0], F_SETFL, flag) == -1)
660*7c478bd9Sstevel@tonic-gate 		fatal("F_SETFL failed: %s", strerror(errno));
661*7c478bd9Sstevel@tonic-gate 
662*7c478bd9Sstevel@tonic-gate 	/* set message discard mode */
663*7c478bd9Sstevel@tonic-gate 	if (ioctl(PCpipe[0], I_SRDOPT, RMSGD) == -1)
664*7c478bd9Sstevel@tonic-gate 		fatal("I_SRDOPT RMSGD failed: %s", strerror(errno));
665*7c478bd9Sstevel@tonic-gate 
666*7c478bd9Sstevel@tonic-gate 	/* register to receive SIGPOLL when data come */
667*7c478bd9Sstevel@tonic-gate 	if (ioctl(PCpipe[0], I_SETSIG, S_INPUT) == -1)
668*7c478bd9Sstevel@tonic-gate 		fatal("I_SETSIG S_INPUT failed: %s", strerror(errno));
669*7c478bd9Sstevel@tonic-gate 
670*7c478bd9Sstevel@tonic-gate #ifdef 	DEBUG
671*7c478bd9Sstevel@tonic-gate 	log("PCpipe[0]\t = %d", PCpipe[0]);
672*7c478bd9Sstevel@tonic-gate 	log("PCpipe[1]\t = %d", PCpipe[1]);
673*7c478bd9Sstevel@tonic-gate #endif
674*7c478bd9Sstevel@tonic-gate }
675