History

20070714-1052

Charles.Forsyth committed 19 years ago

Commit 61ffbe21 parent 047870e8 files · +302 −1Browse files

Unified · Split

8 files
  1. CHANGES +5 −0
  2. appl/cmd/trfs.b +213 −0
  3. dis/trfs.dis +0 −0
  4. emu/port/inferno.c +29 −0
  5. include/version.h +1 −1
  6. man/4/trfs +22 −0
  7. module/sys.m +1 −0
  8. os/port/inferno.c +32 −1
CHANGES+5−0
@@ -1,3 +1,8 @@
1+20070714
2+ add Sys->readn
3+ copy two repairs from emu/port/inferno.c to os/port/inferno.c
4+20070619
5+ remembered to include /appl/cmd/trfs.b /dis/trfs.dis
16 20070614
27 /appl/lib/venti.b bug fixes, a few more errstrs, remove prints to stderr
38 add initial module/vac.m appl/lib/vac.b from mjl (gsoc project ventivac)
appl/cmd/trfs.b+213−0
@@ -0,0 +1,213 @@
1+implement Trfs;
2+
3+include "sys.m";
4+ sys: Sys;
5+
6+include "draw.m";
7+
8+include "styx.m";
9+ styx: Styx;
10+ Rmsg, Tmsg: import styx;
11+
12+Trfs: module
13+{
14+ init: fn(nil: ref Draw->Context, nil: list of string);
15+};
16+
17+Fid: adt {
18+ fid: int;
19+ isdir: int;
20+ aux: int;
21+};
22+
23+Table: adt[T] {
24+ items: array of list of (int, T);
25+ nilval: T;
26+
27+ new: fn(nslots: int, nilval: T): ref Table[T];
28+ add: fn(t: self ref Table, id: int, x: T): int;
29+ del: fn(t: self ref Table, id: int): T;
30+ find: fn(t: self ref Table, id: int): T;
31+};
32+
33+NBspace: con 16r00A0; # Unicode `no-break' space (looks like a faint box in some fonts)
34+NBspacelen: con 2; # length of it in utf-8
35+
36+msize: int;
37+lock: chan of int;
38+fids: ref Table[ref Fid];
39+tfids: ref Table[ref Fid];
40+
41+init(nil: ref Draw->Context, args: list of string)
42+{
43+ sys = load Sys Sys->PATH;
44+ styx = load Styx Styx->PATH;
45+
46+ if(len args != 3){
47+ sys->fprint(sys->fildes(2), "usage: trfs dir mountpoint\n");
48+ raise "fail:usage";
49+ }
50+ dir := hd tl args;
51+ mntpt := hd tl tl args;
52+ p := array[2] of ref Sys->FD;
53+ q := array[2] of ref Sys->FD;
54+ fids = Table[ref Fid].new(11, nil);
55+ tfids = Table[ref Fid].new(11, nil);
56+ lock = chan[1] of int;
57+
58+ styx->init();
59+ sys->pipe(p);
60+ sys->pipe(q);
61+ if(sys->export(q[0], dir, Sys->EXPASYNC) < 0)
62+ fatal("can't export " + dir);
63+ spawn trfsin(p[1], q[1]);
64+ spawn trfsout(p[1], q[1]);
65+ if(sys->mount(p[0], nil, mntpt, Sys->MREPL|Sys->MCREATE, nil) < 0)
66+ fatal("can't mount on " + mntpt);
67+}
68+
69+trfsin(cfd, sfd: ref Sys->FD)
70+{
71+ while((t:=Tmsg.read(cfd, msize)) != nil){
72+ pick m := t {
73+ Clunk or
74+ Remove =>
75+ fids.del(m.fid);
76+ Create =>
77+ fid := ref Fid(m.fid, 0, 0);
78+ fids.add(m.fid, fid);
79+ addtfid(m.tag, fid);
80+ m.name = tr(m.name, NBspace, ' ');
81+ Open =>
82+ fid := ref Fid(m.fid, 0, 0);
83+ fids.add(m.fid, fid);
84+ addtfid(m.tag, fid);
85+ Read =>
86+ fid := fids.find(m.fid);
87+ addtfid(m.tag, fid);
88+ if(fid.isdir){
89+ m.count /= NBspacelen; # translated strings might grow by this much
90+ if(m.offset == big 0)
91+ fid.aux = 0;
92+ m.offset -= big fid.aux;
93+ }
94+ Walk =>
95+ for(i:=0; i<len m.names; i++)
96+ m.names[i] = tr(m.names[i], NBspace, ' ');
97+ Wstat =>
98+ m.stat.name = tr(m.stat.name, NBspace, ' ');
99+ }
100+ sys->write(sfd, t.pack(), t.packedsize());
101+ }
102+}
103+
104+trfsout(cfd, sfd: ref Sys->FD)
105+{
106+ b := array[Styx->MAXFDATA] of byte;
107+ while((r := Rmsg.read(sfd, msize)) != nil){
108+ pick m := r {
109+ Version =>
110+ msize = m.msize;
111+ if(msize > len b)
112+ b = array[msize] of byte; # a bit more than needed but doesn't matter
113+ Create or
114+ Open =>
115+ fid := deltfid(m.tag);
116+ fid.isdir = m.qid.qtype & Sys->QTDIR;
117+ Read =>
118+ fid := deltfid(m.tag);
119+ if(fid.isdir){
120+ bs := 0;
121+ for(n := 0; n < len m.data; ){
122+ (ds, d) := styx->unpackdir(m.data[n:]);
123+ if(ds <= 0)
124+ break;
125+ d.name = tr(d.name, ' ', NBspace);
126+ b[bs:] = styx->packdir(d);
127+ bs += styx->packdirsize(d);
128+ n += ds;
129+ }
130+ fid.aux += bs-n;
131+ m.data = b[0:bs];
132+ }
133+ Stat =>
134+ m.stat.name = tr(m.stat.name, ' ', NBspace);
135+ }
136+ sys->write(cfd, r.pack(), r.packedsize());
137+ }
138+}
139+
140+tr(name: string, c1, c2: int): string
141+{
142+ for(i:=0; i<len name; i++)
143+ if(name[i] == c1)
144+ name[i] = c2;
145+ return name;
146+}
147+
148+Table[T].new(nslots: int, nilval: T): ref Table[T]
149+{
150+ if(nslots == 0)
151+ nslots = 13;
152+ return ref Table[T](array[nslots] of list of (int, T), nilval);
153+}
154+
155+Table[T].add(t: self ref Table[T], id: int, x: T): int
156+{
157+ slot := id % len t.items;
158+ for(q := t.items[slot]; q != nil; q = tl q)
159+ if((hd q).t0 == id)
160+ return 0;
161+ t.items[slot] = (id, x) :: t.items[slot];
162+ return 1;
163+}
164+
165+Table[T].del(t: self ref Table[T], id: int): T
166+{
167+ p: list of (int, T);
168+ slot := id % len t.items;
169+ for(q := t.items[slot]; q != nil; q = tl q){
170+ if((hd q).t0 == id){
171+ t.items[slot] = join(p, tl q);
172+ return (hd q).t1;
173+ }
174+ p = hd q :: p;
175+ }
176+ return t.nilval;
177+}
178+
179+Table[T].find(t: self ref Table[T], id: int): T
180+{
181+ for(p := t.items[id % len t.items]; p != nil; p = tl p)
182+ if((hd p).t0 == id)
183+ return (hd p).t1;
184+ return t.nilval;
185+}
186+
187+join[T](x, y: list of (int, T)): list of (int, T)
188+{
189+ for(; x != nil; x = tl x)
190+ y = hd x :: y;
191+ return y;
192+}
193+
194+addtfid(t: int, fid: ref Fid)
195+{
196+ lock <-= 1;
197+ tfids.add(t, fid);
198+ <- lock;
199+}
200+
201+deltfid(t: int): ref Fid
202+{
203+ lock <-= 1;
204+ r := tfids.del(t);
205+ <- lock;
206+ return r;
207+}
208+
209+fatal(s: string)
210+{
211+ sys->fprint(sys->fildes(2), "trfs: %s: %r\n", s);
212+ raise "fail:error";
213+}
dis/trfs.dis+0−0

