Blob
1 #define _GNU_SOURCE /* for Linux O_DIRECT */2 #include <u.h>3 #define NOPLAN9DEFINES4 #include <sys/file.h>5 #include <unistd.h>6 #include <fcntl.h>7 #include <libc.h>8 #include <sys/stat.h>9 #ifndef O_DIRECT10 #define O_DIRECT 011 #endif13 int14 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 }