Back to index

avfs  1.0.1
prog.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 2000-2001  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 
00009 #include "prog.h"
00010 #include "avfs.h"
00011 
00012 #include <unistd.h>
00013 #include <signal.h>
00014 #include <sys/wait.h>
00015 
00016 char *strsignal(int sig);
00017 
00018 void av_init_proginfo(struct proginfo *pi)
00019 {
00020     pi->prog = NULL;
00021     pi->pid = -1;
00022 
00023     pi->wd = NULL;
00024     pi->ifd = -1;
00025     pi->ofd = -1;
00026     pi->efd = -1;
00027 }
00028 
00029 static char *get_cmdline(const char *args[])
00030 {
00031     char *cat = NULL;
00032 
00033     for(; *args != NULL; args++)
00034         cat = av_stradd(cat, *args, " ", NULL);
00035 
00036     return cat;
00037 }
00038 
00039 int av_start_prog(struct proginfo *pi)
00040 {
00041     char *cmdline = get_cmdline(pi->prog);
00042     av_log(AVLOG_DEBUG, "Starting program %s", cmdline);
00043     av_free(cmdline);
00044 
00045     pi->pid = fork();
00046   
00047     if(pi->pid == -1) {
00048         av_log(AVLOG_ERROR, "Fork failed: %s", strerror(errno));
00049         return -EIO;
00050     }
00051     if(pi->pid == 0) { /* Child */
00052         if(pi->wd != NULL) 
00053             chdir(pi->wd);
00054     
00055         setsid(); /* Don't want to kill my parent if something goes wrong */
00056 
00057         if(pi->ifd != -1) dup2(pi->ifd, 0);
00058         if(pi->ofd != -1) dup2(pi->ofd, 1);
00059         if(pi->efd != -1) dup2(pi->efd, 2);
00060 
00061         execvp(pi->prog[0], (char **) pi->prog);
00062         av_log(AVLOG_ERROR, "Failed to exec %s", pi->prog[0]);
00063         _exit(1);
00064     }
00065 
00066     return 0;
00067 }
00068 
00069 int av_wait_prog(struct proginfo *pi, int tokill, int check)
00070 {
00071     int res;
00072     int retv;
00073 
00074     if(pi->pid == -1)
00075         return 1;
00076 
00077     if(check) {
00078         res = waitpid(pi->pid, &retv, WNOHANG);
00079         if(res == 0)
00080             return 0;
00081     }
00082     else {
00083         if(tokill)
00084             kill(pi->pid, SIGKILL);
00085         
00086         do res = waitpid(pi->pid, &retv, 0);
00087         while(res == -1 && errno == EINTR);
00088     }
00089     pi->pid = -1;
00090 
00091     if(res == -1) {
00092         av_log(AVLOG_ERROR, "waitpid returned error: %s", strerror(errno));
00093         return -EIO;
00094     }
00095 
00096     if(WIFEXITED(retv)) {
00097         int val = WEXITSTATUS(retv);
00098         if(val == 0) {
00099             av_log(AVLOG_DEBUG, "program %s exited normally", pi->prog[0]);
00100             return 1;
00101         }
00102         
00103         av_log(AVLOG_ERROR, "program %s exited with error: %i", pi->prog[0],
00104                  val);
00105     }
00106     else if(WIFSIGNALED(retv))
00107         av_log(AVLOG_ERROR, "program %s: %s", pi->prog[0],
00108                strsignal(WTERMSIG(retv)));
00109     else
00110         av_log(AVLOG_ERROR, "program %s killed with unknown reason",
00111                  pi->prog[0]);
00112 
00113     return -EIO;
00114 }
00115 
00116