8 #include <sys/signal.h>
13 #include <sys/resource.h>
22 extern regex_t **regList;
24 int forkCommand(char **args, int *outfd, int *errfd, int *cmdfd, int quiet) {
25 /* Fork command 'cmd', returning pid, and optionally pointer
26 * to open file descriptor fd */
27 int fdout, fderr, fdcmd, pid;
28 int outpipe[2], errpipe[2], fdpipe[2];
31 if ( (pipe(outpipe)==-1) || (pipe(errpipe)==-1) || (pipe(fdpipe)==-1) ) {
55 fdcmd = open("/dev/null",O_WRONLY);
58 if ((pid = fork())==-1) {
62 /* We exec the command normally as the child. However, if we're getting passed
63 * back arguments via an fd, we'll exec it as the parent. Therefore, if Bill
64 * fucks up and we segfault or something, we don't kill rc.sysinit. */
65 if ( (cmdfd&&!pid) || (pid &&!cmdfd)) {
79 if ( (dup2(fdout,1)==-1) ) {
84 if ((dup2(open("/dev/null",O_WRONLY),1))==-1) {
90 if ((dup2(fderr,2)==-1)) {
95 if ((dup2(open("/dev/null",O_WRONLY),2))==-1) {
101 if ((dup2(fdcmd,CMD_FD)==-1)) {
115 /* close up extra fds, and hope this doesn't break anything */
116 sc_open_max = sysconf(_SC_OPEN_MAX);
117 if(sc_open_max > 1) {
119 for(fd = 3; fd < sc_open_max; fd++) {
120 if (!(cmdfd && fd == CMD_FD))
125 execvp(args[0],args);
131 int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, int debug) {
133 char *buf=malloc(8192*sizeof(char));
145 procpath=malloc(20*sizeof(char));
146 snprintf(procpath,20,"/proc/%d",pid);
149 pfds = malloc(numfds*sizeof(struct pollfd));
150 for (x=0;x<numfds;x++) {
152 pfds[x].events = POLLIN | POLLPRI;
157 if (((x=poll(pfds,numfds,500))==-1)&&errno!=EINTR) {
162 if (waitpid(pid,&rc,WNOHANG))
166 /* if /proc/pid ain't there and /proc is, it's dead... */
167 if (stat(procpath,&sbuf)&&!stat("/proc/cpuinfo",&sbuf))
172 if ( x && ((pfds[y].revents & (POLLIN | POLLPRI)) )) {
176 buf=calloc(8192,sizeof(char));
177 bytesread = read(pfds[y].fd,buf,8192);
183 if (!quiet && !reexec)
184 write(1,buf,bytesread);
186 outbuf=realloc(outbuf,(outbuf ? strlen(outbuf)+bytesread+1 : bytesread+1));
187 if (!output) outbuf[0]='\0';
191 while ((tmpstr=getLine(&buf))) {
197 while (regList[count]) {
198 if (!regexec(regList[count],tmpstr,0,NULL,0)) {
207 if (getenv("IN_INITLOG")) {
208 char *buffer=calloc(8192,sizeof(char));
209 DDEBUG("sending =%s= to initlog parent\n",tmpstr);
210 snprintf(buffer,8192,"-n %s -s \"%s\"\n",
212 /* don't blow up if parent isn't there */
213 signal(SIGPIPE,SIG_IGN);
214 write(CMD_FD,buffer,strlen(buffer));
215 signal(SIGPIPE,SIG_DFL);
218 logString(cmdname,tmpstr);
227 poptParseArgvString(tmpstr,&cmdargc,&tmpargs);
228 cmdargs=malloc( (cmdargc+2) * sizeof(char *) );
229 cmdargs[0]=strdup("initlog");
230 for (z=0;z<(cmdargc);z++) {
231 cmdargs[z+1]=tmpargs[z];
233 cmdargs[cmdargc+1]=NULL;
234 processArgs(cmdargc+1,cmdargs,1);
239 } while ( bytesread==8192 );
244 if ((!WIFEXITED(rc)) || (rc=WEXITSTATUS(rc))) {
245 /* If there was an error and we're quiet, be loud */
247 if (quiet && output) {
248 write(1,outbuf,strlen(outbuf));
255 int runCommand(char *cmd, int reexec, int quiet, int debug) {
258 char **args, **tmpargs;
261 poptParseArgvString(cmd,&x,&tmpargs);
262 args = malloc((x+1)*sizeof(char *));
263 for ( pid = 0; pid < x ; pid++) {
264 args[pid] = strdup(tmpargs[pid]);
267 if (strcmp(args[0],"sh") && strcmp(args[0],"/bin/sh"))
268 cmdname = basename(args[0]);
270 cmdname = basename(args[1]);
271 if ((cmdname[0] =='K' || cmdname[0] == 'S') && ( '0' <= cmdname[1] <= '9' )
272 && ( '0' <= cmdname[2] <= '9' ) )
275 pid=forkCommand(args,&fds[0],&fds[1],NULL,quiet);
276 x=monitor(cmdname,pid,2,fds,reexec,quiet,debug);
278 setenv("IN_INITLOG","yes",1);
279 pid=forkCommand(args,NULL,NULL,&fds[0],quiet);
280 unsetenv("IN_INITLOG");
281 x=monitor(cmdname,pid,1,&fds[0],reexec,quiet,debug);
286 void setupCustomLimits(void) {
290 for (i=0; i< RLIM_NLIMITS; i++) {
291 rlim.rlim_max = rlim.rlim_cur = RLIM_INFINITY;
294 rlim.rlim_max = rlim.rlim_cur = 0;
295 setrlimit(RLIMIT_CORE, &rlim);