#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/fcall.h>
#include <9pm/ns.h>

int
create(char *file, int mode, ulong perm)
{
	char *path, *full, *p, *q, qc, *r;
	volatile int ret;
	volatile Chan *c;
	Mnt *mnt;

	checkerrstack();
	if((path = nsassign(file, &mnt, &full)) == nil){
		/*
		 * figure out who owns the directory, and create there
		 * creates go in the top of unions, unlike in plan 9 (i'm lazy).
		 */
		if((p = fullpath(file)) == nil)
			return -1;
		if((q = strrchr(p, '/')) == nil){
			werrstr("full path has no / (cannot happen)");
			free(p);
			return -1;
		}
		*q++ = '\0';
		qc = *q;
		*q = '\0';
		if(!isrootname(p))
			q[-1] = '\0';
		if((path = nsassign(p, &mnt, nil)) == nil){
			free(p);
			return -1;
		}
		*q = qc;
		if((r = malloc(strlen(path)+1+strlen(q)+1)) == nil){
			free(p);
			return -1;
		}
		strcpy(r, path);
		if(r[strlen(r)-1] != '/')
			strcat(r, "/");
		strcat(r, q);
		full = p;
		free(path);
		path = r;
	}
	c = nil;
	ret = -1;
	if(!waserror()){
		c = newchan(full, mnt);
		(*mnt->dev->_create)(c, mnt, path, mode, perm);
		ret = newfd(c);
		poperror();
	}
	if(ret >= 0){
		c->omode = mode;
		c = nil;	/* ref goes into fd table */
	}
	if(c)
		cclose(c);
	free(full);
	free(path);
	mntclose(mnt);
	checkerrstack();
	return ret;
}
