8 #include <sys/signal.h>
20 extern regex_t **regList;
22 int forkCommand(char **args, int *outfd, int *errfd, int *cmdfd, int quiet) {
23 /* Fork command 'cmd', returning pid, and optionally pointer
24 * to open file descriptor fd */
25 int fdout, fderr, fdcmd, pid;
26 int outpipe[2], errpipe[2], fdpipe[2];
29 if ( (pipe(outpipe)==-1) || (pipe(errpipe)==-1) || (pipe(fdpipe)==-1) ) {
53 fdcmd = open("/dev/null",O_WRONLY);
56 if ((pid = fork())==-1) {
60 /* We exec the command normally as the child. However, if we're getting passed
61 * back arguments via an fd, we'll exec it as the parent. Therefore, if Bill
62 * fucks up and we segfault or something, we don't kill rc.sysinit. */
63 if ( (cmdfd&&!pid) || (pid &&!cmdfd)) {
77 if ( (dup2(fdout,1)==-1) ) {
82 if ((dup2(open("/dev/null",O_WRONLY),1))==-1) {
88 if ((dup2(fderr,2)==-1)) {
93 if ((dup2(open("/dev/null",O_WRONLY),2))==-1) {
99 if ((dup2(fdcmd,CMD_FD)==-1)) {
113 /* close up extra fds, and hope this doesn't break anything */
114 sc_open_max = sysconf(_SC_OPEN_MAX);
115 if(sc_open_max > 1) {
117 for(fd = 3; fd < sc_open_max; fd++) {
118 if (!(cmdfd && fd == CMD_FD))
123 execvp(args[0],args);
129 int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, int debug) {
131 char *buf=malloc(8192*sizeof(char));
143 procpath=malloc(20*sizeof(char));
144 snprintf(procpath,20,"/proc/%d",pid);
147 pfds = malloc(numfds*sizeof(struct pollfd));
148 for (x=0;x<numfds;x++) {
150 pfds[x].events = POLLIN | POLLPRI;
155 if (((x=poll(pfds,numfds,500))==-1)&&errno!=EINTR) {
160 if (waitpid(pid,&rc,WNOHANG))
164 /* if /proc/pid ain't there and /proc is, it's dead... */
165 if (stat(procpath,&sbuf)&&!stat("/proc/cpuinfo",&sbuf))
170 if ( x && ((pfds[y].revents & (POLLIN | POLLPRI)) )) {
174 buf=calloc(8192,sizeof(char));
175 bytesread = read(pfds[y].fd,buf,8192);
181 if (!quiet && !reexec)
182 write(1,buf,bytesread);
184 outbuf=realloc(outbuf,(outbuf ? strlen(outbuf)+bytesread+1 : bytesread+1));
185 if (!output) outbuf[0]='\0';
189 while ((tmpstr=getLine(&buf))) {
195 while (regList[count]) {
196 if (!regexec(regList[count],tmpstr,0,NULL,0)) {
205 if (getenv("IN_INITLOG")) {
206 char *buffer=calloc(8192,sizeof(char));
207 DDEBUG("sending =%s= to initlog parent\n",tmpstr);
208 snprintf(buffer,8192,"-n %s -s \"%s\"\n",
210 /* don't blow up if parent isn't there */
211 signal(SIGPIPE,SIG_IGN);
212 write(CMD_FD,buffer,strlen(buffer));
213 signal(SIGPIPE,SIG_DFL);
216 logString(cmdname,tmpstr);
225 poptParseArgvString(tmpstr,&cmdargc,&tmpargs);
226 cmdargs=malloc( (cmdargc+2) * sizeof(char *) );
227 cmdargs[0]=strdup("initlog");
228 for (z=0;z<(cmdargc);z++) {
229 cmdargs[z+1]=tmpargs[z];
231 cmdargs[cmdargc+1]=NULL;
232 processArgs(cmdargc+1,cmdargs,1);
237 } while ( bytesread==8192 );
242 if ((!WIFEXITED(rc)) || (rc=WEXITSTATUS(rc))) {
243 /* If there was an error and we're quiet, be loud */
245 if (quiet && output) {
246 write(1,outbuf,strlen(outbuf));
253 int runCommand(char *cmd, int reexec, int quiet, int debug) {
256 char **args, **tmpargs;
259 poptParseArgvString(cmd,&x,&tmpargs);
260 args = malloc((x+1)*sizeof(char *));
261 for ( pid = 0; pid < x ; pid++) {
262 args[pid] = strdup(tmpargs[pid]);
265 if (strcmp(args[0],"sh") && strcmp(args[0],"/bin/sh"))
266 cmdname = basename(args[0]);
268 cmdname = basename(args[1]);
269 if ((cmdname[0] =='K' || cmdname[0] == 'S') && ( '0' <= cmdname[1] <= '9' )
270 && ( '0' <= cmdname[2] <= '9' ) )
273 pid=forkCommand(args,&fds[0],&fds[1],NULL,quiet);
274 x=monitor(cmdname,pid,2,fds,reexec,quiet,debug);
276 setenv("IN_INITLOG","yes",1);
277 pid=forkCommand(args,NULL,NULL,&fds[0],quiet);
278 unsetenv("IN_INITLOG");
279 x=monitor(cmdname,pid,1,&fds[0],reexec,quiet,debug);