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
file.c
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 
 All Data Structures