FMEMOPEN(3)

NOM
fmemopen, open_memstream, open_wmemstream - Ouvrir de la mémoire comme un flux

SYNOPSIS
#include <stdio.h>
FILE *fmemopen(void *buf, size_t size, const char *mode);
FILE *open_memstream(char **ptr, size_t *sizeloc);
#include <wchar.h>
FILE *open_wmemstream(wchar_t **ptr, size_t *sizeloc);

Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :

fmemopen(), open_memstream(), open_wmemstream() :
    Depuis la glibc 2.10 :
        _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
    Avant la glibc 2.10 :
        _GNU_SOURCE

DESCRIPTION
La fonction fmemopen() ouvre un flux qui permet l'accès spécifié par mode. Le flux permet d'effectuer des entrées sorties sur la chaîne ou la mémoire du tampon pointée par buf. Ce tampon doit au moins être d'une longueur de size octets.

L'argument mode est le même que celui de la fonction fopen(3). Si mode indique un mode d'ajout (« append mode »), alors la position initiale du fichier est définie à la position du premier octet nul (« \0 ») du tampon ; sinon la position initiale est définie au début du tampon. Depuis la glibc 2.9, la lettre « b » peut être indiquée comme second caractère de mode. Cela fournit le mode binaire : une écriture n'implique pas d'ajouter un octet nul final et fseek(3) SEEK_END est relative à la fin du tampon (c'est-à-dire la valeur indiquée par size) au lieu de la taille de la chaîne actuelle.

Lorsqu'un flux ouvert en écriture est vidé (consultez fflush(3)), ou fermé (consultez fclose(3)), un octet nul est écrit à la fin du tampon s'il y a de la place. L'appelant devrait s'assurer qu'un octet supplémentaire est disponible dans le tampon (et que size en tient compte) pour permettre ceci. Essayer d'écrire plus de size octets dans le tampon crée une erreur. (Par défaut, de telles erreurs ne sont seulement visibles que lorsque le tampon stdio est vidé. Désactiver la mise en tampon avec setbuf(fp, NULL) peut être utile pour détecter les erreurs au moment d'une opération de sortie. Alternativement, l'appelant peut explicitement définir buf comme un tampon de flux stdio, au même moment en informant stdio de la taille du tampon avec setbuffer(fp, buf, size)).

Avec un flux ouvert en lecture, un octet nul dans le tampon ne crée pas d'opérations de lecture et renvoie une indication de fin de fichier. Une lecture depuis le tampon indiquera seulement la fin du fichier quand le pointeur de fichier aura avancé de plus de size octets par rapport au début du tampon.

Si l'argument buf vaut NULL, alors la fonction fmemopen() alloue dynamiquement un tampon de size octets. C'est utile pour les applications qui veulent écrire des données dans un tampon temporaire et les lire ensuite. Le tampon est automatiquement supprimé lorsque le flux est fermé. Notez que l'appelant ne peut pas obtenir un pointeur vers le tampon alloué temporairement avec cette fonction (c'est possible avec open_memstream(), ci-dessous). La fonction open_memstream() ouvre un flux en écriture vers un tampon. Le tampon est dynamiquement alloué (comme avec malloc(3)) et grandit automatiquement à la demande. Après la fermeture du flux, l'appelant doit libérer (free(3)) ce tampon. Lorsqu'un flux est fermé (fclose(3)) ou vidé (fflush(3)), les adresses pointées par ptr et sizeloc sont mises à jour, avec respectivement, un pointeur vers le tampon et la taille du tampon actuel. Ces valeurs restent valides tant que l'appelant n'effectue pas de sortie sur le flux. Si d'autres sorties sont réalisées, alors le flux doit être ne nouveau vidé avant d'essayer d'accéder à ces variables. Un octet nul est conservé à la fin du tampon. Cet octet n'est pas inclus dans la valeur de la taille stockée dans sizeloc. La position du flux de fichier peut être changée avec fseek(3) ou fseeko(3). Déplacer la position après la fin des données déjà écrites remplit l'intervalle vide avec des zéros. La fonction open_wmemstream() est similaire à open_memstream(), mais elle opère sur les caractères larges et non sur des octets.

VALEUR RENVOYÉE
Si elles réussissent intégralement, les fonctions fmemopen(), open_memstream() et open_wmemstream() renvoient un pointeur de type FILE. Sinon, elles renvoient NULL et errno est définie avec le code d'erreur.

