URI:
       tdisk.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdisk.c (2257B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <thread.h>
            5 #include <cursor.h>
            6 #include <mouse.h>
            7 #include <keyboard.h>
            8 #include <frame.h>
            9 #include <fcall.h>
           10 #include <plumb.h>
           11 #include <libsec.h>
           12 #include "dat.h"
           13 #include "fns.h"
           14 
           15 static        Block        *blist;
           16 
           17 int
           18 tempfile(void)
           19 {
           20         char buf[128];
           21         int i, fd;
           22 
           23         snprint(buf, sizeof buf, "/tmp/X%d.%.4sacme", getpid(), getuser());
           24         for(i='A'; i<='Z'; i++){
           25                 buf[5] = i;
           26                 if(access(buf, AEXIST) == 0)
           27                         continue;
           28                 fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
           29                 if(fd >= 0)
           30                         return fd;
           31         }
           32         return -1;
           33 }
           34 
           35 Disk*
           36 diskinit()
           37 {
           38         Disk *d;
           39 
           40         d = emalloc(sizeof(Disk));
           41         d->fd = tempfile();
           42         if(d->fd < 0){
           43                 fprint(2, "acme: can't create temp file: %r\n");
           44                 threadexitsall("diskinit");
           45         }
           46         return d;
           47 }
           48 
           49 static
           50 uint
           51 ntosize(uint n, uint *ip)
           52 {
           53         uint size;
           54 
           55         if(n > Maxblock)
           56                 error("internal error: ntosize");
           57         size = n;
           58         if(size & (Blockincr-1))
           59                 size += Blockincr - (size & (Blockincr-1));
           60         /* last bucket holds blocks of exactly Maxblock */
           61         if(ip)
           62                 *ip = size/Blockincr;
           63         return size * sizeof(Rune);
           64 }
           65 
           66 Block*
           67 disknewblock(Disk *d, uint n)
           68 {
           69         uint i, j, size;
           70         Block *b;
           71 
           72         size = ntosize(n, &i);
           73         b = d->free[i];
           74         if(b)
           75                 d->free[i] = b->u.next;
           76         else{
           77                 /* allocate in chunks to reduce malloc overhead */
           78                 if(blist == nil){
           79                         blist = emalloc(100*sizeof(Block));
           80                         for(j=0; j<100-1; j++)
           81                                 blist[j].u.next = &blist[j+1];
           82                 }
           83                 b = blist;
           84                 blist = b->u.next;
           85                 b->addr = d->addr;
           86                 if(d->addr+size < d->addr){
           87                         error("temp file overflow");
           88                 }
           89                 d->addr += size;
           90         }
           91         b->u.n = n;
           92         return b;
           93 }
           94 
           95 void
           96 diskrelease(Disk *d, Block *b)
           97 {
           98         uint i;
           99 
          100         ntosize(b->u.n, &i);
          101         b->u.next = d->free[i];
          102         d->free[i] = b;
          103 }
          104 
          105 void
          106 diskwrite(Disk *d, Block **bp, Rune *r, uint n)
          107 {
          108         int size, nsize;
          109         Block *b;
          110 
          111         b = *bp;
          112         size = ntosize(b->u.n, nil);
          113         nsize = ntosize(n, nil);
          114         if(size != nsize){
          115                 diskrelease(d, b);
          116                 b = disknewblock(d, n);
          117                 *bp = b;
          118         }
          119         if(pwrite(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
          120                 error("write error to temp file");
          121         b->u.n = n;
          122 }
          123 
          124 void
          125 diskread(Disk *d, Block *b, Rune *r, uint n)
          126 {
          127         if(n > b->u.n)
          128                 error("internal error: diskread");
          129 
          130         ntosize(b->u.n, nil);
          131         if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
          132                 error("read error from temp file");
          133 }