17dd7cddfSDavid du Colombier #include <u.h> 27dd7cddfSDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include <draw.h> 47dd7cddfSDavid du Colombier #include <thread.h> 57dd7cddfSDavid du Colombier #include <mouse.h> 67dd7cddfSDavid du Colombier #include <keyboard.h> 77dd7cddfSDavid du Colombier #include <frame.h> 87dd7cddfSDavid du Colombier #include <auth.h> 97dd7cddfSDavid du Colombier #include <fcall.h> 107dd7cddfSDavid du Colombier #include <plumb.h> 117dd7cddfSDavid du Colombier #include "dat.h" 127dd7cddfSDavid du Colombier #include "fns.h" 137dd7cddfSDavid du Colombier 147dd7cddfSDavid du Colombier static Block *blist; 157dd7cddfSDavid du Colombier 167dd7cddfSDavid du Colombier int 177dd7cddfSDavid du Colombier tempfile(void) 187dd7cddfSDavid du Colombier { 197dd7cddfSDavid du Colombier char dir[DIRLEN]; 207dd7cddfSDavid du Colombier char buf[128]; 217dd7cddfSDavid du Colombier int i, fd; 227dd7cddfSDavid du Colombier 23*59cc4ca5SDavid du Colombier snprint(buf, sizeof buf, "/tmp/X%d.%.4sacme", getpid(), getuser()); 247dd7cddfSDavid du Colombier for(i='A'; i<='Z'; i++){ 257dd7cddfSDavid du Colombier buf[5] = i; 267dd7cddfSDavid du Colombier if(stat(buf, dir) == 0) 277dd7cddfSDavid du Colombier continue; 287dd7cddfSDavid du Colombier fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600); 297dd7cddfSDavid du Colombier if(fd >= 0) 307dd7cddfSDavid du Colombier return fd; 317dd7cddfSDavid du Colombier } 327dd7cddfSDavid du Colombier return -1; 337dd7cddfSDavid du Colombier } 347dd7cddfSDavid du Colombier 357dd7cddfSDavid du Colombier Disk* 367dd7cddfSDavid du Colombier diskinit() 377dd7cddfSDavid du Colombier { 387dd7cddfSDavid du Colombier Disk *d; 397dd7cddfSDavid du Colombier 407dd7cddfSDavid du Colombier d = emalloc(sizeof(Disk)); 417dd7cddfSDavid du Colombier d->fd = tempfile(); 427dd7cddfSDavid du Colombier if(d->fd < 0){ 437dd7cddfSDavid du Colombier fprint(2, "acme: can't create temp file: %r\n"); 447dd7cddfSDavid du Colombier exits("diskinit"); 457dd7cddfSDavid du Colombier } 467dd7cddfSDavid du Colombier return d; 477dd7cddfSDavid du Colombier } 487dd7cddfSDavid du Colombier 497dd7cddfSDavid du Colombier static 507dd7cddfSDavid du Colombier uint 517dd7cddfSDavid du Colombier ntosize(uint n, uint *ip) 527dd7cddfSDavid du Colombier { 537dd7cddfSDavid du Colombier uint size; 547dd7cddfSDavid du Colombier 557dd7cddfSDavid du Colombier if(n > Maxblock) 567dd7cddfSDavid du Colombier error("internal error: ntosize"); 577dd7cddfSDavid du Colombier size = n; 587dd7cddfSDavid du Colombier if(size & (Blockincr-1)) 597dd7cddfSDavid du Colombier size += Blockincr - (size & (Blockincr-1)); 607dd7cddfSDavid du Colombier /* last bucket holds blocks of exactly Maxblock */ 617dd7cddfSDavid du Colombier if(ip) 627dd7cddfSDavid du Colombier *ip = size/Blockincr; 637dd7cddfSDavid du Colombier return size * sizeof(Rune); 647dd7cddfSDavid du Colombier } 657dd7cddfSDavid du Colombier 667dd7cddfSDavid du Colombier Block* 677dd7cddfSDavid du Colombier disknewblock(Disk *d, uint n) 687dd7cddfSDavid du Colombier { 697dd7cddfSDavid du Colombier uint i, j, size; 707dd7cddfSDavid du Colombier Block *b; 717dd7cddfSDavid du Colombier 727dd7cddfSDavid du Colombier size = ntosize(n, &i); 737dd7cddfSDavid du Colombier b = d->free[i]; 747dd7cddfSDavid du Colombier if(b) 757dd7cddfSDavid du Colombier d->free[i] = b->next; 767dd7cddfSDavid du Colombier else{ 777dd7cddfSDavid du Colombier /* allocate in chunks to reduce malloc overhead */ 787dd7cddfSDavid du Colombier if(blist == nil){ 797dd7cddfSDavid du Colombier blist = emalloc(100*sizeof(Block)); 807dd7cddfSDavid du Colombier for(j=0; j<100-1; j++) 817dd7cddfSDavid du Colombier blist[j].next = &blist[j+1]; 827dd7cddfSDavid du Colombier } 837dd7cddfSDavid du Colombier b = blist; 847dd7cddfSDavid du Colombier blist = b->next; 857dd7cddfSDavid du Colombier b->addr = d->addr; 867dd7cddfSDavid du Colombier d->addr += size; 877dd7cddfSDavid du Colombier } 887dd7cddfSDavid du Colombier b->n = n; 897dd7cddfSDavid du Colombier return b; 907dd7cddfSDavid du Colombier } 917dd7cddfSDavid du Colombier 927dd7cddfSDavid du Colombier void 937dd7cddfSDavid du Colombier diskrelease(Disk *d, Block *b) 947dd7cddfSDavid du Colombier { 957dd7cddfSDavid du Colombier uint i; 967dd7cddfSDavid du Colombier 977dd7cddfSDavid du Colombier ntosize(b->n, &i); 987dd7cddfSDavid du Colombier b->next = d->free[i]; 997dd7cddfSDavid du Colombier d->free[i] = b; 1007dd7cddfSDavid du Colombier } 1017dd7cddfSDavid du Colombier 1027dd7cddfSDavid du Colombier void 1037dd7cddfSDavid du Colombier diskwrite(Disk *d, Block **bp, Rune *r, uint n) 1047dd7cddfSDavid du Colombier { 1057dd7cddfSDavid du Colombier int size, nsize; 1067dd7cddfSDavid du Colombier Block *b; 1077dd7cddfSDavid du Colombier 1087dd7cddfSDavid du Colombier b = *bp; 1097dd7cddfSDavid du Colombier size = ntosize(b->n, nil); 1107dd7cddfSDavid du Colombier nsize = ntosize(n, nil); 1117dd7cddfSDavid du Colombier if(size != nsize){ 1127dd7cddfSDavid du Colombier diskrelease(d, b); 1137dd7cddfSDavid du Colombier b = disknewblock(d, n); 1147dd7cddfSDavid du Colombier *bp = b; 1157dd7cddfSDavid du Colombier } 1167dd7cddfSDavid du Colombier if(seek(d->fd, b->addr, 0) < 0) 1177dd7cddfSDavid du Colombier error("seek error in temp file"); 1187dd7cddfSDavid du Colombier if(write(d->fd, r, n*sizeof(Rune)) != n*sizeof(Rune)) 1197dd7cddfSDavid du Colombier error("write error to temp file"); 1207dd7cddfSDavid du Colombier b->n = n; 1217dd7cddfSDavid du Colombier } 1227dd7cddfSDavid du Colombier 1237dd7cddfSDavid du Colombier void 1247dd7cddfSDavid du Colombier diskread(Disk *d, Block *b, Rune *r, uint n) 1257dd7cddfSDavid du Colombier { 1267dd7cddfSDavid du Colombier if(n > b->n) 1277dd7cddfSDavid du Colombier error("internal error: diskread"); 1287dd7cddfSDavid du Colombier 1297dd7cddfSDavid du Colombier ntosize(b->n, nil); 1307dd7cddfSDavid du Colombier if(seek(d->fd, b->addr, 0) < 0) 1317dd7cddfSDavid du Colombier error("seek error in temp file"); 1327dd7cddfSDavid du Colombier if(read(d->fd, r, n*sizeof(Rune)) != n*sizeof(Rune)) 1337dd7cddfSDavid du Colombier error("read error from temp file"); 1347dd7cddfSDavid du Colombier } 135