Provided by: manpages-fr-dev_3.27fr1.4-1_all bug

NOM

       fopencookie - Ouvrir un flux particulier

SYNOPSIS

       #define _GNU_SOURCE
       #include <stdio.h>

       FILE *fopencookie(void *cookie, const char *mode,
                         cookie_io_functions_t io_funcs);

DESCRIPTION

       La   fonction   fopencookie()   permet  au  programmeur  de  creer  des
       implementations  particulieres   de   flux   d'entrees-sorties.   Cette
       implementation  peut  sauvegarder les flux de donnees dans une location
       choisie. Par  exemple,  fopencookie()  est  utilisee  pour  implementer
       fmemopen(3),  qui  fournit  une  interface  qui  sauvegarde les flux de
       donnees dans un tampon en memoire.

       Pour creer un flux particulier, le programmeur doit :

       *  Implementer quatre fonctions de << hook >> qui seront  utilisees  en
          interne   par   la   bibliotheque  standard  d'entrees-sorties  lors
          d'operation d'E/S.

       *  Definit un type de donnees << cookie >>, une structure permettant de
          sauvegarder  des  informations  (par  exemple,  ou  sauvegarder  les
          donnees) utilisee par les  fonctions  de  hook.  Les  fonctions  E/S
          standards  ne  connaissent rien a propos du contenu de ce cookie (il
          est passe comme un type void *  a  fopencookie())  et  celui-ci  est
          automatiquement passe en premier argument des fonctions de hook.

       *  Appeler  fopencookie()  pour  ouvrir  un nouveau flux et associer le
          cookie et les fonctions de << hook >> a ce flux.

       La fonction fopencookie() effectue  une  tache  similaire  a  celle  de
       fopen(3) :  elle  ouvre  un nouveau flux et renvoie un pointeur vers un
       objet FILE utilise pour manipuler le flux.

       L'argument cookie est un pointeur vers la  structure  cookie  appelante
       qui  est  associee  au  nouveau  flux. Ce pointeur est passe en premier
       argument lorsque les bibliotheques d'E/S  standard  appellent  une  des
       fonctions de hook.

       L'argument  mode  a  le meme sens que pour fopen(3). Les modes suivants
       sont geres :  r, w, a, r+, w+ et a+. Consultez fopen(3)  pour  plus  de
       details.

       L'argument  io_funcs  est  une  structure  qui  contient  quatre champs
       pointant vers les fonctions de << hook >> definies par  le  programmeur
       qui  seront  utilisees  dans l'implementation du flux. La structure est
       definie comme suit :

           struct cookie_io_functions_t {
               cookie_read_function_t  *read;
               cookie_write_function_t *write;
               cookie_seek_function_t  *seek;
               cookie_close_function_t *close;
           };

       Les quatre membres sont definis comme suit :

       cookie_read_function_t *read
              Cette fonction implemente les operations  de  lecture  du  flux.
              Lorsqu'elle est appelee, elle recoit trois arguments.

                  ssize_t read(void *cookie, char *buf, size_t size);

              Les  argument  buf  et  size  sont  respectivement, un tampon de
              donnees pour sauvegarder les donnees en provenance du flux et la
              taille  du  tampon.  La fonction read renvoie le nombre d'octets
              copies depuis le flux ou -1 en cas d'erreur.  La  fonction  read
              doit mettre a jour la position dans le flux en consequence.

              Si  *read  est  un  pointeur  NULL,  alors  les lectures du flux
              renvoient toujours fin de fichier.

       cookie_write_function_t *write
              Cette fonction implemente les  operations  d'ecriture  du  flux.
              Lorsqu'elle est appelee, elle recoit trois arguments :

                  ssize_t write(void *cookie, const char *buf, size_t size);

              Les  argument  buf  et  size  sont  respectivement, un tampon de
              donnees a ecrire dans  le  flux  et  la  taille  du  tampon.  La
              fonction  write  renvoie le nombre d'octets copies depuis buf ou
              -1 en cas d'erreur. La fonction write  doit  mettre  a  jour  la
              position dans le flux en consequence.

              Si *write est un pointeur NULL, alors les ecritures dans le flux
              ne sont pas realisees.

       cookie_seek_function_t *seek
              Cette fonction implemente les operations de positionnement  dans
              le flux. Lorsqu'elle est appelee, elle prend trois arguments :

                  int seek(void *cookie, off64_t *offset, int whence);

              L'argument *offset specifie le nouveau decalage du fichier selon
              les trois valeurs suivantes fournies a whence :

              SEEK_SET  Le decalage du flux doit etre defini a *offset  octets
                        apres le debut du flux.

              SEEK_CUR  *offset doit etre ajoute a l'offset courant du flux.

              SEEK_END  L'offset  du flux doit etre defini a la taille du flux
                        plus *offset.

              La fonction seek doit mettre a jour  *offset  pour  indiquer  le
              nouvel offset du flux avant de renvoyer.

              La  function  seek  devrait renvoyee 0 en cas de succes et -1 en
              cas d'erreur.

              Si *seek est un pointeur NULL, alors il  est  impossible  de  se
              positionner dans le flux.

       cookie_close_function_t *close
              Cette  fonction  ferme le flux. Par exemple, la fonction de hook
              peut desallouer des tampons alloues pour  le  flux.  Lorsqu'elle
              est appelee, elle prend un argument :

                  int close(void *cookie);

              L'argument  cookie  est  le  cookie que le programmeur fournit a
              fopencookie().

              La function close devrait renvoyee 0 en cas de succes et EOF  en
              cas d'erreur.

              Si  *close  est NULL, alors aucune action n'est realisee lorsque
              le flux est ferme.

