WvStreams
wvsubproc.h
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * A class for reliably starting/stopping subprocesses.
00006  *
00007  * We want to avoid calling system(), since it uses the shell (and
00008  * thus has strange parsing weirdness, environment variable changes,
00009  * and so on).  Plus calling the shell when we need to is just slow.
00010  * 
00011  * On the other hand, we want handy features like the ability to wait
00012  * for our child process to die, and the ability to kill it if it
00013  * doesn't (without having to use "killall").
00014  * 
00015  * By using setsid(), we also deal with strange situations like
00016  * scripts which launch other programs.  stop() and kill() will kill
00017  * them all. (If you don't want that, use stop_primary() and
00018  * kill_primary().)
00019  */
00020 #ifndef __WVSUBPROC_H
00021 #define __WVSUBPROC_H
00022 
00023 #include "wvstringlist.h"
00024 
00025 #include <stdarg.h>
00026 #include <signal.h>
00027 #include <time.h>
00028 
00029 class WvSubProc
00030 {
00031 public:
00032     DeclareWvList(pid_t);
00033     pid_tList old_pids;
00034     
00035     pid_t pid;
00036     bool running;
00037     int estatus;
00038     WvString pidfile, last_cmd, app;
00039     WvStringList last_args, env;
00040     
00041     WvSubProc() 
00042         { init(); }
00043 
00044     WvSubProc(const char cmd[], const char * const *argv)
00045         { init(); startv(cmd, argv); }
00046 
00047     virtual ~WvSubProc();
00048     
00049 private:
00050     void init();
00051     int _startv(const char cmd[], const char * const *argv);
00052 
00053     int memlimit;
00054     
00055 public:
00056     void prepare(const char cmd[], ...);
00057     void preparev(const char cmd[], va_list ap);
00058     void preparev(const char cmd[], const char * const *argv);
00059     void preparev(const char cmd[], WvStringList &);
00060     
00061     // launch a subprocess, which will be owned by this object.
00062     int start(const char cmd[], ...);
00063     
00064     int startv(const char cmd[], const char * const *argv);
00065     virtual int start_again();
00066     
00067     virtual int fork(int *waitfd);
00068 
00069     // stop (kill -TERM or -KILL as necessary) the subprocess and
00070     // all its children.
00071     virtual void stop(time_t msec_delay, bool kill_children = true);
00072     
00073     // wait for the subprocess (and all its children) to die.
00074     virtual void wait(time_t msec_delay, bool wait_children = true);
00075 
00076     // figure out the pid from the /var/run pidfile
00077     pid_t pidfile_pid();
00078 
00080     // use
00081     void setMemLimit(int megs) { memlimit = megs; }
00082     
00083     // send a signal to the subprocess and all its children.
00084     void kill(int sig);
00085     
00086     // send a signal only to the main subprocess.
00087     void kill_primary(int sig);
00088     
00089     // suspend the process temporarily, or resume it.
00090     virtual void suspend()
00091         { kill(SIGSTOP); }
00092     virtual void resume()
00093         { kill(SIGCONT); }
00094 };
00095 
00096 DeclareWvList(WvSubProc);
00097 
00098 #endif // __WVSUBPROC_H