comparison src/file.cbc @ 52:214d21c891c7

rename to cbc __ncode is not handled as interfaces
author kono
date Mon, 03 Jun 2019 18:12:44 +0900
parents src/file.c@ad1d3b268e2d
children b5ddf6fb0a6d
comparison
equal deleted inserted replaced
51:fadfd62d6b14 52:214d21c891c7
1 //
2 // File descriptors
3 //
4
5 #include "types.h"
6 #include "defs.h"
7 #include "param.h"
8 #include "fs.h"
9 #include "file.h"
10 #include "spinlock.h"
11 #include "proc.h"
12
13 #define __ncode __code
14 #
15 struct devsw devsw[NDEV];
16 struct cbc_devsw cbc_devsw[NDEV];
17
18 struct {
19 struct spinlock lock;
20 struct file file[NFILE];
21 } ftable;
22
23 void fileinit (void)
24 {
25 initlock(&ftable.lock, "ftable");
26 }
27
28 // Allocate a file structure.
29 struct file* filealloc (void)
30 {
31 struct file *f;
32
33 acquire(&ftable.lock);
34
35 for (f = ftable.file; f < ftable.file + NFILE; f++) {
36 if (f->ref == 0) {
37 f->ref = 1;
38 release(&ftable.lock);
39 return f;
40 }
41 }
42
43 release(&ftable.lock);
44 return 0;
45 }
46
47 // Increment ref count for file f.
48 struct file* filedup (struct file *f)
49 {
50 acquire(&ftable.lock);
51
52 if (f->ref < 1) {
53 panic("filedup");
54 }
55
56 f->ref++;
57 release(&ftable.lock);
58 return f;
59 }
60
61 // Close file f. (Decrement ref count, close when reaches 0.)
62 void fileclose (struct file *f)
63 {
64 struct file ff;
65
66 acquire(&ftable.lock);
67
68 if (f->ref < 1) {
69 panic("fileclose");
70 }
71
72 if (--f->ref > 0) {
73 release(&ftable.lock);
74 return;
75 }
76
77 ff = *f;
78 f->ref = 0;
79 f->type = FD_NONE;
80 release(&ftable.lock);
81
82 if (ff.type == FD_PIPE) {
83 pipeclose(ff.pipe, ff.writable);
84
85 } else if (ff.type == FD_INODE) {
86 begin_trans();
87 iput(ff.ip);
88 commit_trans();
89 }
90 }
91
92 // Get metadata about file f.
93 int filestat (struct file *f, struct stat *st)
94 {
95 if (f->type == FD_INODE) {
96 ilock(f->ip);
97 stati(f->ip, st);
98 iunlock(f->ip);
99
100 return 0;
101 }
102
103 return -1;
104 }
105
106 __ncode cbc_fileread1 (int r)
107 {
108 struct file *f = proc->cbc_arg.cbc_console_arg.f;
109 __code (*next)(int ret) = cbc_ret;
110 if (r > 0)
111 f->off += r;
112 iunlock(f->ip);
113 goto next(r);
114 }
115
116 __ncode cbc_fileread (struct file *f, char *addr, int n, __code (*next)(int ret))
117 {
118 if (f->readable == 0) {
119 goto next(-1);
120 }
121
122 if (f->type == FD_PIPE) {
123 goto cbc_piperead(f->pipe, addr, n, next);
124 goto next(-1);
125 }
126
127 if (f->type == FD_INODE) {
128 ilock(f->ip);
129 proc->cbc_arg.cbc_console_arg.f = f;
130 goto cbc_readi(f->ip, addr, f->off, n, cbc_fileread1);
131 }
132
133 goto cbc_panic("fileread");
134 }
135
136 // Read from file f.
137 int fileread (struct file *f, char *addr, int n)
138 {
139 int r;
140
141 if (f->readable == 0) {
142 return -1;
143 }
144
145 if (f->type == FD_PIPE) {
146 return piperead(f->pipe, addr, n);
147 }
148
149 if (f->type == FD_INODE) {
150 ilock(f->ip);
151
152 if ((r = readi(f->ip, addr, f->off, n)) > 0) {
153 f->off += r;
154 }
155
156 iunlock(f->ip);
157
158 return r;
159 }
160
161 panic("fileread");
162 }
163
164 //PAGEBREAK!
165 // Write to file f.
166 int filewrite (struct file *f, char *addr, int n)
167 {
168 int r;
169 int i;
170 int max;
171 int n1;
172
173 if (f->writable == 0) {
174 return -1;
175 }
176
177 if (f->type == FD_PIPE) {
178 return pipewrite(f->pipe, addr, n);
179 }
180
181 if (f->type == FD_INODE) {
182 // write a few blocks at a time to avoid exceeding
183 // the maximum log transaction size, including
184 // i-node, indirect block, allocation blocks,
185 // and 2 blocks of slop for non-aligned writes.
186 // this really belongs lower down, since writei()
187 // might be writing a device like the console.
188 max = ((LOGSIZE - 1 - 1 - 2) / 2) * 512;
189 i = 0;
190
191 while (i < n) {
192 n1 = n - i;
193
194 if (n1 > max) {
195 n1 = max;
196 }
197
198 begin_trans();
199 ilock(f->ip);
200
201 if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) {
202 f->off += r;
203 }
204
205 iunlock(f->ip);
206 commit_trans();
207
208 if (r < 0) {
209 break;
210 }
211
212 if (r != n1) {
213 panic("short filewrite");
214 }
215
216 i += r;
217 }
218
219 return i == n ? n : -1;
220 }
221
222 panic("filewrite");
223 }
224