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 :

'fdopen' signal l'erreur: 'Illegal seek'


Sujet :

C

  1. #1
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut 'fdopen' signal l'erreur: 'Illegal seek'
    Bonjour ,

    Je suis en train de travailler sur un plug-in en C qui intégre une fonction permettant de passer un anti-spam dans le MTA exim , ceci est documenté avec "local_scan".

    Tout va bien, sauf que je dois momentanément désactiver "errno" en utilisant "fdopen" pour ouvrir le descripteur de fichier d'écriture en objet FILE et y écrit des données.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [...]
     
    fd_file = (FILE *)fdopen(fd_out[0], "r");
    /* 'Illegal seek' */
    if (errno == ESPIPE)
        errno = 0;
     
    if ((FILE *)fd_file == NULL)
        BAIL("pipe failed", strerror(errno), "(FILE *)fd_file");
     
    [...]
    Je sais, ce n'est qu'un bout de code, mais c'est un peu long.

    Des idées, pistes ?

    Merci

  2. #2
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut
    C'est quoi l'erreur exacte affichée?

  3. #3
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par publicStaticVoidMain Voir le message
    C'est quoi l'erreur exacte affichée?
    Juste apres l'ouverture de:

    fd_file = (FILE *)fdopen(fd_out[0], "r");

    la valeur "errno" est équal à "ESPIPE" et "strerror(errno)" dit "Illegal seek"

  4. #4
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut
    EN googlant,j'ai trouvé ça sur internet.

    When the underlying open file descriptor references a pipe
    or FIFO, then a call to fseek() sets errno to ESPIPE,
    returns a non-zero value and the value of the file pointer
    is unchanged.
    http://www.open-std.org/JTC1/SC22/WG...9945-1-58.html

  5. #5
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par publicStaticVoidMain Voir le message
    EN googlant,j'ai trouvé ça sur internet.


    http://www.open-std.org/JTC1/SC22/WG...9945-1-58.html
    Merci

    Donc en lisant cette page et ce qui suit ci-dessous:
    An fseek() on a pipe or FIFO need not return an error. If the fseek()
    detects the error, then it must fail with errno set to ESPIPE.
    The POSIX.1 standard does not specify the state of the stream after
    such an error occurs.
    Donc le "stream" est bien ouvert correctement même si j'ai un 'Illegal seek' ?

    Car le reste du code (en isolant "ESPIPE") se déroule correctement. C'est bon ce que développe ?

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pourquoi tous ces casts explicites, exactement?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    errno n'a de sens que si fdopen() a renvoyé NULL. Il ne faut pas regarder errno avant d'avoir regardé la valeur de retour de fdopen(). Est-ce que dans ton cas fdopen() renvoie NULL ?

  8. #8
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    La valeur "errno" est comparée après le passage de "fdopen".

    Par la suite, si "errno" correspond à "ESPIPE", "errno" est mis à "0" pour être isolée.

    Enfin la valeur de retour de "fdopen" est analysée et n'est jamais à "NULL".

    Comme ce qui suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    fd_file = (FILE *)fdopen(fd_out[0], "r");
    /* 'Illegal seek' */
    if (errno == ESPIPE)
        errno = 0;
     
    if ((FILE *)fd_file == NULL)
        BAIL("pipe failed", strerror(errno), "(FILE *)fd_file");
    Puis ça continue correctement....

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par ListD Voir le message
    La valeur "errno" est comparée après le passage de "fdopen".
    <snip>
    Enfin la valeur de retour de "fdopen" est analysée et n'est jamais à "NULL".
    Erreur.
    Tu ne dois pas t'occuper du tout d'errno si fopen() n'a pas retourné NULL.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Erreur.
    Tu ne dois pas t'occuper du tout d'errno si fopen() n'a pas retourné NULL.
    Bien, donc après un passage de "fdopen" correcte, je dois remettre à zero "errno" qui contient "ESPIPE", et continuer mon chemin sans m'inquiéter de cette "manipulation" ?

    C'est cool le C

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Non, tu ne dois pas remettre errno à zéro. Tu ne touches pas à errno, c'est tout.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Non, tu ne dois pas remettre errno à zéro. Tu ne touches pas à errno, c'est tout.
    Ni cela ?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    /* 'Illegal seek' ? */
    if (errno == ESPIPE)
        errno = 0;

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ben non. Tu ne fais pas ça non plus.
    Pourquoi le ferais-tu?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Et bien avec le mode bavard de cette fonction avec "Exim", j'utilise le retour de "errno" pour analyser le déroulement, comme ce qui suit:

    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
     
    exim -be -d '${dlfunc{/home/srv/exim-ext/junkprobe-bmf.so}{junkprobe}{db:$spool_directory/junkprobe/bmf}{test}{/var/spool/exim/spam.mbox}}' 
    [...]
    Starting ${dlfunc junkprobe-bmf/0.3.1d (0.00001 secs).
            (0.00092 secs) database [/var/spool/exim/junkprobe/bmf]
                            backend [db]
            (0.00138 secs) starting pipe...
            Using libjunkprobe/0.1
            (0.00196 secs) command:
                            argv[0]=/usr/bin/bmf
                            argv[1]=-f
                            argv[2]=db
                            argv[3]=-d
                            argv[4]=/var/spool/exim/junkprobe/bmf
                            argv[5]=-t
                            argv[6]=-k
                            argv[7]=15
                            argv[8]=-p
            (0.01314 secs) set timeout 20secs [Success].
            (0.01394 secs) opening pipe to read [Illegal seek].
            (0.01520 secs) generated headers:
    Return-path: <test@home.none>
    Envelope-To: mode@test.test
    Delivery-date: Wed, 04 Mar 2009 17:52:05 +0100
                            scan size: [99 bytes]
            (0.01579 secs) writing headers [Illegal seek].
                            scan size: [99 bytes]
            (0.01651 secs) opening spool file [/var/spool/exim/spam.mbox] [Illegal seek]
                            spool file size [12154 bytes]
            (0.01759 secs) writing body [Illegal seek]
                            scan size [12234 bytes]
            (0.01860 secs) end pipe...
            (0.08541 secs) status [0].
    LOG: MAIN
      ${dlfunc bmf: Yes score=1.000 required=0.900 tests=[bmf] autolearn=no time=0.0853secs
    End ${dlfunc junkprobe-bmf/0.3.1d (0.08739 secs).
    Yes, score=1.000 required=0.900 tests=[bmf]
            autolearn=no time=0.0853secs BMF on home.none
    search_tidyup called
    >>>>>>>>>>>>>>>> Exim pid=2791 terminating with rc=0 >>>>>>>>>>>>>>>>
    Voila... "Illegal seek" est gardé et restitué a chaque appel de "strerror(errno)", et comme c'est pas jolie je voudrais le cacher.

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Eh bien dans ce cas, mets systématiquement (donc, sans le comparer à ESPIPE) errno à zéro:
    • avant d'appeler fopen().
    • si fopen() réussit.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 727
    Points
    1 727
    Par défaut
    Salut,

    Rien t'empeche de mettre le errno dans une variable locale.
    Le man dit rien sur le fait qu'on puisse ou non modifier errno, mais c'est une variable spéciale qu'on est sensée que lire, donc mieux vaut ne pas la modifier.

  17. #17
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    D'accord, en résumé je comprends qu'il ne faut pas toucher à "errno", mais dans le mode bavard de cette fonction, il m'est possible de soudoyer "errno" pour résoudre une question "cosmétique".

    Peut être de cette manière ?:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if ( (debug_selector) && (errno == ESPIPE) )
        errno = 0;
    C'est ça ?

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Mais arrête de tester spécifiquement ESPIPE!
    Si fopen() réussit, c'est qu'il n'y a pas d'erreur, un point c'est tout.

    Donc, si tu mets errno à zéro, tu dois le faire indépendamment de sa précédente valeur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  19. #19
    Candidat au Club
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Bien, alors je ne teste plus "errno" avec "ESPIPE" en mode bavard, mais je le ramène à "zéro" pour résoudre le problème "cosmétique" de ma question existentialiste

    Je tiens a remercier les acteurs de cette discussion, et très bonne soirée.

    Amicalement.

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

Discussions similaires

  1. signal d'erreur pour la dclaration d'un tableau
    Par sandball22 dans le forum C
    Réponses: 2
    Dernier message: 20/04/2007, 11h03
  2. Réponses: 7
    Dernier message: 26/02/2007, 16h54
  3. Réponses: 3
    Dernier message: 24/11/2006, 18h20
  4. Réponses: 1
    Dernier message: 04/10/2006, 09h01

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