From bfb95a3d3e47d45bb570820178b2e703576d5a23 Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Wed, 23 Aug 2017 04:05:31 +0200 Subject: [PATCH] libposix: drafted chdir, fchdir and mkdir --- sys/include/posix.h | 3 ++ sys/src/lib/posix/files.c | 98 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/sys/include/posix.h b/sys/include/posix.h index a055750..5c0817a 100644 --- a/sys/include/posix.h +++ b/sys/include/posix.h @@ -89,6 +89,9 @@ typedef unsigned long clock_t; extern void POSIX_exit(int code) __attribute__((noreturn)); extern int POSIX_chmod(int *errnop, const char *path, int mode); extern int POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag); +extern int POSIX_chdir(int *errnop, const char *path); +extern int POSIX_fchdir(int *errnop, int fd); +extern int POSIX_mkdir(int *errnop, const char *path, int mode); extern int POSIX_close(int *errnop, int file); extern int POSIX_execve(int *errnop, const char *name, char * const*argv, char * const*env); extern int POSIX_fork(int *errnop); diff --git a/sys/src/lib/posix/files.c b/sys/src/lib/posix/files.c index 3999262..7aecb1d 100644 --- a/sys/src/lib/posix/files.c +++ b/sys/src/lib/posix/files.c @@ -475,6 +475,104 @@ FailWithError: return -1; } +int +POSIX_chdir(int *errnop, const char *path) +{ + Dir *d = nil; + PosixError e = 0; + + if(path == nil){ + e = PosixEFAULT; + } else { + d = dirstat(path); + if(d == nil){ + e = PosixENOENT; + } else { + if((d->mode & DMDIR) == 0) + e = PosixENOTDIR; + free(d); + } + } + if(e != 0) + goto FailWithError; + + if(chdir(path) == 0) + return 0; + + *errnop = __libposix_translate_errstr((uintptr_t)POSIX_chdir); + return -1; + +FailWithError: + *errnop = __libposix_get_errno(e); + return -1; +} + +int +POSIX_fchdir(int *errnop, int fd) +{ + Dir *d; + PosixError e = 0; + char buf[4096]; + + if(fd < 0){ + e = PosixEBADF; + } else { + d = dirfstat(fd); + if(d == nil){ + e = PosixENOENT; + } else { + if((d->mode & DMDIR) == 0) + e = PosixENOTDIR; + free(d); + if(fd2path(fd, buf, sizeof(buf)) != 0) + e = PosixENOENT; /* just removed? */ + } + } + if(e != 0) + goto FailWithError; + + if(chdir(buf) == 0) + return 0; + + *errnop = __libposix_translate_errstr((uintptr_t)POSIX_fchdir); + return -1; + +FailWithError: + *errnop = __libposix_get_errno(e); + return -1; +} + +int +POSIX_mkdir(int *errnop, const char *path, int mode) +{ + long cperm = 0; + PosixError e = 0; + int fd; + + if(path == nil) + e = PosixEFAULT; + else if(access(path, AEXIST) == 0) + e = PosixEEXIST; + else + e = __libposix_open_translation(0, mode, nil, &cperm); + if(e != 0) + goto FailWithError; + + fd = create(path, OREAD, DMDIR | cperm); + if(fd >= 0){ + close(fd); + return 0; + } + + *errnop = __libposix_translate_errstr((uintptr_t)POSIX_mkdir); + return -1; + +FailWithError: + *errnop = __libposix_get_errno(e); + return -1; +} + + /* getdents is not POSIX, but is used in POSIX C library to implement * readdir. */