Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
614 serge 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 
35
#include 
36
#ifdef __WIDECHAR__
37
    #include 
38
#endif
39
#include 
40
#include 
41
#include 
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
}