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 :

tmp_file sous windows


Sujet :

C

  1. #1
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut tmp_file sous windows
    Bonjour

    J'ai un problème avec la fonction tmpfile sous windows XP. Je viens de mettre un emplâtre sur une jambe de bois pour que ça marche, mais j'aimerai :
    1) L'enlever.
    2) Prendre la seconde version sécurisée.
    3) Comme je ne vois pas mon fichier temporaire, je me demande si je dois l'enlever ou non.

    Le problème, c'est que tmpfile renvoie 0x0 et si je ne fais pas attention, le programme plante. Sous Linux, ça marche sans problème.
    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
     FILE * sortie=tmpfile();
     
      #ifdef WIN32
     if (sortie==NULL) /* début de l'emplâtre */
     {
        char* name = _tempnam( NULL, NULL );
     
        if( !name )
            return 0;
        sortie = fopen(name, "wb+TD");
     
        printf("Erreur dans tmpfile, fichier temporaire : %s\n",name);
        // When name is no longer needed :
        if(name)
            free(name);
     } /* fin de l'emplâtre */
     #endif

    Une petite recherche ( http://msdn.microsoft.com/fr-fr/libr...=vs.80%29.aspx ) me montre que je devrais plutôt utiliser, mais la fonction tmpnam_s est inconnue sur mon compilo !
    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
     FILE * sortie=tmpfile();
     
     if (sortie==NULL)
     {
        char name[LONG];
     
        if( tmpnam_s( name, LONG ))
            return 0;
        sortie = fopen(name, "wb+TD");
     
        // When name is no longer needed :
        printf("Erreur dans tmpfile : fichier temporaire : %s\n",name);
        if(name)
            free(name);
     }
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par troumad Voir le message
    Une petite recherche ( http://msdn.microsoft.com/fr-fr/libr...=vs.80%29.aspx ) me montre que je devrais plutôt utiliser, mais la fonction tmpnam_s est inconnue sur mon compilo !
    le suffixe _s dit que c'est ré-entrant.

    La version standard est tmpnam
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  3. #3
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    Le man contient des choses pas sympa :
    N'utilisez jamais cette routine. Utilisez mkstemp(3) à la place.
    Alors que microsoft, lui indique d'utiliser tmpnam_s .

    C'est quoi une fonction "ré-entrante".

    Ceci dit, ce que je préférerais, ce serait utiliser tmpfile, à moins de trouver un exemple avec int mkstemp (char *template); qui semble marcher comme _tempnam. C'est à dire que je n'ai rien trouvé quant à l'effacement possible ou non des fichiers temporaires.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par troumad Voir le message
    Le man contient des choses pas sympa : Alors que microsoft, lui indique d'utiliser tmpnam_s .
    Ceci est dû à une "ligne de conduite" qui a prévalu dans les versions de Linux au tournant des années 2000... qui disait qu'il fallait absolument se débarasser de cette fonction.

    Cependant, si l'on regarde les manuels, cela existe toujours, SANS ces commentaires :

    http://pubs.opengroup.org/onlinepubs...ns/tmpnam.html

    http://www.linux-kheops.com/doc/man/.../tmpnam.3.html

    Pour la simple raison que rendre une telle fonction obsolète (surtout brutalement tel que c'était le cas à cette époque) nécessitait tellement de révisions/modifications et de re-compliations par rapport à l'existant...

    D'ailleurs, dans la page Wiki anglophone :

    http://en.wikipedia.org/wiki/Temporary_file

    tu noteras en fin de page :

    Usually a temporary file is deleted automatically when the program exits or the file is closed. To generate a temporary file name that will survive past the lifespan of the creating program, tmpnam(3) or GetTempFileName(...) (Windows only) can be used.
    Maintenant, il y a aussi la fonction tempnam :

    http://pubs.opengroup.org/onlinepubs...s/tempnam.html

    http://www.linux-kheops.com/doc/man/...tempnam.3.html


    Citation Envoyé par troumad Voir le message
    C'est quoi une fonction "ré-entrante".
    http://fr.wikipedia.org/wiki/R%C3%A9entrance

    ou

    http://www-gtr.iutv.univ-paris13.fr/...ntroLangC.html

    permet que les fonctions soient ``réentrantes'', c'est à dire puissent être appellées plusieurs fois simultanément (fonctions récursives ou programmes multi-tâches).
    Pour ton problème, tout dépend de ce qu'on fait de la variable..

    Si on s'en sert telle quelle, et qu'on peut s'en servir plusieurs fois, alors il peut être souhaitable d'utiliser la fonction ré-entrante (mais qui n'est pas implantée dans tous les systèmes/OS/versions)

    Si par exemple on s'en sert pour construire le nom tempo, et par exemple le stocker dans une autre variable, alors il n'y a pas de problème à utiliser la fonction non-réentrante.
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  5. #5
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    tu noteras en fin de page :...
    Donc, les fichiers temporaires sont effacés : tant mieux

    Citation Envoyé par souviron34 Voir le message
    Maintenant, il y a aussi la fonction tempnam :
    On dirait celle que j'ai utilisée ! Elle a juste le _ en moins devant !
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par troumad Voir le message
    Donc, les fichiers temporaires sont effacés : tant mieux
    Comme je disais, ça dépend des utilisations

    Dans certains cas, il faut que ça survive (je pense par exemple à la génération d'un job en background qui prend du temps et un (ou plusieurs) fichiers temporaires)
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  7. #7
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    L'emplâtre plante sous Windows seven (chez moi au moins ! )

    J'ai vu sur un problème équivalent au mien (d'autant plus que je l'utilise pour zipper aussi) : http://www.developpez.net/forums/d13...enied-windows8

    Si je rajoute
    perror("Erreur sur tmpfile()");
    j'ai la même erreur. Comme c'est dit si j'exécute en tant qu'admin, je n'ai plus l'erreur ! Mais, j'ai le problème 1 décrit plus loin.

    Pour le moment, sous windows j'ai deux cas qui se présentent :
    1) Je ne comprime que la fin du document, le début est oublié.
    2) Je ne comprime rien.

    J'ai remplacé l’emplâtre, mais c'est encore moins joli !

    J'envoie un pointeur sur un nom de fichier en plus à ma fonction, ce pointeur doit préalablement pointer sur null pour voir une différence :
    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
    FILE * enregistre_tmp_xml(GMarkupDomNode * ooo, char ** nom_)
    {
     
     FILE * sortie=tmpfile();
     
     if (sortie==NULL)
     {
        char ch[LONG];
        char * s = envp_donne_home();
        sprintf(ch,"%s/perso_tmp",s);
        *nom_=g_strdup(ch);
     
        sortie = fopen(ch, "w");
     
        printf("Erreur d'ouverture de tmpfile, fichier temporaire : %s\n",ch);
     }
     dom_print(ooo,sortie,0);
     
     return sortie;
    }
    Et j'utilise cette fonction comme ça :
    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
        nom_de_fichier=NULL;
        fichier=enregistre_tmp_xml(ooo,&nom_de_fichier);
        sprintf(affichage,"%s%cLibO%cfeuille.zip",tmp1,SEPARATEUR,SEPARATEUR);
        sprintf(aff,"%s%c%s.odt",((char **)param)[CHEMIN],SEPARATEUR,((char **)param)[NOM]);
        copie_fichier(aff,affichage);
        if (nom_de_fichier)
        {
            fclose(fichier);
            fichier=fopen(nom_de_fichier,"r");
        }
        f_zip=zip_open(aff,ZIP_CREATE,NULL);
        n_zip=zip_source_filep(f_zip,fichier,0,0); /* récupération du fichier sous forme FILE * sans avoir à le copier sur le disque */
        zip_replace(f_zip,zip_name_locate(f_zip,"content.xml",ZIP_FL_NOCASE) ,n_zip); /* on l'injecte dans l'archive en lui donnant un nom */
        zip_close(f_zip);   /* on ferme l'archive */ 
        if (nom_de_fichier)
        {
            fclose(fichier);
            free(nom_de_fichier);
            nom_de_fichier=NULL;
        }
    Tous les tests avec nom_de_fichier sont rajoutés par rapport à l'ancienne version.

    nb : je n'efface pas le fichier temporaire car je peux le regarder si besoin de débogage.

    nb 2 : si c'est exécuter en tant qu'administrateur, je récupère bien un retour qui semble correct avec tmpfile, mais le fichier compressé perd sa première partie !
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

Discussions similaires

  1. quel langage choisir pour faire de script sous windows
    Par pas05 dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 18/11/2002, 22h42
  2. Assembleur sous Windows et sous Linux
    Par Bibouda dans le forum x86 32-bits / 64-bits
    Réponses: 3
    Dernier message: 28/10/2002, 07h55
  3. Tester connexion Internet active sous Windows
    Par Altau dans le forum Développement
    Réponses: 3
    Dernier message: 12/08/2002, 12h43
  4. Pas de fork sous Windows?
    Par chezjm dans le forum POSIX
    Réponses: 8
    Dernier message: 11/06/2002, 12h15
  5. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45

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