libc: make stdio_impl.h an internal libc header
[unleashed/tickless.git] / usr / src / lib / efcode / efdaemon / efdaemon.c
blob2450d2d1fac8dadf87d46a1d8feba24bdd774579
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 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * efdaemon - Emebbed Fcode Interpreter daemon.
32 * Opens /dev/fcode, detaches from tty and reads a request. Upon successful
33 * return, invokes the Fcode interpreter via the shell script:
34 * /usr/lib/efcode/efcode.sh Waits for completion of the interpreter.
37 #include <stdio.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41 #include <strings.h>
42 #include <syslog.h>
43 #include <errno.h>
44 #include <sys/wait.h>
45 #include <sys/fcode.h>
47 char efcode_sh_file[] = "/usr/lib/efcode/efcode.sh";
48 char dev_fcode_file[] = "/dev/fcode";
50 int debug = 0;
52 int
53 main(int argc, char **argv)
55 extern char *optarg;
56 extern int optind, opterr, optopt;
57 int c, fd, nbytes, status;
58 char tc;
59 pid_t pid, tpid;
60 long nerr = 0;
61 int error;
63 openlog("efdaemon", LOG_PID|LOG_CONS, LOG_DAEMON);
65 while ((c = getopt(argc, argv, "d")) != EOF) {
66 switch (c) {
68 case 'd':
69 debug++;
70 break;
72 case '?':
73 syslog(LOG_ERR, "Usage: efdaemon [ -d ]\n");
74 exit(1);
79 * Ensure we can open /dev/fcode
81 if ((fd = open(dev_fcode_file, O_RDONLY)) < 0) {
83 * Only output message if debug is on. On most systems,
84 * /dev/fcode will not exist, so this message would pollute the
85 * console.
87 if (debug)
88 syslog(LOG_ERR, "Can't open %s: %s\n", dev_fcode_file,
89 strerror(errno));
90 exit(1);
92 close(fd);
95 * Ensure that /usr/lib/efcode/efcode.sh exists and is executable.
97 if (access(efcode_sh_file, X_OK | R_OK)) {
98 syslog(LOG_ERR, "%s: %s\n", efcode_sh_file, strerror(errno));
99 exit(1);
103 * Fork a child then parent exits so we're a child of initd.
105 if ((pid = fork()) < 0) {
106 syslog(LOG_ERR, "Fork failed: %s\n", strerror(errno));
107 exit(1);
109 if (pid)
110 exit(0);
114 * detach from tty here.
116 setpgrp();
117 close(0);
118 close(1);
119 close(2);
120 (void) open("/dev/null", O_RDWR);
121 (void) dup(0);
122 (void) dup(0);
124 for (;;) {
125 while ((fd = open(dev_fcode_file, O_RDONLY)) < 0) {
126 nerr++;
127 if (nerr == 1)
128 syslog(LOG_ERR, "Can't open %s: %s\n",
129 dev_fcode_file, strerror(errno));
130 sleep(1);
132 if (nerr > 1) {
133 syslog(LOG_ERR, "Open on %s failed %d times\n",
134 dev_fcode_file, nerr);
136 nerr = 0;
137 nbytes = read(fd, &tc, sizeof (tc));
138 if (nbytes < 0) {
139 syslog(LOG_ERR, "Read of %s: %s\n", dev_fcode_file,
140 strerror(errno));
141 close(fd);
142 continue;
144 if (debug)
145 syslog(LOG_DEBUG, "Got request\n");
146 while ((pid = fork()) < 0) {
147 nerr++;
148 if (nerr == 1)
149 syslog(LOG_ERR, "Fork failed: %s\n",
150 strerror(errno));
151 sleep(1);
153 if ((nerr > 1) && pid) {
154 syslog(LOG_ERR, "Fork failed %d times\n", nerr);
156 nerr = 0;
157 if (pid) {
158 tpid = wait(&status);
159 if (tpid < 0)
160 syslog(LOG_ERR, "Wait error: %s\n",
161 strerror(errno));
162 else if (pid != tpid)
163 syslog(LOG_ERR, "Wait error, expect pid: %d"
164 " got %d, status: %x\n", pid, tpid, status);
165 else if (status) {
166 syslog(LOG_ERR, "Wait pid: %d status: %x\n",
167 pid, status);
168 if (WIFEXITED(status) &&
169 (WEXITSTATUS(status) == 1)) {
170 error = FC_FCODE_ABORT;
171 } else {
172 error = FC_EXEC_FAILED;
174 if (ioctl(fd, FC_SET_FCODE_ERROR, &error) < 0) {
175 syslog(LOG_ERR,
176 "ioctl(FC_SET_FCODE_ERROR)"
177 " failed\n");
179 } else if (debug)
180 syslog(LOG_DEBUG, "Wait: pid: %d\n", pid);
181 close(fd);
182 continue;
184 if (debug)
185 syslog(LOG_DEBUG, "Child: %d processing request\n",
186 getpid());
187 fcntl(fd, F_DUP2FD, 0);
188 while (execl("/bin/sh", "sh", efcode_sh_file, NULL)) {
189 nerr++;
190 if (nerr == 1)
191 syslog(LOG_ERR, "execl(/bin/sh) failed: %s\n",
192 strerror(errno));
193 sleep(1);
197 return (0);