9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

open.c (1082B)


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