Subversion Repositories Kolibri OS

Rev

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.             goto __do_until_slash;
  83.         }
  84.         *ptr++ = '/';
  85. __do_until_slash:
  86.         if (*file == '/')
  87.             ++file;
  88.         while (*file && *file!='/')
  89.             *ptr++ = *file++;
  90.     }
  91.     *ptr = 0;
  92. };
  93.  
  94. static char *getccwd(char *buf, size_t size)
  95. {
  96.     int bsize;
  97.     __asm__ __volatile__(
  98.     "int $0x40"
  99.     :"=a"(bsize)
  100.     :"a"(30),"b"(2),"c"(buf), "d"(size)
  101.     :"memory");
  102.  
  103.     return buf;
  104. };
  105.  
  106. int open (const char * filename, int flags, ...)
  107. {
  108.     char buf[1024];
  109.  
  110.     __io_handle *ioh;
  111.     fileinfo_t   info;
  112.     int iomode, rwmode, offset;
  113.     int hid;
  114.     int err;
  115.  
  116.     hid = __io_alloc();
  117.     if(hid < 0)
  118.     {
  119.         errno = EMFILE;
  120.         __io_free(hid);
  121.         return (-1);
  122.     };
  123.  
  124.     if (filename[0]=='/')
  125.     {
  126.         strcpy(buf,filename);
  127.     }
  128.     else
  129.     {
  130.         getccwd(buf, 1024);
  131.         buildpath(buf, filename);
  132.     }
  133.  
  134.     err = get_fileinfo(buf, &info);
  135.  
  136.     if( flags & O_EXCL &&
  137.         flags & O_CREAT )
  138.     {
  139.         if( !err )
  140.         {
  141.             errno = EEXIST;
  142.             __io_free(hid);
  143.             return (-1);
  144.         };
  145.     }
  146.  
  147.     if( err )
  148.     {
  149.         if(flags & O_CREAT)
  150.             err=create_file(buf);
  151.         if( err )
  152.         {
  153.             errno = EACCES;
  154.             __io_free(hid);
  155.             return -1;
  156.         };
  157.     };
  158.  
  159.     if( flags & O_TRUNC )
  160.         set_file_size(buf, 0);
  161.  
  162.     ioh = &__io_tab[hid];
  163.  
  164.     rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR );
  165.  
  166.     iomode = 0;
  167.     offset = 0;
  168.  
  169.     if( rwmode == O_RDWR )
  170.         iomode |= _READ | _WRITE;
  171.     else if( rwmode == O_RDONLY)
  172.         iomode |= _READ;
  173.     else if( rwmode == O_WRONLY)
  174.         iomode |= _WRITE;
  175.  
  176.     if( flags & O_APPEND )
  177.     {
  178.         iomode |= _APPEND;
  179.         offset = info.size;
  180.     };
  181.  
  182.     if( flags & (O_BINARY|O_TEXT) )
  183.     {
  184.         if( flags & O_BINARY )
  185.             iomode |= _BINARY;
  186.     } else
  187.         iomode |= _BINARY;
  188.  
  189.     ioh->name   = strdup(buf);
  190.     ioh->offset = offset;
  191.     ioh->mode   = iomode;
  192.     ioh->read   = read_file;
  193.     ioh->write  = write_file;
  194.  
  195.     return hid;
  196. };
  197.  
  198.  
  199.