1 #define _GNU_SOURCE	/* for Linux O_DIRECT */
2 #include <u.h>
3 #define NOPLAN9DEFINES
4 #include <sys/file.h>
5 #include <libc.h>
6 #ifndef O_DIRECT
7 #define O_DIRECT 0
8 #endif
9 
10 int
p9open(char * name,int mode)11 p9open(char *name, int mode)
12 {
13 	int cexec, rclose;
14 	int fd, umode, lock, rdwr;
15 	struct flock fl;
16 
17 	rdwr = mode&3;
18 	umode = rdwr;
19 	cexec = mode&OCEXEC;
20 	rclose = mode&ORCLOSE;
21 	lock = mode&OLOCK;
22 	mode &= ~(3|OCEXEC|ORCLOSE|OLOCK);
23 	if(mode&OTRUNC){
24 		umode |= O_TRUNC;
25 		mode ^= OTRUNC;
26 	}
27 	if(mode&ODIRECT){
28 		umode |= O_DIRECT;
29 		mode ^= ODIRECT;
30 	}
31 	if(mode&ONONBLOCK){
32 		umode |= O_NONBLOCK;
33 		mode ^= ONONBLOCK;
34 	}
35 	if(mode&OAPPEND){
36 		umode |= O_APPEND;
37 		mode ^= OAPPEND;
38 	}
39 	if(mode){
40 		werrstr("mode 0x%x not supported", mode);
41 		return -1;
42 	}
43 	fd = open(name, umode);
44 	if(fd >= 0){
45 		if(lock){
46 			fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK;
47 			fl.l_whence = SEEK_SET;
48 			fl.l_start = 0;
49 			fl.l_len = 0;
50 			if(fcntl(fd, F_SETLK, &fl) < 0){
51 				close(fd);
52 				werrstr("lock: %r");
53 				return -1;
54 			}
55 		}
56 		if(cexec)
57 			fcntl(fd, F_SETFL, FD_CLOEXEC);
58 		if(rclose)
59 			remove(name);
60 	}
61 	return fd;
62 }
63