aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/create.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9/create.c')
-rw-r--r--src/lib9/create.c50
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;
}