8706 libc lint library missing endian.h functions
[unleashed.git] / usr / src / cmd / ttymon / tmsac.c
blob70002031421e09245489e76d6250e52a18ffe9b9
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include "ttymon.h"
41 #include "tmextern.h"
42 #include "sac.h"
45 * openpid - open the pid and put ttymon's pid in it
46 * - put an advisory lock on the file
47 * - to prevent another instance of ttymon in same directory
48 * - SAC also makes use of the lock
49 * - fd 0 is reserved for pid file
51 void
52 openpid()
54 extern int Lckfd;
55 char lockbuf[16]; /* large enough for a PID string */
57 (void)close(0);
58 /* open for read first, otherwise, may delete the pid already there*/
59 if ((Lckfd = open(PIDFILE, O_RDONLY)) != -1) {
60 if (lockf(Lckfd, F_TEST, 0L) == -1)
61 fatal("pid file is locked. ttymon may already be "
62 "running!");
63 (void)close(Lckfd);
66 if ((Lckfd = open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0644 )) != 0)
67 fatal("open pid file failed: %s", strerror(errno));
69 if (lockf(Lckfd, F_LOCK, 0L) == -1)
70 fatal("lock pid file failed: %s", strerror(errno));
72 (void) snprintf(lockbuf, sizeof (lockbuf), "%ld", getpid());
73 (void) write(Lckfd, lockbuf, strlen(lockbuf) + 1);
74 #ifdef DEBUG
75 log("fd(pid)\t = %d", Lckfd);
76 #endif
80 * openpipes() -- open pmpipe and sacpipe to communicate with SAC
81 * -- Pfd, Sfd are global file descriptors for pmpipe, sacpipe
84 void
85 openpipes()
87 extern int Pfd, Sfd;
89 Sfd = open(SACPIPE, O_WRONLY);
90 if (Sfd < 0)
91 fatal("open sacpipe failed: %s", strerror(errno));
93 Pfd = open(PMPIPE, O_RDWR|O_NONBLOCK);
94 if (Pfd < 0)
95 fatal("open pmpipe failed: %s", strerror(errno));
97 #ifdef DEBUG
98 log("fd(sacpipe)\t = %d",Sfd);
99 log("fd(pmpipe)\t = %d",Pfd);
100 #endif
104 * remove_env(env) - remove an environment variable from the environment
106 static void
107 remove_env(env)
108 char *env;
110 extern char **environ;
111 char **p;
112 char **rp = NULL;
114 p = environ;
115 if (p == NULL)
116 return;
117 while (*p) {
118 if (strncmp(*p, env,strlen(env)) == 0)
119 rp = p;
120 p++;
122 if (rp) {
123 *rp = *--p;
124 *p = NULL;
129 * get_environ() -- get env variables PMTAG, ISTATE
130 * -- set global variables Tag, State
133 void
134 get_environ()
136 extern char State, *Istate, *Tag;
138 if ((Tag = getenv("PMTAG")) == NULL)
139 fatal("PMTAG is missing");
141 if ((Istate = getenv("ISTATE")) == NULL)
142 fatal("ISTATE is missing");
144 State = (!strcmp(Istate, "enabled")) ? PM_ENABLED : PM_DISABLED;
147 * remove the environment variables so they will not
148 * be passed to the children
150 remove_env("ISTATE");
151 remove_env("PMTAG");
155 * sacpoll - the event handler when sac event is posted
157 void
158 sacpoll()
160 int ret;
161 char oldState;
162 struct sacmsg sacmsg;
163 struct pmmsg pmmsg;
164 sigset_t cset;
165 sigset_t tset;
167 #ifdef DEBUG
168 debug("in sacpoll");
169 #endif
171 /* we don't want to be interrupted by sigchild now */
172 (void)sigprocmask(SIG_SETMASK, NULL, &cset);
173 tset = cset;
174 (void)sigaddset(&tset, SIGCLD);
175 (void)sigprocmask(SIG_SETMASK, &tset, NULL);
178 * read sac messages, one at a time until no message
179 * is left on the pipe.
180 * the pipe is open with O_NONBLOCK, read will return -1
181 * and errno = EAGAIN if nothing is on the pipe
183 for (;;) {
185 ret = read(Pfd, &sacmsg, sizeof(sacmsg));
186 if (ret < 0) {
187 switch(errno) {
188 case EAGAIN:
189 /* no more data on the pipe */
190 (void)sigprocmask(SIG_SETMASK, &cset, NULL);
191 return;
192 case EINTR:
193 break;
194 default:
195 fatal("pmpipe read failed: %s",
196 strerror(errno));
197 break; /*NOTREACHED*/
200 else if (ret == 0) {
201 /* no more data on the pipe */
202 (void)sigprocmask(SIG_SETMASK, &cset, NULL);
203 return;
205 else {
206 pmmsg.pm_size = 0;
207 (void) strcpy(pmmsg.pm_tag, Tag);
208 pmmsg.pm_maxclass = TM_MAXCLASS;
209 pmmsg.pm_type = PM_STATUS;
210 switch(sacmsg.sc_type) {
211 case SC_STATUS:
212 break;
213 case SC_ENABLE:
214 log("Got SC_ENABLE message");
215 oldState = State;
216 State = PM_ENABLED;
217 if (State != oldState) {
218 #ifdef DEBUG
219 debug("state changed to ENABLED");
220 #endif
221 state_change();
223 break;
224 case SC_DISABLE:
225 log("Got SC_DISABLE message");
226 oldState = State;
227 State = PM_DISABLED;
228 if (State != oldState) {
229 #ifdef DEBUG
230 debug("state changed to DISABLED");
231 #endif
232 state_change();
234 break;
235 case SC_READDB:
236 log("Got SC_READDB message");
237 Reread_flag = 1;
238 break;
239 default:
240 log("Got unknown message %d", sacmsg.sc_type);
241 pmmsg.pm_type = PM_UNKNOWN;
242 break;
243 } /* end switch */
244 pmmsg.pm_state = State;
246 while (write(Sfd, &pmmsg, sizeof(pmmsg)) != sizeof(pmmsg)) {
247 if (errno == EINTR)
248 continue;
249 log("sanity response to SAC failed: %s",
250 strerror(errno));
251 break;
254 } /* end for loop */