table of contents
- bullseye-backports 4.17.0-2~bpo11+1
- testing 4.17.0-2
- unstable 4.17.0-2
fmemopen(3) | Library Functions Manual | fmemopen(3) |
NOM¶
fmemopen - Ouvrir de la mémoire en tant que flux
BIBLIOTHÈQUE¶
Bibliothèque C standard (libc, -lc)
SYNOPSIS¶
#include <stdio.h>
FILE *fmemopen(void buf[.size], size_t size, const char *mode);
fmemopen() :
Depuis la version 2.10 de la glibc :
_POSIX_C_SOURCE >= 200809L
Avant la version 2.10 de la glibc :
_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 le tampon mémoire pointé par tampon.
L'argument mode spécifie le mode d'ouverture du flux et peut avoir pour valeurs :
- r
- Le flux est ouvert en lecture.
- w
- Le flux est ouvert en écriture.
- a
- Ajout ; le flux est ouvert en écriture, la position initiale du tampon étant définie au premier octet de valeur zéro.
- r+
- Le flux est ouvert en lecture et en écriture.
- w+
- Le flux est ouvert en lecture et en écriture. Le contenu du tampon est écrasé (autrement dit, '\0') est placé dans le premier octet du tampon.
- a+
- Ajout ; le flux est ouvert en lecture et écriture, la position initiale du tampon étant définie au premier octet de valeur zéro.
Le flux conserve la notion de position actuelle qui est l'endroit du tampon où la prochaine opération d'entrée/sortie aura lieu. La position actuelle est automatiquement mise à jour par les opérations d'entrées/sorties. Elle peut aussi être définie de manière explicite à l'aide de fseek(3) et obtenue à l'aide de ftell(3). Dans tous les modes autres que Ajout, la position actuelle est initialisée au début du tampon. En mode Ajout, si aucun octet de valeur zéro n'est trouvé dans le tampon, la position actuelle est initialisée à taille+1.
Si l'argument tampon vaut NULL, alors la fonction fmemopen() alloue un tampon de taille octets. C'est utile pour les applications qui veulent écrire des données dans un tampon temporaire et les lire ensuite. La position initiale est définie au début du tampon. Le tampon est automatiquement supprimé lorsque le flux est fermé. Notez que l'appelant ne peut pas obtenir de pointeur vers le tampon temporaire alloué avec cette fonction (voir à ce sujet open_memstream(3)).
If buf is not NULL, then it should point to a buffer of at least size bytes allocated by the caller.
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. Pour ce faire, l'appelant doit s'assurer qu'un octet supplémentaire est disponible dans le tampon (et que taille en tient compte).
Avec un flux ouvert en lecture, si le tampon contient des octets de valeur ('\0'), les opérations de lecture ne renverront pas une indication de fin de fichier. Une lecture depuis le tampon n'indiquera la fin du fichier que lorsque la position actuelle du tampon aura atteint la valeur taille.
Les opérations d'écriture s'effectuent soit à la position actuelle (pour les modes autres que Ajout), ou à une position correspondant à la taille du flux (pour les mode Ajout).
Essayer d'écrire plus de taille octets dans le tampon crée une erreur. Par défaut, de telles erreurs ne seront visibles (en l'absence de données) que lorsque le tampon stdio sera vidé. Désactiver cette mise en tampon avec l'appel suivant peut s'avérer utile pour détecter les erreurs au moment d'une opération de sortie :
setbuf(stream, NULL);
VALEUR RENVOYÉE¶
En cas de succès, fmemopen() renvoie un pointeur de type FILE. Sinon, elle renvoie NULL et errno contient le code d'erreur.
VERSIONS¶
fmemopen() était déjà disponible dans la version 1.0.x. de la glibc.
ATTRIBUTS¶
Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface | Attribut | Valeur |
fmemopen(), | Sécurité des threads | MT-Safe |
STANDARDS¶
POSIX.1-2008. Cette fonction n'est pas spécifiée dans POSIX.1-2001 et n'est 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 cette fonction (par exemple, fileno(3) retournera une erreur si elle est appelée avec un tel flux).
With glibc 2.22, binary mode (see below) was removed, many longstanding bugs in the implementation of fmemopen() were fixed, and a new versioned symbol was created for this interface.
Mode binaire¶
From glibc 2.9 to glibc 2.21, the glibc implementation of fmemopen() supported a "binary" mode, enabled by specifying the letter 'b' as the second character in mode. In this mode, writes don't implicitly add a terminating null byte, and fseek(3) SEEK_END is relative to the end of the buffer (i.e., the value specified by the size argument), rather than the current string length.
Un bogue de l'API affectait l'implémentation du mode binaire : pour indiquer le mode binaire, le « b » doit être le second caractère de mode. Ainsi, par exemple, « wb+ » a le comportement attendu, mais pas « w+b ». Ce n'était pas cohérent avec le traitement de mode par fopen(3).
Le mode binaire a été supprimé à partir de la version 2.22 de la glibc et un 'b' spécifié dans mode n'a dorénavant aucun effet.
BOGUES¶
Before glibc 2.22, if size is specified as zero, fmemopen() fails with the error EINVAL. It would be more consistent if this case successfully created a stream that then returned end-of-file on the first attempt at reading; since glibc 2.22, the glibc implementation provides that behavior.
Before glibc 2.22, specifying append mode ("a" or "a+") for fmemopen() sets the initial buffer position to the first null byte, but (if the current position is reset to a location other than the end of the stream) does not force subsequent writes to append at the end of the stream. This bug is fixed in glibc 2.22.
Before glibc 2.22, if the mode argument to fmemopen() specifies append ("a" or "a+"), and the size argument does not cover a null byte in buf, then, according to POSIX.1-2008, the initial buffer position should be set to the next byte after the end of the buffer. However, in this case the glibc fmemopen() sets the buffer position to -1. This bug is fixed in glibc 2.22.
Before glibc 2.22, when a call to fseek(3) with a whence value of SEEK_END was performed on a stream created by fmemopen(), the offset was subtracted from the end-of-stream position, instead of being added. This bug is fixed in glibc 2.22.
L'ajout du mode « binaire » dans la glibc 2.9 pour fmemopen() a modifié silencieusement l'ABI : auparavant, fmemopen() ignorait « b » dans mode.
EXEMPLES¶
Le programme ci-dessous utilise fmemopen() pour ouvrir un tampon d'entrée et open_memstream(3) pour ouvrir un tampon de sortie de taille dynamique. Ce programme scrute la chaîne 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' taille=11; ptr=1 529 1849
Source du programme¶
#define _GNU_SOURCE #include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) {
FILE *out, *in;
int v, s;
size_t taille;
char *ptr;
if (argc != 2) {
fprintf(stderr, "Utilisation : %s '<nombre>...'\n", argv[0]);
exit(EXIT_FAILURE);
}
in = fmemopen(argv[1], strlen(argv[1]), "r");
if (in == NULL)
err(EXIT_FAILURE, "fmemopen");
out = open_memstream(&ptr, &size);
if (out == NULL)
err(EXIT_FAILURE, "open_memstream");
for (;;) {
s = fscanf(in, "%d", &v);
if (s <= 0)
break;
s = fprintf(out, "%d ", v * v);
if (s == -1)
err(EXIT_FAILURE, "fprintf");
}
fclose(in);
fclose(out);
printf("taille=%zu; ptr=%s\n", taille, ptr);
free(ptr);
exit(EXIT_SUCCESS); }
VOIR AUSSI¶
TRADUCTION¶
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Frédéric Hantrais <fhantrais@gmail.com> et Lucien Gentis <lucien.gentis@waika9.com>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.
15 décembre 2022 | Pages du manuel de Linux 6.02 |