Reputation: 6929
There is a simple program below that takes a HUP and continues with execv. The problem is when the execv call is executed, after that the code continues from the places where the HUP comes.I want, after execv the code must exit from main and than start again from the beginning of main.
char* a;
char** args;
void hup_func(){
printf("aaaa\n");
if(execv(a,args))
printf("bbb\n");
}
int main(int argc,char* argv[]){
signal(SIGHUP,hup_func);
args=argv;
a=args[0];
printf("%s\n",a);
while(1){
printf("test\n");
sleep(10);
}
return 0;
}
The name of the program is deneme1. The output of the code is when I sent HUP;
./deneme1
test
test
aaa
bbbb
test.
But I want it, when I sent HUP, it must start with the start of the main. like that
./deneme1
test
test
aaa
bbb
./deneme1
test
...
I want it to return at the beginning of the main after HUP, not the place where it was before
Upvotes: 1
Views: 2574
Reputation: 32510
You're not sending the correct arguments to execv
, and therefore the function is exiting with an error. So you're simply exiting the signal handler rather than overlaying the process with a new copy of the process.
The argument signature for execv
is:
int execv(const char *path, char *const argv[]);
The second argument should be an array of const
pointers to char
, with the last element being a NULL
pointer. The char* a
that you're passing for the second argument is not the correct type.
Finally, execv
is not considered an asynchronous signal-safe function, where-as it's sister-function, execve
is. You should use the latter. The same is also true for any of the printf
family of functions ... if you need to write to the terminal, use write
instead.
Update: I re-ran your updated code. The program is restarting properly, but the problem is that the signal mask is being inherited from the original process that was overlaid by the call to execv
. Since you are running execv
from inside a signal-handler, the SIGHUP
will be blocked in the overlaid process, and you won't be able to send any other SIGHUP
signals to the process. To undo this, you need to unblock the SIGHUP
signal using sigprocmask()
right after you assign your signal-handler using signal()
.
For instance, change your main
to:
int main(int argc,char* argv[])
{
sigset_t signal_mask;
signal(SIGHUP,hup_func);
//unblock the SIGHUP signal if it's blocked
sigaddset(&signal_mask, SIGHUP);
sigprocmask(SIG_UNBLOCK, &signal_mask, NULL);
args=argv;
a=args[0];
printf("%s\n",a);
while(1){
printf("test\n");
sleep(10);
}
return 0;
}
I've compiled and run this on Ubuntu 12.04, and it now runs perfectly.
Upvotes: 2
Reputation: 3037
As @Jason pointed, execv is failing. Test yourself with this code.
#include<signal.h>
char* a;
char **args;
void hup_func(){
printf("receivied SIGHUP\n");
execv(a,a);
printf("execv failed\n");
}
int main(int argc,char* argv[]){
int b =0;
printf("setting signal handler for SIGHUP\n");
signal(SIGHUP,hup_func);
args=argv;
a=argv[0];
printf("Before entering while %s\n",a);
while(1){
printf("In while %d\n",++b);
sleep(1);
}
return 0;
}
Then replace
execv(a,a);
with
execv(a,args);
Upvotes: 0
Reputation: 136238
The problem is when the execv call is executed, after that the code continues from the places where the HUP comes
There is no error checking in your code, most likely execv()
call fails.
Try amending it like:
char** gargv;
void hup_func() {
execvp(*gargv, gargv);
abort(); // must never get here
}
int main(int argc,char* argv[]) {
// ...
gargv = argv;
// ...
Upvotes: 0