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

Linux Discussion :

Accept : pourquoi ça marche pas ?


Sujet :

Linux

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut Accept : pourquoi ça marche pas ?
    voici un morceau choisi de mon code, avec :

    sock le descripteur de la socket de connexion
    sockcom la socket de communication qui en resulte.


    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
     
      /* creation de la socket */
      if  (  (sock = socket(AF_INET , SOCK_STREAM , 0 )) < 0 ) {
        perror("socket");
        exit(1);
      }
     
      memset(&sin , 0 , sizeof(sin));
      sin.sin_addr.s_addr = htonl(INADDR_ANY);
      sin.sin_port = htons(server_port);
      sin.sin_family = AF_INET;
     
      if ( bind(sock, (struct sockaddr *)&sin , sizeof(sin)) < 0 ){
        perror("bind");
        exit(1);
      }
     
      if (listen(sock , 5)==-1){
        perror("listen");
        exit(1);
      }
     
      while(1){
        if (  (sockcom = accept( sock , (struct sockaddr*)&hp , &fromlen)) == -1 ){
          perror("accept");
          exit(1);
        }
     
        switch(fork()){
              /* le fils travaille sur sockcom et ferme sock */
              /* le pere ferme sockcom et ne fait rien d'autre */
        }
       } /* while */
    Donc un code de server de base. Le souci , c'est que accept marche nickel pour la premiere requete entrante, me crée sockcom et tout parfait, mais apres cette première requete , sock prend la valeur [0] et je me retrouve avec accept qui me retourne ENOTSOCK (socket operation on non-socket).

    Un printf avant et apres accept met ça en évidence.

    Quelqu'un a une idée ??
    Merci

  2. #2
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    bonjour,
    Je pense que tu te trompe de forum Il y a un forum dédié au C/C++.
    Demande à un modo de déplcaer ton messge...

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    Je pense que tu te trompe de forum Il y a un forum dédié au C/C++.
    Si c'est le cas désolé, mais je parle de developpement d'appli linux là. C'est quoi ici sinon ?

  4. #4
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut Re: accept : pourquoi ça marche pas ?
    Citation Envoyé par doudblast
    <...>
    A priori pas d'erreurs...
    mais apres cette première requete , sock prend la valeur [0] et je me retrouve avec accept qui me retourne ENOTSOCK (socket operation on non-socket).
    Ce n'est pas normal. accept ne peut modifier la valeur de sock, puisque tu la lui passes par valeur. Le probleme ne vient pas de accept. Tu es sur de ne pas modifier autrement la valeur de sock ?
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    Salut,

    Je suis bien d'accord avec toi, et pourtant un printf de sock juste avant et juste apres accept me confirme bien le phénomène. Si tu veux, je te poste le code en entier, peut etre qu'un oeil neuf verra l'erreur que j'ai déjà passé plusieurs heures à chercher sans succes :-)

  6. #6
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par doudblast
    Salut,

    Je suis bien d'accord avec toi, et pourtant un printf de sock juste avant et juste apres accept me confirme bien le phénomène. Si tu veux, je te poste le code en entier, peut etre qu'un oeil neuf verra l'erreur que j'ai déjà passé plusieurs heures à chercher sans succes :-)
    Si le code n'est pas monstrueusement gigantesque, je pense que c'est la meilleure solution
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    Bon, voilà la totale. Pour que ce soit plus facile de suivre, l'idée ici est d'envoyer un fichier à un client en faisant la demande.

    Merci de ton aide, désolé c'est un peu long, mais j'ai préféré ne rien enlever au cas où je supprimerais la cause de l'erreur :

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
     
    #define _POSIX_SOURCE 1
     
     
    #include "server.h"
    #include "cache.h"
    #include "common.h"
    #include <netdb.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <string.h>
    #include <signal.h>
    #include <grp.h>
    #include <pwd.h>
    #include <sys/wait.h>
    #include <errno.h>
    #include <time.h>
     
     
    extern int errno;
     
    void SIGCHLD_handler(int sig){
      signal(SIGCHLD , SIGCHLD_handler);
      wait(NULL);
      printf("un fils mort !\n");
    }
     
    int main(int argc, char ** argv )
    {
      int server_port;
      char vfs_server_port[5];
      char vfs_server_root[PATH_MAX_LEN];
      struct sockaddr_in sin;
      int  sock , sockcom;           /*socket de cnx , socket de comm */
      struct hostent *hp;
      int fromlen=sizeof(hp);
      sigset_t ens , ens_old;
     
     
      void SIGINT_handler(int sig){
        printf("SIGINT !! \n");
        shutdown(sock , 2);
        close(sock);
        shutdown(sockcom,2);
        close(sockcom); 
        exit(0);
      }
     
      sigfillset(&ens);
      sigdelset(&ens , SIGINT);
      /* sigdelset(&ens , SIGCHLD); */
      sigprocmask(SIG_SETMASK , &ens , &ens_old ) ;
     
      setbuf(stdout, NULL);
      setbuf(stdin, NULL);
      signal(SIGINT, SIGINT_handler);
      signal(SIGCHLD , SIGCHLD_handler);
     
      if (getParam(CACHE_CONF_PATH , "vfs_server_port" , vfs_server_port) != E_SUCCESS ){
        fprintf(stderr , "parametre vfs_server_port non trouvé\n");
        exit(1);
      }
     
      server_port = atoi(vfs_server_port);
     
      if (getParam(CACHE_CONF_PATH , "vfs_server_root" , vfs_server_root) != E_SUCCESS ){
        fprintf(stderr , "parametre vfs_server_root non trouvé\n");
        exit(1);
      }
     
        alltrim(vfs_server_root);
     
      /* creation de la socket */
      if  (  (sock = socket(AF_INET , SOCK_STREAM , 0 )) < 0 ) {
        perror("socket");
        exit(1);
      }
     
      memset(&sin , 0 , sizeof(sin));
      sin.sin_addr.s_addr = htonl(INADDR_ANY);
      sin.sin_port = htons(server_port);
      sin.sin_family = AF_INET;
     
      if ( bind(sock, (struct sockaddr *)&sin , sizeof(sin)) < 0 ){
        perror("bind");
        exit(1);
      }
     
      if (listen(sock , 5)==-1){
        perror("listen");
        exit(1);
      }
     
      while(1){
        if (  (sockcom = accept( sock , (struct sockaddr*)&hp , &fromlen)) == -1 ){
          printf("%d\n" , errno );
          printf("[%s]\n" , strerror(errno) );
          perror("accept");
          exit(1);
        }
     
        switch(fork()){
        case -1 : {
          perror("fork");
          exit(1);
        }
        case 0:{
     
          int size , desc , needDL=0;
          char buffer[SYNCH_MSG_LEN];
          char filepath[PATH_MAX_LEN];
          char date_s[300];
          char date_c[300];
          char open_log_path[PATH_MAX_LEN];
          struct lc_requete_open req;
          struct reponse_open rep;
          char req_user_name[USER_LEN];
          char req_group_name[USER_LEN];
          struct group *req_group;
          struct pwd *req_user;
          struct stat sbuf;
          FILE *open_log;
     
          printf("test\n");
     
          if ( (size = read(sockcom , buffer , SYNCH_MSG_LEN)) < 0){
    	perror("read");
    	exit(1);
          }
     
          /*traitement de la requete */
          memcpy(&req , buffer, size);
     
          /* file exists ? */
          if ( ! checkFile(req.path , vfs_server_root , &sbuf) ){
    	rep.status =  STATUS_ERR;
    	rep.error = E_NOT_EXISTS;
    	printf("returning ERR\n");
    	if ( write(sockcom , &rep , sizeof(rep) ) == -1 ){
    	  perror("write");
    	}
    	exit(1);
          }
     
          /* controle des droits en fonctions du mode demandé */       
     
          /* controle des dates */
          ctime_r(&(req.date) , date_c);
          ctime_r( &(sbuf.st_mtime) , date_s);
          printf("locale : %s server : %s " ,date_c , date_s);
          if (sbuf.st_mtime > req.date)
    	needDL = 1;
     
     
          /* envoi STATUS_DL */
          if (needDL)
    	{
    	  rep.status =  STATUS_DL ;
    	  if ( write(sockcom , &rep , sizeof(rep)) == -1 ){
    	    perror("write rep");
    	    exit(1);
    	  }
    	  /* envoi du fichier */
     
    	  strcpy(filepath , vfs_server_root );
    	  strncat(filepath , "/" , 1 );
    	  strncat(filepath , req.path , strlen(req.path) );
    	  if ( (desc=open(filepath , O_RDONLY )) < 0 ){
    	    fprintf(stderr , "[%s]\n" , filepath );
    	    perror("open file");
    	    exit(1);
    	  }
     
    	  while ( (size=read(desc,buffer,SYNCH_MSG_LEN)) > 0 ){
    	    if (write (sockcom , buffer , size) == -1){
    	      perror("write sur sock pendant dl");
    	      exit(1);
    	    }
    	  }
    	  if ( size == -1 ){
    	    perror("read dans le fichier pendant dl");
    	    exit(1);
    	  }
    	  /* envoi date dernière modif */
    	  if ( write(sockcom , &(sbuf.st_mtime) , sizeof(sbuf.st_mtime)) == -1){
    	    perror("write mt_time");
    	    exit(1);
    	  }
    	  close(desc);
    	}
     
          else{
    	/* envoi OK au cache */
    	rep.status =  STATUS_OK ;
    	if ( write(sockcom , &rep , sizeof(rep)) == -1 ){
    	  perror("write rep");
    	  exit(1);
    	}
          }
     
          /* logger l'ouverture de fichier dans le fichier vfs_server_root/.open.log  */
          shutdown(sockcom,2);
          close(sockcom); 
     
          exit(0);
     
        } /* fin fils */
     
        default : close(sockcom) ;  continue ;
        } /* fin switch */
     
      } /* while */
      printf("sortie du while\n");
     
      return 0;  
    }

  8. #8
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Bonjour,
    j'ai regarder rapidement ton code (ne n'y connait rien en programmation réseau donc j'ai regarder uniquement la syntaxe), il ne semble pas y avoir d'erreur de programmation qui engendrerai un comportement indefinie cependant:
    Citation Envoyé par doudblast
    le fait pour toi.

    Evite les exit(), surtout dan le main, un return fait la même chose et il est déconseilé d'avoir plusieurs point de sortie au programme, plutot que de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if( /* echec de l'appel */ )
    {
    /* gestion de l'erreur... */
      return( 1 );
    }
    /* le rete du code */
    je te conseille quelque chose du genre:
    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
    int main( void )
    {
    int ret = EXIT_SUCCESS;
    <...>
    if( /* reussite de l'appel */ )
    {
      /* le rete du code */
    }
    else
    {
      /* gestion de l'erreur... */
      ret = EXIT_FAILURE;
    }
    <...>
    return( ret );
    }
    Enfin, ce ne sont que des conseilles maintenant tu fait comme tu veut.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    tu as raison ce sera plus propre.

    Pour mon accept bancal ... est ce qu'un comportement pareil pourrait venir du client ? voire du systeme ?

  10. #10
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Euh... petite remarque : ca compile, ca ? Parceque la definition de la fonction SIGINT_handler à l'interieur du main....

    Sinon, pour en revenir au probleme initial, ca parait effectivement bizarre....
    Une des raisons qui me vient a l'esprit est que cela pourrait etre du à un eventuel signal SIGCHLD que tu recevrais lorsque le serveur principal est en attente sur accept.
    L'appel systeme echoue, et l'erreur renvoyée n'est plus significative. Pour eviter ce genre de desagremment, il faut utiliser des fonctions comme sigaction lors de la redefinition du traitement du signal, avec le flag sa_flags à la valeur SA_RESTART. Ceci permet aux appels systeme d'etre relancés lorsqu'ils sont interrompus par des signaux... Par ailleurs, la fonction signal est certes correcte, masi pour une utilisation avancée et un controle fin des sigaux, il vaut mieux utiliser les fonctions sigprocmask, sigsuspend, etc....

    Donc si ca ne vient pas d'un probleme de signaux, je ne vois vraiment pas...
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    Merci de ton aide vraiment Pouic.

    les fonctions dans le main oui, ça compile, j'étais surpris moi aussi et gcc ne dit rien, même avec tous les warings allumés, -pedantic et tout le bazar, et c'est pratique parce que tu as acces à toutes les variables de ton main, surtout pour les handler de signaux qui n'acceptent pas de parametres. Et du coup ça évite les variables globales que je répugne à utiliser ( est ce que je gagne en propreté ? c'est un débat ça : )

    Je suis d'accord avec toi pour la gestion des signaux, mais j'avoue que j'ai baclé cet aspect pour essayer de comprendre pourquoi le accept se comportait comme ça. Du coup, j'ai un SIGCHLD_handler mais j'ai tout bonnement masqué SIGCHLD (tu verras la ligne sigdelset(SIGCHLD commentée) , en pensant que je m'occuperais de la propreté quand le code tournerait à peu pres

  12. #12
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par doudblast
    les fonctions dans le main oui, ça compile, j'étais surpris moi aussi et gcc ne dit rien, même avec tous les warings allumés, -pedantic et tout le bazar
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -Wall -Werror -ansi -pedantic -O2
    :
    Citation Envoyé par doudblast
    en pensant que je m'occuperais de la propreté quand le code tournerait à peu pres
    Généralement c'est l'inverse que l'on fait: c'est plus facile de débuguer un programme bien écrit que d'éclaircir un programme qui semble marcher.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    oui voilà, sans -O2 dans les options.

    Puis faut pas dramatiser, il n'est pas si sale apres tout :-)

  14. #14
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Pour avoir vraiment tous les warnings, il ne faut pas oublier l'option -W dans les directives de compilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    alias gcc='gcc -W -Wall -Werror -pedantic -O2'
    Sinon il en manque...
    Donc pour les signaux, oui, on est obligé d'utiliser des variables globales (a moins de servir des signaux temps-réel, masi c'est une autre histoire ) je te conseille de reecrire cette partie de code proprement, on ne sait jamais... Et puis une seule petite socket en global, c'est pas la mort

    Deuxiemement, petite question : si au lieu d'envoyer une seconde connection quand le serveur attend sur accept, si tu fais un Ctr-C (envoi de SIGINT), est-ce que le shutdown du handler SIGINT reussi : s'il ne renvoie pas une erreur avec EBADF ou ENOTSOCK, c''est qu'il faut chercher encore ailleurs....

    Mais commence par reecrire ton code, ca prend 3 secondes, et on y verra plus clair
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    ok je m'y colle je vous poste ça dans qq minutes

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 24
    Points : 17
    Points
    17
    Par défaut
    ça tourne !

    J'ai perdu 3 heures en voulant gagner 5 minutes ....

    Voilà la partie qui a changé :

    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
     
     
    int sock ; /*  :-) */
     
    void SIGCHLD_handler(int sig){
      wait(NULL);
      printf("fils mort\n");
    }
     
    void SIGINT_handler(int sig){
      printf("SIGINT\n");
      if ( shutdown(sock , 2)==-1){
        perror("shutdown");
      }
      else
        close(sock);
      exit(0);
    }
     
    int main(int argc, char ** argv )
    {
     
     /*variables etc. */
     
      sigfillset(&ens);
      sigdelset(&ens , SIGINT);
     
      action.sa_handler = SIGCHLD_handler;
      action.sa_mask = ens;
      action.sa_flags = SA_RESTART;
     
      if ( sigaction(SIGCHLD , &action , NULL) == -1 ){
        perror("sigaction");
        return 1;
      }
     
      setbuf(stdout, NULL);
      setbuf(stdin, NULL);
      signal(SIGINT, SIGINT_handler);
     
    etc...
    }

    Mais alors il faudra VRAIMENT etre propre tout le temps quand on code ??

    Merci à vous, voilà une leçon que je vais retenir !

  17. #17
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par doudblast
    J'ai perdu 3 heures en voulant gagner 5 minutes ....
    au moins ça sert de leçon.

    Citation Envoyé par doudblast
    Mais alors il faudra VRAIMENT etre propre tout le temps quand on code ??
    En C, oui, le compilateur fait confiance au programmeur, il faut tout faire pour ne pas le décevoir.

    Citation Envoyé par doudblast
    Merci à vous, voilà une leçon que je vais retenir !
    Au moins on n'aurait pas perdue notre journée.

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

Discussions similaires

  1. Pourquoi INTERSECT ne marche pas ?
    Par Chatbour dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 25/06/2007, 22h03
  2. [Débutante] Pourquoi ça ne marche pas...?
    Par Tootsi dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 12/02/2006, 16h58
  3. Pourquoi ce code marche pas sous FF?
    Par Death83 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 09/09/2005, 10h04
  4. [W3C] Pourquoi ça ne marche pas sous IE
    Par polo-j dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 16/02/2005, 16h07

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