Subversion Repositories Kolibri OS

Rev

Rev 5198 | Rev 6744 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* open.c -- open a file.
  2.  *
  3.  * Copyright (c) 1995 Cygnus Support
  4.  *
  5.  * The authors hereby grant permission to use, copy, modify, distribute,
  6.  * and license this software and its documentation for any purpose, provided
  7.  * that existing copyright notices are retained in all copies and that this
  8.  * notice is included verbatim in any distributions. No written agreement,
  9.  * license, or royalty fee is required for any of the authorized uses.
  10.  * Modifications to this software may be copyrighted by their authors
  11.  * and need not follow the licensing terms described here, provided that
  12.  * the new terms are clearly indicated on the first page of each file where
  13.  * they apply.
  14.  */
  15. #include <fcntl.h>
  16. #include <errno.h>
  17. #include <string.h>
  18. #include <sys/kos_io.h>
  19. #include "glue.h"
  20. #include "io.h"
  21.  
  22. #undef erro
  23. extern int errno;
  24.  
  25. static inline int is_slash(char c)
  26. {
  27.     return c=='/' || c=='\\';
  28. }
  29.  
  30. void fix_slashes(char * in,char * out)
  31. {
  32.     int slash_count;
  33.  
  34.     for(slash_count=1;in && out && *in;in++)
  35.     {
  36.         if(is_slash(*in))
  37.         {
  38.             slash_count++;
  39.             continue;
  40.         }
  41.         else
  42.         {
  43.             if(slash_count)
  44.             {
  45.                 slash_count=0;
  46.                 *out++='/';
  47.             }
  48.             *out++=*in;
  49.         }
  50.     }
  51.     *out='\0';
  52. };
  53.  
  54.  
  55. void buildpath(char *buf, const char* file)
  56. {
  57.     char *ptr;
  58.  
  59.     ptr = buf + strlen(buf);
  60.  
  61.     while (*file)
  62.     {
  63.         if (file[0] == '.' && file[1] == 0)
  64.             break;
  65.  
  66.         if (file[0] == '.' && file[1] == '/')
  67.         {
  68.             file+=2;
  69.             continue;
  70.         };
  71.  
  72.         if (file[0] == '.' && file[1] == '.' &&
  73.             (file[2] == 0 || file[2] == '/'))
  74.         {
  75.             while (ptr > buf && ptr[-1] != '/')
  76.                 --ptr;
  77.             file+=2;
  78.             if (*file == 0)
  79.                 break;
  80.             ++file;
  81.             continue;
  82.         }
  83.         *ptr++ = '/';
  84.         if (*file == '/')
  85.             ++file;
  86.         while (*file && *file!='/')
  87.             *ptr++ = *file++;
  88.     }
  89.     *ptr = 0;
  90. };
  91.  
  92. static char *getccwd(char *buf, size_t size)
  93. {
  94.     int bsize;
  95.     __asm__ __volatile__(
  96.     "int $0x40"
  97.     :"=a"(bsize)
  98.     :"a"(30),"b"(2),"c"(buf), "d"(size)
  99.     :"memory");
  100.  
  101.     return buf;
  102. };
  103.  
  104. int open (const char * filename, int flags, ...)
  105. {
  106.     char buf[1024];
  107.  
  108.     __io_handle *ioh;
  109.     fileinfo_t   info;
  110.     int iomode, rwmode, offset;
  111.     int hid;
  112.     int err;
  113.  
  114.     hid = __io_alloc();
  115.     if(hid < 0)
  116.     {
  117.         errno = EMFILE;
  118.         return (-1);
  119.     };
  120.  
  121.     if (filename[0]=='/')
  122.     {
  123.         strcpy(buf,filename);
  124.     }
  125.     else
  126.     {
  127.         getccwd(buf, 1024);
  128.         buildpath(buf, filename);
  129.     }
  130.  
  131.     err = get_fileinfo(buf, &info);
  132.  
  133.     if( flags & O_EXCL &&
  134.         flags & O_CREAT )
  135.     {
  136.         if( !err )
  137.         {
  138.             errno = EEXIST;
  139.             return (-1);
  140.         };
  141.     }
  142.  
  143.     if( err )
  144.     {
  145.         if(flags & O_CREAT)
  146.             err=create_file(buf);
  147.         if( err )
  148.         {
  149.             errno = EACCES;
  150.             return -1;
  151.         };
  152.     };
  153.  
  154.     if( flags & O_TRUNC )
  155.         set_file_size(buf, 0);
  156.  
  157.     ioh = &__io_tab[hid];
  158.  
  159.     rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR );
  160.  
  161.     iomode = 0;
  162.     offset = 0;
  163.  
  164.     if( rwmode == O_RDWR )
  165.         iomode |= _READ | _WRITE;
  166.     else if( rwmode == O_RDONLY)
  167.         iomode |= _READ;
  168.     else if( rwmode == O_WRONLY)
  169.         iomode |= _WRITE;
  170.  
  171.     if( flags & O_APPEND )
  172.     {
  173.         iomode |= _APPEND;
  174.         offset = info.size;
  175.     };
  176.  
  177.     if( flags & (O_BINARY|O_TEXT) )
  178.     {
  179.         if( flags & O_BINARY )
  180.             iomode |= _BINARY;
  181.     } else
  182.         iomode |= _BINARY;
  183.  
  184.     ioh->name   = strdup(buf);
  185.     ioh->offset = offset;
  186.     ioh->mode   = iomode;
  187.     ioh->read   = read_file;
  188.     ioh->write  = write_file;
  189.  
  190.     return hid;
  191. };
  192.  
  193.  
  194.