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