summaryrefslogtreecommitdiff
path: root/src/user/lib/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib/file.c')
-rw-r--r--src/user/lib/file.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/user/lib/file.c b/src/user/lib/file.c
index 942b522..080217c 100644
--- a/src/user/lib/file.c
+++ b/src/user/lib/file.c
@@ -18,7 +18,11 @@ FILE *fopen(const char *path, const char *mode) {
FILE *f;
handle_t h;
int flags = 0;
- if (path && path[0] == '!') {
+ char *tmppath = NULL;
+ if (!path) {
+ errno = -1;
+ return NULL;
+ } else if (path[0] == '!') {
/* special handling for "!files" */
path++;
if (!strcmp(path, "stdin")) return file_clone(stdin, mode);
@@ -26,23 +30,32 @@ FILE *fopen(const char *path, const char *mode) {
if (!strcmp(path, "stderr")) return file_clone(stderr, mode);
errno = -1;
return NULL;
- } else {
- if (mode[0] == 'w' || mode[0] == 'a')
- flags |= OPEN_CREATE;
+ }
- h = _syscall_open(path, strlen(path), flags);
- if (h < 0) {
- errno = -h;
- return NULL;
- }
+ if (path && path[0] != '/') {
+ size_t len = absolutepath(NULL, path, 0);
+ tmppath = malloc(len);
+ if (!tmppath) return NULL;
+ absolutepath(tmppath, path, len);
+ path = tmppath;
+ }
- if (mode[0] == 'w')
- _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE);
+ if (mode[0] == 'w' || mode[0] == 'a')
+ flags |= OPEN_CREATE;
- f = fdopen(h, mode);
- if (!f) close(h);
- return f;
+ h = _syscall_open(path, strlen(path), flags);
+ if (tmppath) free(tmppath);
+ if (h < 0) {
+ errno = -h;
+ return NULL;
}
+
+ if (mode[0] == 'w')
+ _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE);
+
+ f = fdopen(h, mode);
+ if (!f) close(h);
+ return f;
}
FILE *freopen(const char *path, const char *mode, FILE *f) {