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