I put together a test code to demonstrate the problem that I am having. Hope
I could get some help.
The program starts a child process to do the modem dialing. The
monitor_thread is used to kill the child process when it’s started. ( In
real environment, there is a timer popup, only kill the modem dialing
process when the modem does not get response in certain amount of time. And
we retry this dialing process for a number of times).
The problem is the call to kill() brings down both child and parent process.
The parent process exited with “Terminate” prompt.
Appreciate any help.
-Beth
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <malloc.h>
pid_t pppdPid=-1;
int num=50;
void* monitor_thread(void* arg);
void modemdial(char * argv[]);
int main(int argc, char * argv[])
{
pthread_create( NULL, NULL, &monitor_thread, NULL );
sleep(5);
while (num >0)
{
if (pppdPid==-1)
{
modemdial(argv);
}
printf(“sleep 10 sec, num=%d\n”, num);
sleep(10);
num–;
}
return 1;
}
void sighandler_child()
{
}
void modemdial( char * argv[])
{
char * arg[4];
signal(SIGCHLD, sighandler_child);
printf(" Start dialing process\n ");
//arg[0]=(char *)malloc(sizeof(argv[1]));
arg[0]=(char *)malloc(sizeof("/usr/sbin/pppd"));
//strcpy(arg[0], argv[1]);
strcpy(arg[0], “/usr/sbin/pppd”);
arg[1]=NULL;
if( (pppdPid=spawnvp ( P_NOWAIT, arg[0], arg)) == -1 )
{
printf(“error\n”);
}
printf(“pppdPid=%d\n”, pppdPid);
}
void* monitor_thread(void* arg)
{
int rc;
int status;
pid_t pid;
printf(“monitor thread start\n”);
sleep(5);
while (1)
{
if(pppdPid >0)
{
printf(“Kill child process %d\n”, pppdPid);
rc=kill(pppdPid, SIGTERM);
if(rc <0 )
{
printf(“Kill error rc=%d\n”, rc);
return NULL;
}
wait:
printf(“waitpid…\n”);
pid=waitpid(pppdPid, &status, WNOHANG);
printf(“pid=%d\n”, pid);
if((pid >0) && (pid==pppdPid))
{
printf(“Process %d is killed\n”, pid);
pppdPid=-1;
}
else
goto wait;
}
sleep(5);
}
return NULL;
}
“David Gibbs” <dagibbs@qnx.com> wrote in message
news:bh0gq8$qd3$1@nntp.qnx.com…
Beth <> id@net.com> > wrote:
I am running QNX 6.2.0.
Yes, I do see the SIGTERM comes into the parent process. If I catch the
SIGTERM, the child process wouldn’t die.
It’s waitpid() that is used to wait the child process to complete and
also
wait on kill() to finish.
The question is why the parent is getting the SIGTERM when killing the
child
process?
It shouldn’t.
The most likely case is a bug in your code as to what you pass to
kill().
I don’t know of any OS issues with misdelivery of signals in that
way, and I don’t know of anything that “automatically” generates
a SIGTERM – SIGHUP, SIGCHLD, and others, yes – but not SIGTERM.
So, I don’t have an answer.
-David
Thank you very much for your help.
-Beth
“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:bgs490$hn6$> 1@nntp.qnx.com> …
Beth <> id@net.com> > wrote:
The child process is doing the pppd connection. The kill() worked
most
time,
the only time it didn’t work was when I wanted to kill the child
process
while it’s dialing modem. I don’t know if that would affect the
kill()
process. I did check the pid before calling kill(), the pid is the
child
process id, not value of zero.
Hm… I’m not sure I asked this before, but what OS version are you
running?
If I call signal(SIGCHLD, SIG_IGN) to ignore the signal before spawn
the
child process, it would work as expected, killing the child only.
However my
pidwait() will not catch the SIGCHLD signal, and what else I would
not
be
able to do?
By pidwait() do you mean waitpid()? (Or is pidwait() your own
routine?)
Hm…what happens if you also catch SIGTERM?
You said: ‘The program exited and prompted with “Terminate”’
Was it actually “Terminated”? If so, that is the shell noticing how
you died and saying it was from a SIGTERM.
Though, ignoring SIGCHLD shouldn’t affect SIGTERM behaviour, and if
you died due to a SIGCHLD, I wouldn’t expect the shell to print out
“Terminated” – it would probably pick something else. I don’t know
what, though. Hm… in fact, I can’t SIGCHLD to actually kill
anything.
Can you verify that you are actually getting that SIGTERM?
-David
Thanks,
-Beth
“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:bgra6m$hki$> 1@nntp.qnx.com> …
Beth <> id@net.com> > wrote:
Before calling spawnnvp() to spawn the child process, there is a
call
to
signal( SIGCHLD, sighandler) to set up the signal handler for
SIGCHLD.
The
sighandler{} does nothing. When the child process was killed, the
parent
process did receive SIGCHLD and the sighandler() routine is
called.
Do I
need to add code in sighandler() routine to prevent the parent
process
exit
when the child process died ?
No, having a signal handler will prevent you from dieing.
The only other likely case is if, somehow, the variable you are
passing
to kill() picks up a value of zero somehow… which would send the
SIGTERM to you, instead of your child.
-David
Appreciate your help.
-Beth
“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:bgpdii$2jn$> 15@nntp.qnx.com> …
Beth <> id@net.com> > wrote:
I have a program that spawns a child process by calling
pid=spawnvp(P_NOWAIT… ). When I need to terminate that child
process,
I
used kill(pid, SIGTERM). Sometime, kill() would bring down the
parent
process. The program exited and prompted with “Terminate”.
Any idea what could cause this to happen?
What does the parent do when it gets a SIGCHLD (notification of
child death) signal? When the child dies, the parent will get
this
signal as notification.
-David
QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.
\
QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.
\
QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.
\
QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.