diff options
Diffstat (limited to 'usr/klibc/stdio/fdopen.c')
-rw-r--r-- | usr/klibc/stdio/fdopen.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/usr/klibc/stdio/fdopen.c b/usr/klibc/stdio/fdopen.c index 51285baeeb123..bbfbd1f9914bb 100644 --- a/usr/klibc/stdio/fdopen.c +++ b/usr/klibc/stdio/fdopen.c @@ -15,7 +15,7 @@ struct _IO_file_pvt __stdio_headnode = .next = &__stdio_headnode, }; -FILE *fdopen(int fd, const char *mode) +FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t funcs) { struct _IO_file_pvt *f; const size_t bufoffs = @@ -29,9 +29,10 @@ FILE *fdopen(int fd, const char *mode) goto err; f->data = f->buf = (char *)f + bufoffs; - f->pub._IO_fileno = fd; + f->funcs = funcs; + f->cookie = cookie; f->bufsiz = BUFSIZ; - f->bufmode = isatty(fd) ? _IOLBF : _IOFBF; + f->bufmode = _IOFBF; /* Insert into linked list */ f->prev = &__stdio_headnode; @@ -48,6 +49,31 @@ err: return NULL; } +FILE *fdopen(int fd, const char *mode) +{ + FILE *file; + + /* + * Cookie operations for ordinary files. This is only safe because + * all Linux architectures pass integers <= sizeof(pointer) and + * pointers the same way, at least for non-structure arguments. + */ + const struct cookie_io_functions_t file_funcs = { + .read = (cookie_read_function_t *)read, + .write = (cookie_write_function_t *)write, + .seek = (cookie_seek_function_t *)lseek, + .close = (cookie_close_function_t *)close + }; + + file = fopencookie((void *)(intptr_t)fd, mode, file_funcs); + if (file) { + struct _IO_file_pvt *f = stdio_pvt(file); + f->isfile = true; + f->bufmode = isatty(fd) ? _IOLBF : _IOFBF; + } + return file; +} + void __init_stdio(void) { stdin = fdopen(0, NULL); |