summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-08-12 14:49:05 -0400
committerJakob Kaivo <jkk@ung.org>2020-08-12 14:49:05 -0400
commitd63be54dd4142d420bce9a40e2d4634d5d1356cc (patch)
tree3de3c952eedfbd3efe6538c490619b70d46f75bf
parent32bb2844f1e40eec4c0f14b40fd23b3ad482c509 (diff)
map symbolic modes to open() omode
-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;