]> pd.if.org Git - pdclib.old/blob - functions/stdio/fclose.c
Merged branch stdio_rewrite back into trunk.
[pdclib.old] / functions / stdio / fclose.c
1 /* $Id$ */
2
3 /* fclose( FILE * )
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 /* FIXME: Last file not removed from list. */
18 int fclose( struct _PDCLIB_file_t * stream )
19 {
20     struct _PDCLIB_file_t * current = _PDCLIB_filelist;
21     struct _PDCLIB_file_t * previous = NULL;
22     /* Checking that the FILE handle is actually one we had opened before. */
23     while ( current != NULL )
24     {
25         if ( stream == current )
26         {
27             /* Flush buffer */
28             if ( stream->status & _PDCLIB_FWRITE )
29             {
30                 if ( _PDCLIB_flushbuffer( stream ) == EOF )
31                 {
32                     /* Flush failed, errno already set */
33                     return EOF;
34                 }
35             }
36             /* Free buffer */
37             if ( stream->status & _PDCLIB_LIBBUFFER )
38             {
39                 free( stream->buffer );
40             }
41             /* Close handle */
42             _PDCLIB_close( stream->handle );
43             /* Remove stream from list */
44             if ( previous != NULL )
45             {
46                 previous->next = stream->next;
47             }
48             else
49             {
50                 _PDCLIB_filelist = stream->next;
51             }
52             /* Free stream */
53             free( stream );
54             return 0;
55         }
56         previous = current;
57         current = current->next;
58     }
59     _PDCLIB_errno = _PDCLIB_EIO;
60     return -1;
61 }
62
63 #endif
64
65 #ifdef TEST
66 #include <_PDCLIB_test.h>
67
68 int main( void )
69 {
70 #ifndef REGTEST
71     struct _PDCLIB_file_t * file1;
72     struct _PDCLIB_file_t * file2;
73     remove( "testfile1" );
74     remove( "testfile2" );
75     TESTCASE( _PDCLIB_filelist == stdin );
76     TESTCASE( ( file1 = fopen( "testfile1", "w" ) ) != NULL );
77     TESTCASE( _PDCLIB_filelist == file1 );
78     TESTCASE( ( file2 = fopen( "testfile2", "w" ) ) != NULL );
79     TESTCASE( _PDCLIB_filelist == file2 );
80     TESTCASE( fclose( file2 ) == 0 );
81     TESTCASE( _PDCLIB_filelist == file1 );
82     TESTCASE( ( file2 = fopen( "testfile1", "w" ) ) != NULL );
83     TESTCASE( _PDCLIB_filelist == file2 );
84     TESTCASE( fclose( file1 ) == 0 );
85     TESTCASE( _PDCLIB_filelist == file2 );
86     TESTCASE( fclose( file2 ) == 0 );
87     TESTCASE( _PDCLIB_filelist == stdin );
88     remove( "testfile1" );
89     remove( "testfile2" );
90 #else
91     puts( " NOTEST fclose() test driver is PDCLib-specific." );
92 #endif
93     return TEST_RESULTS;
94 }
95
96 #endif
97