diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-15 12:43:10 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-15 12:43:10 -0700 |
commit | 36992bd8bb6f6cdd3315032cc9898b1c7b99921c (patch) | |
tree | aa348a8d23cc2e1c9992579ea69394c61c6e7215 | |
parent | b6198b408721a80341d353bdc31b6a043a5ead32 (diff) | |
download | klibc-36992bd8bb6f6cdd3315032cc9898b1c7b99921c.tar.gz |
[klibc] Fold fopen and fdopen
Fold common features of fopen() and fdopen(). In particular,
POSIX doesn't actually require that fdopen() modifies the flags
on the file descriptor, so *don't* -- this is klibc, after all.
With that, we can then remove __fxopen() and __parse_open_mode() and
fold them into fdopen() and fopen() respectively.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | usr/klibc/Kbuild | 1 | ||||
-rw-r--r-- | usr/klibc/stdio/fdopen.c | 58 | ||||
-rw-r--r-- | usr/klibc/stdio/fopen.c | 46 | ||||
-rw-r--r-- | usr/klibc/stdio/fxopen.c | 62 | ||||
-rw-r--r-- | usr/klibc/stdio/openmode.c | 42 | ||||
-rw-r--r-- | usr/klibc/stdio/stdioint.h | 2 |
6 files changed, 93 insertions, 118 deletions
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild index a82ffa92a6509..fc90d53119461 100644 --- a/usr/klibc/Kbuild +++ b/usr/klibc/Kbuild @@ -67,7 +67,6 @@ klib-y += vsnprintf.o snprintf.o vsprintf.o sprintf.o \ userdb/getpwuid.o userdb/root_group.o userdb/root_user.o \ setmntent.o endmntent.o getmntent.o \ stdio/fclose.o stdio/fopen.o stdio/fdopen.o \ - stdio/openmode.o stdio/fxopen.o \ stdio/fread.o stdio/fwrite.o stdio/fflush.o \ stdio/ungetc.o stdio/fgetc.o \ stdio/fseek.o stdio/ftell.o stdio/rewind.o \ diff --git a/usr/klibc/stdio/fdopen.c b/usr/klibc/stdio/fdopen.c index 99f3a807db7e1..a12efe5d5b1b1 100644 --- a/usr/klibc/stdio/fdopen.c +++ b/usr/klibc/stdio/fdopen.c @@ -1,20 +1,62 @@ /* * fdopen.c + * + * Common code between fopen(), fdopen() and the standard descriptors. */ #include "stdioint.h" +FILE *stdin, *stdout, *stderr; + +/* Doubly-linked list of all stdio structures */ +struct _IO_file_pvt __stdio_headnode = +{ + .prev = &__stdio_headnode, + .next = &__stdio_headnode, +}; + FILE *fdopen(int fd, const char *mode) { - int flags = __parse_open_mode(mode); - int oldflags; + struct _IO_file_pvt *f; + const size_t bufoffs = + (sizeof *f + 4*sizeof(void *) - 1) & + ~(4*sizeof(void *) - 1); + + (void)mode; + + f = zalloc(bufoffs + BUFSIZ + _IO_UNGET_SLOP); + if (!f) + goto err; + + f->data = f->buf = (char *)f + bufoffs; + f->pub._io_fileno = fd; + f->pub._io_filepos = lseek(fd, 0, SEEK_CUR); + f->bufsiz = BUFSIZ; + f->bufmode = isatty(fd) ? _IOLBF : _IOFBF; - if (fcntl(fd, F_GETFL, &oldflags)) - return NULL; + /* Insert into linked list */ + f->prev = &__stdio_headnode; + f->next = __stdio_headnode.next; + f->next->prev = f; + __stdio_headnode.next = f; + + return &f->pub; + +err: + if (f) + free(f); + errno = ENOMEM; + return NULL; +} + +void __init_stdio(void) +{ + stdin = fdopen(0, NULL); + stdio_pvt(stdin)->bufmode = _IOLBF; - oldflags = (oldflags & ~O_APPEND) | (flags & O_APPEND); - if (fcntl(fd, F_SETFL, &oldflags)) - return NULL; + stdout = fdopen(1, NULL); + stdio_pvt(stdout)->bufmode = _IOLBF; - return __fxopen(fd, flags, 0); + stderr = fdopen(2, NULL); + stdio_pvt(stderr)->bufmode = _IONBF; } diff --git a/usr/klibc/stdio/fopen.c b/usr/klibc/stdio/fopen.c index 475620fe6da2c..cf098dfdd1dad 100644 --- a/usr/klibc/stdio/fopen.c +++ b/usr/klibc/stdio/fopen.c @@ -4,16 +4,56 @@ #include "stdioint.h" -extern int __parse_open_mode(const char *); +static int __parse_open_mode(const char *mode) +{ + int rwflags = O_RDONLY; + int crflags = 0; + int eflags = 0; + + while (*mode) { + switch (*mode++) { + case 'r': + rwflags = O_RDONLY; + crflags = 0; + break; + case 'w': + rwflags = O_WRONLY; + crflags = O_CREAT | O_TRUNC; + break; + case 'a': + rwflags = O_WRONLY; + crflags = O_CREAT | O_APPEND; + break; + case 'e': + eflags |= O_CLOEXEC; + break; + case 'x': + eflags |= O_EXCL; + break; + case '+': + rwflags = O_RDWR; + break; + } + } + + return rwflags | crflags | eflags; +} FILE *fopen(const char *file, const char *mode) { int flags = __parse_open_mode(mode); - int fd; + int fd, err; + FILE *f; fd = open(file, flags, 0666); if (fd < 0) return NULL; - return __fxopen(fd, flags, 1); + f = fdopen(fd, mode); + if (!f) { + err = errno; + close(fd); + errno = err; + } + return f; } diff --git a/usr/klibc/stdio/fxopen.c b/usr/klibc/stdio/fxopen.c deleted file mode 100644 index 1dcd377a37c53..0000000000000 --- a/usr/klibc/stdio/fxopen.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * fxopen.c - * - * Common code between fopen(), fdopen() and the standard descriptors. - */ - -#include "stdioint.h" - -FILE *stdin, *stdout, *stderr; - -/* Doubly-linked list of all stdio structures */ -struct _IO_file_pvt __stdio_headnode = -{ - .prev = &__stdio_headnode, - .next = &__stdio_headnode, -}; - -FILE *__fxopen(int fd, int flags, bool close_on_err) -{ - struct _IO_file_pvt *f; - const size_t bufoffs = - (sizeof *f + 4*sizeof(void *) - 1) & - ~(4*sizeof(void *) - 1); - - f = zalloc(bufoffs + BUFSIZ + _IO_UNGET_SLOP); - if (!f) - goto err; - - f->data = f->buf = (char *)f + bufoffs; - f->pub._io_fileno = fd; - f->pub._io_filepos = lseek(fd, 0, SEEK_CUR); - f->bufsiz = BUFSIZ; - f->bufmode = isatty(fd) ? _IOLBF : _IOFBF; - - /* Insert into linked list */ - f->prev = &__stdio_headnode; - f->next = __stdio_headnode.next; - f->next->prev = f; - __stdio_headnode.next = f; - - return &f->pub; - -err: - if (f) - free(f); - if (close_on_err) - close(fd); - errno = ENOMEM; - return NULL; -} - -void __init_stdio(void) -{ - stdin = __fxopen(0, O_RDONLY, 0); - stdio_pvt(stdin)->bufmode = _IOLBF; - - stdout = __fxopen(1, O_WRONLY|O_TRUNC, 0); - stdio_pvt(stdout)->bufmode = _IOLBF; - - stderr = __fxopen(2, O_WRONLY|O_TRUNC, 0); - stdio_pvt(stderr)->bufmode = _IONBF; -} diff --git a/usr/klibc/stdio/openmode.c b/usr/klibc/stdio/openmode.c deleted file mode 100644 index 971237d230f47..0000000000000 --- a/usr/klibc/stdio/openmode.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * openmode.c - * - * Parse the mode argument to fopen() or fdopen() - */ - -#include "stdioint.h" - -int __parse_open_mode(const char *mode) -{ - int rwflags = O_RDONLY; - int crflags = 0; - int eflags = 0; - - while (*mode) { - switch (*mode++) { - case 'r': - rwflags = O_RDONLY; - crflags = 0; - break; - case 'w': - rwflags = O_WRONLY; - crflags = O_CREAT | O_TRUNC; - break; - case 'a': - rwflags = O_WRONLY; - crflags = O_CREAT | O_APPEND; - break; - case 'e': - eflags |= O_CLOEXEC; - break; - case 'x': - eflags |= O_EXCL; - break; - case '+': - rwflags = O_RDWR; - break; - } - } - - return rwflags | crflags | eflags; -} diff --git a/usr/klibc/stdio/stdioint.h b/usr/klibc/stdio/stdioint.h index 4653f35102927..526c25a8f7118 100644 --- a/usr/klibc/stdio/stdioint.h +++ b/usr/klibc/stdio/stdioint.h @@ -41,8 +41,6 @@ enum _IO_file_flags { #define _IO_UNGET_SLOP 32 __extern int __fflush(struct _IO_file_pvt *); -__extern int __parse_open_mode(const char *mode); -__extern FILE *__fxopen(int fd, int flags, bool close_on_err); __extern struct _IO_file_pvt __stdio_headnode; |