.\" -*- coding: UTF-8 -*- '\" t .\" Copyright (c) 2008, Linux Foundation, written by Michael Kerrisk .\" .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH fopencookie 3 "20 juillet 2023" "Pages du manuel de Linux 6.05.01" .SH NOM fopencookie \- Ouvrir un flux particulier .SH BIBLIOTHÈQUE Bibliothèque C standard (\fIlibc\fP, \fI\-lc\fP) .SH SYNOPSIS .nf \fB#define _GNU_SOURCE\fP /* Consultez feature_test_macros(7) */ \fB#define _FILE_OFFSET_BITS 64\fP \fB#include \fP .PP \fBFILE *fopencookie(void *restrict \fP\fIcookie\fP\fB, const char *restrict \fP\fImode\fP\fB,\fP \fB cookie_io_functions_t \fP\fIio_funcs\fP\fB);\fP .fi .SH DESCRIPTION La fonction \fBfopencookie\fP() permet au programmeur de créer des implémentations particulières de flux d'entrées\-sorties. Cette implémentation peut sauvegarder les flux de données dans une location choisie. Par exemple, \fBfopencookie\fP() est utilisée pour implémenter \fBfmemopen\fP(3), qui fournit une interface qui sauvegarde les flux de données dans un tampon en mémoire. .PP Pour créer un flux particulier, le programmeur doit\ : .IP \- 3 Implémenter quatre fonctions de «\ hook\ » qui seront utilisées en interne par la bibliothèque standard d'entrées\-sorties lors d'opération d'E/S. .IP \- Définit un type de données «\ cookie\ », une structure permettant de sauvegarder des informations (par exemple, où sauvegarder les données) utilisée par les fonctions de hook. Les fonctions E/S standards ne connaissent rien à propos du contenu de ce cookie (il est passé comme un type \fIvoid\~*\fP à \fBfopencookie\fP()) et celui\-ci est automatiquement passé en premier argument des fonctions de hook. .IP \- Appeler \fBfopencookie\fP() pour ouvrir un nouveau flux et associer le cookie et les fonctions de «\ hook\ » à ce flux. .PP La fonction \fBfopencookie\fP() effectue une tâche similaire à celle de \fBfopen\fP(3)\ : elle ouvre un nouveau flux et renvoie un pointeur vers un objet \fIFILE\fP utilisé pour manipuler le flux. .PP L'argument \fIcookie\fP est un pointeur vers la structure cookie appelante qui est associée au nouveau flux. Ce pointeur est passé en premier argument lorsque les bibliothèques d'E/S standard appellent une des fonctions de hook. .PP L'argument \fImode\fP a le même sens que pour \fBfopen\fP(3). Les modes suivants sont gérés\ : \fIr\fP, \fIw\fP, \fIa\fP, \fIr+\fP, \fIw+\fP et \fIa+\fP. Consultez \fBfopen\fP(3) pour plus de détails. .PP L'argument \fIio_funcs\fP est une structure qui contient quatre champs pointant vers les fonctions de «\ hook\ » définies par le programmeur qui seront utilisées dans l'implémentation du flux. La structure est définie comme suit\ : .PP .in +4n .EX typedef struct { cookie_read_function_t *read; cookie_write_function_t *write; cookie_seek_function_t *seek; cookie_close_function_t *close; } cookie_io_functions_t; .EE .in .PP Les quatre membres sont définis comme suit\ : .TP \fIcookie_read_function_t *read\fP Cette fonction implémente les opérations de lecture du flux. Lorsqu'elle est appelée, elle reçoit trois arguments. .IP .in +4n .EX ssize_t read(void *cookie, char *buf, size_t size); .EE .in .IP Les argument \fIbuf\fP et \fIsize\fP sont respectivement, un tampon de données pour sauvegarder les données en provenance du flux et la taille du tampon. La fonction \fIread\fP renvoie le nombre d'octets copiés depuis le flux ou \-1 en cas d'erreur. La fonction \fIread\fP doit mettre à jour la position dans le flux en conséquence. .IP Si \fI*read\fP est un pointeur NULL, alors les lectures du flux renvoient toujours fin de fichier. .TP \fIcookie_write_function_t *write\fP Cette fonction implémente les opérations d'écriture du flux. Lorsqu'elle est appelée, elle reçoit trois arguments\ : .IP .in +4n .EX ssize_t write(void *cookie, const char *buf, size_t size); .EE .in .IP Les argument \fIbuf\fP et \fIsize\fP sont respectivement, un tampon de données à écrire dans le flux et la taille du tampon. La fonction \fIwrite\fP renvoie le nombre d'octets copiés depuis \fIbuf\fP ou 0 en cas d'erreur (la fonction ne doit pas renvoyer de valeur négative). La fonction \fIwrite\fP doit mettre à jour la position dans le flux en conséquence. .IP Si \fI*write\fP est un pointeur NULL, alors les écritures dans le flux ne sont pas réalisées. .TP \fIcookie_seek_function_t *seek\fP Cette fonction implémente les opérations de positionnement dans le flux. Lorsqu'elle est appelée, elle prend trois arguments\ : .IP .in +4n .EX int seek(void *cookie, off_t *offset, int whence); .EE .in .IP L'argument \fI*offset\fP spécifie le nouveau décalage du fichier selon les trois valeurs suivantes fournies à \fIwhence\fP\ : .RS .TP \fBSEEK_SET\fP Le décalage du flux doit être défini à \fI*offset\fP octets après le début du flux. .TP \fBSEEK_CUR\fP \fI*offset\fP doit être ajouté à l'offset actuel du flux. .TP \fBSEEK_END\fP L'offset du flux doit être défini à la taille du flux plus \fI*offset\fP. .RE .IP La fonction \fIseek\fP doit mettre à jour \fI*offset\fP pour indiquer le nouvel offset du flux avant de renvoyer. .IP La function \fIseek\fP devrait renvoyer \fB0\fP en cas de succès et \fB\-1\fP en cas d'erreur. .IP Si \fI*seek\fP est un pointeur NULL, alors il est impossible de se positionner dans le flux. .TP \fIcookie_close_function_t *close\fP Cette fonction ferme le flux. Par exemple, la fonction de hook peut désallouer des tampons alloués pour le flux. Lorsqu'elle est appelée, elle prend un argument\ : .IP .in +4n .EX int close(void *cookie); .EE .in .IP L'argument \fIcookie\fP est le cookie que le programmeur fournit à \fBfopencookie\fP(). .IP La function \fIclose\fP devrait renvoyée 0 en cas de succès et \fBEOF\fP en cas d'erreur. .IP Si \fI*close\fP est NULL, alors aucune action n'est réalisée lorsque le flux est fermé. .SH "VALEUR RENVOYÉE" .\" .SH ERRORS .\" It's not clear if errno ever gets set... En cas de succès, \fBfopencookie\fP() renvoie un pointeur sur le nouveau flux. En cas d'erreur, NULL est renvoyé. .SH ATTRIBUTS Pour une explication des termes utilisés dans cette section, consulter \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. Interface Attribut Valeur T{ .na .nh \fBfopencookie\fP() T} Sécurité des threads MT\-Safe .TE .sp 1 .SH STANDARDS GNU. .SH EXEMPLES Le programme ci\-dessous implémente un flux particulier dont la fonctionnalité est similaire (mais non identique) à celle de \fBfmemopen\fP(3). Il implémente un flux dont les données sont sauvegardées dans un tampon. Le programme écrit les options de sa ligne de commande dans le flux et se positionne dans le flux afin de lire 2 caractères sur 5 et les écrit sur la sortie standard. La session shell suivante explique comment utiliser ce programme. .PP .in +4n .EX $\fB ./a.out \[aq]hello world\[aq]\fP /he/ / w/ /d/ Fin de fichier atteinte .EE .in .PP Notez qu'une version plus générique et plus robuste du programme ci\-dessous, avec une gestion des erreurs pourrait être implémenté (par exemple, l'ouverture d'un flux avec un cookie en cours d'utilisation par un autre flux\ ; la fermeture d'un flux déjà fermé). .SS "Source du programme" .\" SRC BEGIN (fopencookie.c) \& .EX #define _GNU_SOURCE #include #include #include #include #include \& #define INIT_BUF_SIZE 4 \& struct memfile_cookie { char *buf; /* Tampon de taille dynamique pour les données */ size_t allocated; /* Taille du tampon */ size_t endpos; /* Nombre de caractères dans le tampon */ off_t offset; /* Décalage du fichier actuel dans le tampon */ }; \& ssize_t memfile_write(void *c, const char *buf, size_t size) { char *new_buff; struct memfile_cookie *cookie = c; \& /* Tampon trop petit : doubler sa taille jusqu'à ce qu'il soit assez grand. */ \& while (size + cookie\->offset > cookie\->allocated) { new_buff = realloc(cookie\->buf, cookie\->allocated * 2); if (new_buff == NULL) return \-1; 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; \& /* Obtenir le minimum d'octets requis et d'octets disponibles. */ \& 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, off_t *offset, int whence) { off_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 *stream; struct memfile_cookie mycookie; size_t nread; char buf[1000]; \& /* Définir le cookie avant l'appel de 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; \& stream = fopencookie(&mycookie, "w+", memfile_func); if (stream == NULL) { perror("fopencookie"); exit(EXIT_FAILURE); } \& /* Écrire les arguments de la ligne de commande sur le fichier. */ \& for (size_t j = 1; j < argc; j++) if (fputs(argv[j], stream) == EOF) { perror("fputs"); exit(EXIT_FAILURE); } \& /* Lire deux octets tous les cinq octets jusqu'à EOF. */ \& for (long p = 0; ; p += 5) { if (fseek(stream, p, SEEK_SET) == \-1) { perror("fseek"); exit(EXIT_FAILURE); } nread = fread(buf, 1, 2, stream); if (nread == 0) { if (ferror(stream) != 0) { fprintf(stderr, "échec fread\en"); exit(EXIT_FAILURE); } printf("Fin de fichier atteinte\en"); break; } \& printf("/%.*s/\en", (int) nread, buf); } \& free(mycookie.buf); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH NOTES \fB_FILE_OFFSET_BITS\fP devrait être défini à 64 dans du code qui utilise une valeur de \fIseek\fP non NULL ou qui prend l'adresse de \fBfopencookie\fP, si le code est destiné à être portable pour les plateformes traditionelles x86 et ARM 32\ bits où la taille par défaut de \fBoff_t\fP est 32\ bits. .SH "VOIR AUSSI" \fBfclose\fP(3), \fBfmemopen\fP(3), \fBfopen\fP(3), \fBfseek\fP(3) .PP .SH TRADUCTION La traduction française de cette page de manuel a été créée par Christophe Blaess , Stéphan Rafin , Thierry Vignaud , François Micaux, Alain Portal , Jean-Philippe Guérard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas François , Florentin Duneau , Simon Paillard , Denis Barbier , David Prévot , Frédéric Hantrais et Jean-Pierre Giraud . .PP Cette traduction est une documentation libre ; veuillez vous reporter à la .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3 .UE concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. .PP Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à .MT debian-l10n-french@lists.debian.org .ME .