VERSIONS
fmemopen() est open_memstream() sont déjà disponibles dans la glibc 1.0.x. open_wmemstream() est disponible depuis la glibc 2.4.

CONFORMITÉ
POSIX.1-2008. Ces fonctions ne sont pas spécifiées dans POSIX.1-2001 et ne sont que rarement disponible sur d'autres systèmes. POSIX.1-2008 spécifie que « b » dans mode sera ignoré. Cependant, Technical Corrigendum 1 ajuste la norme pour permettre un traitement spécifique à l'implémentation dans ce cas, permettant ainsi à la glibc de traiter « b ».

NOTES
Il n'y a pas de descripteur de fichier associé avec le flux renvoyé par ces fonctions (par exemple, fileno(3) retournera une erreur si elle est appelée avec un tel flux).

BOGUES
Avant la glibc 2.7, un positionnement après la fin d'un flux crée par open_memstream() n'agrandit pas le tampon ; à la place, l'appel à fseek() échoue et renvoie -1. Si size est indiqué comme nul, fmemopen() échoue avec l'erreur EINVAL. Il serait plus cohérent dans ce cas de créer un flux renvoyant la fin de fichier au premier essai de lecture. De plus, POSIX.1-2008 ne spécifie pas d'échec dans ce cas. Indiquer un mode d'ajout (« a » ou « a+ ») pour fmemopen() définit la position initiale du fichier au premier octet nul, mais (si le décalage du fichier est réinitialisé à un autre endroit que la fin du flux) ne force pas les écritures suivantes à ajouter à la fin du flux. Si l'argument mode de fmemopen() indique un ajout (« a » ou « a+ »), et que l'argument size ne couvre pas d'octet nul dans buf, alors, d'après POSIX.1-2008, la position initiale du fichier devrait être définie à l'octet qui suit la fin du tampon. Cependant, dans ce cas le fmemopen() de la glibc définie la position du fichier à -1. Pour indiquer le mode binaire de fmemopen(), le « b » doit être le deuxième caractère de mode. Ainsi, par exemple, « wb+ » a le comportement attendu, mais pas « w+b ». Ce n'est pas cohérent avec le traitement de mode par fopen(3). L'ajout du mode « binaire » dans la glibc 2.9 pour fmemopen() a modifié silencieusement l'ABI : auparavant, fmemopen() ignorait « b » dans mode.

EXEMPLE
Le programme ci-dessous utilise fmemopen() pour ouvrir un tampon d'entrée et open_memstream() pour ouvrir un tampon de sortie de taille dynamique. Ce programme scrute la chaînes en entrée (récupérée du premier argument de la ligne de commande du programme) sous forme d'entiers, et écrit le carré de ces entiers dans le tampon de sortie. Voici un exemple de la sortie produite par ce programme :
$ ./a.out '1 23 43'
size=11; ptr=1 529 1849

  Source du programme
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
    FILE *out, *in;
    int v, s;
    size_t size;
    char *ptr;
    if (argc != 2) {
        fprintf(stderr, "Utilisation : %s <fichier>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    in = fmemopen(argv[1], strlen(argv[1]), "r");
    if (in == NULL)
        handle_error("fmemopen");
    out = open_memstream(&ptr, &size);
    if (out == NULL)
        handle_error("open_memstream");
    for (;;) {
        s = fscanf(in, "%d", &v);
        if (s <= 0)
            break;
        s = fprintf(out, "%d ", v * v);
        if (s == -1)
            handle_error("fprintf");
    }
    fclose(in);
    fclose(out);
    printf("size=%zu; ptr=%s\n", size, ptr);
    free(ptr);
    exit(EXIT_SUCCESS);
}

VOIR AUSSI
fopen(3), fopencookie(3)

COLOPHON
Cette page fait partie de la publication 3.70 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.

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

Christophe Blaess <http://www.blaess.fr/christophe/> (1996-2003), Alain Portal <http://manpagesfr.free.fr/> (2003-2006). Florentin Duneau et l'équipe francophone de traduction de Debian (2006-2009).

Veuillez signaler toute erreur de traduction en écrivant à <perkamon-fr@traduc.org>.

Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « LC_ALL=C man <section> <page_de_man> ».