Xv6 with picoc & Linkage editor
v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
|
00001 // 00002 // File descriptors 00003 // 00004 00005 #include "types.h" 00006 #include "defs.h" 00007 #include "param.h" 00008 #include "fs.h" 00009 #include "file.h" 00010 #include "spinlock.h" 00011 00012 struct devsw devsw[NDEV]; 00013 struct { 00014 struct spinlock lock; 00015 struct file file[NFILE]; 00016 } ftable; 00017 00018 void 00019 fileinit(void) 00020 { 00021 initlock(&ftable.lock, "ftable"); 00022 } 00023 00024 // Allocate a file structure. 00025 struct file* 00026 filealloc(void) 00027 { 00028 struct file *f; 00029 00030 acquire(&ftable.lock); 00031 for(f = ftable.file; f < ftable.file + NFILE; f++){ 00032 if(f->ref == 0){ 00033 f->ref = 1; 00034 release(&ftable.lock); 00035 return f; 00036 } 00037 } 00038 release(&ftable.lock); 00039 return 0; 00040 } 00041 00042 // Increment ref count for file f. 00043 struct file* 00044 filedup(struct file *f) 00045 { 00046 acquire(&ftable.lock); 00047 if(f->ref < 1) 00048 panic("filedup"); 00049 f->ref++; 00050 release(&ftable.lock); 00051 return f; 00052 } 00053 00054 // Close file f. (Decrement ref count, close when reaches 0.) 00055 void 00056 fileclose(struct file *f) 00057 { 00058 struct file ff; 00059 00060 acquire(&ftable.lock); 00061 if(f->ref < 1) 00062 panic("fileclose"); 00063 if(--f->ref > 0){ 00064 release(&ftable.lock); 00065 return; 00066 } 00067 ff = *f; 00068 f->ref = 0; 00069 f->type = FD_NONE; 00070 release(&ftable.lock); 00071 00072 if(ff.type == FD_PIPE) 00073 pipeclose(ff.pipe, ff.writable); 00074 else if(ff.type == FD_INODE){ 00075 begin_trans(); 00076 iput(ff.ip); 00077 commit_trans(); 00078 } 00079 } 00080 00081 // Get metadata about file f. 00082 int 00083 filestat(struct file *f, struct stat *st) 00084 { 00085 if(f->type == FD_INODE){ 00086 ilock(f->ip); 00087 stati(f->ip, st); 00088 iunlock(f->ip); 00089 return 0; 00090 } 00091 return -1; 00092 } 00093 00094 // Read from file f. 00095 int 00096 fileread(struct file *f, char *addr, int n) 00097 { 00098 int r; 00099 00100 if(f->readable == 0) 00101 return -1; 00102 if(f->type == FD_PIPE) 00103 return piperead(f->pipe, addr, n); 00104 if(f->type == FD_INODE){ 00105 ilock(f->ip); 00106 if((r = readi(f->ip, addr, f->off, n)) > 0) 00107 f->off += r; 00108 iunlock(f->ip); 00109 return r; 00110 } 00111 panic("fileread"); 00112 } 00113 00114 //PAGEBREAK! 00115 // Write to file f. 00116 int 00117 filewrite(struct file *f, char *addr, int n) 00118 { 00119 int r; 00120 00121 if(f->writable == 0) 00122 return -1; 00123 if(f->type == FD_PIPE) 00124 return pipewrite(f->pipe, addr, n); 00125 if(f->type == FD_INODE){ 00126 // write a few blocks at a time to avoid exceeding 00127 // the maximum log transaction size, including 00128 // i-node, indirect block, allocation blocks, 00129 // and 2 blocks of slop for non-aligned writes. 00130 // this really belongs lower down, since writei() 00131 // might be writing a device like the console. 00132 int max = ((LOGSIZE-1-1-2) / 2) * 512; 00133 int i = 0; 00134 while(i < n){ 00135 int n1 = n - i; 00136 if(n1 > max) 00137 n1 = max; 00138 00139 begin_trans(); 00140 ilock(f->ip); 00141 if ((r = writei(f->ip, addr + i, f->off, n1)) > 0) 00142 f->off += r; 00143 iunlock(f->ip); 00144 commit_trans(); 00145 00146 if(r < 0) 00147 break; 00148 if(r != n1) 00149 panic("short filewrite"); 00150 i += r; 00151 } 00152 return i == n ? n : -1; 00153 } 00154 panic("filewrite"); 00155 } 00156 int 00157 fileseek(struct file *f, int off, int mode) 00158 { 00159 if(f->readable == 0) 00160 return -2; 00161 if(f->type == FD_PIPE) 00162 return -2; 00163 if(f->type == FD_INODE){ 00164 if(mode == 0 && off < f->ip->size) 00165 f->off = off; 00166 else if(mode == 1 && (f->off + off) < f->ip->size) 00167 f->off = f->off + off; 00168 else if(mode == 2) { 00169 f->off = f->ip->size - 1 ;// Not implemented 00170 return f->ip->size; 00171 } 00172 else 00173 return -1; 00174 return off; 00175 } 00176 return -1; 00177 } 00178