Subversion Repositories Kolibri OS

Rev

Rev 4921 | Rev 5215 | 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. //  printf("%s %s\n", __FUNCTION__, buf);
  132.  
  133.     err = get_fileinfo(buf, &info);
  134.  
  135.     if( flags & O_EXCL &&
  136.         flags & O_CREAT )
  137.     {
  138.         if( !err )
  139.         {
  140.             errno = EEXIST;
  141.             return (-1);
  142.         };
  143.     }
  144.  
  145.     if( err )
  146.     {
  147.         if(flags & O_CREAT)
  148.             err=create_file(buf);
  149.         if( err )
  150.         {
  151.             errno = EACCES;
  152.             return -1;
  153.         };
  154.     };
  155.  
  156.     if( flags & O_TRUNC )
  157.         set_file_size(buf, 0);
  158.  
  159.     ioh = &__io_tab[hid];
  160.  
  161.     rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR );
  162.  
  163.     iomode = 0;
  164.     offset = 0;
  165.  
  166.     if( rwmode == O_RDWR )
  167.         iomode |= _READ | _WRITE;
  168.     else if( rwmode == O_RDONLY)
  169.         iomode |= _READ;
  170.     else if( rwmode == O_WRONLY)
  171.         iomode |= _WRITE;
  172.  
  173.     if( flags & O_APPEND )
  174.     {
  175.         iomode |= _APPEND;
  176.         offset = info.size;
  177.     };
  178.  
  179.     if( flags & (O_BINARY|O_TEXT) )
  180.     {
  181.         if( flags & O_BINARY )
  182.             iomode |= _BINARY;
  183.     } else
  184.         iomode |= _BINARY;
  185.  
  186.     ioh->name   = strdup(buf);
  187.     ioh->offset = offset;
  188.     ioh->mode   = iomode;
  189.     ioh->read   = read_file;
  190.     ioh->write  = write_file;
  191.  
  192. //    printf("%s %s\n", __FUNCTION__, ioh->name);
  193.  
  194.     return hid;
  195. };
  196.  
  197.  
  198.