Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | 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:  Platform independent fopen() implementation.
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. #include "variety.h"
  33. #include "widechar.h"
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #ifdef __WIDECHAR__
  37.     #include <wctype.h>
  38. #endif
  39. #include <errno.h>
  40. #include <fcntl.h>
  41. #include <sys/stat.h>
  42. #include "fileacc.h"
  43. #include "fmode.h"
  44. #include "openmode.h"
  45. #include "rtdata.h"
  46. #include "seterrno.h"
  47. //#include "defwin.h"
  48. #include "streamio.h"
  49.  
  50. #ifdef __UNIX__
  51.     #define PMODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
  52. #else
  53.     #define PMODE   (S_IREAD | S_IWRITE)
  54. #endif
  55.  
  56.  
  57. int __F_NAME(__open_flags,__wopen_flags)( const CHAR_TYPE *modestr, int *extflags )
  58. {
  59.     int                 flags;
  60.     int                 alive = 1;
  61.     int                 gotplus = 0;
  62.     int                 gottextbin = 0;
  63. #ifndef __NETWARE__
  64.     int                 gotcommit = 0;
  65. #endif
  66.  
  67.     flags = 0;
  68.     if( extflags != NULL ) {
  69. #ifdef __NETWARE__
  70.         *extflags = 0;
  71. #else
  72.         if( _commode == _COMMIT ) {
  73.             *extflags = _COMMIT;
  74.         } else {
  75.             *extflags = 0;
  76.         }
  77. #endif
  78.     }
  79.  
  80.     /*
  81.      * The first character in modestr must be 'r', 'w', or 'a'.
  82.      */
  83.     switch( *modestr ) {
  84.     case 'r':
  85.         flags |= _READ;
  86.         break;
  87.     case 'w':
  88.         flags |= _WRITE;
  89.         break;
  90.     case 'a':
  91.         flags |= _WRITE | _APPEND;
  92.         break;
  93.     default:
  94.         __set_errno( EINVAL );
  95.         return( 0 );
  96.     }
  97.     modestr++;
  98.  
  99.     /*
  100.      * Next we might have, in any order, some additional mode modifier
  101.      * characters:
  102.      *      1.  A '+' character.
  103.      *      2.  Either a 't' or a 'b'.
  104.      *      3.  Either a 'c' or a 'n'.  (Not available for Netware.)
  105.      * For MS compatability, scanning stops when any of the three groups
  106.      * is encountered twice; e.g., "wct+b$&!" is valid and will result in
  107.      * a text, not binary, stream.  Also for MS compatability, scanning
  108.      * stops at any unrecognized character, without causing failure.
  109.      */
  110.     while( (*modestr != NULLCHAR) && alive ) {
  111.         switch( *modestr ) {
  112.         case '+':
  113.             if( gotplus ) {
  114.                 alive = 0;
  115.             } else {
  116.                 flags |= _READ | _WRITE;
  117.                 gotplus = 1;
  118.             }
  119.             break;
  120.         case 't':
  121.             if( gottextbin ) {
  122.                 alive = 0;
  123.             } else {
  124.                 gottextbin = 1;
  125.             }
  126.             break;
  127.         case 'b':
  128.             if( gottextbin ) {
  129.                 alive = 0;
  130.             } else {
  131. #ifndef __UNIX__
  132.                 flags |= _BINARY;
  133. #endif
  134.                 gottextbin = 1;
  135.             }
  136.             break;
  137. #ifndef __NETWARE__
  138.         case 'c':
  139.             if( gotcommit ) {
  140.                 alive = 0;
  141.             } else {
  142.                 *extflags |= _COMMIT;
  143.                 gotcommit = 1;
  144.             }
  145.             break;
  146.         case 'n':
  147.             if( gotcommit ) {
  148.                 alive = 0;
  149.             } else {
  150.                 *extflags &= ~_COMMIT;
  151.                 gotcommit = 1;
  152.             }
  153.             break;
  154. #endif
  155.         default:
  156.             break;
  157.         }
  158.         modestr++;
  159.     }
  160.  
  161.     /*
  162.      * Handle defaults for any unspecified options.
  163.      */
  164. #ifndef __UNIX__
  165.     if( !gottextbin ) {
  166.         if( _RWD_fmode == O_BINARY )  flags |= _BINARY;
  167.     }
  168. #endif
  169.  
  170.     return( flags );
  171. }
  172.  
  173.  
  174. static FILE *__F_NAME(__doopen,__wdoopen)( const CHAR_TYPE *name,
  175.                        CHAR_TYPE    mode,
  176.                        int          file_flags,
  177.                        int          extflags,
  178.                        int          shflag,     /* sharing flag */
  179.                        FILE *       fp )
  180. {
  181.     int open_mode;
  182.     int p_mode;
  183.  
  184.     SetupTGCSandNCS( RETURN_ARG( FILE *, 0 ) );     /* for NW386 */
  185.     fp->_flag &= ~(_READ | _WRITE);
  186.     fp->_flag |= file_flags;
  187.  
  188.     /* we need the mode character to indicate if the original */
  189.     /* intention is to open for read or for write */
  190.     mode = __F_NAME(tolower,towlower)( mode );
  191.     if( mode == 'r' ) {
  192.         open_mode = O_RDONLY;
  193.         if( file_flags & _WRITE ) {         /* if "r+" mode */
  194.             open_mode = O_RDWR;
  195.         }
  196. #if defined( __NETWARE__ )
  197.         open_mode |= O_BINARY;
  198. #elif defined( __UNIX__ )
  199. #else
  200.         if( file_flags & _BINARY ) {
  201.             open_mode |= O_BINARY;
  202.         } else {
  203.             open_mode |= O_TEXT;
  204.         }
  205. #endif
  206.         p_mode = 0;
  207.     } else {        /* mode == 'w' || mode == 'a' */
  208.         if( file_flags & _READ ) {          /* if "a+" or "w+" mode */
  209.             open_mode = O_RDWR | O_CREAT;
  210.         } else {
  211.             open_mode = O_WRONLY | O_CREAT;
  212.         }
  213.         if( file_flags & _APPEND ) {
  214.             open_mode |= O_APPEND;
  215.         } else {                    /* mode == 'w' */
  216.             open_mode |= O_TRUNC;
  217.         }
  218. #if defined( __NETWARE__ )
  219.         open_mode |= O_BINARY;
  220. #elif defined( __UNIX__ )
  221. #else
  222.         if( file_flags & _BINARY ) {
  223.             open_mode |= O_BINARY;
  224.         } else {
  225.             open_mode |= O_TEXT;
  226.         }
  227. #endif
  228.         p_mode = PMODE;
  229.     }
  230.     fp->_handle = __F_NAME(sopen,_wsopen)( name, open_mode, shflag, p_mode );
  231.     if( fp->_handle == -1 ) {
  232.         // since we couldn't open the file, release the FILE struct
  233.         __freefp( fp );
  234.         return( NULL );
  235.     }
  236.     fp->_cnt = 0;
  237.     fp->_bufsize = 0;                       /* was BUFSIZ JBS 31-may-91 */
  238. #ifndef __NETWARE__
  239.     _FP_ORIENTATION(fp) = _NOT_ORIENTED; /* initial orientation */
  240.     _FP_EXTFLAGS(fp) = extflags;
  241. #endif
  242. #if defined( __NT__ ) || defined( __OS2__ )
  243.     _FP_PIPEDATA(fp).isPipe = 0;        /* not a pipe */
  244. #endif
  245.     _FP_BASE(fp) = NULL;
  246.     if( file_flags & _APPEND ) {
  247.         fseek( fp, 0L, SEEK_END );
  248.     }
  249.     __chktty( fp );                         /* JBS 28-aug-90 */
  250.     return( fp );
  251. }
  252.  
  253.  
  254. _WCRTLINK FILE *__F_NAME(_fsopen,_wfsopen)( const CHAR_TYPE *name,
  255.                                 const CHAR_TYPE *access_mode, int shflag )
  256. {
  257.     FILE *          fp;
  258.     int             file_flags;
  259.     int             extflags;
  260.  
  261.     /* validate access_mode */
  262.     file_flags = __F_NAME(__open_flags,__wopen_flags)( access_mode, &extflags );
  263.     if( file_flags == 0 ) {
  264.         return( NULL );
  265.     }
  266.  
  267.     /* specify dummy handle 0 */
  268.     fp = __allocfp( 0 );                    /* JBS 30-aug-91 */
  269.     if( fp != NULL ) {
  270.         fp = __F_NAME(__doopen,__wdoopen)( name, *access_mode,
  271.                                            file_flags, extflags,
  272.                                            shflag, fp );
  273.     }
  274.     return( fp );
  275. }
  276.  
  277.  
  278. _WCRTLINK FILE *__F_NAME(fopen,_wfopen)( const CHAR_TYPE *name, const CHAR_TYPE *access_mode )
  279. {
  280.     return( __F_NAME(_fsopen,_wfsopen)( name, access_mode, OPENMODE_DENY_COMPAT ) );
  281. }
  282.  
  283. static FILE *close_file( FILE *fp )
  284. {
  285.     __stream_link * link;
  286.     __stream_link **owner;
  287.  
  288.     _AccessIOB();
  289.     /* See if the file pointer is a currently open file. */
  290.     link = _RWD_ostream;
  291.     for( ;; ) {
  292.         if( link == NULL ) break;
  293.         if( link->stream == fp ) {
  294.             if( fp->_flag & (_READ|_WRITE) ) {
  295.                 __doclose( fp, 1 );
  296.             }
  297.             _ReleaseIOB();
  298.             return( fp );
  299.         }
  300.         link = link->next;
  301.     }
  302.     /*
  303.        It's not on the list of open files, so check the list of
  304.        recently closed ones.
  305.     */
  306.     owner = &_RWD_cstream;
  307.     for( ;; ) {
  308.         link = *owner;
  309.         if( link == NULL ) break;
  310.         if( link->stream == fp ) {
  311.             /* remove from closed list and put on open */
  312.             *owner = link->next;
  313.             link->next = _RWD_ostream;
  314.             _RWD_ostream = link;
  315.             _ReleaseIOB();
  316.             return( fp );
  317.         }
  318.         owner = &link->next;
  319.     }
  320.     /* We ain't seen that file pointer ever. Leave things be. */
  321.     __set_errno( EBADF );
  322.     _ReleaseIOB();
  323.     return( NULL );
  324. }
  325.  
  326.  
  327. _WCRTLINK FILE *__F_NAME(freopen,_wfreopen)( const CHAR_TYPE *name,
  328.                                 const CHAR_TYPE *access_mode, FILE *fp )
  329. {
  330.     int             hdl;
  331.     int             file_flags;
  332.     int             extflags;
  333.  
  334.     _ValidFile( fp, 0 );
  335.  
  336.     /* validate access_mode */
  337.     file_flags = __F_NAME(__open_flags,__wopen_flags)( access_mode, &extflags );
  338.     if( file_flags == 0 ) {
  339.         return( NULL );
  340.     }
  341.  
  342.     hdl = fileno( fp );
  343.     _AccessFileH( hdl );
  344.  
  345. #ifdef DEFAULT_WINDOWING
  346.     if( _WindowsRemoveWindowedHandle != 0 ) {
  347.         _WindowsRemoveWindowedHandle( hdl );
  348.     }
  349. #endif
  350.     fp = close_file( fp );
  351.     if( fp != NULL ) {
  352.         fp->_flag &= _DYNAMIC;                      /* 24-jul-92 */
  353.         fp = __F_NAME(__doopen,__wdoopen)( name, *access_mode,
  354.                                            file_flags, extflags,
  355.                                            0, fp );
  356.     }
  357.     _ReleaseFileH( hdl );
  358.     return( fp );
  359. }
  360.