1 /*
2  *  Process spawn functions
3  *  Copyright (C) 2008 Andreas Öman
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <sys/stat.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <syslog.h>
29 #include <fcntl.h>
30 #include <dirent.h>
31 #include <signal.h>
32 
33 #include "tvheadend.h"
34 #include "tvhpoll.h"
35 #include "file.h"
36 #include "spawn.h"
37 
38 #if ENABLE_ANDROID
39 #define WIFCONTINUED(s) ((s) == 0xffff)
40 #endif
41 
42 extern char **environ;
43 
44 pthread_mutex_t spawn_mutex = PTHREAD_MUTEX_INITIALIZER;
45 
46 static LIST_HEAD(, spawn) spawns;
47 
48 static char *spawn_info_buf = NULL;
49 static char *spawn_error_buf = NULL;
50 
51 static th_pipe_t spawn_pipe_info;
52 static th_pipe_t spawn_pipe_error;
53 
54 static pthread_t spawn_pipe_tid;
55 
56 static int spawn_pipe_running;
57 
58 typedef struct spawn {
59   LIST_ENTRY(spawn) link;
60   pid_t pid;
61   const char *name;
62   int64_t killed;
63 } spawn_t;
64 
65 static void spawn_reaper(void);
66 
67 /*
68  *
69  */
70 #define SPAWN_PIPE_READ_SIZE 4096
71 
72 static void
spawn_pipe_read(th_pipe_t * p,char ** _buf,int level)73 spawn_pipe_read( th_pipe_t *p, char **_buf, int level )
74 {
75   char *buf = *_buf, *s;
76   size_t len;
77   int r;
78 
79   if (buf == NULL) {
80     buf = malloc(SPAWN_PIPE_READ_SIZE);
81     buf[0] = '\0';
82     buf[SPAWN_PIPE_READ_SIZE - 1] = 0;
83     *_buf = buf;
84   }
85   while (1) {
86     len = strlen(buf);
87     r = read(p->rd, buf + len, SPAWN_PIPE_READ_SIZE - 1 - len);
88     if (r < 1) {
89       if (errno == EAGAIN)
90         break;
91       if (ERRNO_AGAIN(errno))
92         continue;
93       break;
94     }
95     buf[len + r] = '\0';
96     tvhlog_hexdump(LS_SPAWN, buf + len, r);
97     while (1) {
98       s = buf;
99       while (*s && *s != '\n' && *s != '\r')
100         s++;
101       if (*s == '\0')
102         break;
103       *s++ = '\0';
104       if (buf[0])
105         tvhlog(level, LS_SPAWN, "%s", buf);
106       memmove(buf, s, strlen(s) + 1);
107     }
108     if (strlen(buf) == SPAWN_PIPE_READ_SIZE - 1) {
109       tvherror(LS_SPAWN, "pipe buffer full");
110       buf[0] = '\0';
111     }
112   }
113 }
114 
115 static void *
spawn_pipe_thread(void * aux)116 spawn_pipe_thread(void *aux)
117 {
118   tvhpoll_event_t ev[2];
119   tvhpoll_t *efd = tvhpoll_create(2);
120   int nfds;
121 
122   memset(ev, 0, sizeof(ev));
123   ev[0].events   = TVHPOLL_IN;
124   ev[0].fd       = spawn_pipe_info.rd;
125   ev[0].data.ptr = &spawn_pipe_info;
126   ev[1].events   = TVHPOLL_IN;
127   ev[1].fd       = spawn_pipe_error.rd;
128   ev[1].data.ptr = &spawn_pipe_error;
129   tvhpoll_add(efd, ev, 2);
130 
131   while (atomic_get(&spawn_pipe_running)) {
132 
133     nfds = tvhpoll_wait(efd, ev, 2, 500);
134 
135     if (nfds > 0) {
136       spawn_pipe_read(&spawn_pipe_info, &spawn_info_buf, LOG_INFO);
137       spawn_pipe_read(&spawn_pipe_error, &spawn_error_buf, LOG_ERR);
138     }
139     spawn_reaper();
140 
141   }
142 
143   tvhpoll_destroy(efd);
144   return NULL;
145 }
146 
147 static void
spawn_pipe_write(th_pipe_t * p,const char * fmt,va_list ap)148 spawn_pipe_write( th_pipe_t *p, const char *fmt, va_list ap )
149 {
150   char buf[512], *s = buf;
151   int r;
152 
153   vsnprintf(buf, sizeof(buf), fmt, ap);
154   while (*s) {
155     r = write(p->wr, s, strlen(s));
156     if (r < 0) {
157       if (errno == EAGAIN)
158         break;
159       if (ERRNO_AGAIN(errno))
160         continue;
161       break;
162     }
163     if (!r)
164       break;
165     s += r;
166   }
167 }
168 
169 void
spawn_info(const char * fmt,...)170 spawn_info( const char *fmt, ... )
171 {
172   va_list ap;
173 
174   va_start(ap, fmt);
175   spawn_pipe_write(&spawn_pipe_info, fmt, ap);
176   va_end(ap);
177 }
178 
179 void
spawn_error(const char * fmt,...)180 spawn_error( const char *fmt, ... )
181 {
182   va_list ap;
183 
184   va_start(ap, fmt);
185   spawn_pipe_write(&spawn_pipe_error, fmt, ap);
186   va_end(ap);
187 }
188 
189 /*
190  * Search PATH for executable
191  */
192 int
find_exec(const char * name,char * out,size_t len)193 find_exec ( const char *name, char *out, size_t len )
194 {
195   int ret = 0;
196   char bin[512];
197   char *path, *tmp, *tmp2 = NULL;
198   DIR *dir;
199   struct dirent *de;
200   struct stat st;
201   if (name[0] == '/') {
202     if (lstat(name, &st)) return 0;
203     if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) return 0;
204     strlcpy(out, name, len);
205     return 1;
206   }
207   if (!(path = getenv("PATH"))) return 0;
208   path = strdup(path);
209   tmp  = strtok_r(path, ":", &tmp2);
210   while (tmp && !ret) {
211     if ((dir = opendir(tmp))) {
212       while ((de = readdir(dir))) {
213         if (strstr(de->d_name, name) != de->d_name) continue;
214         snprintf(bin, sizeof(bin), "%s/%s", tmp, de->d_name);
215         if (lstat(bin, &st)) continue;
216         if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) continue;
217         strlcpy(out, bin, len);
218         ret = 1;
219         break;
220       }
221       closedir(dir);
222     }
223     tmp = strtok_r(NULL, ":", &tmp2);
224   }
225   free(path);
226   return ret;
227 }
228 
229 /**
230  * Reap one child
231  */
232 int
spawn_reap(pid_t wpid,char * stxt,size_t stxtlen)233 spawn_reap(pid_t wpid, char *stxt, size_t stxtlen)
234 {
235   pid_t pid;
236   int status, res;
237   spawn_t *s;
238 
239   pid = waitpid(wpid, &status, WNOHANG);
240   if(pid < 0 && ERRNO_AGAIN(errno))
241     return -EAGAIN;
242   if(pid < 0)
243     return -errno;
244   if(pid < 1) {
245     if (wpid > 0 && pid != wpid)
246       return -EAGAIN;
247     return 0;
248   }
249 
250   pthread_mutex_lock(&spawn_mutex);
251   LIST_FOREACH(s, &spawns, link)
252     if(s->pid == pid)
253       break;
254 
255   res = -EIO;
256   if (WIFEXITED(status)) {
257     res = WEXITSTATUS(status);
258     if (stxt)
259       snprintf(stxt, stxtlen, "exited, status=%d", WEXITSTATUS(status));
260   } else if (WIFSIGNALED(status)) {
261     if (stxt)
262       snprintf(stxt, stxtlen, "killed by signal %d, "
263                               "stopped by signal %d",
264                               WTERMSIG(status),
265                               WSTOPSIG(status));
266   } else if (WIFCONTINUED(status)) {
267     if (stxt)
268       snprintf(stxt, stxtlen, "continued");
269   } else {
270     if (stxt)
271       snprintf(stxt, stxtlen, "unknown status");
272   }
273 
274   if(s != NULL) {
275     LIST_REMOVE(s, link);
276     free((void *)s->name);
277     free(s);
278   }
279   pthread_mutex_unlock(&spawn_mutex);
280   return res;
281 }
282 
283 /**
284  * The reaper is called once a second to finish of any pending spawns
285  */
286 static void
spawn_reaper(void)287 spawn_reaper(void)
288 {
289   int r;
290   spawn_t *s;
291 
292   do {
293     r = spawn_reap(-1, NULL, 0);
294     if (r == -EAGAIN)
295       continue;
296     if (r <= 0)
297       break;
298   } while (1);
299 
300   /* forced kill for expired PIDs */
301   pthread_mutex_lock(&spawn_mutex);
302   LIST_FOREACH(s, &spawns, link)
303     if (s->killed && s->killed < mclk()) {
304       /* kill the whole process group */
305       r = kill(-(s->pid), SIGKILL);
306       if (r && errno == EPERM)
307         tvherror(LS_SPAWN, "Unable to kill task pid %d (not enough permissions)", s->pid);
308     }
309   pthread_mutex_unlock(&spawn_mutex);
310 }
311 
312 /**
313  * Kill the pid (only if waiting)
314  */
315 int
spawn_kill(pid_t pid,int sig,int timeout)316 spawn_kill(pid_t pid, int sig, int timeout)
317 {
318   int r = -ESRCH;
319   spawn_t *s;
320 
321   if (pid > 0) {
322     spawn_reaper();
323 
324     pthread_mutex_lock(&spawn_mutex);
325     LIST_FOREACH(s, &spawns, link)
326       if(s->pid == pid)
327         break;
328     if (s) {
329       if (!s->killed)
330         s->killed = mclk() + sec2mono(MINMAX(timeout, 5, 3600));
331       /* kill the whole process group */
332       r = kill(-pid, sig);
333       if (r < 0) {
334         if (errno == EPERM)
335           tvherror(LS_SPAWN, "Unable to kill task pid %d (not enough permissions)", s->pid);
336         r = -errno;
337       }
338     }
339     pthread_mutex_unlock(&spawn_mutex);
340   }
341   return r;
342 }
343 
344 /**
345  * Enqueue a spawn on the pending spawn list
346  */
347 static spawn_t *
spawn_enq(const char * name,int pid)348 spawn_enq(const char *name, int pid)
349 {
350   spawn_t *s = calloc(1, sizeof(spawn_t));
351   s->name = strdup(name);
352   s->pid = pid;
353   pthread_mutex_lock(&spawn_mutex);
354   LIST_INSERT_HEAD(&spawns, s, link);
355   pthread_mutex_unlock(&spawn_mutex);
356   return s;
357 }
358 
359 
360 /**
361  *
362  */
363 int
spawn_parse_args(char *** argv,int argc,const char * cmd,const char ** replace)364 spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace)
365 {
366   char *s, *f, *p, *a;
367   const char **r;
368   int i = 0, l, eow;
369 
370   if (!argv || !cmd)
371     return -1;
372 
373   s = tvh_strdupa(cmd);
374   *argv = calloc(argc, sizeof(char *));
375 
376   while (*s && i < argc - 1) {
377     while (*s == ' ')
378       s++;
379     f = s;
380     eow = 0;
381     while (*s) {
382       if (*s == '\\') {
383         l = *(s + 1);
384         if (l == 'b')
385           l = '\b';
386         else if (l == 'f')
387           l = '\f';
388         else if (l == 'n')
389           l = '\n';
390         else if (l == 'r')
391           l = '\r';
392         else if (l == 't')
393           l = '\t';
394         else
395           l = 0;
396         if (l) {
397           *s++ = l;
398           memmove(s, s + 1, strlen(s));
399         } else {
400           memmove(s, s + 1, strlen(s));
401           if (*s)
402             s++;
403         }
404       } else if (eow) {
405         if (*s == eow) {
406           memmove(s, s + 1, strlen(s));
407           eow = 0;
408         } else {
409           s++;
410         }
411       } else if (*s == '\'' || *s == '"') {
412         eow = *s;
413         memmove(s, s + 1, strlen(s));
414       } else if (*s == ' ') {
415         break;
416       } else {
417         s++;
418       }
419     }
420     if (f != s) {
421       if (*s) {
422         *(char *)s = '\0';
423         s++;
424       }
425       for (r = replace; r && *r; r += 2) {
426         p = strstr(f, *r);
427         if (p) {
428           l = strlen(*r);
429           a = malloc(strlen(f) + strlen(r[1]) + 1);
430           *p = '\0';
431           strcpy(a, f);
432           strcat(a, r[1]);
433           strcat(a, p + l);
434           (*argv)[i++] = a;
435           break;
436         }
437       }
438       if (r && *r)
439         continue;
440       (*argv)[i++] = strdup(f);
441     }
442   }
443   (*argv)[i] = NULL;
444   return 0;
445 }
446 
447 /**
448  *
449  */
450 void
spawn_free_args(char ** argv)451 spawn_free_args(char **argv)
452 {
453   char **a = argv;
454   for (; *a; a++)
455     free(*a);
456   free(argv);
457 }
458 
459 /**
460  * Execute the given program and return its standard output as file-descriptor (pipe).
461  */
462 int
spawn_and_give_stdout(const char * prog,char * argv[],char * envp[],int * rd,pid_t * pid,int redir_stderr)463 spawn_and_give_stdout(const char *prog, char *argv[], char *envp[],
464                       int *rd, pid_t *pid, int redir_stderr)
465 {
466   pid_t p;
467   int fd[2], f, i, maxfd;
468   char bin[256];
469   const char *local_argv[2] = { NULL, NULL };
470   char **e, **e0, **e2, **e3, *p1, *p2;
471 
472   if (*prog != '/' && *prog != '.') {
473     if (!find_exec(prog, bin, sizeof(bin))) return -1;
474     prog = bin;
475   }
476 
477   if (!argv) argv = (void *)local_argv;
478   if (!argv[0]) {
479     if (argv != (void *)local_argv) {
480       for (i = 1, e = argv + 1; *e; i++, e++);
481       i = (i + 1) * sizeof(char *);
482       e = alloca(i);
483       memcpy(e, argv, i);
484       argv = e;
485     }
486     argv[0] = (char *)prog;
487   }
488 
489   if (!envp || !envp[0]) {
490     e = environ;
491   } else {
492     for (i = 0, e2 = environ; *e2; i++, e2++);
493     for (f = 0, e2 = envp; *e2; f++, e2++);
494     e = alloca((i + f + 1) * sizeof(char *));
495     memcpy(e, environ, i * sizeof(char *));
496     e0 = e + i;
497     *e0 = NULL;
498     for (e2 = envp; *e2; e2++) {
499       for (e3 = e; *e3; e3++) {
500         p1 = strchr(*e2, '=');
501         p2 = strchr(*e3, '=');
502         if (p1 - *e2 == p2 - *e3 && !strncmp(*e2, *e3, p1 - *e2)) {
503           *e3 = *e2;
504           break;
505         }
506       }
507       if (!*e3) {
508         *e0++ = *e2;
509         *e0 = NULL;
510       }
511     }
512     *e0 = NULL;
513   }
514 
515   maxfd = sysconf(_SC_OPEN_MAX);
516 
517   pthread_mutex_lock(&fork_lock);
518 
519   if(pipe(fd) == -1) {
520     pthread_mutex_unlock(&fork_lock);
521     return -1;
522   }
523 
524   p = fork();
525 
526   if(p == -1) {
527     pthread_mutex_unlock(&fork_lock);
528     tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s",
529              prog, strerror(errno));
530     return -1;
531   }
532 
533   if(p == 0) {
534     f = open("/dev/null", O_RDWR);
535     if(f == -1) {
536       spawn_error("pid %d cannot open /dev/null for redirect %s -- %s",
537                   getpid(), prog, strerror(errno));
538       exit(1);
539     }
540 
541     close(0);
542     close(1);
543     close(2);
544 
545     dup2(f, 0);
546     dup2(fd[1], 1);
547     dup2(redir_stderr ? spawn_pipe_error.wr : f, 2);
548 
549     close(fd[0]);
550     close(fd[1]);
551     close(f);
552 
553     spawn_info("Executing \"%s\"\n", prog);
554 
555     for (f = 3; f < maxfd; f++)
556       close(f);
557 
558     execve(prog, argv, e);
559     spawn_error("pid %d cannot execute %s -- %s\n",
560                 getpid(), prog, strerror(errno));
561     exit(1);
562   }
563 
564   pthread_mutex_unlock(&fork_lock);
565 
566   spawn_enq(prog, p);
567 
568   close(fd[1]);
569 
570   *rd = fd[0];
571   if (pid) {
572     *pid = p;
573 
574     // make the spawned process a session leader so killing the
575     // process group recursively kills any child process that
576     // might have been spawned
577     setpgid(p, p);
578   }
579   return 0;
580 }
581 
582 /**
583  * Execute the given program with arguments
584  *
585  * *outp will point to the allocated buffer
586  * The function will return the size of the buffer
587  */
588 int
spawnv(const char * prog,char * argv[],pid_t * pid,int redir_stdout,int redir_stderr)589 spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int redir_stderr)
590 {
591   pid_t p, f, maxfd;
592   char bin[256];
593   const char *local_argv[2] = { NULL, NULL };
594 
595   if (*prog != '/' && *prog != '.') {
596     if (!find_exec(prog, bin, sizeof(bin))) return -1;
597     prog = bin;
598   }
599 
600   if(!argv) argv = (void *)local_argv;
601   if (!argv[0]) argv[0] = (char*)prog;
602 
603   maxfd = sysconf(_SC_OPEN_MAX);
604 
605   pthread_mutex_lock(&fork_lock);
606 
607   p = fork();
608 
609   if(p == -1) {
610     pthread_mutex_unlock(&fork_lock);
611     tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s",
612 	     prog, strerror(errno));
613     return -1;
614   }
615 
616   if(p == 0) {
617     f = open("/dev/null", O_RDWR);
618     if(f == -1) {
619       spawn_error("pid %d cannot open /dev/null for redirect %s -- %s",
620                   getpid(), prog, strerror(errno));
621       exit(1);
622     }
623 
624     close(0);
625     close(1);
626     close(2);
627 
628     dup2(f, 0);
629     dup2(redir_stdout ? spawn_pipe_info.wr : f, 1);
630     dup2(redir_stderr ? spawn_pipe_error.wr : f, 2);
631 
632     close(f);
633 
634     spawn_info("Executing \"%s\"\n", prog);
635 
636     for (f = 3; f < maxfd; f++)
637       close(f);
638 
639     execve(prog, argv, environ);
640     spawn_error("pid %d cannot execute %s -- %s\n",
641 	        getpid(), prog, strerror(errno));
642     close(1);
643     exit(1);
644   }
645 
646   pthread_mutex_unlock(&fork_lock);
647 
648   spawn_enq(prog, p);
649 
650   if (pid)
651     *pid = p;
652 
653   return 0;
654 }
655 
656 /*
657  *
658  */
spawn_init(void)659 void spawn_init(void)
660 {
661   tvh_pipe(O_NONBLOCK, &spawn_pipe_info);
662   tvh_pipe(O_NONBLOCK, &spawn_pipe_error);
663   atomic_set(&spawn_pipe_running, 1);
664   pthread_create(&spawn_pipe_tid, NULL, spawn_pipe_thread, NULL);
665 }
666 
spawn_done(void)667 void spawn_done(void)
668 {
669   spawn_t *s;
670 
671   atomic_set(&spawn_pipe_running, 0);
672   pthread_kill(spawn_pipe_tid, SIGTERM);
673   pthread_join(spawn_pipe_tid, NULL);
674   tvh_pipe_close(&spawn_pipe_error);
675   tvh_pipe_close(&spawn_pipe_info);
676   free(spawn_error_buf);
677   free(spawn_info_buf);
678   while ((s = LIST_FIRST(&spawns)) != NULL) {
679     LIST_REMOVE(s, link);
680     free((char *)s->name);
681     free(s);
682   }
683 }
684