Provided by:
manpages-fr-dev_3.27fr1.4-1_all 
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)