diff options
Diffstat (limited to 'src/lib9/create.c')
-rw-r--r-- | src/lib9/create.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/lib9/create.c b/src/lib9/create.c index abef0c35..bdad5f6a 100644 --- a/src/lib9/create.c +++ b/src/lib9/create.c @@ -1,8 +1,54 @@ #include <u.h> +#define NOPLAN9DEFINES #include <libc.h> +#include <sys/stat.h> + +extern char *_p9translate(char*); int -create(char *path, int mode, ulong perm) +p9create(char *xpath, int mode, ulong perm) { - return open(path, mode|O_CREAT|O_TRUNC, perm); + int fd, cexec, umode, rclose; + char *path; + + if((path = _p9translate(xpath)) == nil) + return -1; + + cexec = mode&OCEXEC; + rclose = mode&ORCLOSE; + mode &= ~(ORCLOSE|OCEXEC); + + /* XXX should get mode mask right? */ + fd = -1; + if(perm&DMDIR){ + if(mode != OREAD){ + werrstr("bad mode in directory create"); + goto out; + } + if(mkdir(path, perm&0777) < 0) + goto out; + fd = open(path, O_RDONLY); + }else{ + umode = (mode&3)|O_CREAT|O_TRUNC; + mode &= ~(3|OTRUNC); + if(mode&OEXCL){ + umode |= O_EXCL; + mode &= ~OEXCL; + } + if(mode){ + werrstr("unsupported mode in create"); + goto out; + } + fd = open(path, umode, perm); + } +out: + if(fd >= 0){ + if(cexec) + fcntl(fd, F_SETFL, FD_CLOEXEC); + if(rclose) + remove(path); + } + if(path != xpath) + free(path); + return fd; } |