aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2012-05-15 12:43:10 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2012-05-15 12:43:10 -0700
commit36992bd8bb6f6cdd3315032cc9898b1c7b99921c (patch)
treeaa348a8d23cc2e1c9992579ea69394c61c6e7215
parentb6198b408721a80341d353bdc31b6a043a5ead32 (diff)
downloadklibc-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/Kbuild1
-rw-r--r--usr/klibc/stdio/fdopen.c58
-rw-r--r--usr/klibc/stdio/fopen.c46
-rw-r--r--usr/klibc/stdio/fxopen.c62
-rw-r--r--usr/klibc/stdio/openmode.c42
-rw-r--r--usr/klibc/stdio/stdioint.h2
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;