xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/open.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <errno.h>
23e12c5d1SDavid du Colombier #include <stdarg.h>
33e12c5d1SDavid du Colombier #include <stdlib.h>
43e12c5d1SDavid du Colombier #include <unistd.h>
53e12c5d1SDavid du Colombier #include <string.h>
63e12c5d1SDavid du Colombier #include "lib.h"
7*219b2ee8SDavid du Colombier #include <sys/stat.h>
83e12c5d1SDavid du Colombier #include "sys9.h"
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier /*
113e12c5d1SDavid du Colombier  * O_NOCTTY has no effect
123e12c5d1SDavid du Colombier  */
133e12c5d1SDavid du Colombier int
143e12c5d1SDavid du Colombier open(const char *path, int flags, ...)
153e12c5d1SDavid du Colombier {
163e12c5d1SDavid du Colombier 	int n;
173e12c5d1SDavid du Colombier 	long f;
183e12c5d1SDavid du Colombier 	int mode;
193e12c5d1SDavid du Colombier 	Fdinfo *fi;
203e12c5d1SDavid du Colombier 	va_list va;
21*219b2ee8SDavid du Colombier 	struct stat sbuf;
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier 	f = flags&O_ACCMODE;
243e12c5d1SDavid du Colombier 	if(flags&O_CREAT){
253e12c5d1SDavid du Colombier 		if(access(path, 0) >= 0){
263e12c5d1SDavid du Colombier 			if(flags&O_EXCL){
273e12c5d1SDavid du Colombier 				errno = EEXIST;
283e12c5d1SDavid du Colombier 				return -1;
293e12c5d1SDavid du Colombier 			}else{
303e12c5d1SDavid du Colombier 				if((flags&O_TRUNC)&&(flags&(O_RDWR|O_WRONLY)))
313e12c5d1SDavid du Colombier 					f |= 16;
323e12c5d1SDavid du Colombier 				n = _OPEN(path, f);
333e12c5d1SDavid du Colombier 			}
343e12c5d1SDavid du Colombier 		}else{
353e12c5d1SDavid du Colombier 			va_start(va, flags);
363e12c5d1SDavid du Colombier 			mode = va_arg(va, int);
373e12c5d1SDavid du Colombier 			va_end(va);
383e12c5d1SDavid du Colombier 			n = _CREATE(path, f, mode&0777);
393e12c5d1SDavid du Colombier 		}
403e12c5d1SDavid du Colombier 		if(n < 0)
413e12c5d1SDavid du Colombier 			_syserrno();
423e12c5d1SDavid du Colombier 	}else{
433e12c5d1SDavid du Colombier 		if((flags&O_TRUNC)&&(flags&(O_RDWR|O_WRONLY)))
443e12c5d1SDavid du Colombier 			f |= 16;
453e12c5d1SDavid du Colombier 		n = _OPEN(path, f);
463e12c5d1SDavid du Colombier 		if(n < 0)
473e12c5d1SDavid du Colombier 			_syserrno();
483e12c5d1SDavid du Colombier 	}
493e12c5d1SDavid du Colombier 	if(n >= 0){
503e12c5d1SDavid du Colombier 		fi = &_fdinfo[n];
513e12c5d1SDavid du Colombier 		fi->flags = FD_ISOPEN;
523e12c5d1SDavid du Colombier 		fi->oflags = flags&(O_ACCMODE|O_NONBLOCK|O_APPEND);
53*219b2ee8SDavid du Colombier 		if(stat(path, &sbuf) >= 0) {
54*219b2ee8SDavid du Colombier 			fi->uid = sbuf.st_uid;
55*219b2ee8SDavid du Colombier 			fi->gid = sbuf.st_gid;
56*219b2ee8SDavid du Colombier 		}
573e12c5d1SDavid du Colombier 		fi->name = malloc(strlen(path)+1);
583e12c5d1SDavid du Colombier 		if(fi->name)
593e12c5d1SDavid du Colombier 			strcpy(fi->name, path);
603e12c5d1SDavid du Colombier 		if(fi->oflags&O_APPEND)
613e12c5d1SDavid du Colombier 			_SEEK(n, 0, 2);
623e12c5d1SDavid du Colombier 	}
633e12c5d1SDavid du Colombier 	return n;
643e12c5d1SDavid du Colombier }
65