]> pd.if.org Git - pdclib/blob - functions/stdio/fopen.c
48c07d2b3ff41d6c2244461bc417832546063161
[pdclib] / functions / stdio / fopen.c
1 /* $Id$ */
2
3 /* fopen( const char *, const char * )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #ifndef REGTEST
13 #include <_PDCLIB_glue.h>
14
15 extern struct _PDCLIB_file_t * _PDCLIB_filelist;
16
17 struct _PDCLIB_file_t * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode )
18 {
19     struct _PDCLIB_file_t * rc;
20     if ( mode == NULL || filename == NULL || filename[0] == '\0' )
21     {
22         /* Mode or filename invalid */
23         return NULL;
24     }
25     if ( ( rc = calloc( 1, sizeof( struct _PDCLIB_file_t ) ) ) == NULL )
26     {
27         /* no memory for another FILE */
28         return NULL;
29     }
30     if ( ( rc->status = _PDCLIB_filemode( mode ) ) == 0 ) 
31     {
32         /* invalid mode */
33         free( rc );
34         return NULL;
35     }
36     rc->handle = _PDCLIB_open( filename, rc->status );
37     if ( rc->handle == _PDCLIB_NOHANDLE )
38     {
39         /* OS open() failed */
40         free( rc );
41         return NULL;
42     }
43     /* Adding to list of open files */
44     rc->next = _PDCLIB_filelist;
45     _PDCLIB_filelist = rc;
46     /* Setting buffer, and mark as internal. TODO: Check for unbuffered */
47     if ( ( rc->buffer = malloc( BUFSIZ ) ) == NULL )
48     {
49         free( rc );
50         return NULL;
51     }
52     if ( ( rc->ungetbuf = malloc( _PDCLIB_UNGETCBUFSIZE ) ) == NULL )
53     {
54        free( rc->buffer );
55        free( rc );
56        return NULL;
57     }
58     rc->bufsize = BUFSIZ;
59     rc->bufidx = 0;
60     rc->ungetidx = 0;
61     /* Setting buffer to _IOLBF because "when opened, a stream is fully
62        buffered if and only if it can be determined not to refer to an
63        interactive device."
64     */
65     rc->status |= _PDCLIB_LIBBUFFER | _IOLBF;
66     /* TODO: Setting mbstate */
67     return rc;
68 }
69
70 #endif
71
72 #ifdef TEST
73 #include <_PDCLIB_test.h>
74
75 int main( void )
76 {
77     /* Some of the tests are not executed for regression tests, as the libc on
78        my system is at once less forgiving (segfaults on mode NULL) and more
79        forgiving (accepts undefined modes).
80     */
81     remove( "testfile" );
82     TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );
83     TESTCASE( fopen( NULL, "w" ) == NULL );
84     TESTCASE_NOREG( fopen( "", NULL ) == NULL );
85     TESTCASE( fopen( "", "w" ) == NULL );
86     TESTCASE( fopen( "foo", "" ) == NULL );
87     TESTCASE_NOREG( fopen( "testfile", "wq" ) == NULL ); /* Undefined mode */
88     TESTCASE_NOREG( fopen( "testfile", "wr" ) == NULL ); /* Undefined mode */
89     TESTCASE( fopen( "testfile", "w" ) != NULL );
90     remove( "testfile" );
91     return TEST_RESULTS;
92 }
93
94 #endif