Subversion Repositories Kolibri OS

Rev

Rev 9346 | 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/ksys.h>
  19.  
  20. #include "glue.h"
  21. #include "io.h"
  22.  
  23. #undef errno
  24. extern int errno;
  25.  
  26. extern int write_file(const char *path,const void *buff,
  27.                       size_t offset, size_t count, size_t *writes);
  28.  
  29. extern int read_file(const char *path, void *buff,
  30.                size_t offset, size_t count, size_t *reads);
  31.  
  32. static inline int is_slash(char c)
  33. {
  34.     return c=='/' || c=='\\';
  35. }
  36.  
  37. void fix_slashes(char * in,char * out)
  38. {
  39.     int slash_count;
  40.  
  41.     for(slash_count=1;in && out && *in;in++)
  42.     {
  43.         if(is_slash(*in))
  44.         {
  45.             slash_count++;
  46.             continue;
  47.         }
  48.         else
  49.         {
  50.             if(slash_count)
  51.             {
  52.                 slash_count=0;
  53.                 *out++='/';
  54.             }
  55.             *out++=*in;
  56.         }
  57.     }
  58.     *out='\0';
  59. }
  60.  
  61.  
  62. void buildpath(char *buf, const char* file)
  63. {
  64.     char *ptr;
  65.  
  66.     ptr = buf + strlen(buf);
  67.  
  68.     while (*file)
  69.     {
  70.         if (file[0] == '.' && file[1] == 0)
  71.             break;
  72.  
  73.         if (file[0] == '.' && file[1] == '/')
  74.         {
  75.             file+=2;
  76.             continue;
  77.         };
  78.  
  79.         if (file[0] == '.' && file[1] == '.' &&
  80.             (file[2] == 0 || file[2] == '/'))
  81.         {
  82.             while (ptr > buf && ptr[-1] != '/')
  83.                 --ptr;
  84.             file+=2;
  85.             if (*file == 0)
  86.                 break;
  87.             ++file;
  88.             //continue;
  89.             goto __do_until_slash;
  90.         }
  91.         *ptr++ = '/';
  92. __do_until_slash:
  93.         if (*file == '/')
  94.             ++file;
  95.         while (*file && *file!='/')
  96.             *ptr++ = *file++;
  97.     }
  98.     *ptr = 0;
  99. }
  100.  
  101. int open (const char * filename, int flags, ...)
  102. {
  103.     char buf[1024];
  104.  
  105.     __io_handle *ioh;
  106.     ksys_file_info_t info;
  107.     int iomode, rwmode, offset;
  108.     int hid;
  109.     int err;
  110.  
  111.     hid = __io_alloc();
  112.     if(hid < 0)
  113.     {
  114.         errno = EMFILE;
  115.         __io_free(hid);
  116.         return (-1);
  117.     };
  118.  
  119.     if (filename[0]=='/')
  120.     {
  121.         strcpy(buf,filename);
  122.     }
  123.     else
  124.     {
  125.         _ksys_getcwd(buf, 1024);
  126.         buildpath(buf, filename);
  127.     }
  128.  
  129.     err = _ksys_file_info(buf, &info);
  130.  
  131.     if (flags & O_EXCL &&
  132.         flags & O_CREAT )
  133.     {
  134.         if (!err)
  135.         {
  136.             errno = EEXIST;
  137.             __io_free(hid);
  138.             return (-1);
  139.         }
  140.     }
  141.  
  142.     if (err)
  143.     {
  144.         if(flags & O_CREAT)
  145.             err = _ksys_file_create(buf).status;
  146.         if(err)
  147.         {
  148.             errno = EACCES;
  149.             __io_free(hid);
  150.             return -1;
  151.         };
  152.     };
  153.  
  154.     if (flags & O_TRUNC)
  155.         _ksys_file_set_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.     }
  182.     else
  183.     {
  184.         iomode |= _BINARY;
  185.     }
  186.  
  187.     ioh->name   = strdup(buf);
  188.     ioh->offset = offset;
  189.     ioh->mode   = iomode;
  190.     ioh->read   = read_file;
  191.     ioh->write  = write_file;
  192.  
  193.     return hid;
  194. }
  195.