Subversion Repositories Kolibri OS

Rev

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