1 /* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )
3 This file is part of the Public Domain C Library (PDCLib).
4 Permission is granted to use, modify, and / or redistribute at will.
11 #include "_PDCLIB_glue.h"
12 #include "_PDCLIB_io.h"
16 extern FILE * _PDCLIB_filelist;
18 FILE * _PDCLIB_fvopen(
20 const _PDCLIB_fileops_t *_PDCLIB_restrict ops,
22 const char *_PDCLIB_restrict filename
32 /* To reduce the number of malloc calls, all data fields are concatenated:
33 * the FILE structure itself,
37 Data buffer comes last because it might change in size ( setvbuf() ).
39 filename_len = filename ? strlen( filename ) + 1 : 1;
40 if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )
46 if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {
54 /* Setting pointers into the memory block allocated above */
55 rc->ungetbuf = (unsigned char *)rc + sizeof( FILE );
56 rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;
57 rc->buffer = rc->filename + filename_len;
58 /* Copying filename to FILE structure */
59 if(filename) strcpy( rc->filename, filename );
60 /* Initializing the rest of the structure */
63 #ifdef _PDCLIB_NEED_EOL_TRANSLATION
67 /* Setting buffer to _IOLBF because "when opened, a stream is fully
68 buffered if and only if it can be determined not to refer to an
72 /* TODO: Setting mbstate */
73 /* Adding to list of open files */
74 rc->next = _PDCLIB_filelist;
75 _PDCLIB_filelist = rc;
82 #include "_PDCLIB_test.h"
86 /* Some of the tests are not executed for regression tests, as the libc on
87 my system is at once less forgiving (segfaults on mode NULL) and more
88 forgiving (accepts undefined modes).
92 TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );
93 TESTCASE( fopen( NULL, "w" ) == NULL );
94 TESTCASE_NOREG( fopen( "", NULL ) == NULL );
95 TESTCASE( fopen( "", "w" ) == NULL );
96 TESTCASE( fopen( "foo", "" ) == NULL );
97 TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */
98 TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */
99 TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL );
100 TESTCASE( fclose( fh ) == 0 );
101 TESTCASE( remove( testfile ) == 0 );