Introduction
Introduction Statistics Contact Development Disclaimer Help
io.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
io.c (4703B)
---
1 #include "sam.h"
2
3 #define NSYSFILE 3
4 #define NOFILE 128
5
6 void
7 checkqid(File *f)
8 {
9 int i, w;
10 File *g;
11
12 w = whichmenu(f);
13 for(i=1; i<file.nused; i++){
14 g = file.filepptr[i];
15 if(w == i)
16 continue;
17 if(f->dev==g->dev && f->qidpath==g->qidpath)
18 warn_SS(Wdupfile, &f->name, &g->name);
19 }
20 }
21
22 void
23 writef(File *f)
24 {
25 Posn n;
26 char *name;
27 int i, samename, newfile;
28 ulong dev;
29 uvlong qid;
30 long mtime, appendonly, length;
31
32 newfile = 0;
33 samename = Strcmp(&genstr, &f->name) == 0;
34 name = Strtoc(&f->name);
35 i = statfile(name, &dev, &qid, &mtime, 0, 0);
36 if(i == -1)
37 newfile++;
38 else if(samename &&
39 (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
40 f->dev = dev;
41 f->qidpath = qid;
42 f->mtime = mtime;
43 warn_S(Wdate, &genstr);
44 return;
45 }
46 if(genc)
47 free(genc);
48 genc = Strtoc(&genstr);
49 if((io=create(genc, 1, 0666L)) < 0)
50 error_r(Ecreate, genc);
51 dprint("%s: ", genc);
52 if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly &…
53 error(Eappend);
54 n = writeio(f);
55 if(f->name.s[0]==0 || samename){
56 if(addr.r.p1==0 && addr.r.p2==f->b.nc)
57 f->cleanseq = f->seq;
58 state(f, f->cleanseq==f->seq? Clean : Dirty);
59 }
60 if(newfile)
61 dprint("(new file) ");
62 if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
63 warn(Wnotnewline);
64 closeio(n);
65 if(f->name.s[0]==0 || samename){
66 if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
67 f->dev = dev;
68 f->qidpath = qid;
69 f->mtime = mtime;
70 checkqid(f);
71 }
72 }
73 }
74
75 Posn
76 readio(File *f, int *nulls, int setdate, int toterm)
77 {
78 int n, b, w;
79 Rune *r;
80 Posn nt;
81 Posn p = addr.r.p2;
82 ulong dev;
83 uvlong qid;
84 long mtime;
85 char buf[BLOCKSIZE+1], *s;
86
87 *nulls = FALSE;
88 b = 0;
89 if(f->unread){
90 nt = bufload(&f->b, 0, io, nulls);
91 if(toterm)
92 raspload(f);
93 }else
94 for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r…
95 n += b;
96 b = 0;
97 r = genbuf;
98 s = buf;
99 while(n > 0){
100 if((*r = *(uchar*)s) < Runeself){
101 if(*r)
102 r++;
103 else
104 *nulls = TRUE;
105 --n;
106 s++;
107 continue;
108 }
109 if(fullrune(s, n)){
110 w = chartorune(r, s);
111 if(*r)
112 r++;
113 else
114 *nulls = TRUE;
115 n -= w;
116 s += w;
117 continue;
118 }
119 b = n;
120 memmove(buf, s, b);
121 break;
122 }
123 loginsert(f, p, genbuf, r-genbuf);
124 }
125 if(b)
126 *nulls = TRUE;
127 if(*nulls)
128 warn(Wnulls);
129 if(setdate){
130 if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
131 f->dev = dev;
132 f->qidpath = qid;
133 f->mtime = mtime;
134 checkqid(f);
135 }
136 }
137 return nt;
138 }
139
140 Posn
141 writeio(File *f)
142 {
143 int m, n;
144 Posn p = addr.r.p1;
145 char *c;
146
147 while(p < addr.r.p2){
148 if(addr.r.p2-p>BLOCKSIZE)
149 n = BLOCKSIZE;
150 else
151 n = addr.r.p2-p;
152 bufread(&f->b, p, genbuf, n);
153 c = Strtoc(tmprstr(genbuf, n));
154 m = strlen(c);
155 if(Write(io, c, m) != m){
156 free(c);
157 if(p > 0)
158 p += n;
159 break;
160 }
161 free(c);
162 p += n;
163 }
164 return p-addr.r.p1;
165 }
166 void
167 closeio(Posn p)
168 {
169 close(io);
170 io = 0;
171 if(p >= 0)
172 dprint("#%lud\n", p);
173 }
174
175 int remotefd0 = 0;
176 int remotefd1 = 1;
177
178 void
179 bootterm(char *machine, char **argv)
180 {
181 int ph2t[2], pt2h[2];
182
183 if(machine){
184 dup(remotefd0, 0);
185 dup(remotefd1, 1);
186 close(remotefd0);
187 close(remotefd1);
188 argv[0] = "samterm";
189 execvp(samterm, argv);
190 fprint(2, "can't exec %s: %r\n", samterm);
191 _exits("damn");
192 }
193 if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
194 panic("pipe");
195 switch(fork()){
196 case 0:
197 dup(ph2t[0], 0);
198 dup(pt2h[1], 1);
199 close(ph2t[0]);
200 close(ph2t[1]);
201 close(pt2h[0]);
202 close(pt2h[1]);
203 argv[0] = "samterm";
204 execvp(samterm, argv);
205 fprint(2, "can't exec: ");
206 perror(samterm);
207 _exits("damn");
208 case -1:
209 panic("can't fork samterm");
210 }
211 dup(pt2h[0], 0);
212 dup(ph2t[1], 1);
213 close(ph2t[0]);
214 close(ph2t[1]);
215 close(pt2h[0]);
216 close(pt2h[1]);
217 }
218
219 void
220 connectto(char *machine, char **argv)
221 {
222 int p1[2], p2[2];
223 char **av;
224 int ac;
225
226 /* count args */
227 for(av = argv; *av; av++)
228 ;
229 av = malloc(sizeof(char*)*((av-argv) + 5));
230 if(av == nil){
231 dprint("out of memory\n");
232 exits("fork/exec");
233 }
234 ac = 0;
235 av[ac++] = RX;
236 av[ac++] = machine;
237 av[ac++] = rsamname;
238 av[ac++] = "-R";
239 while(*argv)
240 av[ac++] = *argv++;
241 av[ac] = 0;
242 if(pipe(p1)<0 || pipe(p2)<0){
243 dprint("can't pipe\n");
244 exits("pipe");
245 }
246 remotefd0 = p1[0];
247 remotefd1 = p2[1];
248 switch(fork()){
249 case 0:
250 dup(p2[0], 0);
251 dup(p1[1], 1);
252 close(p1[0]);
253 close(p1[1]);
254 close(p2[0]);
255 close(p2[1]);
256 execvp(RXPATH, av);
257 dprint("can't exec %s\n", RXPATH);
258 exits("exec");
259
260 case -1:
261 dprint("can't fork\n");
262 exits("fork");
263 }
264 free(av);
265 close(p1[1]);
266 close(p2[0]);
267 }
268
269 void
270 startup(char *machine, int Rflag, char **argv, char **files)
271 {
272 if(machine)
273 connectto(machine, files);
274 if(!Rflag)
275 bootterm(machine, argv);
276 downloaded = 1;
277 outTs(Hversion, VERSION);
278 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.