| plan 9 kernel history: overview | file list | diff list |
1990/1110/port/devsrv.c (diff list | history)
| 1990/1002/sys/src/9/port/devsrv.c:7,27 – 1990/1110/sys/src/9/port/devsrv.c:7,28 (short | long | prev | next) | ||
| 1990/0227 | #include "devtab.h" | |
| 1990/1002 | #include "fcall.h" | |
| 1990/0227 | ||
| 1990/1002 |
| |
| 1990/1110 | void *calloc(unsigned, unsigned); | |
| 1990/1002 | void free(void *); /* This structure holds the contents of a directory entry. Entries are kept * in a linked list. */ | |
| 1990/1110 | typedef struct Entry Entry; struct Entry { | |
| 1990/0227 | Lock; | |
| 1990/1002 |
| |
| 1990/1110 | Entry *next; /* next entry */ Entry **back; /* entry pointer */ Entry *parent; /* parent directory */ | |
| 1990/1002 | Dir dir; /* dir structure */ | |
| 1990/1110 | union{ Chan *chan; /* if not a subdirectory */ Entry *entries; /* directory entries */ | |
| 1990/1002 | }; }; | |
| 1990/0227 | ||
| 1990/1002/sys/src/9/port/devsrv.c:35,45 – 1990/1110/sys/src/9/port/devsrv.c:36,48 | ||
| 1990/0227 | { } | |
| 1990/1002 |
| |
| 1990/1110 | Entry * srvalloc(int mode){ Entry *e; | |
| 1990/1002 | static Lock qidlock; static nextqid; | |
| 1990/1110 | e = calloc(1, sizeof(Entry)); | |
| 1990/1002 | e->dir.atime = e->dir.mtime = seconds(); lock(&qidlock); /* for qid allocation */ e->dir.qid = mode | nextqid++; | |
| 1990/1002/sys/src/9/port/devsrv.c:52,62 – 1990/1110/sys/src/9/port/devsrv.c:55,65 | ||
| 1990/0227 | { | |
| 1990/1002 | Chan *c; static Lock rootlock; | |
| 1990/1110 | static Entry *root; | |
| 1990/1002 | lock(&rootlock); | |
| 1990/1110 | if(root==0){ root = srvalloc(CHDIR); | |
| 1990/1002 | root->dir.mode = CHDIR | 0777; } unlock(&rootlock); | |
| 1990/1002/sys/src/9/port/devsrv.c:77,99 – 1990/1110/sys/src/9/port/devsrv.c:80,102 | ||
| 1990/0227 | int srvwalk(Chan *c, char *name) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *dir, *e; | |
| 1990/1002 | isdir(c); | |
| 1990/1110 | if(strcmp(name, ".") == 0) | |
| 1990/1002 | return 1; | |
| 1990/1110 | if((dir=c->aux) == 0) | |
| 1990/1002 | panic("bad aux pointer in srvwalk"); | |
| 1990/1110 | if(strcmp(name, "..") == 0) | |
| 1990/1002 | e = dir->parent; | |
| 1990/1110 | else{ | |
| 1990/1002 | lock(dir); | |
| 1990/1110 | for(e=dir->entries; e; e=e->next) | |
| 1990/1002 | if (strcmp(name, e->dir.name) == 0) break; unlock(dir); } | |
| 1990/1110 | if(e==0){ | |
| 1990/1002 | u->error.code = Enonexist; u->error.type = 0; u->error.dev = 0; | |
| 1990/1002/sys/src/9/port/devsrv.c:107,114 – 1990/1110/sys/src/9/port/devsrv.c:110,118 | ||
| 1990/0227 | void srvstat(Chan *c, char *db) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *e; | |
| 1990/1002 | ||
| 1990/1110 | e = c->aux; | |
| 1990/1002 | convD2M(&e->dir, db); | |
| 1990/0227 | } | |
| 1990/1002/sys/src/9/port/devsrv.c:115,125 – 1990/1110/sys/src/9/port/devsrv.c:119,129 | ||
| 1990/0227 | Chan * srvopen(Chan *c, int omode) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *e; | |
| 1990/0227 | Chan *f; | |
| 1990/1002 |
| |
| 1990/1110 | if(c->qid & CHDIR){ if(omode != OREAD) | |
| 1990/0227 | error(0, Eisdir); c->mode = omode; c->flag |= COPEN; | |
| 1990/1002/sys/src/9/port/devsrv.c:126,138 – 1990/1110/sys/src/9/port/devsrv.c:130,142 | ||
| 1990/0227 | c->offset = 0; return c; } | |
| 1990/1002 |
| |
| 1990/1110 | if((e=c->aux) == 0) error(0, Egreg); if((f=e->chan) == 0) | |
| 1990/0227 | error(0, Eshutdown); | |
| 1990/1002 |
| |
| 1990/1110 | if(omode & OTRUNC) | |
| 1990/0227 | error(0, Eperm); | |
| 1990/1002 |
| |
| 1990/1110 | if(omode!=f->mode && f->mode!=ORDWR) | |
| 1990/0227 | error(0, Eperm); close(c); incref(f); | |
| 1990/1002/sys/src/9/port/devsrv.c:142,166 – 1990/1110/sys/src/9/port/devsrv.c:146,172 | ||
| 1990/0227 | void srvcreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *parent, *e; | |
| 1990/0227 | ||
| 1990/1110 | parent = c->aux; | |
| 1990/1002 | isdir(c); lock(parent); | |
| 1990/1110 | if (waserror()){ | |
| 1990/1002 | unlock(parent); | |
| 1990/0227 | nexterror(); } | |
| 1990/1002 |
| |
| 1990/1110 | for(e=parent->entries; e; e=e->next) if(strcmp(name, e->dir.name) == 0) | |
| 1990/0227 | error(0, Einuse); | |
| 1990/1002 |
| |
| 1990/1110 | e = srvalloc(perm & CHDIR); | |
| 1990/1002 | e->parent = parent; strcpy(e->dir.name, name); e->dir.mode = perm & parent->dir.mode; e->dir.gid = parent->dir.gid; | |
| 1990/1110 | if(e->next = parent->entries) /* assign = */ | |
| 1990/1002 | e->next->back = &e->next; | |
| 1990/1110 | e->back = &parent->entries; *e->back = e; | |
| 1990/1002 | parent->dir.mtime = e->dir.mtime; unlock(parent); poperror(); | |
| 1990/1002/sys/src/9/port/devsrv.c:173,197 – 1990/1110/sys/src/9/port/devsrv.c:179,203 | ||
| 1990/0227 | void srvremove(Chan *c) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *e; | |
| 1990/0227 | ||
| 1990/1002 |
| |
| 1990/1110 | e = c->aux; if(e->parent == 0) | |
| 1990/0227 | error(0, Eperm); | |
| 1990/1002 | lock(e->parent); | |
| 1990/1110 | if(waserror()){ | |
| 1990/1002 | unlock(e->parent); | |
| 1990/0227 | nexterror(); } | |
| 1990/1002 |
| |
| 1990/1110 | if(e->dir.mode & CHDIR){ | |
| 1990/1002 | if (e->entries != 0) error(0, Eperm); | |
| 1990/1110 | }else{ if(e->chan == 0) | |
| 1990/1002 | error(0, Eshutdown); close(e->chan); } | |
| 1990/1110 | if(*e->back = e->next) /* assign = */ | |
| 1990/1002 | e->next->back = e->back; unlock(e->parent); | |
| 1990/0227 | poperror(); | |
| 1990/1002/sys/src/9/port/devsrv.c:213,223 – 1990/1110/sys/src/9/port/devsrv.c:219,231 | ||
| 1990/1002 | * to a list of entries in this directory. Count is the size to be * read. */ | |
| 1990/1110 | int srvdirentry(Entry *e, char *a, long count){ | |
| 1990/1002 | Dir dir; | |
| 1990/1110 | int n; | |
| 1990/1002 |
| |
| 1990/1110 | n = 0; while(n!=count && e!=0){ | |
| 1990/1002 | n += convD2M(&e->dir, a + n); e = e->next; } | |
| 1990/1002/sys/src/9/port/devsrv.c:227,249 – 1990/1110/sys/src/9/port/devsrv.c:235,258 | ||
| 1990/0227 | long srvread(Chan *c, void *va, long n) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *dir, *e; int offset; | |
| 1990/0227 | ||
| 1990/1110 | dir = c->aux; offset = c->offset; | |
| 1990/1002 | isdir(c); | |
| 1990/1110 | if(n <= 0) | |
| 1990/1002 | return 0; | |
| 1990/1110 | if(offset%DIRLEN || n%DIRLEN) error(0, Ebaddirread); | |
| 1990/1002 | lock(dir); | |
| 1990/1110 | for(e=dir->entries; e; e=e->next) if(offset <= 0){ n = srvdirentry(e, va, n); | |
| 1990/1002 | unlock(dir); c->offset += n; return n; | |
| 1990/1110 | }else | |
| 1990/1002 | offset -= DIRLEN; unlock(dir); return 0; | |
| 1990/1002/sys/src/9/port/devsrv.c:252,271 – 1990/1110/sys/src/9/port/devsrv.c:261,281 | ||
| 1990/0227 | long srvwrite(Chan *c, void *va, long n) { | |
| 1990/1002 |
| |
| 1990/1110 | Entry *e; | |
| 1990/0227 | int i, fd; char buf[32]; | |
| 1990/1002 |
| |
| 1990/1110 | e = c->aux; if(e->dir.mode & CHDIR) | |
| 1990/1002 | panic("write to directory"); lock(e); | |
| 1990/1110 | if(waserror()){ | |
| 1990/1002 | unlock(e); nexterror(); } | |
| 1990/1110 | if(e->chan) | |
| 1990/0227 | error(0, Egreg); | |
| 1990/1002 |
| |
| 1990/1110 | if(n >= sizeof buf) | |
| 1990/0227 | error(0, Egreg); memcpy(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; | |