feat(stdio): getline/getdelim/stream locking

This commit is contained in:
2026-09-05 17:18:18 -04:00
parent 14c6fd6cf6
commit a2f7c33601
7 changed files with 1625 additions and 13 deletions
+82
View File
@@ -347,4 +347,86 @@ int
vasprintf(char **restrict strp, const char *restrict format, va_list ap);
#endif
/* line input, stream locking, and memory streams (todo 18) */
/*
* Read one line from stream into a malloc'd, NUL-terminated buffer. On the
* first call *lineptr may be NULL (a buffer is allocated); *n is the buffer
* capacity and grows as needed. The newline is kept in the output; embedded
* NUL bytes are preserved (the length comes from the return value, not
* strlen). Returns the number of bytes read including the delimiter, or -1
* at end of file (nothing read) or on error.
*/
ssize_t
getline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream);
/*
* Like getline, but reads up to the given delimiter byte (which is kept in
* the output). Reading stops at end of file without the delimiter; a partial
* final line is still returned with its byte count.
*/
ssize_t
getdelim(char **restrict lineptr, size_t *restrict n, int delim, FILE *restrict stream);
/* Write s to stdout followed by a newline. Returns a non-negative value,
* or EOF on error. */
int
puts(const char *s);
/*
* Per-stream advisory locks (POSIX.1-2008 base). flockfile is recursive:
* the owning thread may lock the same stream any number of times, and
* funlockfile must be called once per successful flockfile. ftrylockfile
* acquires without blocking: 0 on success, nonzero when the stream is
* already locked. Single-threaded today; the lock fields become real
* blocking locks when the thread runtime lands.
*/
void
flockfile(FILE *stream);
int
ftrylockfile(FILE *stream);
void
funlockfile(FILE *stream);
/*
* Unlocked character I/O: the stream must already be locked by the caller
* (see flockfile). Identical to fgetc/fputc over stdin/stdout without
* taking the per-stream lock.
*/
int
getc_unlocked(FILE *stream);
int
getchar_unlocked(void);
int
putc_unlocked(int c, FILE *stream);
int
putchar_unlocked(int c);
/*
* Open a stream over the memory region buf of size bytes. With buf == NULL
* the stream allocates and owns a growable buffer of its own that is freed
* on fclose. Modes are fopen-like ('r', 'w', 'a', optional '+' and 'b',
* where 'b' is accepted but on Linux only disables the string semantics):
* 'w' truncates the current length to zero, 'a' positions at the end of the
* data currently in the buffer (the first NUL byte in string mode), and
* writing past the buffer size is an error. Returns the stream, or NULL
* with errno set.
*/
FILE *
fmemopen(void *buf, size_t size, const char *mode);
/*
* Open a write-only dynamic memory stream. The stream owns a growable
* buffer; after fflush or fclose the buffer is NUL-terminated at the current
* data length, *ptr points at it (it may have moved), and *sizeloc holds the
* length. The caller releases the buffer with free() after fclose.
*/
FILE *
open_memstream(char **ptr, size_t *sizeloc);
#endif /* VLIBC_STDIO_H */