Subversion Repositories Kolibri OS

Rev

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