create.c (1385B)
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 12 13 int 14 p9create(char *path, int mode, ulong perm) 15 { 16 int fd, cexec, umode, rclose, lock, rdwr; 17 struct flock fl; 18 19 rdwr = mode&3; 20 lock = mode&OLOCK; 21 cexec = mode&OCEXEC; 22 rclose = mode&ORCLOSE; 23 mode &= ~(ORCLOSE|OCEXEC|OLOCK); 24 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&OAPPEND){ 47 umode |= O_APPEND; 48 mode &= ~OAPPEND; 49 } 50 if(mode){ 51 werrstr("unsupported mode in create"); 52 goto out; 53 } 54 fd = open(path, umode, perm); 55 } 56 out: 57 if(fd >= 0){ 58 if(lock){ 59 fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK; 60 fl.l_whence = SEEK_SET; 61 fl.l_start = 0; 62 fl.l_len = 0; 63 if(fcntl(fd, F_SETLK, &fl) < 0){ 64 close(fd); 65 werrstr("lock: %r"); 66 return -1; 67 } 68 } 69 if(cexec) 70 fcntl(fd, F_SETFL, FD_CLOEXEC); 71 if(rclose) 72 remove(path); 73 } 74 return fd; 75 }