VALEUR RENVOY'EE

       En cas de succes, fopencookie() renvoie  un  pointeur  sur  le  nouveau
       flux. En cas d'erreur, NULL est renvoye.

CONFORMIT'E

       Cette fonction est une extension GNU non standard.

EXEMPLE

       Le   programme  ci-dessous  implemente  un  flux  particulier  dont  la
       fonctionnalite  est  similaire  (mais  non  identique)   a   celle   de
       fmemopen(3).  Il  implemente un flux dont les donnees sont sauvegardees
       dans un tampon. Le programme ecrit les options de sa ligne de  commande
       dans  le  flux  et se positionne dans le flux afin de lire 2 caracteres
       sur 5 et les ecrit sur la sortie standard. La  session  shell  suivante
       explique comment utiliser ce programme.

           $ ./a.out 'hello world'
           /he/
           / w/
           /d/
           Reached end of file

       Notez  qu'une  version  plus  generique  et  plus  robuste du programme
       ci-dessous, avec une gestion des erreurs pourrait etre implemente  (par
       exemple,  l'ouverture  d'un  flux avec un cookie en cours d'utilisation
       par un autre flux ; la fermeture d'un flux deja ferme).

   Source du programme

       #define _GNU_SOURCE
       #include <sys/types.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <string.h>

       #define INIT_BUF_SIZE 4

       struct memfile_cookie {
           char   *buf;        /* Dynamically sized buffer for data */
           size_t  allocated;  /* Size of buf */
           size_t  endpos;     /* Number of characters in buf */
           off_t   offset;     /* Current file offset in buf */
       };

       ssize_t
       memfile_write(void *c, const char *buf, size_t size)
       {
           char *new_buff;
           struct memfile_cookie *cookie = c;

           /* Buffer too small? Keep doubling size until big enough */

           while (size + cookie->offset > cookie->allocated) {
               new_buff = realloc(cookie->buf, cookie->allocated * 2);
               if (new_buff == NULL) {
                   return -1;
               } else {
                   cookie->allocated *= 2;
                   cookie->buf = new_buff;
               }
           }

           memcpy(cookie->buf + cookie->offset, buf, size);

           cookie->offset += size;
           if (cookie->offset > cookie->endpos)
               cookie->endpos = cookie->offset;

           return size;
       }

       ssize_t
       memfile_read(void *c, char *buf, size_t size)
       {
           ssize_t xbytes;
           struct memfile_cookie *cookie = c;

           /* Fetch minimum of bytes requested and bytes available */

           xbytes = size;
           if (cookie->offset + size > cookie->endpos)
               xbytes = cookie->endpos - cookie->offset;
           if (xbytes < 0)     /* offset may be past endpos */
              xbytes = 0;

           memcpy(buf, cookie->buf + cookie->offset, xbytes);

           cookie->offset += xbytes;
           return xbytes;
       }

       int
       memfile_seek(void *c, off64_t *offset, int whence)
       {
           off64_t new_offset;
           struct memfile_cookie *cookie = c;

           if (whence == SEEK_SET)
               new_offset = *offset;
           else if (whence == SEEK_END)
               new_offset = cookie->endpos + *offset;
           else if (whence == SEEK_CUR)
               new_offset = cookie->offset + *offset;
           else
               return -1;

           if (new_offset < 0)
               return -1;

           cookie->offset = new_offset;
           *offset = new_offset;
           return 0;
       }

       int
       memfile_close(void *c)
       {
           struct memfile_cookie *cookie = c;

           free(cookie->buf);
           cookie->allocated = 0;
           cookie->buf = NULL;

           return 0;
       }

       int
       main(int argc, char *argv[])
       {
           cookie_io_functions_t  memfile_func = {
               .read  = memfile_read,
               .write = memfile_write,
               .seek  = memfile_seek,
               .close = memfile_close
           };
           FILE *fp;
           struct memfile_cookie mycookie;
           ssize_t nread;
           long p;
           int j;
           char buf[1000];

           /* Set up the cookie before calling fopencookie() */

           mycookie.buf = malloc(INIT_BUF_SIZE);
           if (mycookie.buf == NULL) {
               perror("malloc");
               exit(EXIT_FAILURE);
           }

           mycookie.allocated = INIT_BUF_SIZE;
           mycookie.offset = 0;
           mycookie.endpos = 0;

           fp = fopencookie(&mycookie,"w+", memfile_func);
           if (fp == NULL) {
               perror("fopencookie");
               exit(EXIT_FAILURE);
           }

           /* Write command-line arguments to our file */

           for (j = 1; j < argc; j++)
               if (fputs(argv[j], fp) == EOF) {
                   perror("fputs");
                   exit(EXIT_FAILURE);
               }

           /* Read two bytes out of every five, until EOF */

           for (p = 0; ; p += 5) {
               if (fseek(fp, p, SEEK_SET) == -1) {
                   perror("fseek");
                   exit(EXIT_FAILURE);
               }
               nread = fread(buf, 1, 2, fp);
               if (nread == -1) {
                   perror("fread");
                   exit(EXIT_FAILURE);
               }
               if (nread == 0) {
                   printf("Reached end of file\n");
                   break;
               }

               printf("/%.*s/\n", nread, buf);
           }

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       fclose(3), fmemopen(3), fopen(3), fseek(3), feature_test_macros(7)

COLOPHON

       Cette page fait partie de  la  publication  3.27  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      etre       trouvees       a       l'adresse
       <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

       Depuis  2010,  cette  traduction est maintenue a l'aide de l'outil po4a
       <URL:http://po4a.alioth.debian.org/>   par   l'equipe   de   traduction
       francophone        au        sein        du       projet       perkamon
       <URL:http://perkamon.alioth.debian.org/>.

       Florentin   Duneau   et   l'equipe   francophone   de   traduction   de
       Debian (2006-2009).

       Veuillez   signaler   toute   erreur   de   traduction  en  ecrivant  a
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous  pouvez  toujours avoir acces a la version anglaise de ce document
       en utilisant la commande << man -L C <section> <page_de_man> >>.

Linux                           5 decembre 2008                 FOPENCOOKIE(3)