IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

interruption d'appel système par un signal


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2025
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2025
    Messages : 4
    Par défaut interruption d'appel système par un signal
    Hello,

    je souhaite qu'un programme suspendu par un appel system bloquant (read(2)) reprenne le contrôle lors de la réception d'un signal. La doc de read(2) indique bien un code de retour EINTR et renvoie vers signal(7) qui mentionne le drapeau SA_RESTART nécessaire lors du positionnement du "handler" du signal pour que ça fonctionne... mais benh si je suis là à poser la question... c'est que ça ne marche pas... je dois faire qqch de travers? Mais quoi?

    ci-dessous un petit bout de code pour illustrer ce que j'aimerai voir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    ~ > cat eintr.c
    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <errno.h>
    #include <assert.h>
    #include <string.h>
     
    #define BUFSIZE 100
     
    void handler(int s);
    void reader(int fd);
     
    int main()
    {
        struct sigaction sigact;
     
        sigact.sa_handler = &handler;
        sigact.sa_flags = SA_RESTART;
        sigaction(SIGTERM, &sigact, NULL);
        sigaction(SIGINT, &sigact, NULL);
     
        reader(0);
    }
     
    void handler(int s)
    {
        fprintf(stderr, "received signal %d\n", s);
    }
     
    void reader(int fd)
    {
        char buffer[BUFSIZE+1];
        int ret = -1;
     
        while(ret <= 0)
        {
            ret = read(fd, buffer, BUFSIZE);
            if(ret < 0)
                if(errno == EINTR)
                    fprintf(stderr, "Signal received in read() call, looping\n");
                else
                    fprintf(stderr, "read() failed with error: %s\n", strerror(errno));
            else
                if(ret == 0)
                    fprintf(stderr, "Reached End of File\n");
                else /* ret > 0 , but ret should be less than or equal to BUFSIZE */
                {
                    assert(ret <= BUFSIZE);
                    buffer[ret+1] = '\0';
                    fprintf(stderr, "read() provided %n bytes: %s", ret, (char*)(buffer));
                }
        }
    }
    Or, une fois le programme lancé, par exemple taper CTRL-C (signal SIGINT) ne fait pas sortir de l'appel system read() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    ~ >./eintr
    coucou
    read() provided 7 bytes: coucou
     
     ~ >./eintr
    ^Creceived signal 2
    ^Creceived signal 2
    ^Creceived signal 2
    ^Creceived signal 2
    ^Creceived signal 2
    ^Creceived signal 2
    des idées de ce qui cloche dans ce que je fais ???
    merci pour toute aide

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Tu sembles être sous Linux, je ne le connais pas bien. Je te propose de remplir tous les champs non utilisés à zéro et de ne surtout pas utiliser SA_RESTART (il sert justement en cas de signal de garder les fonctions en attente).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct sigaction sigact = {0};
     
        sigact.sa_handler = &handler;
        sigact.sa_flags = 0;
        sigaction(SIGTERM, &sigact, NULL);
        sigaction(SIGINT, &sigact, NULL);

  3. #3
    Membre à l'essai
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2025
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2025
    Messages : 4
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Bonjour,

    Tu sembles être sous Linux, je ne le connais pas bien.
    Bonjour,

    oui, Linux et FreeBSD, j'ai essayé plusieurs OS Unix.

    Je te propose de remplir tous les champs non utilisés à zéro et de ne surtout pas utiliser SA_RESTART (il sert justement en cas de signal de garder les fonctions en attente).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct sigaction sigact = {0};
     
        sigact.sa_handler = &handler;
        sigact.sa_flags = 0;
        sigaction(SIGTERM, &sigact, NULL);
        sigaction(SIGINT, &sigact, NULL);
    Ben, malheureusement, les symptomes ne changement pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ~ >./eintr
    ^Creceived signal 2
    Signal received in read() call, looping
    ^Creceived signal 2
    Signal received in read() call, looping
    ^Creceived signal 2
    Signal received in read() call, looping
    ^Creceived signal 2
    Signal received in read() call, looping
    coucou
    read() provided 7 bytes: coucou
    ~ >
    merci quand même pour la suggestion

  4. #4
    Membre à l'essai
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2025
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2025
    Messages : 4
    Par défaut problème résolu !
    Effectivement il ne fallait utiliser le drapeau SA_RESTART, qui fait le contraire de ce que je cherche à faire...

    Mais ça ne suffit pas, avec la glibc (libc standard utilisée sous bon nombre de distro Linux) pour activer la possibilité de sortir d'un appel système (ici read(2)) avec le code d'erreur EINTR il faut ajouter ces macros:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    /* for glibc 2.19 and earlier  */
    #define _BSD_SOURCE 1
     
    /* since glibc 2.19 */
    #define _DEFAULT_SOURCE 1
    On obtient alors le comportement attendu (interruption de read() avec errno à EINTR)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ~ >./eintr
    ^Creceived signal 2
    Signal received in read() call, looping
    ^Creceived signal 2
    Signal received in read() call, looping
    hello world!
    read() provided 13 bytes: hello world!
    ~ >

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme appel constructeur par default en extern
    Par Delgador dans le forum C++
    Réponses: 3
    Dernier message: 25/04/2007, 16h15
  2. Stopper un thread par un signal
    Par kazh75 dans le forum Général Python
    Réponses: 4
    Dernier message: 04/04/2007, 14h53
  3. Réponses: 2
    Dernier message: 15/01/2007, 14h35
  4. Appeler Access par commande
    Par sgauvin dans le forum Access
    Réponses: 2
    Dernier message: 01/12/2005, 21h42
  5. [VB.Net] Problème appel fonction par un bouton
    Par balibo dans le forum ASP.NET
    Réponses: 4
    Dernier message: 25/11/2005, 10h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo