PDA

View Full Version : Pass user parameter to signal handler in linux



nima0102
04-02-2012, 12:32 PM
Hi
In my program, I want to use signal handler so that if signal alarm is sent to the process my function is to called.till no everything is ok.but I want to pass some parameters to signal handler.but "signal" function does not have any parameter for this. according to it's prototype:

sighandler_t signal (int signum, sighandler_t action)


Thanks for any help or guidance

Elkvis
04-02-2012, 01:43 PM
there's also sigaction (http://linux.die.net/man/2/sigaction), but it also doesn't allow a user-defined pointer to be sent to the handler. there may be a way to do it, but as far as I know, signal and sigaction are the only way to get signals in linux.

anduril462
04-02-2012, 03:04 PM
Unfortunately there is no way to pass user data to the signal handler. This is actually one of the few cases where global variables are an acceptable solution.

brewbuck
04-02-2012, 04:31 PM
A signal handler is a global object in every sense. If you need to "pass" data into it, it must be done with a global variable.

nima0102
04-02-2012, 11:54 PM
Hi
Thanks for your reply.
I did not want to use Global Variable at all.But I think there is no any way.
Maybe it's better that I study more on limitation and disadvantage of global variables.I always think that use of Global Variable is bad idea in program.

Thanks in advance

MK27
04-03-2012, 06:11 AM
You can put the signal handler in a file by itself like this:



static void *Data;

void initializeData (void *p) {
Data = p;
}

void handler (int sig) {
// access *Data here
}


Then you call initializeData() before you register the handler with signal(). Since *Data is declared static, only handler() has access to it.

However, if you are adverse to globals, you might also want to think about how a signal handler is itself "a global object in every sense" even if it doesn't access any data, implying it has a restricted use value. What signal do you want to catch and why?

nima0102
04-03-2012, 07:10 AM
In our program I have used timer for some purpose. I have used "create_time" with signal alarm,after timer expiration, one signal alarm is sent to my process.
So I have to handle signal in my program.

Thanks again

MK27
04-03-2012, 07:29 AM
What's the purpose of the timer? If the signal handler initiates a sequence where you are writing to anything used elsewhere, or reading data that the process might have been writing to at the time, I would think this is subject to the same caveats as threading, namely, that even with a single int, it is possible that you occasionally interrupt a write halfway through (meaning, reading from that int will produce a garbage value), in which case you would be better off actually using a thread and proper thread safe locks on the data.



#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// compile C99 -lpthread

// for passing data to the timer
struct threadData {
pthread_mutex_t *lock;
int sleepTime;
int *data;
};

// timer function
void *timer (void *data) {
struct threadData *td = data;

sleep(td->sleepTime);

pthread_mutex_lock(td->lock);
// reset
*(td->data) = 0;
pthread_mutex_unlock(td->lock);

return NULL;
}

int main(void) {
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int x = 1;
struct threadData data = {
.lock = &lock,
.sleepTime = 3,
.data = &x
};
pthread_t id;

// create and detach the timer
pthread_create(&id, NULL, timer, (void*)&data);
pthread_detach(id);

// do stuff until the timer goes off
while (1) {
pthread_mutex_lock(&lock);
if (!x) break;
printf("%d\n", x++);
pthread_mutex_unlock(&lock);
}

printf("done\n");

pthread_mutex_destroy(&lock);

return 0;
}

phantomotap
04-03-2012, 08:02 AM
The only way I know to do this portably would see you using a thread to watch a variable triggered by the signal anyway; you should just use "Posix" facilities from the outset.

Soma