int syscreate(char *path, int mode, uint32_t perm) { ERRSTACK(2); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } openmode(mode & ~OEXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if (waserror()) { cclose(c); nexterror(); } fd = newfd(c); if (fd < 0) error(Enofd); poperror(); poperror(); return fd; }
void sysopen(Ar0* ar0, ...) { Proc *up = externup(); va_list list; char *aname; int fd, omode; Chan *c; /* * int open(char* file, int omode); */ va_start(list, ar0); aname = va_arg(list, char*); omode = va_arg(list, int); va_end(list); openmode(omode); /* error check only */ c = nil; if(waserror()){ if(c != nil) cclose(c); nexterror(); } aname = validaddr(aname, 1, 0); c = namec(aname, Aopen, omode, 0); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); ar0->i = fd; }
void syscreate(Ar0* ar0, ...) { Proc *up = externup(); char *aname; int fd, omode, perm; Chan *c; va_list list; va_start(list, ar0); /* * int create(char* file, int omode, uint32_t perm); * should be * int create(char* file, int omode, int perm); */ aname = va_arg(list, char*); omode = va_arg(list, int); perm = va_arg(list, int); va_end(list); openmode(omode & ~OEXCL); /* error check only; OEXCL okay here */ c = nil; if(waserror()) { if(c != nil) cclose(c); nexterror(); } c = namec(validaddr(aname, 1, 0), Acreate, omode, perm); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); ar0->i = fd; }
void chanfd::newfd (svccb *sbp) { assert (sbp->prog () == REX_PROG && sbp->proc () == REX_NEWFD); rex_newfd_arg *argp = sbp->Xtmpl getarg<rex_newfd_arg> (); assert (argp->channel == channo); if (argp->fd < 0 || implicit_cast<size_t> (argp->fd) >= fdi.size () || fdi[argp->fd].weof) { warn ("newfd invalid fd %d\n", argp->fd); sbp->replyref (rex_newfd_res (false)); return; } int fds[2]; if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0) { warn ("socketpair: %m\n"); sbp->replyref (rex_newfd_res (false)); return; } close_on_exec (fds[0]); close_on_exec (fds[1]); fdinfo *fdip = &fdi[argp->fd]; /* Need to make sure file descriptors get sent no later than data */ if (!fdip->fdsendq.empty ()) fdip->wuio.breakiov (); fdip->fdsendq.push_back (fds[0]); rex_newfd_res res (true); *res.newfd = newfd (fds[1]); sbp->replyref (res); }
int syscreate(char *path, int mode, uint32_t perm) { ERRSTACK(2); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } openmode(mode & ~O_EXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if (waserror()) { cclose(c); nexterror(); } fd = newfd(c, mode); /* 9ns mode is the O_FLAGS and perm is glibc mode */ if (fd < 0) error(-fd, ERROR_FIXME); poperror(); poperror(); return fd; }
int syspipe(int fd[2]) { ERRSTACK(1); struct dev *d; struct chan *c[2]; static char *names[] = { "data", "data1" }; d = &devtab[devno("pipe", 0)]; c[0] = 0; c[1] = 0; fd[0] = -1; fd[1] = -1; if (waserror()) { /* need to remove from the fd table and make sure the chan is closed * exactly once. if fd[i] >= 0, then the fd is valid (or it was!) and * the fd table has the only ref (newfd() currently decrefs/consumes the * reference). cclose() doesn't care if you pass it 0 (like kfree()). */ if (fd[0] >= 0) close_fd(¤t->open_files, fd[0]); else cclose(c[0]); if (fd[1] >= 0) close_fd(¤t->open_files, fd[1]); else cclose(c[1]); poperror(); return -1; } c[0] = namec("#pipe", Atodir, 0, 0); c[1] = cclone(c[0]); if (walk(&c[0], &names[0], 1, FALSE, NULL) < 0) error(EINVAL, ERROR_FIXME); if (walk(&c[1], &names[1], 1, FALSE, NULL) < 0) error(EINVAL, ERROR_FIXME); c[0] = d->open(c[0], O_RDWR); c[1] = d->open(c[1], O_RDWR); fd[0] = newfd(c[0], 0); if (fd[0] < 0) error(-fd[0], ERROR_FIXME); fd[1] = newfd(c[1], 0); if (fd[1] < 0) error(-fd[1], ERROR_FIXME); poperror(); return 0; }
void sysdup(Ar0* ar0, ...) { Proc *up = externup(); int nfd, ofd; Chan *nc, *oc; Fgrp *f; va_list list; va_start(list, ar0); /* * int dup(int oldfd, int newfd); * * Close after dup'ing, so date > #d/1 works */ ofd = va_arg(list, int); oc = fdtochan(ofd, -1, 0, 1); nfd = va_arg(list, int); va_end(list); if(nfd != -1){ f = up->fgrp; lock(&f->r.l); if(nfd < 0 || growfd(f, nfd) < 0) { unlockfgrp(f); cclose(oc); error(Ebadfd); } if(nfd > f->maxfd) f->maxfd = nfd; nc = f->fd[nfd]; f->fd[nfd] = oc; unlockfgrp(f); if(nc != nil) cclose(nc); }else{ if(waserror()) { cclose(oc); nexterror(); } nfd = newfd(oc); if(nfd < 0) error(Enofd); poperror(); } ar0->i = nfd; }
void sysfauth(Ar0* ar0, va_list list) { Chan *c, *ac; char *aname; int fd; /* * int fauth(int fd, char *aname); */ fd = va_arg(list, int); aname = va_arg(list, char*); aname = validaddr(aname, 1, 0); aname = validnamedup(aname, 1); if(waserror()){ free(aname); nexterror(); } c = fdtochan(fd, ORDWR, 0, 1); if(waserror()){ cclose(c); nexterror(); } ac = mntauth(c, aname); /* at this point ac is responsible for keeping c alive */ cclose(c); poperror(); /* c */ free(aname); poperror(); /* aname */ if(waserror()){ cclose(ac); nexterror(); } fd = newfd(ac); if(fd < 0) error(Enofd); poperror(); /* ac */ /* always mark it close on exec */ ac->flag |= CCEXEC; ar0->i = fd; }
ssize_t chanfd::readfd (int fdn, void *buf, size_t len, bool &fdrecv) { int rfd; ssize_t n = ::readfd (fdi[fdn].fd, buf, len, &rfd); if (rfd >= 0) { fdrecv = true; close_on_exec (rfd); rexcb_newfd_arg arg; arg.channel = channo; arg.fd = fdn; arg.newfd = newfd (rfd, false); ref<bool> okp (New refcounted<bool> (false)); c->call (REXCB_NEWFD, &arg, okp, wrap (this, &chanfd::newfdrep, arg.newfd, okp)); } return n; }
long sysopen(ulong *arg) { int fd; Chan *c; openmode(arg[1]); /* error check only */ validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Aopen, arg[1], 0); if(waserror()){ cclose(c); nexterror(); } fd = newfd(c); if(fd < 0) error(Enofd); poperror(); return fd; }
long syscreate(ulong *arg) { int fd; Chan *c; openmode(arg[1]&~OEXCL); /* error check only; OEXCL okay here */ validaddr(arg[0], 1, 0); c = namec((char*)arg[0], Acreate, arg[1], arg[2]); if(waserror()) { cclose(c); nexterror(); } fd = newfd(c); if(fd < 0) error(Enofd); poperror(); return fd; }
long _sysopen(char *name, int mode) { int fd; Chan *c = 0; openmode(mode); /* error check only */ if(waserror()){ if(c) cclose(c); nexterror(); } c = namec(name, Aopen, mode, 0); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); return fd; }
int kcreate(char *path, int mode, ulong perm) { int fd; volatile struct { Chan *c; } c; c.c = nil; if(waserror()) { cclose(c.c); return -1; } openmode(mode&~OEXCL); /* error check only; OEXCL okay here */ c.c = namec(path, Acreate, mode, perm); fd = newfd(c.c); if(fd < 0) error(Enofd); poperror(); return fd; }
long sysfauth(ulong *arg) { Chan *c, *ac; char *aname; int fd; validaddr(arg[1], 1, 0); aname = validnamedup((char*)arg[1], 1); if(waserror()){ free(aname); nexterror(); } c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ cclose(c); nexterror(); } ac = mntauth(c, aname); /* at this point ac is responsible for keeping c alive */ poperror(); /* c */ cclose(c); poperror(); /* aname */ free(aname); if(waserror()){ cclose(ac); nexterror(); } fd = newfd(ac); if(fd < 0) error(Enofd); poperror(); /* ac */ /* always mark it close on exec */ ac->flag |= CCEXEC; return fd; }
long syscreate(uint32 *arg) { int fd; Chan *c = 0; char *name; openmode(arg[1]&~OEXCL); /* error check only; OEXCL okay here */ if(waserror()) { if(c) cclose(c); nexterror(); } name = uvalidaddr(arg[0], 1, 0); c = namec(name, Acreate, arg[1], arg[2]); fd = newfd(c); if(fd < 0) error(Enofd); poperror(); return fd; }
long sysdup(ulong *arg) { int fd; Chan *c, *oc; Fgrp *f = up->fgrp; /* * Close after dup'ing, so date > #d/1 works */ c = fdtochan(arg[0], -1, 0, 1); fd = arg[1]; if(fd != -1){ lock(f); if(fd<0 || growfd(f, fd)<0) { unlockfgrp(f); cclose(c); error(Ebadfd); } if(fd > f->maxfd) f->maxfd = fd; oc = f->fd[fd]; f->fd[fd] = c; unlockfgrp(f); if(oc) cclose(oc); }else{ if(waserror()) { cclose(c); nexterror(); } fd = newfd(c); if(fd < 0) error(Enofd); poperror(); } return fd; }
int sysdup(int old) { ERRSTACK(1); int fd; struct chan *c; if (waserror()) { poperror(); return -1; } c = fdtochan(¤t->open_files, old, -1, 0, 1); if (c->qid.type & QTAUTH) { cclose(c); error(EPERM, ERROR_FIXME); } fd = newfd(c, 0); if (fd < 0) { cclose(c); error(-fd, ERROR_FIXME); } poperror(); return fd; }
int kcreate(char *path, int mode, ulong perm) { int fd; Chan *c; if(waserror()) return -1; openmode(mode&~OEXCL); /* error check only; OEXCL okay here */ c = namec(path, Acreate, mode, perm); if(waserror()) { cclose(c); nexterror(); } fd = newfd(c); if(fd < 0) error(Enofd); poperror(); poperror(); return fd; }
int sysfauth(int fd, char *aname) { ERRSTACK(2); struct chan *c, *ac; if (waserror()) { poperror(); return -1; } validname(aname, 0); c = fdtochan(¤t->open_files, fd, O_RDWR, 0, 1); if (waserror()) { cclose(c); nexterror(); } ac = mntauth(c, aname); /* at this point ac is responsible for keeping c alive */ poperror(); /* c */ cclose(c); if (waserror()) { cclose(ac); nexterror(); } fd = newfd(ac, 0); if (fd < 0) error(-fd, ERROR_FIXME); poperror(); /* ac */ poperror(); return fd; }
static void sysrfork(void) { u32int flags; int rc, i; Process *p; Segment *s, *t; Fd *old; flags = arg(0); if(systrace) fprint(2, "rfork(%#o)\n", flags); if((flags & (RFFDG | RFCFDG)) == (RFFDG | RFCFDG) || (flags & (RFNAMEG | RFCNAMEG)) == (RFNAMEG | RFCNAMEG) || (flags & (RFENVG | RFCENVG)) == (RFENVG | RFCENVG)) { P->R[0] = -1; cherrstr("bad arg in syscall"); return; } if((flags & RFPROC) == 0) { if(flags & RFFDG) { old = P->fd; P->fd = copyfd(P->fd); fddecref(old); } if(flags & RFCFDG) { old = P->fd; P->fd = newfd(); fddecref(old); } P->R[0] = noteerr(rfork(flags), 0); return; } incref(&nproc); p = emallocz(sizeof(Process)); memcpy(p, P, sizeof(Process)); for(i = 0; i < SEGNUM; i++) { s = p->S[i]; if(s == nil) continue; if((flags & RFMEM) == 0 && i != SEGTEXT || i == SEGSTACK) { t = emallocz(sizeof(Segment)); incref(t); t->size = s->size; t->start = s->start; t->dref = emalloc(sizeof(Ref) + s->size); memset(t->dref, 0, sizeof(Ref)); incref(t->dref); t->data = t->dref + 1; memcpy(t->data, s->data, s->size); p->S[i] = t; } else { incref(s->dref); incref(s); } } if(flags & RFFDG) p->fd = copyfd(P->fd); else if(flags & RFCFDG) p->fd = newfd(); else incref(P->fd); incref(P->path); rc = rfork(RFMEM | flags); if(rc < 0) /* this should NEVER happen */ sysfatal("rfork failed wtf: %r"); if(rc == 0) { P = p; atexit(cleanup); P->pid = getpid(); inittos(); addproc(P); } P->R[0] = rc; }
chanfd::chanfd (u_int32_t cn, ref<aclnt> cc, const vec<int> f, pid_t p) : chanbase (cn, cc, p), destroyed (New refcounted<bool> (false)) { for (size_t i = 0; i < f.size (); i++) newfd (f[i]); }
int lfdfd(int fd) { return newfd(lfdchan(fd)); }