📄 sysfile.c
字号:
lock(&c->ref.lk); c->devoffset += nn; c->offset += nnn; unlock(&c->ref.lk); poperror(); cclose(c); return nnn;}longsys_read(ulong *arg){ return doread(arg, nil);}longsyspread(ulong *arg){ vlong v; // Plan 9 VX replaced dodgy varargs code v = *(vlong*)&arg[3]; if(v == ~0ULL) return doread(arg, nil); return doread(arg, &v);}static longdowrite(ulong *arg, vlong *offp){ Chan *c; long m, n; vlong off; uchar *p; p = uvalidaddr(arg[1], arg[2], 0); n = 0; c = fdtochan(arg[0], OWRITE, 1, 1); if(waserror()) { if(offp == nil){ lock(&c->ref.lk); c->offset -= n; unlock(&c->ref.lk); } cclose(c); nexterror(); } if(c->qid.type & QTDIR) error(Eisdir); n = arg[2]; if(offp == nil){ /* use and maintain channel's offset */ lock(&c->ref.lk); off = c->offset; c->offset += n; unlock(&c->ref.lk); }else off = *offp; if(off < 0) error(Enegoff); m = devtab[c->type]->write(c, p, n, off); if(offp == nil && m < n){ lock(&c->ref.lk); c->offset -= n - m; unlock(&c->ref.lk); } poperror(); cclose(c); return m;}longsys_write(ulong *arg){ return dowrite(arg, nil);}longsyspwrite(ulong *arg){ vlong v; // Plan 9 VX replaced dodgy varargs code v = *(vlong*)&arg[3]; if(v == ~0ULL) return dowrite(arg, nil); return dowrite(arg, &v);}static voidsseek(ulong *arg){ Chan *c; uchar buf[sizeof(Dir)+100]; Dir dir; int n; vlong off; union { vlong v; ulong u[2]; } o; c = fdtochan(arg[1], -1, 1, 1); if(waserror()){ cclose(c); nexterror(); } if(devtab[c->type]->dc == '|') error(Eisstream); off = 0; o.u[0] = arg[2]; o.u[1] = arg[3]; switch(arg[4]){ case 0: off = o.v; if((c->qid.type & QTDIR) && off != 0) error(Eisdir); if(off < 0) error(Enegoff); c->offset = off; break; case 1: if(c->qid.type & QTDIR) error(Eisdir); lock(&c->ref.lk); /* lock for read/write update */ off = o.v + c->offset; if(off < 0){ unlock(&c->ref.lk); error(Enegoff); } c->offset = off; unlock(&c->ref.lk); break; case 2: if(c->qid.type & QTDIR) error(Eisdir); n = devtab[c->type]->stat(c, buf, sizeof buf); if(convM2D(buf, n, &dir, nil) == 0) error("internal error: stat error in seek"); off = dir.length + o.v; if(off < 0) error(Enegoff); c->offset = off; break; default: error(Ebadarg); } *(vlong*)arg[0] = off; /* caller translated arg[0] already */ c->uri = 0; c->dri = 0; cclose(c); poperror();}longsysseek(ulong *arg){ arg[0] = (ulong)uvalidaddr(arg[0], BY2V, 1); sseek(arg); return 0;}longsysoseek(ulong *arg){ union { vlong v; ulong u[2]; } o; ulong a[5]; o.v = (long)arg[1]; a[0] = (ulong)&o.v; a[1] = arg[0]; a[2] = o.u[0]; a[3] = o.u[1]; a[4] = arg[2]; sseek(a); return o.v;}voidvalidstat(uchar *s, int n){ int m; char buf[64]; if(statcheck(s, n) < 0) error(Ebadstat); /* verify that name entry is acceptable */ s += STATFIXLEN - 4*BIT16SZ; /* location of first string */ /* * s now points at count for first string. * if it's too long, let the server decide; this is * only for his protection anyway. otherwise * we'd have to allocate and waserror. */ m = GBIT16(s); s += BIT16SZ; if(m+1 > sizeof buf) return; memmove(buf, s, m); buf[m] = '\0'; /* name could be '/' */ if(strcmp(buf, "/") != 0) validname(buf, 0);}static char*pathlast(Path *p){ char *s; if(p == nil) return nil; if(p->len == 0) return nil; s = strrchr(p->s, '/'); if(s) return s+1; return p->s;}longsysfstat(ulong *arg){ Chan *c; uint l; uchar *p; l = arg[2]; p = uvalidaddr(arg[1], l, 1); c = fdtochan(arg[0], -1, 0, 1); if(waserror()) { cclose(c); nexterror(); } l = devtab[c->type]->stat(c, p, l); poperror(); cclose(c); return l;}longsysstat(ulong *arg){ char *name; Chan *c; uint l; uchar *p; l = arg[2]; p = uvalidaddr(arg[1], l, 1); name = uvalidaddr(arg[0], 1, 0); c = namec(name, Aaccess, 0, 0); if(waserror()){ cclose(c); nexterror(); } l = devtab[c->type]->stat(c, p, l); name = pathlast(c->path); if(name) l = dirsetname(name, strlen(name), p, l, arg[2]); poperror(); cclose(c); return l;}longsyschdir(ulong *arg){ Chan *c; char *name; name = uvalidaddr(arg[0], 1, 0); c = namec(name, Atodir, 0, 0); cclose(up->dot); up->dot = c; return 0;}longbindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec){ int ret; Chan *c0, *c1, *ac, *bc; struct{ Chan *chan; Chan *authchan; char *spec; int flags; }bogus; if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER)) error(Ebadarg); bogus.flags = flag & MCACHE; if(ismount){ if(up->pgrp->noattach) error(Enoattach); ac = nil; bc = fdtochan(fd, ORDWR, 0, 1); if(waserror()) { if(ac) cclose(ac); cclose(bc); nexterror(); } if(afd >= 0) ac = fdtochan(afd, ORDWR, 0, 1); bogus.chan = bc; bogus.authchan = ac; bogus.spec = spec; if(waserror()) error(Ebadspec); spec = validnamedup(spec, 1); poperror(); if(waserror()){ free(spec); nexterror(); } ret = devno('M', 0); c0 = devtab[ret]->attach((char*)&bogus); poperror(); /* spec */ free(spec); poperror(); /* ac bc */ if(ac) cclose(ac); cclose(bc); }else{ bogus.spec = 0; c0 = namec(arg0, Abind, 0, 0); } if(waserror()){ cclose(c0); nexterror(); } c1 = namec(arg1, Amount, 0, 0); if(waserror()){ cclose(c1); nexterror(); } ret = cmount(&c0, c1, flag, bogus.spec); poperror(); cclose(c1); poperror(); cclose(c0); if(ismount) fdclose(fd, 0); return ret;}longsysbind(ulong *arg){ return bindmount(0, -1, -1, uvalidaddr(arg[0], 1, 0), uvalidaddr(arg[1], 1, 0), arg[2], nil);}longsysmount(ulong *arg){ return bindmount(1, arg[0], arg[1], nil, uvalidaddr(arg[2], 1, 0), arg[3], uvalidaddr(arg[4], 1, 0));}longsys_mount(ulong *arg){ return bindmount(1, arg[0], -1, nil, uvalidaddr(arg[1], 1, 0), arg[2], uvalidaddr(arg[3], 1, 0));}longsysunmount(ulong *arg){ Chan *cmount, *cmounted; char *mount, *mounted; cmounted = 0; mount = uvalidaddr(arg[1], 1, 0); cmount = namec(mount, Amount, 0, 0); if(arg[0]) { if(waserror()) { cclose(cmount); nexterror(); } mounted = uvalidaddr(arg[0], 1, 0); /* * This has to be namec(..., Aopen, ...) because * if arg[0] is something like /srv/cs or /fd/0, * opening it is the only way to get at the real * Chan underneath. */ cmounted = namec(mounted, Aopen, OREAD, 0); poperror(); } if(waserror()) { cclose(cmount); if(cmounted) cclose(cmounted); nexterror(); } cunmount(cmount, cmounted); cclose(cmount); if(cmounted) cclose(cmounted); poperror(); return 0;}longsyscreate(ulong *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;}longsysremove(ulong *arg){ Chan *c; char *name; name = uvalidaddr(arg[0], 1, 0); c = namec(name, Aremove, 0, 0); /* * Removing mount points is disallowed to avoid surprises * (which should be removed: the mount point or the mounted Chan?). */ if(c->ismtpt){ cclose(c); error(Eismtpt); } if(waserror()){ c->type = 0; /* see below */ cclose(c); nexterror(); } devtab[c->type]->remove(c); /* * Remove clunks the fid, but we need to recover the Chan * so fake it up. rootclose() is known to be a nop. */ c->type = 0; poperror(); cclose(c); return 0;}static longwstat(Chan *c, uchar *d, int nd){ long l; int namelen; if(waserror()){ cclose(c); nexterror(); } if(c->ismtpt){ /* * Renaming mount points is disallowed to avoid surprises * (which should be renamed? the mount point or the mounted Chan?). */ dirname(d, &namelen); if(namelen) nameerror(chanpath(c), Eismtpt); } l = devtab[c->type]->wstat(c, d, nd); poperror(); cclose(c); return l;}longsyswstat(ulong *arg){ Chan *c; uint l; char *name; uchar *p; l = arg[2]; p = uvalidaddr(arg[1], l, 0); validstat(p, l); name = uvalidaddr(arg[0], 1, 0); c = namec(name, Aaccess, 0, 0); return wstat(c, p, l);}longsysfwstat(ulong *arg){ Chan *c; uint l; uchar *p; l = arg[2]; p = uvalidaddr(arg[1], l, 0); validstat(p, l); c = fdtochan(arg[0], -1, 1, 1); return wstat(c, p, l);}static voidpackoldstat(uchar *buf, Dir *d){ uchar *p; ulong q; /* lay down old stat buffer - grotty code but it's temporary */ p = buf; strncpy((char*)p, d->name, 28); p += 28; strncpy((char*)p, d->uid, 28); p += 28; strncpy((char*)p, d->gid, 28); p += 28; q = d->qid.path & ~DMDIR; /* make sure doesn't accidentally look like directory */ if(d->qid.type & QTDIR) /* this is the real test of a new directory */ q |= DMDIR; PBIT32(p, q); p += BIT32SZ; PBIT32(p, d->qid.vers); p += BIT32SZ; PBIT32(p, d->mode); p += BIT32SZ; PBIT32(p, d->atime); p += BIT32SZ; PBIT32(p, d->mtime); p += BIT32SZ; PBIT64(p, d->length); p += BIT64SZ; PBIT16(p, d->type); p += BIT16SZ; PBIT16(p, d->dev);}longsys_stat(ulong *arg){ Chan *c; uint l; uchar buf[128]; /* old DIRLEN plus a little should be plenty */ char strs[128], *name, *elem; Dir d; char old[] = "old stat system call - recompile"; uchar *p; p = uvalidaddr(arg[1], 116, 1); name = uvalidaddr(arg[0], 1, 0); c = namec(name, Aaccess, 0, 0); if(waserror()){ cclose(c); nexterror(); } l = devtab[c->type]->stat(c, buf, sizeof buf); /* buf contains a new stat buf; convert to old. yuck. */ if(l <= BIT16SZ) /* buffer too small; time to face reality */ error(old); elem = pathlast(c->path); if(elem) l = dirsetname(elem, strlen(elem), buf, l, sizeof buf); l = convM2D(buf, l, &d, strs); if(l == 0) error(old); packoldstat(p, &d); poperror(); cclose(c); return 0;}longsys_fstat(ulong *arg){ Chan *c; char *name; uint l; uchar buf[128]; /* old DIRLEN plus a little should be plenty */ char strs[128]; Dir d; char old[] = "old fstat system call - recompile"; uchar *p; p = uvalidaddr(arg[1], 116, 1); c = fdtochan(arg[0], -1, 0, 1); if(waserror()){ cclose(c); nexterror(); } l = devtab[c->type]->stat(c, buf, sizeof buf); /* buf contains a new stat buf; convert to old. yuck. */ if(l <= BIT16SZ) /* buffer too small; time to face reality */ error(old); name = pathlast(c->path); if(name) l = dirsetname(name, strlen(name), buf, l, sizeof buf); l = convM2D(buf, l, &d, strs); if(l == 0) error(old); packoldstat(p, &d); poperror(); cclose(c); return 0;}longsys_wstat(ulong *u){ error("old wstat system call - recompile"); return -1;}longsys_fwstat(ulong *u){ error("old fwstat system call - recompile"); return -1;}// Plan 9 VX additionslongkbind(char *new, char *old, int flag){ return bindmount(0, -1, -1, new, old, flag, nil);}longsyspassfd(ulong *u){ error("passfd unimplemented"); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -