]> git.pld-linux.org Git - projects/rc-scripts.git/blob - src/process.c
pare zmian
[projects/rc-scripts.git] / src / process.c
1
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7
8 #include <sys/poll.h>
9 #include <sys/wait.h>
10
11 #include <popt.h>
12
13 #include "initlog.h"
14 #include "process.h"
15
16 int forkCommand(char **args, int *outfd, int *errfd, int *cmdfd, int quiet) {
17    /* Fork command 'cmd', returning pid, and optionally pointer
18     * to open file descriptor fd */
19     int fdin, fdout, fderr, fdcmd, pid;
20     int outpipe[2], errpipe[2], fdpipe[2];
21     
22     if ( (pipe(outpipe)==-1) || (pipe(errpipe)==-1) || (pipe(fdpipe)==-1) ) {
23         perror("pipe");
24         return -1;
25     }
26     
27     fdin=dup(0);
28     if (outfd) {
29        fdout = outpipe[1];
30       *outfd = outpipe[0];
31     } else {
32        if (!quiet)
33          fdout=dup(1);
34     }
35     if (errfd) {
36        fderr = errpipe[1];
37       *errfd = errpipe[0];
38     } else {
39        if (!quiet)
40          fderr=dup(2);
41     }
42     fdcmd = fdpipe[1];
43     if (cmdfd)
44       *cmdfd = fdpipe[0];
45     if ((pid = fork())==-1) {
46         perror("fork");
47         return -1;
48     }
49     if (pid) {
50         /* parent */
51         close(fdin);
52         close(fdout);
53         close(fderr);
54         close(fdcmd);
55         return pid;
56     } else {
57         /* kid */
58        if (outfd) { 
59          if ( (dup2(fdout,1)==-1) ) {
60             perror("dup2");
61             exit(-1);
62          }
63        } else if (quiet)
64             if ((dup2(open("/dev/null",O_WRONLY),1))==-1) {
65              perror("dup2");
66              exit(-1);
67             }
68
69        if (errfd)  {
70          if ((dup2(fderr,2)==-1)) {
71             perror("dup2");
72             exit(-1);
73          }
74        } else if (quiet) 
75             if ((dup2(open("/dev/null",O_WRONLY),2))==-1)  {
76                perror("dup2");
77                exit(-1);
78             }
79
80  
81        if ((dup2(fdcmd,CMD_FD)==-1)) {
82             perror("dup2");
83             exit(-1);
84         }
85         close(fdout);
86         close(fderr);
87         close(fdcmd);
88         if (outfd)
89           close(*outfd);
90         if (errfd)
91           close(*errfd);
92         if (cmdfd)
93           close(*cmdfd);
94         execvp(args[0],args);
95         perror("execvp");
96         exit(-1);
97     }
98 }
99
100 int monitor(char *cmdname, int pid, int numfds, int *fds, int reexec, int quiet, int debug) {
101     struct pollfd *pfds;
102     char *buf=malloc(2048*sizeof(char));
103     int outpipe[2];
104     char *tmpstr=NULL;
105     int x,y,rc=-1;
106     int done=0;
107     int output=0;
108     
109     pipe(outpipe);
110    
111     pfds = malloc(numfds*sizeof(struct pollfd));
112     for (x=0;x<numfds;x++) {
113         pfds[x].fd = fds[x];
114         pfds[x].events = POLLIN | POLLPRI;
115     }
116         
117     while (!done) {
118        if (((x=poll(pfds,numfds,500))==-1)&&errno!=EINTR) {
119           perror("poll");
120           return -1;
121        }
122        if (waitpid(pid,&rc,WNOHANG))
123          done=1;
124        y=0;
125        while (y<numfds) {
126           if ( x && ((pfds[y].revents & (POLLIN | POLLPRI)) )) {
127              int bytesread = 0;
128              
129              do {
130                 buf=calloc(2048,sizeof(char));
131                 bytesread = read(pfds[y].fd,buf,2048);
132                 if (bytesread==-1) {
133                    perror("read");
134                    return -1;
135                 }
136                 if (bytesread) {
137                   if (!quiet && !reexec)
138                     write(1,buf,bytesread);
139                   if (quiet) {
140                      output = 1;
141                      write(outpipe[1],buf,bytesread);
142                   }
143                   while ((tmpstr=getLine(&buf))) {
144                      if (!reexec) {
145                          if (getenv("IN_INITLOG")) {
146                              char *buffer=calloc(2048,sizeof(char));
147                              DDEBUG("sending =%s= to initlog parent\n",tmpstr);
148                              snprintf(buffer,2048,"-n %s -s \"%s\"\n",
149                                       cmdname,tmpstr);
150                              write(CMD_FD,buffer,strlen(buffer));
151                              free(buffer);
152                          } else {
153                              logString(cmdname,tmpstr);
154                          }
155                      } else {
156                         char **cmdargs=NULL;
157                         char **tmpargs=NULL;
158                         int cmdargc,x;
159                         
160                         poptParseArgvString(tmpstr,&cmdargc,&tmpargs);
161                         cmdargs=malloc( (cmdargc++) * sizeof(char *) );
162                         cmdargs[0]=strdup("initlog");
163                         for (x=0;x<(cmdargc-1);x++) {
164                            cmdargs[x+1]=tmpargs[x];
165                         }
166                         processArgs(cmdargc,cmdargs,1);
167                      }
168                   }
169                 }
170                 
171              } while ( bytesread==2048 );
172           }
173           y++;
174        }
175     }
176     if ((!WIFEXITED(rc)) || (rc=WEXITSTATUS(rc))) {
177       /* If there was an error and we're quiet, be loud */
178       int x;
179       
180       if (quiet && output) {
181          buf=calloc(2048,sizeof(char));
182          do {
183             x=read(outpipe[0],buf,2048);
184             write(1,"\n",1);
185             write(1,buf,x);
186             buf=calloc(2048,sizeof(char));
187          } while (x==2048);
188       }
189       return (rc);
190    }
191    return 0;
192 }
193
194 int runCommand(char *cmd, int reexec, int quiet, int debug) {
195     int fds[2];
196     int pid,x;
197     char **args, **tmpargs;
198     char *cmdname;
199     
200     poptParseArgvString(cmd,&x,&tmpargs);
201     args = malloc((x+1)*sizeof(char *));
202     for ( pid = 0; pid < x ; pid++) {
203         args[pid] = strdup(tmpargs[pid]);
204     }
205     args[pid] = NULL;
206     if (strcmp(args[0],"sh") && strcmp(args[0],"/bin/sh")) 
207       cmdname = basename(args[0]);
208     else
209       cmdname = basename(args[1]);
210     if ((cmdname[0] =='K' || cmdname[0] == 'S') && ( 30 <= cmdname[1] <= 39 )
211        && ( 30 <= cmdname[2] <= 39 ) )
212       cmdname+=3;
213     if (!reexec) {
214        pid=forkCommand(args,&fds[0],&fds[1],NULL,quiet);
215        x=monitor(cmdname,pid,2,fds,reexec,quiet,debug);
216     } else {
217        setenv("IN_INITLOG","yes",1);
218        pid=forkCommand(args,NULL,NULL,&fds[0],quiet);
219        unsetenv("IN_INITLOG");
220        x=monitor(cmdname,pid,1,&fds[0],reexec,quiet,debug);
221     }
222     return x;
223 }
This page took 0.047557 seconds and 4 git commands to generate.