-/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )\r
-\r
- This file is part of the Public Domain C Library (PDCLib).\r
- Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_glue.h"\r
-#include "_PDCLIB_io.h"\r
-#include <string.h>\r
-#include <threads.h>\r
-\r
-extern FILE * _PDCLIB_filelist;\r
-\r
-FILE * _PDCLIB_fvopen(\r
- _PDCLIB_fd_t fd,\r
- const _PDCLIB_fileops_t *_PDCLIB_restrict ops,\r
- int mode,\r
- const char *_PDCLIB_restrict filename\r
-)\r
-{\r
- size_t filename_len;\r
- FILE * rc;\r
- if ( mode == NULL )\r
- {\r
- /* Mode invalid */\r
- return NULL;\r
- }\r
- /* To reduce the number of malloc calls, all data fields are concatenated:\r
- * the FILE structure itself,\r
- * ungetc buffer,\r
- * filename buffer,\r
- * data buffer.\r
- Data buffer comes last because it might change in size ( setvbuf() ).\r
- */\r
- filename_len = filename ? strlen( filename ) + 1 : 1;\r
- if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )\r
- {\r
- /* no memory */\r
- return NULL;\r
- }\r
-\r
- if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {\r
- free(rc);\r
- return NULL;\r
- }\r
-\r
- rc->status = mode;\r
- rc->ops = ops;\r
- rc->handle = fd;\r
- /* Setting pointers into the memory block allocated above */\r
- rc->ungetbuf = (unsigned char *)rc + sizeof( FILE );\r
- rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;\r
- rc->buffer = rc->filename + filename_len;\r
- /* Copying filename to FILE structure */\r
- if(filename) strcpy( rc->filename, filename );\r
- /* Initializing the rest of the structure */\r
- rc->bufsize = BUFSIZ;\r
- rc->bufidx = 0;\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
- rc->bufnlexp = 0;\r
-#endif\r
- rc->ungetidx = 0;\r
- /* Setting buffer to _IOLBF because "when opened, a stream is fully\r
- buffered if and only if it can be determined not to refer to an\r
- interactive device."\r
- */\r
- rc->status |= _IOLBF;\r
- /* TODO: Setting mbstate */\r
- /* Adding to list of open files */\r
- rc->next = _PDCLIB_filelist;\r
- _PDCLIB_filelist = rc;\r
- return rc;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
- /* Some of the tests are not executed for regression tests, as the libc on\r
- my system is at once less forgiving (segfaults on mode NULL) and more\r
- forgiving (accepts undefined modes).\r
- */\r
- FILE * fh;\r
- remove( testfile );\r
- TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );\r
- TESTCASE( fopen( NULL, "w" ) == NULL );\r
- TESTCASE_NOREG( fopen( "", NULL ) == NULL );\r
- TESTCASE( fopen( "", "w" ) == NULL );\r
- TESTCASE( fopen( "foo", "" ) == NULL );\r
- TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */\r
- TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */\r
- TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL );\r
- TESTCASE( fclose( fh ) == 0 );\r
- TESTCASE( remove( testfile ) == 0 );\r
- return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_glue.h"
+#include "_PDCLIB_io.h"
+#include <string.h>
+#include <threads.h>
+
+extern FILE * _PDCLIB_filelist;
+
+FILE * _PDCLIB_fvopen(
+ _PDCLIB_fd_t fd,
+ const _PDCLIB_fileops_t *_PDCLIB_restrict ops,
+ int mode,
+ const char *_PDCLIB_restrict filename
+)
+{
+ size_t filename_len;
+ FILE * rc;
+ if ( mode == NULL )
+ {
+ /* Mode invalid */
+ return NULL;
+ }
+ /* To reduce the number of malloc calls, all data fields are concatenated:
+ * the FILE structure itself,
+ * ungetc buffer,
+ * filename buffer,
+ * data buffer.
+ Data buffer comes last because it might change in size ( setvbuf() ).
+ */
+ filename_len = filename ? strlen( filename ) + 1 : 1;
+ if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )
+ {
+ /* no memory */
+ return NULL;
+ }
+
+ if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {
+ free(rc);
+ return NULL;
+ }
+
+ rc->status = mode;
+ rc->ops = ops;
+ rc->handle = fd;
+ /* Setting pointers into the memory block allocated above */
+ rc->ungetbuf = (unsigned char *)rc + sizeof( FILE );
+ rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;
+ rc->buffer = rc->filename + filename_len;
+ /* Copying filename to FILE structure */
+ if(filename) strcpy( rc->filename, filename );
+ /* Initializing the rest of the structure */
+ rc->bufsize = BUFSIZ;
+ rc->bufidx = 0;
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+ rc->bufnlexp = 0;
+#endif
+ rc->ungetidx = 0;
+ /* Setting buffer to _IOLBF because "when opened, a stream is fully
+ buffered if and only if it can be determined not to refer to an
+ interactive device."
+ */
+ rc->status |= _IOLBF;
+ /* TODO: Setting mbstate */
+ /* Adding to list of open files */
+ rc->next = _PDCLIB_filelist;
+ _PDCLIB_filelist = rc;
+ return rc;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+ /* Some of the tests are not executed for regression tests, as the libc on
+ my system is at once less forgiving (segfaults on mode NULL) and more
+ forgiving (accepts undefined modes).
+ */
+ FILE * fh;
+ remove( testfile );
+ TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );
+ TESTCASE( fopen( NULL, "w" ) == NULL );
+ TESTCASE_NOREG( fopen( "", NULL ) == NULL );
+ TESTCASE( fopen( "", "w" ) == NULL );
+ TESTCASE( fopen( "foo", "" ) == NULL );
+ TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */
+ TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */
+ TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL );
+ TESTCASE( fclose( fh ) == 0 );
+ TESTCASE( remove( testfile ) == 0 );
+ return TEST_RESULTS;
+}
+
+#endif