-// ----------------------------------------------------------------------------
-// $Id$
-// ----------------------------------------------------------------------------
-// Public Domain C Library - http://pdclib.sourceforge.net
-// This code is Public Domain. Use, modify, and redistribute at will.
-// ----------------------------------------------------------------------------
-
-FILE * fopen( const char * restrict filename, const char * restrict mode ) { /* TODO */ };
+/* $Id$ */
+
+/* fopen( const char *, const char * )
+
+ 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 <string.h>
+#include <errno.h>
+
+extern struct _PDCLIB_file_t * _PDCLIB_filelist;
+
+FILE * fopen( const char * _PDCLIB_restrict filename,
+ const char * _PDCLIB_restrict mode )
+{
+ int imode = _PDCLIB_filemode( mode );
+
+ if( imode == 0 || filename == NULL )
+ return NULL;
+
+ _PDCLIB_fd_t fd = _PDCLIB_open( filename, imode );
+ if(fd == _PDCLIB_NOHANDLE) {
+ return NULL;
+ }
+
+ FILE * f = _PDCLIB_fdopen( fd, imode, filename );
+ if(!f) {
+ int saveErrno = errno;
+ _PDCLIB_close( fd );
+ errno = saveErrno;
+ }
+ return f;
+}
+
+#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