9 #include "wvtimeutils.h"
12 #include <sys/types.h>
21 void WvSubProc::init()
30 WvSubProc::~WvSubProc()
38 int WvSubProc::_startv(
const char cmd[],
const char *
const *argv)
55 memset(&rlim, 0,
sizeof(rlim));
56 rlim.rlim_cur = memlimit * 1024 * 1024;
57 rlim.rlim_max = memlimit * 1024 * 1024;
58 setrlimit(RLIMIT_AS, &rlim);
63 execvp(cmd, (
char *
const *)argv);
79 void WvSubProc::prepare(
const char cmd[], ...)
88 void WvSubProc::preparev(
const char cmd[], va_list ap)
95 while ((argptr = va_arg(ap,
const char *)) != NULL)
96 last_args.append(
new WvString(argptr),
true);
100 void WvSubProc::preparev(
const char cmd[],
const char *
const *argv)
102 const char *
const *argptr;
107 for (argptr = argv; argptr && *argptr; argptr++)
108 last_args.append(
new WvString(*argptr),
true);
111 void WvSubProc::preparev(
const char cmd[],
WvStringList &args)
116 WvStringList::Iter i(args);
117 for (i.rewind(); i.next(); )
118 last_args.append(
new WvString(*i),
true);
121 int WvSubProc::start(
const char cmd[], ...)
128 return start_again();
132 int WvSubProc::startv(
const char cmd[],
const char *
const *argv)
135 return start_again();
139 int WvSubProc::start_again()
147 const char **argv =
new const char*[last_args.count() + 1];
148 WvStringList::Iter i(last_args);
149 for (argptr = argv, i.rewind(); i.next(); argptr++)
154 retval = _startv(last_cmd, argv);
163 int WvSubProc::fork(
int *waitfd)
165 static WvString ldpreload, ldlibrary;
182 WvStringList::Iter i(env);
183 for (i.rewind(); i.next(); )
189 if (name ==
"LD_LIBRARY_PATH" && getenv(
"LD_LIBRARY_PATH"))
194 ldlibrary =
WvString(
"%s=%s:%s", name,
195 value, getenv(
"LD_LIBRARY_PATH"));
196 putenv(ldlibrary.
edit());
199 else if (name ==
"LD_PRELOAD" && getenv(
"LD_PRELOAD"))
204 ldpreload =
WvString(
"%s=%s:%s", name,
205 value, getenv(
"LD_PRELOAD"));
206 putenv(ldpreload.
edit());
232 pid_t WvSubProc::pidfile_pid()
239 FILE *file = fopen(pidfile,
"r");
241 memset(buf, 0,
sizeof(buf));
242 if (file && fread(buf, 1,
sizeof(buf), file) > 0)
255 void WvSubProc::kill(
int sig)
257 assert(!running || pid > 0 || !old_pids.isempty());
264 if (::kill(-pid, sig) < 0 && errno == ESRCH)
269 pid_tList::Iter i(old_pids);
270 for (i.rewind(); i.next(); )
273 assert(subpid != 1 && subpid != -1);
274 if (::kill(-subpid, sig) < 0 && errno == ESRCH)
280 void WvSubProc::kill_primary(
int sig)
282 assert(!running || pid > 0 || !old_pids.isempty());
284 if (running && pid > 0)
289 void WvSubProc::stop(time_t msec_delay,
bool kill_children)
298 kill_primary(SIGTERM);
300 wait(msec_delay, kill_children);
308 kill_primary(SIGKILL);
310 wait(-1, kill_children);
315 void WvSubProc::wait(time_t msec_delay,
bool wait_children)
320 struct timeval tv1, tv2;
323 assert(!running || pid > 0 || !old_pids.isempty());
328 xrunning = (running || (wait_children && !old_pids.isempty()));
330 if (!xrunning)
return;
332 gettimeofday(&tv1, &tz);
343 dead_pid = waitpid(pid, &status, (msec_delay >= 0) ? WNOHANG : 0);
349 || (dead_pid < 0 && (errno == ECHILD || errno == ESRCH)))
353 old_pids.append(
new pid_t(pid),
true);
355 pid_t p2 = pidfile_pid();
361 else if (dead_pid < 0)
362 perror(
"WvSubProc::waitpid");
368 pid_tList::Iter i(old_pids);
369 for (i.rewind(); i.next(); )
376 waitpid(subpid, NULL, WNOHANG);
378 if (::kill(-subpid, 0) && errno == ESRCH)
385 if (!wait_children || old_pids.isempty())
390 if (xrunning && msec_delay != 0)
393 gettimeofday(&tv2, &tz);
395 }
while (xrunning && msec_delay
396 && (msec_delay < 0 || msecdiff(tv2, tv1) < msec_delay));