blob: e76aabe3181ca3dd4bf776e24cd7fbb5e6738e9a [file] [log] [blame]
rscbe36ff62004-04-29 17:13:24 +00001#define _GNU_SOURCE /* for Linux O_DIRECT */
rscb3994ec2003-12-11 17:50:28 +00002#include <u.h>
3#define NOPLAN9DEFINES
rsce7504002004-06-11 14:38:56 +00004#include <sys/file.h>
rscb3994ec2003-12-11 17:50:28 +00005#include <libc.h>
rsc983990c2004-05-14 20:19:53 +00006#ifndef O_DIRECT
7#define O_DIRECT 0
8#endif
rscb3994ec2003-12-11 17:50:28 +00009
rscb3994ec2003-12-11 17:50:28 +000010int
rsc8ad51792004-03-25 23:03:57 +000011p9open(char *name, int mode)
rscb3994ec2003-12-11 17:50:28 +000012{
rscb3994ec2003-12-11 17:50:28 +000013 int cexec, rclose;
rscd9e16d22004-06-11 18:57:32 +000014 int fd, umode, lock, rdwr;
rscc71af672005-01-07 07:19:35 +000015 struct flock fl;
rscb3994ec2003-12-11 17:50:28 +000016
rscd9e16d22004-06-11 18:57:32 +000017 rdwr = mode&3;
18 umode = rdwr;
rscb3994ec2003-12-11 17:50:28 +000019 cexec = mode&OCEXEC;
20 rclose = mode&ORCLOSE;
rsce7504002004-06-11 14:38:56 +000021 lock = mode&OLOCK;
22 mode &= ~(3|OCEXEC|ORCLOSE|OLOCK);
rscb3994ec2003-12-11 17:50:28 +000023 if(mode&OTRUNC){
24 umode |= O_TRUNC;
25 mode ^= OTRUNC;
26 }
rscbe36ff62004-04-29 17:13:24 +000027 if(mode&ODIRECT){
28 umode |= O_DIRECT;
29 mode ^= ODIRECT;
30 }
rsca19ff5b2005-01-07 18:03:36 +000031 if(mode&ONONBLOCK){
32 umode |= O_NONBLOCK;
33 mode ^= ONONBLOCK;
34 }
rscb3994ec2003-12-11 17:50:28 +000035 if(mode){
rscdebcecb2004-05-14 19:45:23 +000036 werrstr("mode 0x%x not supported", mode);
rscb3994ec2003-12-11 17:50:28 +000037 return -1;
38 }
rscb3994ec2003-12-11 17:50:28 +000039 fd = open(name, umode);
40 if(fd >= 0){
rsce7504002004-06-11 14:38:56 +000041 if(lock){
rscc71af672005-01-07 07:19:35 +000042 fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK;
43 fl.l_whence = SEEK_SET;
44 fl.l_start = 0;
45 fl.l_len = 0;
46 if(fcntl(fd, F_SETLK, &fl) < 0){
rsce7504002004-06-11 14:38:56 +000047 close(fd);
48 return -1;
49 }
50 }
rscb3994ec2003-12-11 17:50:28 +000051 if(cexec)
52 fcntl(fd, F_SETFL, FD_CLOEXEC);
53 if(rclose)
54 remove(name);
55 }
rscb3994ec2003-12-11 17:50:28 +000056 return fd;
57}