Python signal delivery under BSD 4.4
Donn Cave
donn at u.washington.edu
Wed Aug 13 14:04:12 EDT 2003
In article <m3bruuk080.fsf at drizzle.com>,
"Elf M. Sternberg" <elf at drizzle.com> wrote:
> I'm having a devil of a time with signal handling under BSD 4.4 with
> Python and I was hoping that this might ring a bell with someone. Using
> the Webware Application Server (a multi-threaded Python application), I
> fork off a process to run independently and do some heavy-duty multi-
> threaded I/O churning. The process is launched with os.spawnvp().
>
> The user may, at any time, elect to terminate this process
> before it reaches its end. I do that by having the Application Server
> send a SIGUSR1 signal to the process ID returned by os.spawnvp(), which
> so far has been reliably returned and stored in the appserver's session
> mananger. So far, so good.
>
> This worked well under Python 2.1, where I used os.fork() instead
> of os.spawnvp().
>
> We have upgraded to Python 2.2.3 and it has mysteriously stopped
> working. Processes launched off the appserver, whether using os.fork()
> or os.spawnvp(), are now completely deaf to signals. Nothing gets its
> attention except, of course, SIGKILL. Not when sent from the appserver,
> and not when sent from the shell, not even by root.
>
> If the process is launched from the command line, however, it
> is well-behaved and responds to signal reliably.
>
> What gives?
Don't know. Can you duplicate it in a simpler environment?
I'd like to run the following C program from spawnv, from a
Python program like
import os
import time
import signal
p = os.spawnv(os.P_NOWAIT, 'prsig', ['prsig'])
time.sleep(1.0)
os.kill(p, signal.SIGTERM)
print 'process exit', os.waitpid(p, 0)
if you think that represents what you're doing. This seems
to work as expected with Python 2.2 on a BSD platform (if
your "BSD 4.4" is actually NetBSD 1.6 or FreeBSD 5.1, I could
try that.)
The reasons I can think of in principle are
1. handler set to SIG_IGN (if the child process is supposed
to exit due to the default signal handler.)
2. blocked via signal mask
3. wrong process
Donn Cave, donn at u.washington.edu/donn at drizzle.com
include <signal.h>
#include <stdio.h>
#include <string.h>
static void
handler(int sig)
{
switch (sig) {
case SIGALRM:
fprintf(stderr, "caught SIGALRM\n");
break;
case SIGUSR1:
fprintf(stderr, "caught SIGUSR1\n");
break;
default:
fprintf(stderr, "caught %d\n", sig);
}
exit(0);
}
static void
prsig(int sig)
{
struct sigaction sa;
int status;
memset(&sa, 0, sizeof(sa));
status = sigaction(sig, 0, &sa);
if (status == 0) {
printf("sigaction {\n");
printf(" sa_handler 0x%08x,\n", sa.sa_handler);
printf(" sa_flags 0x%08x\n", sa.sa_flags);
/* printf(" sa_mask 0x%08x\n", sa.sa_mask); */
printf("}\n");
} else {
perror("sigaction query");
exit(2);
}
}
static void
prmask()
{
sigset_t mask;
int status;
status = sigprocmask(SIG_SETMASK, 0, &mask);
if (status == 0)
fprintf(stdout, "mask 0x%lx\n", mask);
else {
perror("sigprocmask");
exit(2);
}
}
static void
sethandler(int sig, void (*hf)(int))
{
struct sigaction sa;
int status;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = hf;
status = sigaction(sig, &sa, 0);
if (status == 0) {
} else {
perror("sigaction");
exit(2);
}
}
static void
pause()
{
char buffer[4];
read(0, buffer, 4);
}
int
main(int argc, char **argv)
{
prsig(SIGUSR1);
prmask();
sethandler(SIGUSR1, handler);
sethandler(SIGALRM, handler);
alarm(3);
pause();
return 0;
}
More information about the Python-list
mailing list