]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/acme/disk.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[plan9front.git] / sys / src / cmd / acme / disk.c
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 "dat.h"
12 #include "fns.h"
13
14 static  Block   *blist;
15
16 int
17 tempfile(void)
18 {
19         char buf[128];
20         int i, fd;
21
22         snprint(buf, sizeof buf, "/tmp/X%d.%.4sacme", getpid(), getuser());
23         for(i='A'; i<='Z'; i++){
24                 buf[5] = i;
25                 if(access(buf, AEXIST) == 0)
26                         continue;
27                 fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
28                 if(fd >= 0)
29                         return fd;
30         }
31         return -1;
32 }
33
34 Disk*
35 diskinit()
36 {
37         Disk *d;
38
39         d = emalloc(sizeof(Disk));
40         d->fd = tempfile();
41         if(d->fd < 0){
42                 fprint(2, "acme: can't create temp file: %r\n");
43                 threadexitsall("diskinit");
44         }
45         return d;
46 }
47
48 static
49 uint
50 ntosize(uint n, uint *ip)
51 {
52         uint size;
53
54         if(n > Maxblock)
55                 error("internal error: ntosize");
56         size = n;
57         if(size & (Blockincr-1))
58                 size += Blockincr - (size & (Blockincr-1));
59         /* last bucket holds blocks of exactly Maxblock */
60         if(ip)
61                 *ip = size/Blockincr;
62         return size * sizeof(Rune);
63 }
64
65 Block*
66 disknewblock(Disk *d, uint n)
67 {
68         uint i, j, size;
69         Block *b;
70
71         size = ntosize(n, &i);
72         b = d->free[i];
73         if(b)
74                 d->free[i] = b->next;
75         else{
76                 /* allocate in chunks to reduce malloc overhead */
77                 if(blist == nil){
78                         blist = emalloc(100*sizeof(Block));
79                         for(j=0; j<100-1; j++)
80                                 blist[j].next = &blist[j+1];
81                 }
82                 b = blist;
83                 blist = b->next;
84                 b->addr = d->addr;
85                 d->addr += size;
86         }
87         b->n = n;
88         return b;
89 }
90
91 void
92 diskrelease(Disk *d, Block *b)
93 {
94         uint i;
95
96         ntosize(b->n, &i);
97         b->next = d->free[i];
98         d->free[i] = b;
99 }
100
101 void
102 diskwrite(Disk *d, Block **bp, Rune *r, uint n)
103 {
104         int size, nsize;
105         Block *b;
106
107         b = *bp;
108         size = ntosize(b->n, nil);
109         nsize = ntosize(n, nil);
110         if(size != nsize){
111                 diskrelease(d, b);
112                 b = disknewblock(d, n);
113                 *bp = b;
114         }
115         if(pwrite(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
116                 error("write error to temp file");
117         b->n = n;
118 }
119
120 void
121 diskread(Disk *d, Block *b, Rune *r, uint n)
122 {
123         if(n > b->n)
124                 error("internal error: diskread");
125
126         ntosize(b->n, nil);
127         if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
128                 error("read error from temp file");
129 }