#include #include #include #include #include #include #include #define NODEFINE #include #include #include #include "fd.h" File fdtbl[Nfd]; File* pm_lockfile(int fd, int closedokay) { File *f; if(fd < 0 || fd >= Nfd){ pm_werrstr("bad file descriptor"); return nil; } f = &fdtbl[fd]; pm_qlock(&f->lk); if(!closedokay && f->type == Tfree){ pm_qunlock(&f->lk); pm_werrstr("bad file descriptor"); return nil; } return f; } File* pm_allocfile(int fd) { File *f; if(fd < 0 || fd >= Nfd){ pm_werrstr("bad file descriptor"); return nil; } f = &fdtbl[fd]; pm_qlock(&f->lk); if(f->type != Tfree){ pm_qunlock(&f->lk); pm_werrstr("file descriptor already in use"); return nil; } return f; } int pm_closefile(File *f) { int ret; switch(f->type){ default: pm_werrstr("cannot happen in pm_close"); ret = -1; break; case Tfree: pm_werrstr("file descriptor not open"); ret = -1; break; case Tpipe: case Tfile: close(f->ufd); f->ufd = -1; ret = 0; break; case Tdir: close(f->ufd); f->ufd = -1; pm_free(f->dents); f->dents = 0; f->mdents = 0; ret = 0; break; } f->type = Tfree; pm_free(f->path); f->path = nil; pm_qunlock(&f->lk); return ret; } static int isopen(int ufd) { struct stat s; if(fstat(ufd, &s) < 0 && errno == EBADF) return 0; return 1; } void pm_fdinit(void) { int i; for(i=0; ist_dev; d.qid.path = s->st_ino; d.qid.vers = s->st_mtime; d.mode = (s->st_mode&0777); d.length = s->st_size; if(S_ISDIR(s->st_mode)){ d.length = 0; d.mode |= PM_DMDIR; } if(s->st_flags&(UF_APPEND|SF_APPEND)) d.mode |= PM_DMAPPEND; d.qid.type = d.mode>>24; d.atime = s->st_atimespec.tv_sec; d.mtime = s->st_mtimespec.tv_sec; if((p = pm_strrchr(name, '/')) != nil) d.name = p+1; else d.name = name; if((pw = getpwuid(s->st_uid)) != nil) d.uid = pw->pw_name; else d.uid = ""; if((gp = getgrgid(s->st_gid)) != nil) d.gid = gp->gr_name; else d.gid = ""; d.muid = ""; if((n=convD2M(&d, buf, nbuf)) <= BIT16SZ) return 0; return n; } char* pm_openpath(char *p) { return pm_strdup(p); } int pm_pmfd2ufd(int fd) { File *f; int ufd; if((f = pm_lockfile(fd, 0)) == nil) return -1; ufd = f->ufd; pm_qunlock(&f->lk); return ufd; }