io.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 && length>0)
           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-genbuf)){
           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 }