int newfd(struct chan *c) { int i; struct fgrp *f = current->fgrp; spin_lock(&f->lock); if (f->closed) { spin_unlock(&f->lock); return -1; } /* VFS hack */ /* We'd like to ask it to start at f->minfd, but that would require us to * know if we closed anything. Since we share the FD numbers with the VFS, * there is no way to know that. */ #if 1 // VFS hack i = get_fd(¤t->open_files, 0); #else // 9ns style /* TODO: use a unique integer allocator */ for (i = f->minfd; i < f->nfd; i++) if (f->fd[i] == 0) break; #endif if (growfd(f, i) < 0) { spin_unlock(&f->lock); return -1; } assert(f->fd[i] == 0); f->minfd = i + 1; if (i > f->maxfd) f->maxfd = i; f->fd[i] = c; spin_unlock(&f->lock); return i; }
/* * this assumes that the fgrp is locked */ static int findfreefd(Fgrp *f, int start) { int fd; for(fd=start; fd<f->nfd; fd++) if(f->fd[fd] == 0) break; if(fd >= f->nfd && growfd(f, fd) < 0) return -1; return fd; }
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; }
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 newfd(Chan *c) { int i; Fgrp *f = up->env->fgrp; lock(f); for(i=f->minfd; i<f->nfd; i++) if(f->fd[i] == 0) break; if(i >= f->nfd && growfd(f, i) < 0){ unlock(f); exhausted("file descriptors"); return -1; } f->minfd = i + 1; if(i > f->maxfd) f->maxfd = i; f->fd[i] = c; unlock(f); return i; }