Fork and then exec problem with signals


 
Thread Tools Search this Thread
Top Forums Programming Fork and then exec problem with signals
# 1  
Old 10-06-2010
Question Fork and then exec problem with signals

Hi All,

In my program i am handling SIGHUP signal. In the handler i fork and then exec on child process same binary file which is running. Parent process will die after 10 mins.
Now my child process which was exec with same binary file is not receiving SIGHUP signal. Below is the progran code:
Code:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
pid_t pid;
void sigHandler(int signo)
{
  printf("[%d]signal received \n",getpid());
  pid = fork();
  if(pid  ==  0)
  {
    printf("[%d] I m child process \n",getpid());
    signal(SIGHUP,sigHandler);
    execl("./chainNew", "chainNew", (char *)0);
  }
  else if(pid > 0)
  {
    printf("[%d] I m Parent process \n",getpid());
    <Logic so i will exit after 10 mins.>
    exit(0);
  }
  else
  {
    printf("[%d]  Fork Failed \n",getpid());
  }
}
int main ()
{
  signal(SIGHUP,sigHandler);
  signal (SIGCHLD, SIG_IGN);
  while (1)
  {
    printf("[%d] Waiting for SIGHUP \n",getpid());
    sleep(2);
  }
}


Last edited by Franklin52; 10-06-2010 at 08:44 AM.. Reason: Please use code tags.
# 2  
Old 10-06-2010
Why would it get SIGHUP when SIGHUP has already been handled?
# 3  
Old 10-07-2010
Hi ,

As parent will die after 10 mins, i have a requirement where by now child will have to receive SIGHUP signal and repeat the process by creating further child of it.
As soon this grand child will be created the previous child will die after 10 mins.
this way it will go on....

But as the parent child is dying my child process is not receiving SIGHUP signal.

Hope u understand the problem.
# 4  
Old 10-07-2010
Code:
else if(pid > 0)
  {
    printf("[%d] I m Parent process \n",getpid());
    <Logic so i will exit after 10 mins.>
    exit(0);
  }

as posted this will exit immediately on the first SIGHUP, the <Logic ...> part will not compile, so you might want to show that
# 5  
Old 10-07-2010
Yes, Find below the code.. Smilie

Code:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
pid_t pid;
void sigHandler(int signo)
{
  printf("[%d]signal received \n",getpid());
  pid = fork();
  if(pid  ==  0)
  {
    printf("[%d] I m child process \n",getpid());
    signal(SIGHUP,sigHandler);
    execl("./chainNew", "chainNew", (char *)0);
  }
  else if(pid > 0)
  {
    printf("[%d] I m Parent process \n",getpid());
    sleep(60*10);
    exit(0);
  }
  else
  {
    printf("[%d]  Fork Failed \n",getpid());
  }
}
int main ()
{
  signal(SIGHUP,sigHandler);
  signal (SIGCHLD, SIG_IGN);
  while (1)
  {
    printf("[%d] Waiting for SIGHUP \n",getpid());
    sleep(2);
  }
}

# 6  
Old 10-07-2010
Are execl(), printf(), and sleep() all async-signal safe?

I don't think execl() is, and I'd bet a lot that printf() isn't, and whether or not sleep() is async-signal safe probably depends on the implementation.

And FWIW, the custom signal-handler will not propagate across any of the exec()-type calls:

Quote:
execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded. The program invoked inherits the calling process's PID, and any open file descriptors that are not set to close-on-exec. Signals pending on the calling process are cleared. Any signals set to be caught by the calling process are reset to their default behaviour. The SIGCHLD signal (when set to SIG_IGN) may or may not be reset to SIG_DFL.
# 7  
Old 10-15-2010
Quote:
Originally Posted by sushil_shalin
Yes, Find below the code.. Smilie

Code:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
pid_t pid;
void sigHandler(int signo)
{
  printf("[%d]signal received \n",getpid());
  pid = fork();
  if(pid  ==  0)
  {
    printf("[%d] I m child process \n",getpid());
    signal(SIGHUP,sigHandler);
    execl("./chainNew", "chainNew", (char *)0);
  }
  else if(pid > 0)
  {
    printf("[%d] I m Parent process \n",getpid());
    sleep(60*10);
    exit(0);
  }
  else
  {
    printf("[%d]  Fork Failed \n",getpid());
  }
}
int main ()
{
  signal(SIGHUP,sigHandler);
  signal (SIGCHLD, SIG_IGN);
  while (1)
  {
    printf("[%d] Waiting for SIGHUP \n",getpid());
    sleep(2);
  }
}

When you install any signal handler, they are just installed and not executed untill the signal is received by them.

Now from your code its clear that you are not creating any child inside the main(). However, the SIGHUP is handled, what does it mean is that untill the calling shell program exits; this process is not going to get SIGHUP rather it runs in the while(1) only.

