added base src
[xv6-db.git] / file.c
blobe10b8249211046414a20c0f8b2a55eadf53a55fb
1 #include "types.h"
2 #include "defs.h"
3 #include "param.h"
4 #include "fs.h"
5 #include "file.h"
6 #include "spinlock.h"
8 struct devsw devsw[NDEV];
9 struct {
10 struct spinlock lock;
11 struct file file[NFILE];
12 } ftable;
14 void
15 fileinit(void)
17 initlock(&ftable.lock, "ftable");
20 // Allocate a file structure.
21 struct file*
22 filealloc(void)
24 struct file *f;
26 acquire(&ftable.lock);
27 for(f = ftable.file; f < ftable.file + NFILE; f++){
28 if(f->ref == 0){
29 f->ref = 1;
30 release(&ftable.lock);
31 return f;
34 release(&ftable.lock);
35 return 0;
38 // Increment ref count for file f.
39 struct file*
40 filedup(struct file *f)
42 acquire(&ftable.lock);
43 if(f->ref < 1)
44 panic("filedup");
45 f->ref++;
46 release(&ftable.lock);
47 return f;
50 // Close file f. (Decrement ref count, close when reaches 0.)
51 void
52 fileclose(struct file *f)
54 struct file ff;
56 acquire(&ftable.lock);
57 if(f->ref < 1)
58 panic("fileclose");
59 if(--f->ref > 0){
60 release(&ftable.lock);
61 return;
63 ff = *f;
64 f->ref = 0;
65 f->type = FD_NONE;
66 release(&ftable.lock);
68 if(ff.type == FD_PIPE)
69 pipeclose(ff.pipe, ff.writable);
70 else if(ff.type == FD_INODE)
71 iput(ff.ip);
74 // Get metadata about file f.
75 int
76 filestat(struct file *f, struct stat *st)
78 if(f->type == FD_INODE){
79 ilock(f->ip);
80 stati(f->ip, st);
81 iunlock(f->ip);
82 return 0;
84 return -1;
87 // Read from file f. Addr is kernel address.
88 int
89 fileread(struct file *f, char *addr, int n)
91 int r;
93 if(f->readable == 0)
94 return -1;
95 if(f->type == FD_PIPE)
96 return piperead(f->pipe, addr, n);
97 if(f->type == FD_INODE){
98 ilock(f->ip);
99 if((r = readi(f->ip, addr, f->off, n)) > 0)
100 f->off += r;
101 iunlock(f->ip);
102 return r;
104 panic("fileread");
107 // Write to file f. Addr is kernel address.
109 filewrite(struct file *f, char *addr, int n)
111 int r;
113 if(f->writable == 0)
114 return -1;
115 if(f->type == FD_PIPE)
116 return pipewrite(f->pipe, addr, n);
117 if(f->type == FD_INODE){
118 ilock(f->ip);
119 if((r = writei(f->ip, addr, f->off, n)) > 0)
120 f->off += r;
121 iunlock(f->ip);
122 return r;
124 panic("filewrite");