Strange signal/process group feature in HP-UX
Tor Lillqvist
tml at tik.vtt.fi
Wed Feb 6 07:31:46 AEST 1991
We have noticed an interesting feature related to signals and process
groups (and sessions) in HP-UX 7.0 (both s800 and s300). Here is a
description of the scenario:
A process, let's call it "master", detaches itself from the
controlling terminal and wants to be sure it doesn't acquire a new
one:
fork(), setsid(), signal(SIGHUP, SIG_IGN), and fork() again. The last
child is the one that continues executing. Maybe this is overdoing it
a bit.
Now master starts several other processes.
Later you send a SIGSTOP to one of master's children, let's call it foo.
It stops as you would expect.
Then you send a SIGKILL to another of master's children. Now comes
the interesting bit: foo continues!
I even wrote a small demonstration program:
#ifdef __STDC__
#define _HPUX_SOURCE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#define NCHILDREN 5
#define Sleep (void) sleep
#define Printf (void) printf
main(argc, argv)
int argc;
char **argv;
{
int i, j;
pid_t pid, child[NCHILDREN];
long lrand48();
void srand48();
if (argc == 1) {
pid = fork();
if (pid == -1)
perror("fork"), exit(1);
else if (pid > 0)
exit(0);
if (setsid() == -1)
perror("setsid"), exit(1);
(void) signal(SIGHUP, SIG_IGN);
pid = fork();
if (pid == -1)
perror("fork");
else if (pid > 0)
exit(0);
Printf("now in grandchild...\n");
}
Sleep(2);
(void) setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
Printf("starting children...\n");
for (i = 0; i < NCHILDREN; i++) {
child[i] = fork();
if (child[i] == -1)
perror("fork"), exit(1);
else if (child[i] == 0) {
pid = getpid();
for (i = 0; i < 10; i++) {
time_t t = time((time_t*) NULL);
Printf("%d: %s", pid, ctime(&t));
Sleep(5);
}
exit(0);
}
}
Printf("children have started... sleeping again...\n");
Sleep(3);
srand48((long) time((time_t*) NULL));
i = lrand48() % NCHILDREN;
Printf("stopping child %d...\n", child[i]);
if (kill(child[i], SIGSTOP) == -1)
perror("kill"), exit(1);
Sleep(13);
while ((j = lrand48() % NCHILDREN) == i)
;
Printf("killing child %d...\n", child[j]);
if (kill(child[j], SIGKILL) == -1)
perror("kill"), exit(1);
Sleep(200);
return(0);
}
When you run this program you notice that as soon as it says "killing
child %d" the previously stopped one continues...
I tried a similar program on VAX Ultrix 3.1 (using setpgrp and
TIOCNOTTY), and this behaviour didn't occur.
--
Tor Lillqvist,
working, but not speaking, for the Technical Research Centre of Finland
More information about the Comp.unix.wizards
mailing list