Subversion Repositories Kolibri OS

Rev

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

  1. /* read.c -- read bytes from a input device.
  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 <errno.h>
  16. #include <unistd.h>
  17. #include "io.h"
  18.  
  19. #undef erro
  20. extern int errno;
  21.  
  22. ssize_t read(int fd, void *buf, size_t cnt)
  23. {
  24.     _ssize_t ret;
  25.  
  26.     _ssize_t  read_len, total_len;
  27.     unsigned  reduce_idx, finish_idx;
  28.     unsigned  iomode_flags;
  29.     char     *buffer = buf;
  30.     int       rc;
  31.     int       h;
  32.     unsigned amount_read;
  33.     int err;
  34.  
  35.     __io_handle *ioh;
  36.  
  37.     if( (fd < 0) || (fd >=64) )
  38.     {
  39.         errno = EBADF;
  40.         return -1;
  41.     };
  42.  
  43.     ioh = &__io_tab[fd];
  44.  
  45.     iomode_flags = ioh->mode;
  46.  
  47.     if( iomode_flags == 0 )
  48.     {
  49.         errno = EBADF;
  50.         return( -1 );
  51.     }
  52.  
  53.     if( !(iomode_flags & _READ) )
  54.     {
  55.         errno = EACCES;
  56.         return( -1 );
  57.     }
  58.  
  59.     if( iomode_flags & _BINARY )   /* if binary mode */
  60.     {
  61.         err = ioh->read(ioh->name, buffer, ioh->offset, cnt, &amount_read);
  62.         ioh->offset+= amount_read;
  63.         total_len  = amount_read;
  64.  
  65.         if(err)
  66.             if ( amount_read == 0)
  67.                 return (-1);
  68.     }
  69.     else
  70.     {
  71.         total_len = 0;
  72.         read_len = cnt;
  73.         do
  74.         {
  75.             err=ioh->read(ioh->name,buffer, ioh->offset, cnt, &amount_read);
  76.             ioh->offset+=amount_read;
  77.  
  78.             if( amount_read == 0 )
  79.                 break;                   /* EOF */
  80.  
  81.             reduce_idx = 0;
  82.             finish_idx = reduce_idx;
  83.             for( ; reduce_idx < amount_read; ++reduce_idx )
  84.             {
  85.                 if( buffer[ reduce_idx ] == 0x1a )     /* EOF */
  86.                 {
  87.                     lseek(fd, ((long)reduce_idx - (long)amount_read)+1L, SEEK_CUR );
  88.                     total_len += finish_idx;
  89.                     return( total_len );
  90.                 }
  91.                 if( buffer[ reduce_idx ] != '\r' )
  92.                 {
  93.                     buffer[ finish_idx++ ] = buffer[ reduce_idx ];
  94.                 };
  95.             }
  96.  
  97.             total_len += finish_idx;
  98.             buffer += finish_idx;
  99.             read_len -= finish_idx;
  100.             if( iomode_flags & _ISTTY )
  101.             {
  102.                 break;
  103.             }
  104.         } while( read_len != 0 );
  105.     }
  106.     return( total_len );
  107. }
  108.