summaryrefslogtreecommitdiff
path: root/src/stdio/freopen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdio/freopen.c')
-rw-r--r--src/stdio/freopen.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/stdio/freopen.c b/src/stdio/freopen.c
index e26f353f..2bb4420c 100644
--- a/src/stdio/freopen.c
+++ b/src/stdio/freopen.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include "string.h"
#include "errno.h"
#include "_stdio.h"
@@ -12,10 +13,44 @@
/** reopen a file stream with a new file **/
FILE * freopen(const char * restrict filename, const char * restrict mode, FILE * restrict stream)
{
+ struct {
+ char *smode;
+ int omode;
+ } modemap[] = {
+ { "r", O_RDONLY },
+ { "rb", O_RDONLY },
+
+ { "w", O_WRONLY | O_CREAT | O_TRUNC },
+ { "wb", O_WRONLY | O_CREAT | O_TRUNC },
+
+ { "a", O_WRONLY | O_CREAT | O_APPEND },
+ { "ab", O_WRONLY | O_CREAT | O_APPEND },
+
+ { "r+", O_RDWR },
+ { "rb+", O_RDWR },
+ { "r+b", O_RDWR },
+
+ { "w+", O_RDWR | O_CREAT | O_TRUNC },
+ { "wb+", O_RDWR | O_CREAT | O_TRUNC },
+ { "w+b", O_RDWR | O_CREAT | O_TRUNC },
+
+ { "a+", O_RDWR | O_CREAT | O_APPEND },
+ { "ab+", O_RDWR | O_CREAT | O_APPEND },
+ { "a+b", O_RDWR | O_CREAT | O_APPEND },
+ };
+ int openmode = 0;
+ size_t i;
+ int fd = -1;
+
flockfile(stream);
- (void)mode;
- int openmode = 0; /* modetoflag(mode); */
+ for (i = 0; i < sizeof(modemap) / sizeof(modemap[0]); i++) {
+ if (!strcmp(modemap[i].smode, mode)) {
+ openmode = modemap[i].omode;
+ break;
+ }
+ }
+
if (openmode == 0) {
#ifdef EINVAL
errno = EINVAL;
@@ -23,7 +58,7 @@ FILE * freopen(const char * restrict filename, const char * restrict mode, FILE
return NULL;
}
- int fd = open(filename, openmode, 0);
+ fd = open(filename, openmode, 0);
if (fd == -1) {
/* set errno */
return NULL;