tests: verify live daemon cleanup
This commit is contained in:
@@ -228,12 +228,15 @@ startdaemon(Daemon *d, char *program, char *mapdir)
|
||||
dup2(errpipe[1], STDERR_FILENO) < 0)
|
||||
_exit(126);
|
||||
close(errpipe[1]);
|
||||
setenv("XDG_RUNTIME_DIR", d->runtime, 1);
|
||||
setenv("XDG_CONFIG_HOME", d->config, 1);
|
||||
setenv("HOME", d->home, 1);
|
||||
unsetenv("DISPLAY");
|
||||
unsetenv("DBUS_SESSION_BUS_ADDRESS");
|
||||
unsetenv("IBUS_ADDRESS");
|
||||
if(setenv("XDG_RUNTIME_DIR", d->runtime, 1) < 0 ||
|
||||
setenv("XDG_CONFIG_HOME", d->config, 1) < 0 ||
|
||||
setenv("HOME", d->home, 1) < 0 || unsetenv("DISPLAY") < 0 ||
|
||||
unsetenv("DBUS_SESSION_BUS_ADDRESS") < 0 ||
|
||||
unsetenv("IBUS_ADDRESS") < 0){
|
||||
dprintf(STDERR_FILENO, "set daemon environment: %s\n",
|
||||
strerror(errno));
|
||||
_exit(126);
|
||||
}
|
||||
execl(program, program, mapdir, missing, (char*)0);
|
||||
dprintf(STDERR_FILENO, "exec %s: %s\n", program, strerror(errno));
|
||||
_exit(127);
|
||||
@@ -297,36 +300,82 @@ rmdirknown(char *path)
|
||||
return fail("rmdir %s: %s", path, strerror(errno));
|
||||
}
|
||||
|
||||
static int
|
||||
killdaemon(Daemon *d, int *status)
|
||||
{
|
||||
int n, ok;
|
||||
|
||||
ok = 1;
|
||||
if(kill(d->pid, SIGKILL) < 0 && errno != ESRCH){
|
||||
fail("kill -9 %ld: %s", (long)d->pid, strerror(errno));
|
||||
ok = 0;
|
||||
}
|
||||
do
|
||||
n = waitpid(d->pid, status, 0);
|
||||
while(n < 0 && errno == EINTR);
|
||||
if(n != d->pid){
|
||||
fail("reap %ld after SIGKILL: %s", (long)d->pid,
|
||||
n < 0 ? strerror(errno) : "wrong child");
|
||||
ok = 0;
|
||||
}else
|
||||
d->pid = -1;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
stopdaemon(Daemon *d)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
int ok, status, n;
|
||||
int ok, status, n, reaped;
|
||||
int64_t deadline;
|
||||
|
||||
ok = 1;
|
||||
if(d->pid > 0){
|
||||
if(kill(d->pid, SIGTERM) < 0 && errno != ESRCH){
|
||||
do
|
||||
n = waitpid(d->pid, &status, WNOHANG);
|
||||
while(n < 0 && errno == EINTR);
|
||||
if(n == d->pid){
|
||||
fail("daemon exited before test termination with wait status %#x",
|
||||
status);
|
||||
d->pid = -1;
|
||||
ok = 0;
|
||||
}else if(n < 0){
|
||||
fail("check daemon %ld before termination: %s",
|
||||
(long)d->pid, strerror(errno));
|
||||
if(errno == ECHILD)
|
||||
d->pid = -1;
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if(d->pid > 0){
|
||||
if(kill(d->pid, SIGTERM) < 0){
|
||||
fail("kill %ld: %s", (long)d->pid, strerror(errno));
|
||||
ok = 0;
|
||||
}
|
||||
reaped = 0;
|
||||
deadline = nowms() + Stoptimeout;
|
||||
for(;;){
|
||||
n = waitpid(d->pid, &status, WNOHANG);
|
||||
if(n == d->pid)
|
||||
if(n == d->pid){
|
||||
reaped = 1;
|
||||
d->pid = -1;
|
||||
break;
|
||||
if(n < 0 && errno != EINTR){
|
||||
}
|
||||
if(n < 0 && errno == EINTR)
|
||||
continue;
|
||||
if(n < 0){
|
||||
fail("waitpid %ld: %s", (long)d->pid, strerror(errno));
|
||||
ok = 0;
|
||||
if(errno == ECHILD)
|
||||
d->pid = -1;
|
||||
break;
|
||||
}
|
||||
n = leftms(deadline);
|
||||
if(n == 0){
|
||||
fail("daemon %ld did not stop after SIGTERM", (long)d->pid);
|
||||
ok = 0;
|
||||
kill(d->pid, SIGKILL);
|
||||
while(waitpid(d->pid, &status, 0) < 0 && errno == EINTR)
|
||||
;
|
||||
if(!killdaemon(d, &status))
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
pfd.fd = d->errfd;
|
||||
@@ -335,14 +384,19 @@ stopdaemon(Daemon *d)
|
||||
if(poll(&pfd, 1, n) < 0 && errno != EINTR){
|
||||
fail("poll daemon %ld: %s", (long)d->pid, strerror(errno));
|
||||
ok = 0;
|
||||
kill(d->pid, SIGKILL);
|
||||
while(waitpid(d->pid, &status, 0) < 0 && errno == EINTR)
|
||||
;
|
||||
if(!killdaemon(d, &status))
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
readerrors(d);
|
||||
}
|
||||
d->pid = -1;
|
||||
/* plan9port turns a caught termination note into exit status 1. */
|
||||
if(reaped &&
|
||||
!((WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM) ||
|
||||
(WIFEXITED(status) && WEXITSTATUS(status) == 1))){
|
||||
fail("daemon exited with unexpected wait status %#x", status);
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
readerrors(d);
|
||||
if(d->errfd >= 0){
|
||||
|
||||
Reference in New Issue
Block a user