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&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 }