Binary file not shown.

emu/port/inferno.c+29−0
@@ -270,6 +270,35 @@ Sys_read(void *fp) · 269 unmodified lines
270270 acquire();
271271 }
272272
273+void
274+Sys_readn(void *fp)
275+{
276+ int fd, m, n, t;
277+ F_Sys_readn *f;
278+
279+ f = fp;
280+ n = f->n;
281+ if(f->buf == (Array*)H || n < 0) {
282+ *f->ret = 0;
283+ return;
284+ }
285+ if(n > f->buf->len)
286+ n = f->buf->len;
287+ fd = fdchk(f->fd);
288+
289+ release();
290+ for(t = 0; t < n; t += m){
291+ m = kread(fd, (char*)f->buf->data+t, n-t);
292+ if(m <= 0){
293+ if(t == 0)
294+ t = m;
295+ break;
296+ }
297+ }
298+ *f->ret = t;
299+ acquire();
300+}
301+
273302 void
274303 Sys_pread(void *fp)
275304 {
include/version.h+1−1
@@ -1 +1 @@
1−#define VERSION "Fourth Edition (20070614)"
1+#define VERSION "Fourth Edition (20070714)"
man/4/trfs+22−0
@@ -0,0 +1,22 @@
1+.TH TRFS 4
2+.SH NAME
3+trfs \- translate spaces and other runes in names in a file system
4+.SH SYNOPSIS
5+.B trfs
6+.I olddir
7+.I mountdir
8+.SH DESCRIPTION
9+.I Trfs
10+makes the contents of directory
11+.I olddir
12+appear on the directory
13+.IR mountdir ,
14+but every space character in file and directory names viewed through
15+.I mountdir
16+is made visible as a special `no-break space' character (U+00A0).
17+Other Inferno applications will not mistake it for the end of a file name,
18+and it has some visible representation in most fonts.
19+.SH SOURCE
20+.B /appl/cmd/trfs.b
21+.SH BUGS
22+There can be error or ambiguity if the existing tree also uses no-break space in its names.
module/sys.m+1−0
@@ -145,6 +145,7 @@ Sys: module · 144 unmodified lines
145145 pread: fn(fd: ref FD, buf: array of byte, n: int, off: big): int;
146146 pwrite: fn(fd: ref FD, buf: array of byte, n: int, off: big): int;
147147 read: fn(fd: ref FD, buf: array of byte, n: int): int;
148+ readn: fn(fd: ref FD, buf: array of byte, n: int): int;
148149 remove: fn(s: string): int;
149150 seek: fn(fd: ref FD, off: big, start: int): big;
150151 sleep: fn(period: int): int;
os/port/inferno.c+32−1
@@ -62,7 +62,8 @@ freeFD(Heap *h, int swept) · 61 unmodified lines
6262 handle = H2D(FD*, h);
6363
6464 release();
65− kfgrpclose(handle->grp, handle->fd.fd);
65+ if(handle->fd.fd >= 0)
66+ kfgrpclose(handle->grp, handle->fd.fd);
6667 closefgrp(handle->grp);
6768 acquire();
6869 }
@@ -272,6 +273,35 @@ Sys_read(void *fp) · 203 unmodified lines
272273 acquire();
273274 }
274275
276+void
277+Sys_readn(void *fp)
278+{
279+ int fd, m, n, t;
280+ F_Sys_readn *f;
281+
282+ f = fp;
283+ n = f->n;
284+ if(f->buf == (Array*)H || n < 0) {
285+ *f->ret = 0;
286+ return;
287+ }
288+ if(n > f->buf->len)
289+ n = f->buf->len;
290+ fd = fdchk(f->fd);
291+
292+ release();
293+ for(t = 0; t < n; t += m){
294+ m = kread(fd, (char*)f->buf->data+t, n-t);
295+ if(m <= 0){
296+ if(t == 0)
297+ t = m;
298+ break;
299+ }
300+ }
301+ *f->ret = t;
302+ acquire();
303+}
304+
275305 void
276306 Sys_pread(void *fp)
277307 {
@@ -380,6 +410,7 @@ packdir(Sys_Dir *sd) · 102 unmodified lines
380410 for(i=0; i<4; i++){
381411 n = strlen(nm[i])+1;
382412 memmove(p, nm[i], n);
413+ nm[i] = p;
383414 p += n;
384415 }
385416 d->name = nm[0];