Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /* Reentrant versions of read system call. */
  2.  
  3. #include <reent.h>
  4. #include <unistd.h>
  5. #include <_syslist.h>
  6. #include <errno.h>
  7.  
  8. /* Some targets provides their own versions of this functions.  Those
  9.    targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS.  */
  10.  
  11. #ifdef _REENT_ONLY
  12. #ifndef REENTRANT_SYSCALLS_PROVIDED
  13. #define REENTRANT_SYSCALLS_PROVIDED
  14. #endif
  15. #endif
  16.  
  17. #ifndef REENTRANT_SYSCALLS_PROVIDED
  18.  
  19. /* We use the errno variable used by the system dependent layer.  */
  20.  
  21. /*
  22. FUNCTION
  23.         <<_read_r>>---Reentrant version of read
  24.  
  25. INDEX
  26.         _read_r
  27.  
  28. ANSI_SYNOPSIS
  29.         #include <reent.h>
  30.         _ssize_t _read_r(struct _reent *<[ptr]>,
  31.                          int <[fd]>, void *<[buf]>, size_t <[cnt]>);
  32.  
  33. TRAD_SYNOPSIS
  34.         #include <reent.h>
  35.         _ssize_t _read_r(<[ptr]>, <[fd]>, <[buf]>, <[cnt]>)
  36.         struct _reent *<[ptr]>;
  37.         int <[fd]>;
  38.         char *<[buf]>;
  39.         size_t <[cnt]>;
  40.  
  41. DESCRIPTION
  42.         This is a reentrant version of <<read>>.  It
  43.         takes a pointer to the global data block, which holds
  44.         <<errno>>.
  45. */
  46.  
  47.  
  48. extern unsigned  __NFiles;
  49.  
  50. #define _READ   0x0001  /* file opened for reading */
  51. #define _BINARY 0x0040  /* file is binary, skip CRLF processing */
  52. #define _ISTTY  0x2000  /* is console device */
  53.  
  54. #define __handle_check( __h, __r )                \
  55.         if( (__h) < 0  ||  (__h) > __NFiles ) {   \
  56.            ptr->_errno =  EBADF;                  \
  57.            return( __r );                         \
  58.         }
  59.  
  60. _ssize_t
  61. _DEFUN (_read, (fd, buf, cnt),
  62.      int fd _AND
  63.      _PTR buf _AND
  64.      size_t cnt)
  65. {
  66.  
  67.     return _read_r( _REENT, fd, buf, cnt);
  68. }
  69.  
  70. _ssize_t
  71. _DEFUN (_read_r, (ptr, fd, buf, cnt),
  72.      struct _reent *ptr _AND
  73.      int fd _AND
  74.      _PTR buf _AND
  75.      size_t cnt)
  76. {
  77.     _ssize_t ret;
  78.  
  79.     _ssize_t  read_len, total_len;
  80.     unsigned  reduce_idx, finish_idx;
  81.     unsigned  iomode_flags;
  82.     char     *buffer = buf;
  83.     int       rc;
  84.     int       h;
  85.     unsigned amount_read;
  86.     int err;
  87.  
  88.     __file_handle *fh;
  89.  
  90.     __handle_check( fd, -1 );
  91.     __ChkTTYIOMode( fd );
  92.     iomode_flags = __GetIOMode( fd );
  93.     if( iomode_flags == 0 )
  94.     {
  95.         ptr->_errno = EBADF;
  96.         return( -1 );
  97.     }
  98.     if( !(iomode_flags & _READ) )
  99.     {
  100.         ptr->_errno = EACCES;      /* changed from EBADF to EACCES 23-feb-89 */
  101.         return( -1 );
  102.     }
  103.  
  104.     fh = (__file_handle*) __getOSHandle( fd );
  105.  
  106.     if( iomode_flags & _BINARY )   /* if binary mode */
  107.     {
  108.         err = read_file(fh->name, buffer, fh->offset, cnt, &amount_read);
  109.         fh->offset+= amount_read;
  110.         total_len  = amount_read;
  111.  
  112.         if(err)
  113.             if ( amount_read == 0)
  114.                 return (-1);
  115.     }
  116.     else
  117.     {
  118.         total_len = 0;
  119.         read_len = cnt;
  120.         do
  121.         {
  122.             err=read_file(fh->name,buffer, fh->offset, cnt, &amount_read);
  123.             fh->offset+=amount_read;
  124.  
  125.             if( amount_read == 0 )
  126.                 break;                   /* EOF */
  127.  
  128.             reduce_idx = 0;
  129.             finish_idx = reduce_idx;
  130.             for( ; reduce_idx < amount_read; ++reduce_idx )
  131.             {
  132.                 if( buffer[ reduce_idx ] == 0x1a )     /* EOF */
  133.                 {
  134.                     _lseek_r(ptr, fd, ((long)reduce_idx - (long)amount_read)+1L,
  135.                            SEEK_CUR );
  136.                     total_len += finish_idx;
  137.                     return( total_len );
  138.                 }
  139.                 if( buffer[ reduce_idx ] != '\r' )
  140.                 {
  141.                     buffer[ finish_idx++ ] = buffer[ reduce_idx ];
  142.                 };
  143.             }
  144.  
  145.             total_len += finish_idx;
  146.             buffer += finish_idx;
  147.             read_len -= finish_idx;
  148.             if( iomode_flags & _ISTTY )
  149.             {
  150.                 break;  /* 04-feb-88, FWC */
  151.             }
  152.         } while( read_len != 0 );
  153.     }
  154.     return( total_len );
  155. }
  156.  
  157.  
  158. _ssize_t
  159. _DEFUN (read, (fd, buf, cnt),
  160.      int fd _AND
  161.      _PTR buf _AND
  162.      size_t cnt)
  163. {
  164.  
  165.     return _read_r(_REENT, fd, buf, cnt);
  166. };
  167.  
  168. #endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */
  169.