xref: /illumos-gate/usr/src/cmd/ttymon/tmsac.c (revision 3bb2c156)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27*3bb2c156SToomas Soome /*	  All Rights Reserved	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <errno.h>
327c478bd9Sstevel@tonic-gate #include <fcntl.h>
337c478bd9Sstevel@tonic-gate #include <signal.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <unistd.h>
36*3bb2c156SToomas Soome #include "ttymon.h"
37*3bb2c156SToomas Soome #include "tmextern.h"
38*3bb2c156SToomas Soome #include "sac.h"
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  *	openpid	- open the pid and put ttymon's pid in it
42*3bb2c156SToomas Soome  *		- put an advisory lock on the file
437c478bd9Sstevel@tonic-gate  *		- to prevent another instance of ttymon in same directory
447c478bd9Sstevel@tonic-gate  *		- SAC also makes use of the lock
457c478bd9Sstevel@tonic-gate  *		- fd 0 is reserved for pid file
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate void
openpid(void)48*3bb2c156SToomas Soome openpid(void)
497c478bd9Sstevel@tonic-gate {
507c478bd9Sstevel@tonic-gate 	char lockbuf[16];	/* large enough for a PID string */
517c478bd9Sstevel@tonic-gate 
52*3bb2c156SToomas Soome 	(void) close(0);
53*3bb2c156SToomas Soome 	/* open for read first, otherwise, may delete the pid already there */
547c478bd9Sstevel@tonic-gate 	if ((Lckfd = open(PIDFILE, O_RDONLY)) != -1) {
55*3bb2c156SToomas Soome 		if (lockf(Lckfd, F_TEST, 0L) == -1)
567c478bd9Sstevel@tonic-gate 			fatal("pid file is locked. ttymon may already be "
577c478bd9Sstevel@tonic-gate 			    "running!");
58*3bb2c156SToomas Soome 		(void) close(Lckfd);
597c478bd9Sstevel@tonic-gate 	}
607c478bd9Sstevel@tonic-gate 
61*3bb2c156SToomas Soome 	if ((Lckfd = open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0644)) != 0)
627c478bd9Sstevel@tonic-gate 		fatal("open pid file failed: %s", strerror(errno));
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	if (lockf(Lckfd, F_LOCK, 0L) == -1)
657c478bd9Sstevel@tonic-gate 		fatal("lock pid file failed: %s", strerror(errno));
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	(void) snprintf(lockbuf, sizeof (lockbuf), "%ld", getpid());
687c478bd9Sstevel@tonic-gate 	(void) write(Lckfd, lockbuf, strlen(lockbuf) + 1);
697c478bd9Sstevel@tonic-gate #ifdef	DEBUG
707c478bd9Sstevel@tonic-gate 	log("fd(pid)\t = %d", Lckfd);
717c478bd9Sstevel@tonic-gate #endif
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate  * openpipes() -- open pmpipe and sacpipe to communicate with SAC
767c478bd9Sstevel@tonic-gate  *	       -- Pfd, Sfd are global file descriptors for pmpipe, sacpipe
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate void
openpipes(void)80*3bb2c156SToomas Soome openpipes(void)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	Sfd = open(SACPIPE, O_WRONLY);
837c478bd9Sstevel@tonic-gate 	if (Sfd < 0)
847c478bd9Sstevel@tonic-gate 		fatal("open sacpipe failed: %s", strerror(errno));
857c478bd9Sstevel@tonic-gate 
86*3bb2c156SToomas Soome 	Pfd = open(PMPIPE, O_RDWR|O_NONBLOCK);
877c478bd9Sstevel@tonic-gate 	if (Pfd < 0)
887c478bd9Sstevel@tonic-gate 		fatal("open pmpipe failed: %s", strerror(errno));
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate #ifdef	DEBUG
91*3bb2c156SToomas Soome 	log("fd(sacpipe)\t = %d", Sfd);
92*3bb2c156SToomas Soome 	log("fd(pmpipe)\t = %d", Pfd);
937c478bd9Sstevel@tonic-gate #endif
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * remove_env(env) - remove an environment variable from the environment
987c478bd9Sstevel@tonic-gate  */
997c478bd9Sstevel@tonic-gate static	void
remove_env(char * env)100*3bb2c156SToomas Soome remove_env(char *env)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 	char	**p;
1037c478bd9Sstevel@tonic-gate 	char	**rp = NULL;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	p = environ;
1067c478bd9Sstevel@tonic-gate 	if (p == NULL)
1077c478bd9Sstevel@tonic-gate 		return;
1087c478bd9Sstevel@tonic-gate 	while (*p) {
109*3bb2c156SToomas Soome 		if (strncmp(*p, env, strlen(env)) == 0)
1107c478bd9Sstevel@tonic-gate 			rp = p;
1117c478bd9Sstevel@tonic-gate 		p++;
1127c478bd9Sstevel@tonic-gate 	}
1137c478bd9Sstevel@tonic-gate 	if (rp) {
1147c478bd9Sstevel@tonic-gate 		*rp = *--p;
1157c478bd9Sstevel@tonic-gate 		*p = NULL;
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate /*
1207c478bd9Sstevel@tonic-gate  * get_environ() -- get env variables PMTAG, ISTATE
1217c478bd9Sstevel@tonic-gate  *		 -- set global variables Tag, State
1227c478bd9Sstevel@tonic-gate  */
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate void
get_environ(void)125*3bb2c156SToomas Soome get_environ(void)
1267c478bd9Sstevel@tonic-gate {
1277c478bd9Sstevel@tonic-gate 	if ((Tag = getenv("PMTAG")) == NULL)
128*3bb2c156SToomas Soome 		fatal("PMTAG is missing");
1297c478bd9Sstevel@tonic-gate 
130*3bb2c156SToomas Soome 	if ((Istate = getenv("ISTATE")) == NULL)
1317c478bd9Sstevel@tonic-gate 		fatal("ISTATE is missing");
1327c478bd9Sstevel@tonic-gate 
133*3bb2c156SToomas Soome 	State = (strcmp(Istate, "enabled") == 0) ? PM_ENABLED : PM_DISABLED;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	/*
1367c478bd9Sstevel@tonic-gate 	 * remove the environment variables so they will not
1377c478bd9Sstevel@tonic-gate 	 * be passed to the children
1387c478bd9Sstevel@tonic-gate 	 */
1397c478bd9Sstevel@tonic-gate 	remove_env("ISTATE");
1407c478bd9Sstevel@tonic-gate 	remove_env("PMTAG");
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate  * sacpoll	- the event handler when sac event is posted
1457c478bd9Sstevel@tonic-gate  */
1467c478bd9Sstevel@tonic-gate void
sacpoll(void)147*3bb2c156SToomas Soome sacpoll(void)
1487c478bd9Sstevel@tonic-gate {
149*3bb2c156SToomas Soome 	int	ret;
1507c478bd9Sstevel@tonic-gate 	char	oldState;
151*3bb2c156SToomas Soome 	struct	sacmsg sacmsg;
152*3bb2c156SToomas Soome 	struct	pmmsg pmmsg;
1537c478bd9Sstevel@tonic-gate 	sigset_t	cset;
1547c478bd9Sstevel@tonic-gate 	sigset_t	tset;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate #ifdef	DEBUG
1577c478bd9Sstevel@tonic-gate 	debug("in sacpoll");
1587c478bd9Sstevel@tonic-gate #endif
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	/* we don't want to be interrupted by sigchild now */
161*3bb2c156SToomas Soome 	(void) sigprocmask(SIG_SETMASK, NULL, &cset);
1627c478bd9Sstevel@tonic-gate 	tset = cset;
163*3bb2c156SToomas Soome 	(void) sigaddset(&tset, SIGCLD);
164*3bb2c156SToomas Soome 	(void) sigprocmask(SIG_SETMASK, &tset, NULL);
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 	/*
1677c478bd9Sstevel@tonic-gate 	 *	read sac messages, one at a time until no message
1687c478bd9Sstevel@tonic-gate 	 *	is left on the pipe.
1697c478bd9Sstevel@tonic-gate 	 *	the pipe is open with O_NONBLOCK, read will return -1
1707c478bd9Sstevel@tonic-gate 	 *	and errno = EAGAIN if nothing is on the pipe
1717c478bd9Sstevel@tonic-gate 	 */
1727c478bd9Sstevel@tonic-gate 	for (;;) {
1737c478bd9Sstevel@tonic-gate 
174*3bb2c156SToomas Soome 		ret = read(Pfd, &sacmsg, sizeof (sacmsg));
1757c478bd9Sstevel@tonic-gate 		if (ret < 0) {
176*3bb2c156SToomas Soome 			switch (errno) {
1777c478bd9Sstevel@tonic-gate 			case EAGAIN:
1787c478bd9Sstevel@tonic-gate 				/* no more data on the pipe */
179*3bb2c156SToomas Soome 				(void) sigprocmask(SIG_SETMASK, &cset, NULL);
1807c478bd9Sstevel@tonic-gate 				return;
1817c478bd9Sstevel@tonic-gate 			case EINTR:
1827c478bd9Sstevel@tonic-gate 				break;
183*3bb2c156SToomas Soome 			default:
1847c478bd9Sstevel@tonic-gate 				fatal("pmpipe read failed: %s",
1857c478bd9Sstevel@tonic-gate 				    strerror(errno));
1867c478bd9Sstevel@tonic-gate 				break;  /*NOTREACHED*/
1877c478bd9Sstevel@tonic-gate 			}
188*3bb2c156SToomas Soome 		} else if (ret == 0) {
1897c478bd9Sstevel@tonic-gate 			/* no more data on the pipe */
190*3bb2c156SToomas Soome 			(void) sigprocmask(SIG_SETMASK, &cset, NULL);
1917c478bd9Sstevel@tonic-gate 			return;
192*3bb2c156SToomas Soome 		} else {
1937c478bd9Sstevel@tonic-gate 			pmmsg.pm_size = 0;
1947c478bd9Sstevel@tonic-gate 			(void) strcpy(pmmsg.pm_tag, Tag);
1957c478bd9Sstevel@tonic-gate 			pmmsg.pm_maxclass = TM_MAXCLASS;
1967c478bd9Sstevel@tonic-gate 			pmmsg.pm_type = PM_STATUS;
197*3bb2c156SToomas Soome 			switch (sacmsg.sc_type) {
1987c478bd9Sstevel@tonic-gate 			case SC_STATUS:
1997c478bd9Sstevel@tonic-gate 				break;
2007c478bd9Sstevel@tonic-gate 			case SC_ENABLE:
2017c478bd9Sstevel@tonic-gate 				log("Got SC_ENABLE message");
2027c478bd9Sstevel@tonic-gate 				oldState = State;
2037c478bd9Sstevel@tonic-gate 				State = PM_ENABLED;
204*3bb2c156SToomas Soome 				if (State != oldState) {
2057c478bd9Sstevel@tonic-gate #ifdef	DEBUG
2067c478bd9Sstevel@tonic-gate 					debug("state changed to ENABLED");
2077c478bd9Sstevel@tonic-gate #endif
2087c478bd9Sstevel@tonic-gate 					state_change();
2097c478bd9Sstevel@tonic-gate 				}
2107c478bd9Sstevel@tonic-gate 				break;
2117c478bd9Sstevel@tonic-gate 			case SC_DISABLE:
2127c478bd9Sstevel@tonic-gate 				log("Got SC_DISABLE message");
2137c478bd9Sstevel@tonic-gate 				oldState = State;
2147c478bd9Sstevel@tonic-gate 				State = PM_DISABLED;
215*3bb2c156SToomas Soome 				if (State != oldState) {
2167c478bd9Sstevel@tonic-gate #ifdef	DEBUG
2177c478bd9Sstevel@tonic-gate 					debug("state changed to DISABLED");
2187c478bd9Sstevel@tonic-gate #endif
2197c478bd9Sstevel@tonic-gate 					state_change();
2207c478bd9Sstevel@tonic-gate 				}
2217c478bd9Sstevel@tonic-gate 				break;
2227c478bd9Sstevel@tonic-gate 			case SC_READDB:
2237c478bd9Sstevel@tonic-gate 				log("Got SC_READDB message");
2247c478bd9Sstevel@tonic-gate 				Reread_flag = 1;
2257c478bd9Sstevel@tonic-gate 				break;
2267c478bd9Sstevel@tonic-gate 			default:
2277c478bd9Sstevel@tonic-gate 				log("Got unknown message %d", sacmsg.sc_type);
2287c478bd9Sstevel@tonic-gate 				pmmsg.pm_type = PM_UNKNOWN;
2297c478bd9Sstevel@tonic-gate 				break;
2307c478bd9Sstevel@tonic-gate 			} /* end switch */
2317c478bd9Sstevel@tonic-gate 			pmmsg.pm_state = State;
2327c478bd9Sstevel@tonic-gate 
233*3bb2c156SToomas Soome 			while (write(Sfd, &pmmsg, sizeof (pmmsg)) !=
234*3bb2c156SToomas Soome 			    sizeof (pmmsg)) {
2357c478bd9Sstevel@tonic-gate 				if (errno == EINTR)
2367c478bd9Sstevel@tonic-gate 					continue;
2377c478bd9Sstevel@tonic-gate 				log("sanity response to SAC failed: %s",
2387c478bd9Sstevel@tonic-gate 				    strerror(errno));
2397c478bd9Sstevel@tonic-gate 				break;
2407c478bd9Sstevel@tonic-gate 			}
2417c478bd9Sstevel@tonic-gate 		}
2427c478bd9Sstevel@tonic-gate 	} /* end for loop */
2437c478bd9Sstevel@tonic-gate }
244