home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / posix / unistd / write.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-15  |  2.0 KB  |  84 lines

  1. /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
  2. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  3. #include <libc/stubs.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <go32.h>
  7. #include <dpmi.h>
  8. #include <io.h>
  9. #include <errno.h>
  10. #include <libc/farptrgs.h>
  11.  
  12. #include <libc/dosio.h>
  13. #include <libc/ttyprvt.h>
  14.  
  15. #define tblen _go32_info_block.size_of_transfer_buffer
  16.  
  17. int (*__libc_write_termios_hook)(int handle, const void *buffer, size_t count,
  18.                  ssize_t *rv) = NULL;
  19.  
  20. ssize_t
  21. write(int handle, const void* buffer, size_t count)
  22. {
  23.   const char *buf = (const char *)buffer;
  24.   int bytes_in_tb = 0;
  25.   int offset_into_buf = 0;
  26.   __dpmi_regs r;
  27.  
  28.   /* termios special hook */
  29.   if (__libc_write_termios_hook != NULL)
  30.     {
  31.       ssize_t rv;
  32.       if (__libc_write_termios_hook(handle, buffer, count, &rv) != 0)
  33.         return rv;
  34.     }
  35.  
  36.   if (count == 0)
  37.     return 0; /* POSIX.1 requires this */
  38.  
  39.   if(__file_handle_modes[handle] & O_BINARY)
  40.     return _write(handle, buf, count);
  41.  
  42.   while (offset_into_buf < count)
  43.   {
  44.     _farsetsel(_dos_ds);
  45.     while (bytes_in_tb < tblen && offset_into_buf < count)
  46.     {
  47.       if (buf[offset_into_buf] == '\n')
  48.       {
  49.     if (bytes_in_tb == tblen - 1)
  50.       break; /* can't fit two more */
  51.     _farnspokeb(__tb + bytes_in_tb, '\r');
  52.     bytes_in_tb++;
  53.       }
  54.       _farnspokeb(__tb + bytes_in_tb, buf[offset_into_buf]);
  55.       bytes_in_tb++;
  56.       offset_into_buf++;
  57.     }
  58.  
  59.     /* we now have a transfer buf stuffed with data; write it out */
  60.     r.x.ax = 0x4000;
  61.     r.x.bx = handle;
  62.     r.x.cx = bytes_in_tb;
  63.     r.x.dx = __tb & 15;
  64.     r.x.ds = __tb / 16;
  65.     __dpmi_int(0x21, &r);
  66.     if (r.x.flags & 1)
  67.     {
  68.       errno = __doserr_to_errno(r.x.ax);
  69.       return -1;
  70.     }
  71.  
  72.     if (r.x.ax < bytes_in_tb) /* disk full? */
  73.     {
  74.       offset_into_buf += r.x.ax;
  75.       errno = ENOSPC;
  76.       return count - offset_into_buf;
  77.     }
  78.  
  79.     bytes_in_tb = 0;
  80.   }
  81.  
  82.   return count;    /* Don't return count with CR's (TC) */
  83. }
  84.