1.\" 2.\" This file and its contents are supplied under the terms of the 3.\" Common Development and Distribution License ("CDDL"), version 1.0. 4.\" You may only use this file in accordance with the terms of version 5.\" 1.0 of the CDDL. 6.\" 7.\" A full copy of the text of the CDDL should have accompanied this 8.\" source. A copy of the CDDL is also available via the Internet at 9.\" http://www.illumos.org/license/CDDL. 10.\" 11.\" 12.\" Copyright 2020 Robert Mustacchi 13.\" 14.Dd March 25, 2020 15.Dt OPEN_MEMSTREAM 3C 16.Os 17.Sh NAME 18.Nm open_memstream , 19.Nm open_wmemstream 20.Nd open a memory stream 21.Sh SYNOPSIS 22.In stdio.h 23.Ft "FILE *" 24.Fo open_memstream 25.Fa "char **bufp" 26.Fa "size_t *sizep" 27.Fc 28.In wchar.h 29.Ft "FILE *" 30.Fo open_wmemstream 31.Fa "wchar_t **bufp" 32.Fa "size_t *sizep" 33.Fc 34.Sh DESCRIPTION 35The 36.Fn open_memstream 37and 38.Fn open_wmemstream 39functions create an I/O stream that is backed by a dynamic memory buffer 40which will grow as needed. 41The stream is seekable and writable. 42The stream is not readable. 43The stream is byte-oriented in the case of the 44.Fn open_memstream 45function or it is wide-oriented in the case of the 46.Fn open_wmemstream 47function. 48.Pp 49Memory for the stream is dynamically allocated and reallocated as though 50a call to 51.Xr malloc 3C . 52As the stream is written to, flushed, or closed, the underlying buffer 53will be grown automatically as required. 54After the stream is flushed or closed, the 55.Fa bufp 56argument will be filled in with a pointer to the current buffer. 57The 58.Fa sizep 59argument will be filled in with the smaller of the current buffer length 60and the current position in bytes 61.Pq Fn open_memstream 62or wide characters 63.Pq Fn open_wmemstream , 64excluding a NUL character. 65Note, because the current position is taken into account, the actual 66size of the buffer may be larger than is found in 67.Fa sizep ; 68however data should not be accessed beyond the indicated size. 69The values stored in the 70.Fa bufp 71and 72.Fa sizep 73arguments are only valid until the next write operation on the stream 74or a call to 75.Xr fclose 3C . 76.Pp 77The stream maintains both the current position and the current length of 78the stream. 79Both the initial position and length of the buffer are set to zero. 80Whenever a write at the current position exceeds the current length of the 81buffer, the current length is increased and a NUL character, 82.Sq \e0 83.Pq Fn open_memstream 84or NUL wide character, 85.Sq L\e0 86.Pq Fn open_wmemstream 87will be added to the buffer. 88If the stream is seeked beyond the current length and a subsequent write 89occurs, intervening characters will be filled with the corresponding NUL 90character for the stream. 91.Pp 92To release the stream, the caller must call the 93.Xr fclose 3C 94function. 95The corresponding dynamically allocated memory will be disassociated 96from the stream and will become owned by the caller. 97The caller must eventually release the memory buffer pointed to in the 98.Fa bufp 99argument with a call to 100.Xr free 3C . 101.Ss Fn open_wmemstream , Xr fseek 3C , Xr fsetops 3C, and Xr ftell 3C 102The specification for the 103.Fn open_wmemstream 104function causes the 105.Xr fseek 3C 106and 107.Xr ftell 3C 108families of functions to operate differently. 109Traditionally, these functions always return units in bytes, regardless 110of whether the underlying stream is byte- or wide-oriented. 111However, when used against a stream created by the 112.Fn open_wmemstream 113function these now count in terms of units of wide characters. 114While this is different from the traditional behavior, this does mean 115that the units will be the same as tracked in 116.Fa sizep . 117.Ss Fn open_wmemstream and byte-oriented functions 118Unlike other streams, streams created by 119.Fn open_wmemstream 120are not only wide-oriented, but operate in terms of the 121.Vt wchar_t 122data type. 123When normal bytes are written to the stream, an implicit multi-byte 124conversion state is maintained. 125Writing byte sequences that don't correspond to valid byte sequences in 126the locale can cause I/O errors to occur when using write functions such 127as 128.Xr fputc 3C 129or 130.Xr fwrite 3C , 131or when buffered data is flushed through functions like 132.Xr fflush 3C 133or 134.Xr fclose 3C . 135.Pp 136The same problem can occur when explicitly using wide characters, for 137example, 138.Xr fputwc 3C , 139if the 140wide character represents a code point that is not valid in the current 141locale. 142To avoid these errors when flushing or closing, one can disable 143buffering by passing 144.Dv _IONBF 145as the buffering type with 146.Xr setvbuf 3C . 147.Pp 148It is not recommended to change the locale of such a stream while 149writing a byte sequence that represents valid wide characters. 150The behavior of using byte-oriented functions is not standardized and 151not all systems will behave the same way. 152.Sh RETURN VALUES 153Upon successful completion, the 154.Fn open_memstream 155and 156.Fn open_wmemstream 157functions returns a pointer to a stream. 158Otherwise, 159.Dv NULL 160is returned and 161.Dv errno 162is set to indicate the error. 163.Sh ERRORS 164The 165.Fn fmemopen 166function will fail if: 167.Bl -tag -width Er 168.It Er EINVAL 169Either of the 170.Fa bufp 171or 172.Fa sizep 173arguments are 174.Dv NULL . 175.It Er EMFILE 176.Brq FOPEN_MAX 177streams are currently open in the calling process. 178.Pp 179.Brq STREAM_MAX 180streams are currently open in the calling process. 181.It Er ENOMEM 182The system was unable to allocate memory for the stream or its backing 183memory buffer. 184.El 185.Sh MT-LEVEL 186.Sy MT-Safe 187.Sh INTERFACE STABILITY 188.Sy Committed 189.Sh SEE ALSO 190.Xr fclose 3C , 191.Xr fflush 3C , 192.Xr fmemopen 3C , 193.Xr free 3C , 194.Xr malloc 3C , 195.Xr setvbuf 3C 196