xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/open.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <errno.h>
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include "lib.h"
7 #include <sys/stat.h>
8 #include "sys9.h"
9 
10 /*
11  * O_NOCTTY has no effect
12  */
13 int
14 open(const char *path, int flags, ...)
15 {
16 	int n;
17 	long f;
18 	int mode;
19 	Fdinfo *fi;
20 	va_list va;
21 	struct stat sbuf;
22 
23 	f = flags&O_ACCMODE;
24 	if(flags&O_CREAT){
25 		if(access(path, 0) >= 0){
26 			if(flags&O_EXCL){
27 				errno = EEXIST;
28 				return -1;
29 			}else{
30 				if((flags&O_TRUNC)&&(flags&(O_RDWR|O_WRONLY)))
31 					f |= 16;
32 				n = _OPEN(path, f);
33 			}
34 		}else{
35 			va_start(va, flags);
36 			mode = va_arg(va, int);
37 			va_end(va);
38 			n = _CREATE(path, f, mode&0777);
39 		}
40 		if(n < 0)
41 			_syserrno();
42 	}else{
43 		if((flags&O_TRUNC)&&(flags&(O_RDWR|O_WRONLY)))
44 			f |= 16;
45 		n = _OPEN(path, f);
46 		if(n < 0)
47 			_syserrno();
48 	}
49 	if(n >= 0){
50 		fi = &_fdinfo[n];
51 		fi->flags = FD_ISOPEN;
52 		fi->oflags = flags&(O_ACCMODE|O_NONBLOCK|O_APPEND);
53 		if(stat(path, &sbuf) >= 0) {
54 			fi->uid = sbuf.st_uid;
55 			fi->gid = sbuf.st_gid;
56 		}
57 		fi->name = malloc(strlen(path)+1);
58 		if(fi->name)
59 			strcpy(fi->name, path);
60 		if(fi->oflags&O_APPEND)
61 			_SEEK(n, 0, 2);
62 	}
63 	return n;
64 }
65