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: file_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
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,size_t size,size_t nmemb,fileDescriptor *fd) {
00179   size_t i = 0x0;
00180 
00181   if (fd == 0x0)
00182     return(0x0);
00183 
00184    if (nmemb == 0x0)
00185      nmemb = 1; //Temp Fix
00186 
00187    assert(fd);
00188    assert(fd->mp);
00189    assert(fd->mp->fs);
00190 
00191    i = fd->mp->fs->vfsRead(fd,ptr,fd->offset,size * nmemb);
00192 
00193    fd->offset += size * nmemb;
00194 
00195    //kprintf("fread: %i:%i",i,size *nmemb);
00196 
00197    return(i);
00198   }
00199 
00200 size_t fwrite(void *ptr,int size,int nmemb,fileDescriptor *fd) {
00201   if (fd != 0x0) {
00202     fd->mp->fs->vfsWrite(fd,ptr,fd->offset,size * nmemb);
00203     fd->offset += size * nmemb;
00204     }
00205   return(0x0);
00206   }
00207 
00208 int fseek(fileDescriptor *tmpFd,long offset,int whence) {
00209   tmpFd->offset = offset+whence;
00210   return(tmpFd->offset);
00211   }
00212 
00213 /************************************************************************
00214 
00215 Function: int feof(fileDescriptor *fd)
00216 Description: Check A File Descriptor For EOF And Return Result
00217 Notes:
00218 
00219 ************************************************************************/  
00220 int feof(fileDescriptor *fd) {
00221   if (fd->status == fdEof) {
00222     return(-1);
00223     }
00224   return(0);
00225   }
00226   
00227 /************************************************************************
00228 
00229 Function: int fputc(int ch,fileDescriptor *fd)
00230 Description: This Will Write Character To FD
00231 Notes:
00232 
00233 ************************************************************************/
00234 int fputc(int ch,fileDescriptor *fd) {
00235   if (fd != 0x0) {
00236     ch = fd->mp->fs->vfsWrite(fd,(char *)ch,fd->offset,1);
00237     fd->offset++;
00238     return(ch);
00239     }
00240   /* Return NULL If FD Is Not Found */
00241   return(0x0);
00242   }
00243   
00244 /************************************************************************
00245 
00246 Function: int fgetc(fileDescriptor *fd)
00247 Description: This Will Return The Next Character In A FD Stream
00248 Notes:
00249 
00250 ************************************************************************/  
00251 int fgetc(fileDescriptor *fd) {
00252   int ch = 0x0;
00253   /* If Found Return Next Char */
00254   if (fd != 0x0) {
00255     fd->mp->fs->vfsRead(fd,(char *)&ch,fd->offset,1);
00256     fd->offset++;
00257     return(ch);
00258     }
00259 
00260   /* Return NULL If FD Is Not Found */
00261   return(0x0);
00262   }
00263 
00264 /************************************************************************
00265 
00266 Function: fileDescriptor *fopen(const char *file,cont char *flags)
00267 Description: This Will Open A File And Return A File Descriptor
00268 Notes:
00269 
00270 08/05/02 - Just Started A Rewrite Of This Function Should Work Out Well
00271 
00272 ************************************************************************/
00273 
00274 fileDescriptor *fopen(const char *file,const char *flags) {
00275   int             i          = 0x0;
00276   char           *path       = 0x0;
00277   char           *mountPoint = 0x0;
00278   char            fileName[1024];
00279   fileDescriptor *tmpFd      = 0x0;
00280 
00281   /* Allocate Memory For File Descriptor */
00282     if((tmpFd = (fileDescriptor *)kmalloc(sizeof(fileDescriptor))) == 0x0) {
00283       kprintf("Error: tmpFd == NULL, File: %s, Line: %i\n",__FILE__,__LINE__);
00284       return(NULL);
00285     }
00286 
00287   strcpy(fileName,file);
00288 
00289   if (strstr(fileName,":")) {
00290     mountPoint = (char *)strtok((char *)&fileName,":");
00291     path = strtok(NULL,"\n");
00292     }
00293   else {
00294     path = fileName;
00295     }
00296  
00297   if (path[0] == '/')
00298     strcpy(tmpFd->fileName, path);
00299   else
00300     sprintf(tmpFd->fileName,"/%s",path);
00301 
00302   /* Find our mount point or set default to sys */
00303   if (mountPoint == 0x0)
00304     tmpFd->mp = vfs_findMount("sys");
00305   else
00306     tmpFd->mp = vfs_findMount(mountPoint);
00307 
00308   if (tmpFd->mp == 0x0) {
00309     kprintf("Mount Point Bad\n");
00310     return(0x0);
00311     }
00312 
00313   /* This Will Set Up The Descriptor Modes */
00314   tmpFd->mode = 0;
00315   for  (i = 0; '\0' != flags[i] ;i++ ) {
00316     switch(flags[i]) {
00317       case 'w':
00318       case 'W':
00319         tmpFd->mode |= fileWrite;
00320         break;
00321       case 'r':
00322       case 'R':
00323         tmpFd->mode |= fileRead;
00324         break;
00325       case 'b':
00326       case 'B':
00327         tmpFd->mode |= fileBinary;
00328         break;
00329       case 'a':
00330       case 'A':
00331         tmpFd->mode |= fileAppend;
00332         break;
00333       default:
00334         kprintf("Invalid mode '%c' for fopen\n", flags[i]);
00335         break;
00336       }
00337     }
00338   /* Search For The File */
00339   if (tmpFd->mp->fs->vfsOpenFile(tmpFd->fileName,tmpFd) == 0x1) {
00340     /* If The File Is Found Then Set Up The Descriptor */
00341 
00342 
00343    /* in order to save resources we will allocate the buffer later when it is needed */
00344 
00345     tmpFd->buffer = (char *)kmalloc(4096);
00346     if(tmpFd->buffer == 0x0)
00347     {
00348       kfree(tmpFd);
00349       kprintf("Error: tmpFd->buffer == NULL, File: %s, Line: %i\n",__FILE__,__LINE__);
00350       spinUnlock(&fdTable_lock);
00351       return 0x1;
00352     }
00353     /* Set Its Status To Open */
00354     tmpFd->status = fdOpen;
00355 
00356     /* Initial File Offset Is Zero */
00357     tmpFd->offset = 0;
00358     tmpFd->prev = 0x0;
00359 
00360    /* we do not want to be in a spinlock longer than we need to, so
00361      it has been moved to here. */
00362       spinLock(&fdTable_lock);
00363 
00364     /* Increment Number Of Open Files */
00365     systemVitals->openFiles++;
00366 
00367     tmpFd->next = fdTable;
00368 
00369     if (fdTable != 0x0)
00370       fdTable->prev = tmpFd;
00371 
00372      fdTable = tmpFd;
00373 
00374       spinUnlock(&fdTable_lock);
00375 
00376     /* Return The FD */
00377     return(tmpFd);
00378     }
00379   else {
00380     kfree(tmpFd->buffer);
00381     kfree(tmpFd);
00382     spinUnlock(&fdTable_lock);
00383     kprintf("File Not Found? %s\n",file);
00384     return (NULL);
00385     }
00386 
00387     /* Return NULL */
00388     return(0x0);
00389   }
00390 
00391 /************************************************************************
00392 
00393 Function: int fclose(fileDescriptor *fd);
00394 Description: This Will Close And Free A File Descriptor
00395 Notes:
00396 
00397 ************************************************************************/
00398 int fclose(fileDescriptor *fd) {
00399   fileDescriptor *tmpFd = 0x0;
00400   assert(fd);
00401   
00402   spinLock(&fdTable_lock);
00403   
00404   for (tmpFd = fdTable;tmpFd != 0x0;tmpFd = tmpFd->next) {
00405     if (tmpFd == fd) {
00406       if (tmpFd->prev)
00407         tmpFd->prev->next = tmpFd->next;
00408       if (tmpFd->next)
00409         tmpFd->next->prev = tmpFd->prev;
00410 
00411       if (tmpFd == fdTable)
00412         fdTable = tmpFd->next;
00413 
00414       systemVitals->openFiles--;
00415       spinUnlock(&fdTable_lock);
00416         if(tmpFd->buffer != NULL)
00417                 kfree(tmpFd->buffer);
00418       kfree(tmpFd);
00419       return(0x0);      
00420       }
00421     }
00422   
00423   spinUnlock(&fdTable_lock);
00424   return(0x1);
00425   }
00426 
00427 /* UBU */
00428 
00429 /************************************************************************
00430 
00431 Function: void sysMkDir(const char *path)
00432 Description: This Will Create A New Directory
00433 Notes:
00434 
00435 ************************************************************************/
00436 void sysMkDir(const char *path) {
00437   fileDescriptor *tmpFD = 0x0; 
00438   char tmpDir[1024];
00439   char rootPath[256];
00440   char *dir = 0x0;//UBU*mountPoint = 0x0;
00441   char *tmp = 0x0;
00442   rootPath[0] = '\0';
00443   dir = (char *)path; 
00444 
00445   if (strstr(path,":") == 0x0) {
00446     sprintf(tmpDir,"%s%s",_current->oInfo.cwd,path);
00447     dir = (char *)&tmpDir;
00448     }
00449   while (strstr(dir,"/")) {
00450     if (rootPath[0] == 0x0)
00451       sprintf(rootPath,"%s/",strtok(dir,"/"));
00452     else
00453       sprintf(rootPath,"%s%s/",rootPath,strtok(dir,"/"));
00454     tmp = strtok(NULL,"\n");
00455     dir = tmp;
00456     }
00457 
00458   //kprintf("rootPath: [%s]\n",rootPath);
00459   tmpFD = fopen(rootPath,"rb");
00460 
00461   if (tmpFD->mp == 0x0) {
00462     kprintf("Invalid Mount Point\n");
00463     }
00464   tmpFD->mp->fs->vfsMakeDir(dir,tmpFD);
00465 
00466   fclose(tmpFD);
00467 
00468   return;
00469   }
00470 
00471 
00472 /************************************************************************
00473 
00474 Function: int unlink(const char *node)
00475 Description: This will unlink a file
00476 Notes:
00477 
00478 ************************************************************************/
00479 
00480 int unlink(const char *node) {
00481   char *path = 0x0,*mountPoint = 0x0;
00482   struct vfs_mountPoint *mp = 0x0;
00483 
00484   path = (char *)strtok((char *)node,"@");
00485   mountPoint = strtok(NULL,"\n");
00486   if (mountPoint == 0x0) {
00487     mp = vfs_findMount("sys"); /* _current->oInfo.container; */
00488     }
00489   else {
00490     mp = vfs_findMount(mountPoint);
00491     }
00492   if (mp == 0x0) {
00493     //kpanic("Mount Point Bad");
00494     return(0x0);
00495     }
00496   mp->fs->vfsUnlink(path,mp);
00497   return(0x0);
00498   }
00499 
00500 
00501 /***
00502  END
00503  ***/
00504 

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7