|
Home > Archive > Unix Programming > January 2006 > fork, exec, and killing a child process manually while it's running
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
fork, exec, and killing a child process manually while it's running
|
|
| simonboland@gmail.com 2006-01-25, 8:38 am |
| I'm experimenting with a problem where I want to have a parent process
continue running even when its child process is killed my mistake.
I'm testing this with a simple program below.
What I do is this:
1) Run the program where the child process tries to telnet to another
machine. The parent sits in a loop and tries to read input from the
stdin.
2) I then find the pid of the telnet process and kill it from another
terminal, i.e. kill -9 <insert telnet pid>
The problem I have is that when I kill it, I get the character string
"Enter something" displayed continually to the stdout. I'm not sure
why this is occurring. Can someone explain why this is occurring and
what I can do to fix the problem?
Thanks.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/types.h>
#include <string>
#include <iostream>
#include <errno.h>
void signal_handler(int signal_id)
{
pid_t pid;
int stat;
switch(signal_id)
{
case SIGCHLD:
pid = waitpid(-1, &stat, WNOHANG);
std::cout << "signal_handler: caught SIGCHLD, pid " << pid << "
terminated\n";
break;
default:
// Should not be here
break;
}
}
void InitSignalHandler()
{
struct sigaction signal_action;
signal_action.sa_handler = signal_handler;
sigemptyset(&signal_action.sa_mask);
signal_action.sa_flags = 0;
int main()
{
InitSignalHandler();
int childPID = fork();
if (childPID < 0)
{
return -1;
}
else if (childPID == 0)
{
char* arguments[] = {"telnet", "mymachine.com", (char *) 0};
if (execvp("/usr/bin/telnet", arguments) != 0)
{
std::cout << "execlp failed \n";
return -1;
}
return -1;
}
// The parent
char ch;
do
{
std::cout << "Enter something:\n";
std::cin >> ch;
}
while (ch != 'q');
return 0;
}
| |
| Fletcher Glenn 2006-01-29, 9:31 pm |
| simonboland@gmail.com wrote:
> I'm experimenting with a problem where I want to have a parent process
> continue running even when its child process is killed my mistake.
> I'm testing this with a simple program below.
>
> What I do is this:
> 1) Run the program where the child process tries to telnet to another
> machine. The parent sits in a loop and tries to read input from the
> stdin.
> 2) I then find the pid of the telnet process and kill it from another
> terminal, i.e. kill -9 <insert telnet pid>
>
> The problem I have is that when I kill it, I get the character string
> "Enter something" displayed continually to the stdout. I'm not sure
> why this is occurring. Can someone explain why this is occurring and
> what I can do to fix the problem?
>
> Thanks.
>
> #include <stdio.h>
> #include <unistd.h>
> #include <signal.h>
> #include <sys/wait.h>
> #include <sys/types.h>
> #include <sys/time.h>
> #include <sys/types.h>
> #include <string>
> #include <iostream>
> #include <errno.h>
>
> void signal_handler(int signal_id)
> {
> pid_t pid;
> int stat;
>
> switch(signal_id)
> {
> case SIGCHLD:
> pid = waitpid(-1, &stat, WNOHANG);
> std::cout << "signal_handler: caught SIGCHLD, pid " << pid << "
> terminated\n";
> break;
> default:
> // Should not be here
> break;
> }
> }
>
> void InitSignalHandler()
> {
> struct sigaction signal_action;
> signal_action.sa_handler = signal_handler;
> sigemptyset(&signal_action.sa_mask);
> signal_action.sa_flags = 0;
>
> int main()
> {
> InitSignalHandler();
> int childPID = fork();
>
> if (childPID < 0)
> {
> return -1;
> }
> else if (childPID == 0)
> {
> char* arguments[] = {"telnet", "mymachine.com", (char *) 0};
> if (execvp("/usr/bin/telnet", arguments) != 0)
> {
> std::cout << "execlp failed \n";
> return -1;
> }
>
> return -1;
> }
>
> // The parent
> char ch;
> do
> {
> std::cout << "Enter something:\n";
> std::cin >> ch;
> }
> while (ch != 'q');
>
> return 0;
> }
>
Your function InitSignalHandler() is incomplete, so it's hard
to say what's happening. However, from your description, it sounds
like cin is being interrupted by a signal other than SIGCHLD.
Try putting a cout on the default of your signal handler
switch and see what signal is being delivered. On the other
hand, you could also try running the parent process in
a debugger and seeing exactly what is happening.
--
Fletcher Glenn
| |
| Gordon Burditt 2006-01-29, 9:31 pm |
| >I'm experimenting with a problem where I want to have a parent process
>continue running even when its child process is killed my mistake.
>I'm testing this with a simple program below.
>
>What I do is this:
>1) Run the program where the child process tries to telnet to another
>machine. The parent sits in a loop and tries to read input from the
>stdin.
>2) I then find the pid of the telnet process and kill it from another
>terminal, i.e. kill -9 <insert telnet pid>
>
>The problem I have is that when I kill it, I get the character string
>"Enter something" displayed continually to the stdout. I'm not sure
>why this is occurring. Can someone explain why this is occurring and
>what I can do to fix the problem?
Your program needs to recognize EOF when it sees it. What you *DO*
in that situation is problematic. You want to continue reading
from a dead child? Why?
Gordon L. Burditt
| |
| Mark B 2006-01-29, 9:31 pm |
| "Fletcher Glenn" <fletcher@removethisfoglight.com> wrote in message
news:aONBf.16502$Yu.9286@newssvr27.news.prodigy.net...
> simonboland@gmail.com wrote:
<snip>
<snip>[vbcol=seagreen]
> Your function InitSignalHandler() is incomplete, so it's hard
> to say what's happening. However, from your description, it sounds
> like cin is being interrupted by a signal other than SIGCHLD.
> Try putting a cout on the default of your signal handler
> switch and see what signal is being delivered. On the other
> hand, you could also try running the parent process in
> a debugger and seeing exactly what is happening.
I believe Gordon's response properly explains why OP is having a problem,
but I have a question about OP's code, and your suggestion.
In C, calling any standard library function other than abort() or signal()
(with
first arg equal to signal which invoked the handler) inside of a signal
handler
invokes undefined behavior.
Is this not the case in C++?
Is this one of the places in which the languages differ?
Is my question flawed because cout is not a function? (but a stream object)
Just curious,
Mark
| |
| Bjorn Reese 2006-01-29, 9:31 pm |
| Mark B wrote:
> In C, calling any standard library function other than abort() or signal()
> (with
> first arg equal to signal which invoked the handler) inside of a signal
> handler
> invokes undefined behavior.
>
> Is this not the case in C++?
> Is this one of the places in which the languages differ?
> Is my question flawed because cout is not a function? (but a stream object)
std::cout is not async-signal-safe either. When it comes to signal
handlers it is better to use only functions that you know are safe.
SUSv3 requires the following functions to be safe:
http://www.opengroup.org/onlinepubs..._chap02_04.html
--
mail1dotstofanetdotdk
| |
| Jordan Abel 2006-01-29, 9:31 pm |
| On 2006-01-25, Bjorn Reese <breese@see.signature> wrote:
> Mark B wrote:
>
>
> std::cout is not async-signal-safe either. When it comes to signal
> handlers it is better to use only functions that you know are safe.
> SUSv3 requires the following functions to be safe:
I assume by std::cout you actually mean std::cout.operator<< in its
various instances.
>
> http://www.opengroup.org/onlinepubs..._chap02_04.html
>
|
|
|
|
|