Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/waterbox/libc/functions/stdio/_PDCLIB_fvopen.c
2 views
1
/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )
2
3
This file is part of the Public Domain C Library (PDCLib).
4
Permission is granted to use, modify, and / or redistribute at will.
5
*/
6
7
#include <stdio.h>
8
#include <stdlib.h>
9
10
#ifndef REGTEST
11
#include "_PDCLIB_glue.h"
12
#include "_PDCLIB_io.h"
13
#include <string.h>
14
#include <threads.h>
15
16
extern FILE * _PDCLIB_filelist;
17
18
FILE * _PDCLIB_fvopen(
19
_PDCLIB_fd_t fd,
20
const _PDCLIB_fileops_t *_PDCLIB_restrict ops,
21
int mode,
22
const char *_PDCLIB_restrict filename
23
)
24
{
25
size_t filename_len;
26
FILE * rc;
27
if ( mode == NULL )
28
{
29
/* Mode invalid */
30
return NULL;
31
}
32
/* To reduce the number of malloc calls, all data fields are concatenated:
33
* the FILE structure itself,
34
* ungetc buffer,
35
* filename buffer,
36
* data buffer.
37
Data buffer comes last because it might change in size ( setvbuf() ).
38
*/
39
filename_len = filename ? strlen( filename ) + 1 : 1;
40
if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )
41
{
42
/* no memory */
43
return NULL;
44
}
45
46
if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {
47
free(rc);
48
return NULL;
49
}
50
51
rc->status = mode;
52
rc->ops = ops;
53
rc->handle = fd;
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 */
61
rc->bufsize = BUFSIZ;
62
rc->bufidx = 0;
63
#ifdef _PDCLIB_NEED_EOL_TRANSLATION
64
rc->bufnlexp = 0;
65
#endif
66
rc->ungetidx = 0;
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
69
interactive device."
70
*/
71
rc->status |= _IOLBF;
72
/* TODO: Setting mbstate */
73
/* Adding to list of open files */
74
rc->next = _PDCLIB_filelist;
75
_PDCLIB_filelist = rc;
76
return rc;
77
}
78
79
#endif
80
81
#ifdef TEST
82
#include "_PDCLIB_test.h"
83
84
int main( void )
85
{
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).
89
*/
90
FILE * fh;
91
remove( testfile );
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 );
102
return TEST_RESULTS;
103
}
104
105
#endif
106
107