file.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002 The UbixOS Project
00003  All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are
00006 permitted provided that the following conditions are met:
00007 
00008 Redistributions of source code must retain the above copyright notice, this list of
00009 conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010 form must reproduce the above copyright notice, this list of conditions, the following
00011 disclaimer and the list of authors in the documentation and/or other materials provided
00012 with the distribution. Neither the name of the UbixOS Project nor the names of its
00013 contributors may be used to endorse or promote products derived from this software
00014 without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id$
00027 
00028 *****************************************************************************************/
00029 
00030 #include <vfs/vfs.h>
00031 #include <vfs/file.h>
00032 #include <ubixos/sched.h>
00033 #include <ubixos/vitals.h>
00034 #include <ubixos/kpanic.h>
00035 #include <ubixos/spinlock.h>
00036 #include <lib/kmalloc.h>
00037 #include <lib/string.h>
00038 #include <vmm/paging.h>
00039 #include <lib/kprintf.h>
00040 #include <assert.h>
00041 
00042 static spinLock_t fdTable_lock = SPIN_LOCK_INITIALIZER;
00043 
00044 
00045 fileDescriptor *fdTable = 0x0;
00046 
00047 /* USER */
00048 
00049 void sysFwrite(char *ptr,int size,userFileDescriptor *userFd) {
00050   if (userFd == 0x0) {
00051       tty_print(ptr,_current->term);
00052     }
00053   else {
00054     fwrite(ptr,size,1,userFd->fd);
00055     }
00056   return;
00057   }
00058   
00059 void sysFgetc(int *ptr,userFileDescriptor *userFd) {
00060   fileDescriptor *tmpFd = 0x0;
00061   tmpFd = userFd->fd;
00062   if (userFd->fd == 0x0) {
00063     while (1) {
00064       if (_current->term == tty_foreground) {
00065         if ((*ptr = getch()) != 0x0)
00066           return;
00067         sched_yield();
00068         }
00069       else {
00070         sched_yield();
00071         }
00072  /*
00073        else {
00074          kprintf("Waking Task: %i\n",tty_foreground->owner);
00075          sched_setStatus(tty_foreground->owner,READY);
00076          kprintf("Sleeping Task: %i\n",_current->id);
00077          sched_setStatus(_current->id,WAIT);
00078          sched_yield();
00079          }
00080 */
00081       }
00082     }
00083   else {
00084     ptr[0] = (int) fgetc(tmpFd);
00085     }
00086   }
00087 
00088 void sysRmDir() {
00089   return;
00090   }
00091 
00092 void sysFseek(userFileDescriptor *userFd,long offset,int whence) {
00093   // TODO : coredump?
00094   if (userFd == NULL)
00095         return;
00096   if (userFd->fd == NULL)
00097         return;
00098 
00099   userFd->fd->offset = offset+whence;
00100   }
00101 
00102 void sysChDir(const char *path) {
00103   if (strstr(path,":") == 0x0) {
00104     sprintf(_current->oInfo.cwd,"%s%s",_current->oInfo.cwd,path);
00105     }
00106   else {
00107     sprintf(_current->oInfo.cwd,path);
00108     }
00109   }
00110 
00111 void sysUnlink(const char *path,int *retVal) {
00112   *retVal = unlink(path);
00113   }
00114 
00115 /************************************************************************
00116 
00117 Function: void sysFopen();
00118 Description: Opens A File Descriptor For A User Task
00119 Notes:
00120 
00121 ************************************************************************/
00122 void sysFopen(const char *file,char *flags,userFileDescriptor *userFd) {
00123   if (userFd == NULL)
00124     kprintf("Error: userFd == NULL, File: %s, Line: %i\n",__FILE__,__LINE__);
00125   userFd->fd = fopen(file,flags);
00126   if (userFd->fd != 0x0) {
00127     userFd->fdSize = userFd->fd->size;
00128     }
00129   /* Return */
00130   return;
00131   }
00132   
00133 /************************************************************************
00134 
00135 Function: void sysFread();
00136 Description: Reads SIZE Bytes From The userFd Into DATA
00137 Notes:
00138 
00139 ************************************************************************/  
00140 void sysFread(void *data,long size,userFileDescriptor *userFd) {
00141   /* TODO : coredump? */
00142   if (userFd == NULL)
00143         return;
00144   if (userFd->fd == NULL)
00145         return;
00146   fread(data,size,1,userFd->fd);
00147     return;
00148   }
00149 
00150 /************************************************************************
00151 
00152 Function: void sysFclse();
00153 Description: Closes A File Descriptor For A User Task
00154 Notes:
00155 
00156 ************************************************************************/
00157 void sysFclose(userFileDescriptor *userFd,int *status) {
00158   if (userFd == NULL )
00159   {
00160         *status = -1;
00161         return;
00162   }
00163   if (userFd->fd == NULL)
00164   {
00165         *status = -1;
00166         return;
00167   }
00168   *status = fclose(userFd->fd);
00169   /* Return */
00170   return;
00171   }
00172   
00173   
00174 
00175 /* KERNEL */
00176 
00177 
00178 size_t fread(void *ptr,int size,int nmemb,fileDescriptor *fd) {
00179  
00180   if (fd == 0x0)
00181     return(0x0);
00182     
00183  if (nmemb == 0x0) nmemb = 1; //Temp Fix
00184  assert(fd);
00185  //kprintf("fd->fileName: %s:%i\n",fd->fileName,_current->id);
00186  assert(fd->mp);
00187  assert(fd->mp->fs);
00188  fd->mp->fs->vfsRead(fd,ptr,fd->offset,size * nmemb);
00189  fd->offset += size * nmemb;
00190  return(size * nmemb);
00191   }
00192 
00193 size_t fwrite(void *ptr,int size,int nmemb,fileDescriptor *fd) {
00194   if (fd != 0x0) {
00195     fd->mp->fs->vfsWrite(fd,ptr,fd->offset,size * nmemb);
00196     fd->offset += size * nmemb;
00197     }
00198   return(0x0);
00199   }
00200 
00201 int fseek(fileDescriptor *tmpFd,long offset,int whence) {
00202   tmpFd->offset = offset+whence;
00203   return(tmpFd->offset);
00204   }
00205 
00206 /************************************************************************
00207 
00208 Function: int feof(fileDescriptor *fd)
00209 Description: Check A File Descriptor For EOF And Return Result
00210 Notes:
00211 
00212 ************************************************************************/  
00213 int feof(fileDescriptor *fd) {
00214   if (fd->status == fdEof) {
00215     return(-1);
00216     }
00217   return(0);
00218   }
00219   
00220 /************************************************************************
00221 
00222 Function: int fputc(int ch,fileDescriptor *fd)
00223 Description: This Will Write Character To FD
00224 Notes:
00225 
00226 ************************************************************************/
00227 int fputc(int ch,fileDescriptor *fd) {
00228   if (fd != 0x0) {
00229     ch = fd->mp->fs->vfsWrite(fd,(char *)ch,fd->offset,1);
00230     fd->offset++;
00231     return(ch);
00232     }
00233   /* Return NULL If FD Is Not Found */
00234   return(0x0);
00235   }
00236   
00237 /************************************************************************
00238 
00239 Function: int fgetc(fileDescriptor *fd)
00240 Description: This Will Return The Next Character In A FD Stream
00241 Notes:
00242 
00243 ************************************************************************/  
00244 int fgetc(fileDescriptor *fd) {
00245   int ch = 0x0;
00246   /* If Found Return Next Char */
00247   if (fd != 0x0) {
00248     fd->mp->fs->vfsRead(fd,(char *)&ch,fd->offset,1);
00249     fd->offset++;
00250     return(ch);
00251     }
00252 
00253   /* Return NULL If FD Is Not Found */
00254   return(0x0);
00255   }
00256 
00257 /************************************************************************
00258 
00259 Function: fileDescriptor *fopen(const char *file,cont char *flags)
00260 Description: This Will Open A File And Return A File Descriptor
00261 Notes:
00262 
00263 08/05/02 - Just Started A Rewrite Of This Function Should Work Out Well
00264 
00265 ************************************************************************/
00266 
00267 fileDescriptor *fopen(const char *file,const char *flags) {
00268   int             i          = 0x0;
00269   char           *path       = 0x0;
00270   char           *mountPoint = 0x0;
00271   char            fileName[1024];
00272   fileDescriptor *tmpFd      = 0x0;
00273   
00274   /* Allocate Memory For File Descriptor */
00275     if((tmpFd = (fileDescriptor *)kmalloc(sizeof(fileDescriptor))) == 0x0) {
00276       kprintf("Error: tmpFd == NULL, File: %s, Line: %i\n",__FILE__,__LINE__);
00277       return(NULL);
00278     }
00279     
00280   sprintf(fileName,"%s",file);
00281   if (strstr(fileName,":")) {
00282     mountPoint = (char *)strtok((char *)&fileName,":");
00283     path = strtok(NULL,"\n");
00284     }
00285   else {
00286     path = fileName;
00287     //path = &fileName;
00288     }
00289  
00290   if (path[0] == '/') {
00291     sprintf(tmpFd->fileName,"%s", path);
00292     }
00293   else { 
00294     sprintf(tmpFd->fileName,"/%s",path);
00295     }    
00296 
00297   /* Find our mount point or set default to sys */
00298   if (mountPoint == 0x0) {
00299     tmpFd->mp = vfs_findMount("sys");
00300     }
00301   else {
00302     tmpFd->mp = vfs_findMount(mountPoint);
00303     }
00304   
00305   if (tmpFd->mp == 0x0) {
00306     kprintf("Mount Point Bad\n");
00307     return(0x0);
00308     }
00309     
00310   /* This Will Set Up The Descriptor Modes */
00311   tmpFd->mode = 0;
00312   for  (i = 0; '\0' != flags[i] ;i++ ) {
00313     switch(flags[i]) {
00314       case 'w':
00315       case 'W':
00316         tmpFd->mode |= fileWrite;
00317         break;
00318       case 'r':
00319       case 'R':
00320         tmpFd->mode |= fileRead;
00321         break;
00322       case 'b':
00323       case 'B':
00324         tmpFd->mode |= fileBinary;
00325         break;
00326       case 'a':
00327       case 'A':
00328         tmpFd->mode |= fileAppend;
00329         break;
00330       default:
00331         kprintf("Invalid mode '%c' for fopen\n", flags[i]);
00332         break;
00333       }
00334     }
00335   /* Search For The File */
00336   if (tmpFd->mp->fs->vfsOpenFile(tmpFd->fileName,tmpFd) == 0x1) {
00337     /* If The File Is Found Then Set Up The Descriptor */
00338 
00339 
00340    /* in order to save resources we will allocate the buffer later when it is needed */
00341 
00342     tmpFd->buffer = (char *)kmalloc(4096);
00343     if(tmpFd->buffer == 0x0)
00344     {
00345       kfree(tmpFd);
00346       kprintf("Error: tmpFd->buffer == NULL, File: %s, Line: %i\n",__FILE__,__LINE__);
00347       spinUnlock(&fdTable_lock);
00348       return 0x1;
00349     }
00350     /* Set Its Status To Open */
00351     tmpFd->status = fdOpen;
00352     
00353     /* Initial File Offset Is Zero */
00354     tmpFd->offset = 0;
00355     tmpFd->prev = 0x0;
00356 
00357    /* we do not want to be in a spinlock longer than we need to, so
00358      it has been moved to here. */
00359       spinLock(&fdTable_lock);
00360 
00361     /* Increment Number Of Open Files */
00362     systemVitals->openFiles++;
00363     
00364     tmpFd->next = fdTable;
00365     
00366     if (fdTable != 0x0)
00367       fdTable->prev = tmpFd;
00368 
00369      fdTable = tmpFd;
00370 
00371       spinUnlock(&fdTable_lock);
00372       
00373     
00374     /* Return The FD */
00375     return(tmpFd);
00376     }
00377   else {
00378     kfree(tmpFd->buffer);
00379     kfree(tmpFd);
00380     spinUnlock(&fdTable_lock);
00381     kprintf("File Not Found?\n");
00382     return (NULL);
00383     }
00384     
00385     /* Return NULL */
00386     return(0x0);
00387   }
00388 
00389 /************************************************************************
00390 
00391 Function: int fclose(fileDescriptor *fd);
00392 Description: This Will Close And Free A File Descriptor
00393 Notes:
00394 
00395 ************************************************************************/
00396 int fclose(fileDescriptor *fd) {
00397   fileDescriptor *tmpFd = 0x0;
00398   assert(fd);
00399   
00400   spinLock(&fdTable_lock);
00401   
00402   for (tmpFd = fdTable;tmpFd != 0x0;tmpFd = tmpFd->next) {
00403     if (tmpFd == fd) {
00404       if (tmpFd->prev)
00405         tmpFd->prev->next = tmpFd->next;
00406       if (tmpFd->next)
00407         tmpFd->next->prev = tmpFd->prev;
00408 
00409       if (tmpFd == fdTable)
00410         fdTable = tmpFd->next;
00411 
00412       systemVitals->openFiles--;
00413       spinUnlock(&fdTable_lock);
00414         if(tmpFd->buffer != NULL)
00415                 kfree(tmpFd->buffer);
00416       kfree(tmpFd);
00417       return(0x0);      
00418       }
00419     }
00420   
00421   spinUnlock(&fdTable_lock);
00422   return(0x1);
00423   }
00424 
00425 /* UBU */
00426 
00427 /************************************************************************
00428 
00429 Function: void sysMkDir(const char *path)
00430 Description: This Will Create A New Directory
00431 Notes:
00432 
00433 ************************************************************************/
00434 void sysMkDir(const char *path) {
00435   fileDescriptor *tmpFD = 0x0; 
00436   char tmpDir[1024];
00437   char rootPath[256];
00438   char *dir = 0x0;//UBU*mountPoint = 0x0;
00439   char *tmp = 0x0;
00440   rootPath[0] = '\0';
00441   dir = (char *)path; 
00442 
00443   if (strstr(path,":") == 0x0) {
00444     sprintf(tmpDir,"%s%s",_current->oInfo.cwd,path);
00445     dir = (char *)&tmpDir;
00446     }
00447   while (strstr(dir,"/")) {
00448     if (rootPath[0] == 0x0)
00449       sprintf(rootPath,"%s/",strtok(dir,"/"));
00450     else
00451       sprintf(rootPath,"%s%s/",rootPath,strtok(dir,"/"));
00452     tmp = strtok(NULL,"\n");
00453     dir = tmp;
00454     }
00455 
00456   //kprintf("rootPath: [%s]\n",rootPath);
00457   tmpFD = fopen(rootPath,"rb");
00458 
00459   if (tmpFD->mp == 0x0) {
00460     kprintf("Invalid Mount Point\n");
00461     }
00462   tmpFD->mp->fs->vfsMakeDir(dir,tmpFD);
00463 
00464   fclose(tmpFD);
00465 
00466   return;
00467   }
00468 
00469 
00470 /************************************************************************
00471 
00472 Function: int unlink(const char *node)
00473 Description: This will unlink a file
00474 Notes:
00475 
00476 ************************************************************************/
00477 
00478 int unlink(const char *node) {
00479   char *path = 0x0,*mountPoint = 0x0;
00480   struct vfs_mountPoint *mp = 0x0;
00481 
00482   path = (char *)strtok((char *)node,"@");
00483   mountPoint = strtok(NULL,"\n");
00484   if (mountPoint == 0x0) {
00485     mp = vfs_findMount("sys"); /* _current->oInfo.container; */
00486     }
00487   else {
00488     mp = vfs_findMount(mountPoint);
00489     }
00490   if (mp == 0x0) {
00491     //kpanic("Mount Point Bad");
00492     return(0x0);
00493     }
00494   mp->fs->vfsUnlink(path,mp);
00495   return(0x0);
00496   }
00497 
00498 
00499 /***
00500  END
00501  ***/
00502 

Generated on Tue Dec 5 23:34:59 2006 for UbixOS V2 by  doxygen 1.4.7