2016-03-27 1 views
1

Je ne sais vraiment pas exactement ce que je fais de mal ici. Je veux extraire le pid d'un appelant du signal entrant, mais la valeur que je reçois est totalement incorrecte.Processus d'appel incorrect lors de la gestion du signal en C

Voici mon code pour "receveur":

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <unistd.h> 

int SIGNALS_RECEIVED = 0; 
pid_t CALLING_PID; 

void signal_received(int sig, siginfo_t *info, void *context) { 
    SIGNALS_RECEIVED++; 

    if(SIGNALS_RECEIVED == 1) { 
     CALLING_PID = info->si_pid; 
     printf("%ld\n", (long) CALLING_PID); 
    } 
} 

int main() { 
    struct sigaction act; 
    act.sa_sigaction = &signal_received; 

    sigaction(SIGUSR1, &act, NULL); 

    while(1) { 

    } 

    return 0; 
} 

Et "expéditeur":

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <unistd.h> 

int main(int argc, char **argv) { 

    char line[10]; 
    FILE *cmd = popen("pidof -s catcher", "r"); 

    fgets(line, 10, cmd); 
    pid_t pid = strtoul(line, NULL, 10); 

    pclose(cmd); 

    int i; 
    for(i = 0; i < 400; i++) { 
     kill(pid, SIGUSR1); 
    } 

    kill(pid, SIGUSR2); 

    return 0; 
} 

En conséquence, lors de l'exécution au premier receveur, puis l'expéditeur, je reçois:

./catcher 
398533948 
SIGNALS_RECEIVED: 24 

Alors que le pid de l'expéditeur est:

ps aux | grep *sender 
maciej 4704 100 0.0 4328 1268 pts/13 R+ 22:46 0:15 ./sender 

Ma version Linux:

Linux version 4.2.0-34-generic ([email protected]) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)) #39~14.04.1-Ubuntu SMP Fri Mar 11 11:38:02 UTC 2016 

Répondre

0

Lire la page de manuel pour sigaction():

sa_handler spécifie l'action à associer à signum ... Cette fonction reçoit le numéro de signal comme seul argument .

Ce n'est pas ce que vous voulez. Vous voulez ceci:

Si SA_SIGINFO est spécifié dans sa_flags, puis sa_sigaction (au lieu de sa_handler) spécifie la fonction de signal de traitement pour signum. Cette fonction reçoit le numéro de signal comme premier argument, un pointeur vers un siginfo_t comme second argument ...

Vous n'avez pas défini le drapeau SA_SIGINFO lorsque vous avez installé le gestionnaire.

Ajoutez la ligne suivante à votre code avant d'appeler sigaction:

act.sa_flags = SA_SIGINFO;