Partage
  • Partager sur Facebook
  • Partager sur Twitter

fonction lockf()

Sujet résolu
    23 mars 2020 à 11:46:24

    Bonjour,

    je dois créer une fonction qui pose un verrou sur une partie de mon script unix (notamment lorsque j'écris dans une partie d'un fichier) et une autre qui le lève.

    Du genre

    //Variant 0: pas de lock
    //Variant 1: lock bloquant
    //Variant 2: lock non-bloquant
    int verrouillage(int fd, int offset, int variant)
    {
    
    }
    
    //Deverouille -> Attention a l'offset: un offset invalide peut creer des petits bouts de fichier verrouille.
    void deverrouillage(int fd, int offset)
    {
    
    }

    Je sais qu'il faut utiliser la fonction lockf().

    Est-ce que j'ai le droit de faire quelque chose comme ça

    int cmd;
            if (variant == 0) {
                return 0;
            } else if (variant == 1) {
                cmd=F_LOCK;
            } else if (variant == 2) {
                cmd=F_TLOCK;
            }

    et ensuite

    lockf(fd,cmd,len);



    J'ai lu la documentation mais je ne compends pas bien comment l'utiliser quand même. Comme on n'a pas eu de cours, directement le TP à réaliser et plus de prof sous la main pour poser des questions (dans cette matière)...Je suis preneuse de tout fragment d'explication ! Merci :)

    • Partager sur Facebook
    • Partager sur Twitter
      23 mars 2020 à 18:12:34

      Quelle documentation as-tu lue? Voici ce que j'ai trouvé:
      http://manpagesfr.free.fr/man/man3/lockf.3.html
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        23 mars 2020 à 19:58:04

        C'est celle là que j'ai lue... Ainsi que ça http://manpages.ubuntu.com/manpages/xenial/fr/man3/lockf.3.html

        En fait j'aurais besoin d'un code d'exemple, d'une utilisation concrète...

        • Partager sur Facebook
        • Partager sur Twitter
          24 mars 2020 à 3:25:49

          Je n'écrirais qu'une seule fonction qui aurait l'air de ceci:
          -
          //Variant 0: pas de lock
          //Variant 1: lock bloquant
          //Variant 2: lock non-bloquant
          // Variant 3: unlock (déverrouillage)
          int verrouillage(int fd, off_t offset, int variant) {
              int cmd;
              switch (variant) {
                  case 0:
                      return(0);
                  case 1:
                      cmd = F_LOCK;
                      break;
                  case 2:
          ♠           cmd = F_TLOCK;
                      break;
                  case 3:
          ♠           cmd = F_ULOCK;
                      break;
                  default:
                      // erreur, variant invalide
              }
              lockf(fd, cmd, offset);
              // vérifier et retourner le code d'erreur de flock (-1)
              // le code est dans la variable globale errno, inclure <errno.h>
              // appeler perror() si désiré.
          }
          -
          J'ai trouvé ceci qui explique un peu à quoi ça sert:
          https://openclassrooms.com/forum/sujet/utilisation-de-quot-lockfquot-83559
          https://sites.uclouvain.be/SystInfo/notes/Theorie/html/Fichiers/fichiers-signaux.html

          -
          Edité par PierrotLeFou 24 mars 2020 à 4:10:37

          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            24 mars 2020 à 21:02:23

            Merci beaucoup pour cette réponse, je me repenche dessus demain après midi !! :)
            • Partager sur Facebook
            • Partager sur Twitter
              26 mars 2020 à 22:22:31

              Bon, j'ai fini, je ne sais pas si ça fonctionne correctement car je ne sais pas comment je peux vérifier ça mais mon programme s'execute correctement et compile sans erreur.

              //Variant 0: pas de lock
              //Variant 1: lock bloquant
              //Variant 2: lock non-bloquant
              int verrouillage(int fd, int offset, int variant) {
                  int cmd;
                  switch (variant) {
                      case 0:
                          return 0;
                      case 1:
                          cmd = F_LOCK;
                          break;
                      case 2:
                       		cmd = F_TLOCK;
                          break;
                      default:
                          return 0;
                  }
                  if (lockf(fd, cmd, offset) == -1) {
                  	perror("Verrouillage impossible\n");
                  	return -1;
                  } else {
                  	return 0;
                  }
              }
              
              //Deverouille -> Attention a l'offset: un offset invalide peut creer des petits bouts de fichier verrouille.
              void deverrouillage(int fd, int offset)
              {
              		if (lockf(fd, F_ULOCK, offset) == -1) {
                  	perror("Deverrouillage impossible\n");
                  	exit(2);
                  }
              }

              et je les appelle comme ça

              //Ajoute une entree en fin de fichier
              void ajout(char* fileName)
              {
              	  int fd;
              	  int fdbis;    
                  struct contact newContact;
                  scanContact(&newContact);
                  if ((fd=open(fileName,O_WRONLY|O_APPEND|O_CREAT,BUFF_SIZE))<0)
                  {
                      perror("Error open fichier Contact");
                      exit(2);
                  }
                  fdbis=fd;
                  if (verrouillage(fd,sizeof(struct contact),1)==-1){
                  		perror("Verrouillage impossible");
                  } else { 
              				if(write(fd,&newContact,sizeof(newContact))!=sizeof(struct contact)) {
              				    perror("Error write fichier Contact");
              				    exit(2);
              				} else {
              					deverrouillage(fdbis,sizeof(struct contact));
              				}
              		}
                  close(fd);
              }
              
              
              //Modifie une entree donnee 
              void modificationEntree(char* fileName)
              {
              		int fd,i,cpt,fdbis;
                  void * buffer;
                  int nbOct;
                  int lireID,lireNom,lirePrenom;
              		struct contact lireContact;
              		printf("Quelle entree souhaitez vous modifier ? ");fflush(stdout);
                  scanf("%d",&cpt);
                  i=0;
              		
                  if ((fd=open(fileName,O_RDWR,BUFF_SIZE))<0) 
              		{
              			perror("Error open fichier source");
              			exit(2);
              		}
              		while(i<(cpt-1)) {
              		  if((lireID=read(fd,&lireContact,sizeof(struct contact)))!=sizeof(struct contact))
              		  {
              		      perror("Erreur read");
              		      exit(2);
              		  }
              		  i++;
                  }
                  scanContact(&lireContact);
                  if (verrouillage(fd,sizeof(struct contact),2)==-1){
                  		perror("ajout impossible");
                  } else { 
                  		fdbis=fd;
              				if(write(fd,&lireContact,sizeof(struct contact))!=sizeof(struct contact))
              				{
              				    perror("Error write fichier Contact");
              				    exit(2);
              				} else {
              					deverrouillage(fdbis,sizeof(struct contact));
              				}
                  }
              		close (fd);
              }//fin de modificationEntree
              




              • Partager sur Facebook
              • Partager sur Twitter
                27 mars 2020 à 0:40:44

                Si ton code s'exécute correctement et fait ce que tu veux, il y a des chances qu'il soit correct.
                Tu pourras pousser tes test plus loin si tu veux.
                Puis-je me permettre quelques remarques?
                Certains des messages dans les perror() ne sont peut-être pas pertinents, tu le verras quand tu les auras.
                perror() envoie ses messages d'erreur en anglais. Essaies d'ouvrir un fichier qui n'existe pas pour voir ce que ça donne.
                Tu peux mettre un printf à la suite du perror() pour indiquer plus précisément l'erreur.
                Par exemple, dans les appels à lockf(), tu peux indiquer le fd et le code (cmd ou variant).
                Dans les open, tu peux indiquer le nom du fichier, etc.
                Tu rappelles perror() dans la fonction verrouillage() et à l'extérieur. Une seule fois suffit.
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  27 mars 2020 à 14:02:28

                  Merci beaucoup pour ces remarques, je vais modifier tout ça!

                  Je n'étais pas très sûre d'avoir le droit de faire ce que j'ai fait pour la position de la tete de lecture dans mon fichier. J'ai copié le fd dans un fdbis pour pouvoir revenir en arrière déverouiller ma portion de code. J'aurais peut-être du utiliser lseek...

                  • Partager sur Facebook
                  • Partager sur Twitter

                  fonction lockf()

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown