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