home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / IO / READ.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  2.5 KB  |  89 lines

  1. /* read.c (emx+gcc) -- Copyright (c) 1990-1993 by Eberhard Mattes */
  2.  
  3. #include <sys/emx.h>
  4. #include <io.h>
  5. #include <errno.h>
  6. #include <string.h>
  7. #include <fcntl.h>
  8.  
  9. /* Read nbyte characters, use lookahead, if available. This is simple unless */
  10. /* O_NDELAY is in effect. */
  11.  
  12. static int read_lookahead (int handle, void *buf, size_t nbyte)
  13. {
  14.   int i, n, saved_errno;
  15.   char *dst;
  16.  
  17.   i = 0; dst = buf; saved_errno = errno;
  18.   if (nbyte > 0 && _lookahead[handle] != -1)
  19.     {
  20.       *dst = (char)_lookahead[handle];
  21.       _lookahead[handle] = -1;
  22.       ++i; --nbyte;
  23.     }
  24.   n = __read (handle, dst+i, nbyte);
  25.   if (n == -1)
  26.     {
  27.       if (errno == EAGAIN && i > 0)           /* lookahead and O_NDELAY */
  28.         {
  29.           errno = saved_errno;                /* hide EAGAIN */
  30.           return (i);                         /* and be successful */
  31.         }
  32.       return (-1);
  33.     }
  34.   return (i + n);
  35. }
  36.  
  37.  
  38. int read (int handle, void *buf, size_t nbyte)
  39. {
  40.   int n;
  41.   size_t j;
  42.   char *dst, c;
  43.  
  44.   if (handle < 0 || handle >= _nfiles)
  45.     {
  46.       errno = EBADF;
  47.       return (-1);
  48.     }
  49.   if (nbyte > 0 && (_files[handle] & F_EOF))
  50.     return (0);
  51.   dst = buf;
  52.   n = read_lookahead (handle, dst, nbyte);
  53.   if (n == -1)
  54.     return (-1);
  55.   if ((_files[handle] & O_TEXT) && !(_files[handle] & F_TERMIO) && n > 0)
  56.     {
  57.       /* special processing for text mode */
  58.       if (!(_files[handle] & (F_NPIPE|F_DEV)) && dst[n-1] == 0x1a &&
  59.           eof (handle))
  60.         {
  61.           /* remove last Ctrl-Z in text files */
  62.           --n;
  63.           _files[handle] |= F_EOF;
  64.           if (n == 0)
  65.             return (0);
  66.         }
  67.       if (n == 1 && dst[0] == '\r')
  68.         {
  69.           /* This is the tricky case as we are not allowed to decrement n  */
  70.           /* by one as 0 indicates end of file. We have to use look ahead. */
  71.           int saved_errno = errno;
  72.           j = read_lookahead (handle, &c, 1); /* look ahead */
  73.           if (j == -1 && errno == EAGAIN)
  74.             {
  75.               _lookahead[handle] = dst[0];
  76.               return (-1);
  77.             }
  78.           errno = saved_errno;                /* hide error */
  79.           if (j == 1 && c == '\n')            /* CR/LF ? */
  80.             dst[0] = '\n';                    /* yes -> replace with LF */
  81.           else
  82.             _lookahead[handle] = c;           /* no -> save the 2nd char */
  83.         }
  84.       else if (_crlf (dst, n, &n))            /* CR/LF conversion */
  85.         _lookahead[handle] = '\r';            /* buffer ends with CR */
  86.     }
  87.   return (n);
  88. }
  89.