Blob


1 #define _GNU_SOURCE /* for Linux O_DIRECT */
2 #include <u.h>
3 #define NOPLAN9DEFINES
4 #include <sys/file.h>
5 #include <libc.h>
6 #include <sys/stat.h>
7 #ifndef O_DIRECT
8 #define O_DIRECT 0
9 #endif
11 int
12 p9create(char *path, int mode, ulong perm)
13 {
14 int fd, cexec, umode, rclose, lock, rdwr;
16 rdwr = mode&3;
17 lock = mode&OLOCK;
18 cexec = mode&OCEXEC;
19 rclose = mode&ORCLOSE;
20 mode &= ~(ORCLOSE|OCEXEC|OLOCK);
22 /* XXX should get mode mask right? */
23 fd = -1;
24 if(perm&DMDIR){
25 if(mode != OREAD){
26 werrstr("bad mode in directory create");
27 goto out;
28 }
29 if(mkdir(path, perm&0777) < 0)
30 goto out;
31 fd = open(path, O_RDONLY);
32 }else{
33 umode = (mode&3)|O_CREAT|O_TRUNC;
34 mode &= ~(3|OTRUNC);
35 if(mode&ODIRECT){
36 umode |= O_DIRECT;
37 mode &= ~ODIRECT;
38 }
39 if(mode&OEXCL){
40 umode |= O_EXCL;
41 mode &= ~OEXCL;
42 }
43 if(mode){
44 werrstr("unsupported mode in create");
45 goto out;
46 }
47 fd = open(path, umode, perm);
48 }
49 out:
50 if(fd >= 0){
51 if(lock){
52 if(flock(fd, (rdwr==OREAD) ? LOCK_SH : LOCK_EX) < 0){
53 close(fd);
54 return -1;
55 }
56 }
57 if(cexec)
58 fcntl(fd, F_SETFL, FD_CLOEXEC);
59 if(rclose)
60 remove(path);
61 }
62 return fd;
63 }