Subversion Repositories Kolibri OS

Rev

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

  1. /* write.c -- write bytes to an output 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 <alloca.h>
  18. #include <sys/kos_io.h>
  19. #include "io.h"
  20.  
  21. #undef erro
  22. extern int errno;
  23.  
  24.  
  25. #if 0
  26. #define PAD_SIZE 512
  27.  
  28. static int zero_pad(int handle )           /* 09-jan-95 */
  29. /*******************************/
  30. {
  31.     int         rc;
  32.     long        curPos, eodPos;
  33.     long        bytesToWrite;
  34.     unsigned    writeAmt;
  35.     char        zeroBuf[PAD_SIZE];
  36.  
  37.     // Pad with zeros due to lseek() past EOF (POSIX)
  38.     curPos = lseek( handle, 0L, SEEK_CUR );   /* current offset */
  39.     if( curPos == -1 )
  40.         return( -1 );
  41.     eodPos = lseek( handle, 0L, SEEK_END );   /* end of data offset */
  42.     if( eodPos == -1 )
  43.         return( -1 );
  44.  
  45.     if( curPos > eodPos ) {
  46.         bytesToWrite = curPos - eodPos;         /* amount to pad by */
  47.  
  48.         if( bytesToWrite > 0 ) {                /* only write if needed */
  49.             memset( zeroBuf, 0x00, PAD_SIZE );  /* zero out a buffer */
  50.             do {                                /* loop until done */
  51.                 if( bytesToWrite > PAD_SIZE )
  52.                     writeAmt = 512;
  53.                 else
  54.                     writeAmt = (unsigned)bytesToWrite;
  55.                 rc = _write_r(ptr, handle, zeroBuf, writeAmt );
  56.                 if( rc < 0 )
  57.                     return( rc );
  58.                 bytesToWrite -= writeAmt;       /* more bytes written */
  59.             } while( bytesToWrite != 0 );
  60.         }
  61.     } else {
  62.         curPos = _lseek_r( ptr, handle, curPos, SEEK_SET );
  63.         if( curPos == -1 ) {
  64.             return( -1 );
  65.         }
  66.     }
  67.  
  68.     return( 0 );                /* return success code */
  69. }
  70. #endif
  71.  
  72. static int os_write(int handle, const void *buffer, unsigned len, unsigned *amt )
  73. {
  74.     __io_handle *ioh;
  75.     int          rc;
  76.  
  77.     rc   = 0;
  78.     *amt = 0;
  79.  
  80.     ioh = &__io_tab[handle];
  81.  
  82.     rc = ioh->write(ioh->name,(const void*)buffer,ioh->offset,len,amt);
  83.  
  84.     ioh->offset+= *amt;
  85.  
  86.     if( *amt && *amt != len )
  87.     {
  88.         rc = ENOSPC;
  89.         errno = rc;
  90.     }
  91.  
  92.     return( rc );
  93. }
  94.  
  95. /*
  96.  * write -- write bytes to the serial port. Ignore fd, since
  97.  *          stdout and stderr are the same. Since we have no filesystem,
  98.  *          open will only return an error.
  99.  */
  100. ssize_t write(int fd, const void *buffer, size_t cnt)
  101. {
  102.     _ssize_t      ret;
  103.     unsigned int  iomode_flags;
  104.     unsigned      len_written, i, j;
  105.     int           rc2;
  106.     char         *buf;
  107.  
  108.     __io_handle  *ioh;
  109.  
  110.     if( (fd < 0) || (fd >=64) )
  111.     {
  112.         errno = EBADF;
  113.         return -1;
  114.     };
  115.  
  116.     ioh = &__io_tab[fd];
  117.  
  118.     iomode_flags = ioh->mode;
  119.  
  120.     if( iomode_flags == 0 )
  121.     {
  122.         errno = EBADF;
  123.         return( -1 );
  124.     }
  125.  
  126.     if( !(iomode_flags & _WRITE) )
  127.     {
  128.         errno = EACCES ;
  129.         return( -1 );
  130.     }
  131.  
  132.     if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) )
  133.     {
  134.         ioh->offset = lseek(fd, 0L, SEEK_END );   /* end of data offset */
  135.     }
  136.  
  137.     len_written = 0;
  138.     rc2 = 0;
  139.  
  140.     // Pad the file with zeros if necessary
  141.     if( iomode_flags & _FILEEXT )
  142.     {
  143.         // turn off file extended flag
  144.         ioh->mode = iomode_flags & (~_FILEEXT);
  145.  
  146.         // It is not required to pad a file with zeroes on an NTFS file system;
  147.         // unfortunately it is required on FAT (and probably FAT32). (JBS)
  148. //        rc2 = zero_pad( ptr, fd );
  149.     }
  150.  
  151.     if( rc2 == 0 )
  152.     {
  153.         if( iomode_flags & _BINARY ) {  /* if binary mode */
  154.             rc2 = os_write(fd, buffer, cnt, &len_written );
  155.             /* end of binary mode part */
  156.         } else {    /* text mode */
  157.  
  158.             int buf_size = 512;
  159.  
  160.             buf = (char*)alloca( buf_size );
  161.  
  162.             j = 0;
  163.             for( i = 0; i < cnt; )
  164.             {
  165.                 if( ((const char*)buffer)[i] == '\n' )
  166.                 {
  167.                     buf[j] = '\r';
  168.                     ++j;
  169.                     if( j == buf_size )
  170.                     {
  171.                         rc2 = os_write(fd, buf, buf_size, &j );
  172.                         if( rc2 == -1 )
  173.                             break;
  174.                         len_written += j;
  175.                         if( rc2 == ENOSPC )
  176.                             break;
  177.                         len_written = i;
  178.                         j = 0;
  179.                     }
  180.                 }
  181.                 buf[j] = ((const char*)buffer)[i];
  182.                 ++i;
  183.                 ++j;
  184.                 if( j == buf_size ) {
  185.                     rc2 = os_write(fd, buf, buf_size, &j );
  186.                     if( rc2 == -1 )
  187.                         break;
  188.                     len_written += j;
  189.                     if( rc2 == ENOSPC )
  190.                         break;
  191.                     len_written = i;
  192.                     j = 0;
  193.                 }
  194.             }
  195.             if( j ) {
  196.                 rc2 = os_write(fd, buf, j, &i );
  197.                 if( rc2 == ENOSPC ) {
  198.                     len_written += i;
  199.                 } else {
  200.                     len_written = cnt;
  201.                 }
  202.             }
  203.             /* end of text mode part */
  204.         }
  205.     }
  206.  
  207.     if( rc2 == -1 ) {
  208.         return( rc2 );
  209.     } else {
  210.         return( len_written );
  211.     }
  212.  
  213.   return 0;
  214. }
  215.  
  216.