Now when you exit the bash (or whatever shell you use) itself , the SIGHUP handler gets called (you might not been able to see this after you exited) and here a child gets created which inturn calls execl() to replace the child process memory area with a new binary. In this process, only the PCB is kept by the scheduler but with the EIP reset as well as other execution stack pointers along with the binary text. Hence whatever signals this new binary code has handled only works and not the earlier haldlers hold good.

It means the parent now exits after a sleep of 60 seconds and the child is all togather a new executable with a overridden signal handlers.

Now lets examine a few more cases:
1) This new binary has not handled SIGHUP -means the default disposition would apply, and you won't see your sighandler executing.

2) This new binary has a different handler for SIGHUP -it'll execute only that and not the above signalhandler which you wrote.

3) This new binary is the same your executable -It should go in the execution scenario which you are expecting, however there is a default timeout is associated with the signal handlers when the Linux kernel executes them asychronously. Hence the fork() and the sleep of 60 seconds inside the handler is not advicable; instead use vfork() and a sleep of not more than a few hundred miliseconds.

I feel you should use a different terminal to see the results or call bash on your default the login shell prompt before starting your program in the background (& option) and then exit bash to see the results.

Last edited by Praveen_218; 10-15-2010 at 03:44 PM.. Reason: Typo error correction.
This User Gave Thanks to Praveen_218 For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Question about global environment variables & fork() exec()

Hello... And thanks in advance for any help anyone can offer me on my question! I've been doing a lot of reading to try and find my answer... But I haven't had any luck What I'm trying to understand is where a child process inherits global environment variables from? I understand the exec()... (2 Replies)
Discussion started by: bodisha
2 Replies

2. UNIX for Dummies Questions & Answers

fork with exec

What is is difference between 'fork with exec' and 'fork without exec'? How both are related? (1 Reply)
Discussion started by: kkalyan
1 Replies

3. Programming

Newbie question on exec,fork, wait,pipe C

Hello everybody.I want to make clear that i am not going to ask from anybody to build my asignement but i have a big problem. I can't seem to find anywhere ONE good example on C about what i am trying to do:wall:.I think it is simple. All i ask is one example, even a link is fine. So, i want to... (1 Reply)
Discussion started by: Cuervo
1 Replies

4. Programming

How forbid use fork() in exec() program.

Hello World! I am writing code in C++ which have to launch another application X using exec(). I would like to set some limits on it using setrlimit etc... My problem is that i don't know how to forbid using fork() and strlimit by application X. How can i do it? (3 Replies)
Discussion started by: kzi
3 Replies

5. Shell Programming and Scripting

fork and exec

I need to ssh to a remote server and run my script there. This is my script. $ssh = "ssh username@host"; $cmd = "$ssh 'cd <my dir> && < sudo Run_exe>'"; my $pid = fork; if ($pid == 0){ exec $cmd; } When I run this I get: pccons_getchar: got r == 0 (1 Reply)
Discussion started by: looza
1 Replies

6. Solaris

fork and exec ftp

Hi, I need to find/implement an application that FTPs (puts) all new files in a certain directory to an external storage unit. This application should check for new files every 10 seconds (leaving the FTP connection open in between the 10 seconds). The easiest way would be if there are... (2 Replies)
Discussion started by: KittyJ
2 Replies

7. Programming

fork/exec clobbers write. I need ideas why...

On my *nix box, I have a telegram program. When I go like tel person "la\nla\nla\n" the person sees "la\nla\nla\n" However, when I have a program that forks and execs tel like: pid = fork(); if (pid < 0) { perror("fork failed"); exit(EXIT_FAILURE); } if (pid == 0) {... (7 Replies)
Discussion started by: frequency8
7 Replies

8. UNIX for Dummies Questions & Answers

FORK/EXEC technique

Hi! Can someone explain me exactly this technique? Why a process (PARENT) creates a copy of itself with FORK (CHILD)? What's the reason of this behaviour? Sorry, but I cannot understand the logic behind it. Thanks. (4 Replies)
Discussion started by: marshmallow
4 Replies

9. Programming

Problem with signals - 3 process communication

Hello, I would like to ask you for a little help with program I'm working on. I have problems with signals and synchronizing processes (I'm quite new to this part of programming). Process "parent" creates new child process "child1" and this process creates new child process "child2". The... (2 Replies)
Discussion started by: Nightwright
2 Replies

10. Programming

Fork and exec

Hello! I am working on a server where I should have 4 (resident)processes, one of them being "the father" of the others, so I do 3 forks. The problem that I have is that I do an accept (for sockets) in the "father" process and I want to transmit the job to one of the processes "child" with... (3 Replies)
Discussion started by: driki
3 Replies
Login or Register to Ask a Question