Blob


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