Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  Handle manager routines.
  28. *
  29. ****************************************************************************/
  30.  
  31. #include <reent.h>
  32. #include <unistd.h>
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <errno.h>
  38. #include <fcntl.h>
  39.  
  40. #define _NFILES   20
  41. #define _DYNAMIC  0x4000 /* FILE is dynamically allocated   */
  42.  
  43. #define _READ   0x0001  /* file opened for reading */
  44. #define _WRITE  0x0002  /* file opened for writing */
  45.  
  46. #define NULL_HANDLE  (int)-1
  47. #define DUMMY_HANDLE (int)-2
  48. #define INVALID_HANDLE_VALUE (int) -1
  49.  
  50. #define _AccessIOB()
  51. #define _ReleaseIOB()
  52.  
  53. #undef __getOSHandle
  54.  
  55. void __ChkTTYIOMode( int handle );
  56.  
  57. void __initPOSIXHandles( void ) __attribute__ ((constructor));
  58.  
  59. void  __grow_iomode( int num );
  60. int   debugwrite(const char *path,const void *buff,
  61.                  size_t offset, size_t count, size_t *writes);
  62.  
  63.  
  64. int _fmode;
  65.  
  66. #define NUM_STD_STREAMS  3
  67. #define _ISTTY           0x2000  /* is console device */
  68.  
  69. unsigned __init_mode[_NFILES] = { /* file mode information (flags) */
  70.         _READ,          /* stdin */
  71.         _WRITE,         /* stdout */
  72.         _WRITE          /* stderr */
  73. };
  74.  
  75. unsigned *__io_mode = __init_mode;      /* initially points to static array */
  76.  
  77. unsigned  __NFiles   = _NFILES;          /* maximum # of files we can open */
  78.  
  79. unsigned  __NHandles = 0;
  80.  
  81. int *__OSHandles = NULL;
  82.  
  83.  
  84. static __file_handle
  85. stdin_handle = {
  86.                     NULL,
  87.                     0,
  88.                     NULL
  89.                 };
  90.  
  91. static __file_handle
  92. stdout_handle =
  93.                 {
  94.                     NULL,
  95.                     0,
  96.                     debugwrite
  97.                 };
  98.  
  99.  
  100. static __file_handle
  101. stderr_handle =
  102.                 {
  103.                     NULL,
  104.                     0,
  105.                     debugwrite
  106.                 };
  107.  
  108.  
  109. unsigned __growPOSIXHandles( unsigned num )
  110. {
  111.     int       *new2;
  112.     unsigned   i;
  113.  
  114.     if( num > __NHandles )
  115.     {
  116.         if( __OSHandles == NULL )
  117.         {
  118.             new2 = malloc( num * sizeof( int ) );
  119.         }
  120.         else
  121.         {
  122.             new2 = realloc( __OSHandles, num * sizeof( int ) );
  123.         }
  124.         if( new2 == NULL )
  125.         {
  126. //            __set_errno( ENOMEM );
  127.             num = __NHandles;
  128.         }
  129.         else
  130.         {
  131.             for( i = __NHandles; i < num; i++ )
  132.             {
  133.                 new2[ i ] = NULL_HANDLE;
  134.             }
  135.             __OSHandles = new2;
  136.             __NHandles = num;
  137.         }
  138.     }
  139.     return( __NHandles );
  140. }
  141.  
  142. int __allocPOSIXHandle( int hdl )
  143. {
  144.     int i;
  145.  
  146.     for( i = 0; i < __NHandles; i++ )
  147.     {
  148.         if( __OSHandles[i] == NULL_HANDLE ) break;
  149.     }
  150.     if( i >= __NHandles )
  151.     {
  152.                                 // 20 -> (20+10+1) -> 31
  153.                                 // 31 -> (31+15+1) -> 47
  154.                                 // 47 -> (47+23+1) -> 71
  155.         __growPOSIXHandles( i + (i >> 1) + 1 );
  156.         // keep iomode array in sync
  157.         if( __NHandles > __NFiles ) __grow_iomode( __NHandles );
  158.         for( ; i < __NHandles; i++ )
  159.         {
  160.             if( __OSHandles[i] == NULL_HANDLE ) break;
  161.         }
  162.     }
  163.     if( i >= __NHandles )
  164.     {
  165.         i = -1;
  166.     } else {
  167.         __OSHandles[i] = hdl;
  168.     }
  169.     return( i );
  170. }
  171.  
  172. void __freePOSIXHandle( int hid )
  173. {
  174.     __OSHandles[ hid ] = NULL_HANDLE;
  175. }
  176.  
  177.  
  178. int __getOSHandle( int hid )
  179. {
  180.     return( __OSHandles[ hid ] );
  181. }
  182.  
  183.  
  184. int __setOSHandle( unsigned hid, int hdl )
  185. {
  186.     // call the Win32 API for a standard file handle
  187.     switch( hid ) {
  188.         case STDIN_FILENO:
  189. //        SetStdHandle( STD_INPUT_HANDLE, hdl );
  190.         break;
  191.     case STDOUT_FILENO:
  192. //        SetStdHandle( STD_OUTPUT_HANDLE, hdl );
  193.         break;
  194.     case STDERR_FILENO:
  195. //        SetStdHandle( STD_ERROR_HANDLE, hdl );
  196.         break;
  197.     }
  198.     if( hid < __NHandles )
  199.     {
  200.         __OSHandles[ hid ] = hdl;
  201.     }
  202.     else
  203.     {
  204.         hid = (unsigned)-1;     // this should never happen
  205.     }
  206.     return( hid );
  207. }
  208.  
  209. // called from library startup code
  210.  
  211.  
  212. void __initPOSIXHandles( void )
  213. {
  214.     int h;
  215.  
  216.     _fmode = O_BINARY;
  217.  
  218.     __growPOSIXHandles( __NFiles );
  219.  
  220.     h = (int)&stdin_handle;
  221.     __allocPOSIXHandle( h );        // should return 0==STDIN_FILENO
  222.     h = (int)&stdout_handle;
  223.     __allocPOSIXHandle( h );        // should return 1==STDOUT_FILENO
  224.     h = (int)&stderr_handle;
  225.     __allocPOSIXHandle( h );        // should return 3==STDERR_FILENO
  226. }
  227.  
  228. /*
  229. static void __finiPOSIXHandles( void )
  230. {
  231.     if( __OSHandles != NULL ) {
  232.         free( __OSHandles );
  233.         __OSHandles = NULL;
  234.     }
  235.     if( __FakeHandles != NULL )
  236.     {
  237.         int i;
  238.         for( i = 0 ; i < __topFakeHandle ; i++ )
  239.         {
  240.           //  CloseHandle( __FakeHandles[i] );
  241.         }
  242.         free( __FakeHandles );
  243.         __FakeHandles = 0;
  244.     }
  245. }
  246. */
  247.  
  248.  
  249. void __set_handles( int num )
  250. {
  251.     __NHandles = num;
  252. }
  253.  
  254. int _grow_handles( int num )
  255. {
  256.     if( num > __NHandles )
  257.     {
  258.         num = __growPOSIXHandles( num );
  259.  
  260.         if( num > __NFiles ) {
  261.             __grow_iomode( num );   // sets new __NFiles if successful
  262.         }
  263.         __NHandles = num;
  264.     }
  265.     return( __NHandles );
  266. }
  267.  
  268.  
  269.  
  270. static  unsigned _init_NFiles;          // original __NFiles value;
  271.  
  272. void __grow_iomode( int num )
  273. {
  274.     unsigned    *new;
  275.  
  276.     _AccessIOB();
  277.     if( __io_mode == __init_mode )
  278.     {
  279.         _init_NFiles = __NFiles;
  280.         new = (unsigned *) malloc( num * sizeof( unsigned ) );
  281.         if( new != NULL ) {
  282.             memcpy( new, __init_mode, __NFiles * sizeof(unsigned) );
  283.         }
  284.     }
  285.     else
  286.     {
  287.         new = (unsigned *) realloc( __io_mode, num * sizeof( unsigned ) );
  288.     }
  289.     if( new == NULL )
  290.     {
  291. //        __set_errno( ENOMEM );
  292.     }
  293.     else
  294.     {
  295.         memset( &new[__NFiles], 0, (num-__NFiles)*sizeof(unsigned) );
  296.         __io_mode = new;
  297.         __NFiles = num;
  298.     }
  299.     _ReleaseIOB();
  300. }
  301.  
  302. void __shrink_iomode( void )
  303. {
  304.     _AccessIOB();
  305.     // free any malloc'd iomode array
  306.     if( __io_mode != __init_mode )
  307.     {
  308.         free( __io_mode );
  309.         __io_mode = __init_mode;
  310.         __NFiles = _init_NFiles;
  311.     }
  312.     _ReleaseIOB();
  313. }
  314.  
  315. #define _INITIALIZED    _DYNAMIC
  316.  
  317. signed __SetIOMode( int handle, unsigned value )
  318. {
  319.     int         i;
  320.  
  321.     if( handle >= __NFiles )
  322.     {
  323.         i = __NFiles;           // 20 -> (20+10+1) -> 31
  324.                                 // 31 -> (31+15+1) -> 47
  325.                                 // 47 -> (47+23+1) -> 71
  326.         __grow_iomode( i + (i > 1) + 1 );
  327.     }
  328.     if( handle >= __NFiles )
  329.     {
  330.         // return an error indication (errno should be set to ENOMEM)
  331.         return( -1 );
  332.     }
  333.     else
  334.     {
  335.         if( value != 0 )
  336.         {
  337.             __ChkTTYIOMode( handle );
  338.             __io_mode[handle] = value | _INITIALIZED;
  339.         }
  340.         else
  341.         {
  342.             __io_mode[handle] = value;    /* we're closing it; smite _INITIALIZED */
  343.         }
  344.         return( handle );
  345.     }
  346. }
  347.  
  348. int _isatty( int hid )
  349. {
  350.     return( 0 );
  351. }
  352.  
  353. void __ChkTTYIOMode( int handle )
  354. {
  355.     if( handle < NUM_STD_STREAMS && !(__io_mode[handle] & _INITIALIZED) )
  356.     {
  357.         __io_mode[handle] |= _INITIALIZED;
  358.         if( _isatty( handle ) )
  359.         {
  360.             __io_mode[handle] |= _ISTTY;
  361.         }
  362.     }
  363. }
  364.  
  365. unsigned __GetIOMode( int handle )
  366. {
  367.     if( handle >= __NFiles )
  368.     {
  369.         return( 0 );
  370.     }
  371.     return( __io_mode[handle] );
  372. };
  373.  
  374. void __SetIOMode_nogrow( int handle, unsigned value )
  375. {
  376.     if( handle < __NFiles )
  377.     {
  378.         __io_mode[handle] = value;    /* we're closing it; smite _INITIALIZED */
  379.     }
  380. }
  381.  
  382.