]> pd.if.org Git - pdclib/commitdiff
Fixed broken filename handling in freopen().
authorsolar <unknown>
Sat, 20 Nov 2010 08:53:56 +0000 (08:53 +0000)
committersolar <unknown>
Sat, 20 Nov 2010 08:53:56 +0000 (08:53 +0000)
functions/stdio/fclose.c
functions/stdio/freopen.c
includes/stdio.h

index 5c1e4d44d96c0b44e44a990468f25b32c3159769..456acc171656a015487466a57eb9a1d8c0ddd7a5 100644 (file)
@@ -49,7 +49,7 @@ int fclose( struct _PDCLIB_file_t * stream )
                 remove( stream->filename );
             }
             /* Free stream */
-            if ( ! stream->status & _PDCLIB_STATIC )
+            if ( ! ( stream->status & _PDCLIB_STATIC ) )
             {
                 free( stream );
             }
index a2c0adade6b91908d5644c7b3dbb1e7ad66fd6b7..482b82025d225cf5d5cdbb2b1e9a2e0000177ba0 100644 (file)
 
 #include <_PDCLIB_glue.h>
 #include <stdlib.h>
+#include <string.h>
 
-/* Close any file currently associated with the given stream. Open the file
-   identified by the given filename with the given mode (equivalent to fopen()),
-   and associate it with the given stream. If filename is a NULL pointer,
-   attempt to change the mode of the given stream.
-   This implementation allows any mode changes.
-   (Primary use of this function is to redirect stdin, stdout, and stderr.)
-*/
 struct _PDCLIB_file_t * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, struct _PDCLIB_file_t * _PDCLIB_restrict stream )
 {
     unsigned int status = stream->status & ( _IONBF | _IOLBF | _IOFBF | _PDCLIB_FREEBUFFER | _PDCLIB_DELONCLOSE );
@@ -28,14 +22,37 @@ struct _PDCLIB_file_t * freopen( const char * _PDCLIB_restrict filename, const c
     {
         _PDCLIB_flushbuffer( stream );
     }
+    if ( ( filename == NULL ) && ( stream->filename == NULL ) )
+    {
+        /* TODO: Special handling for mode changes on std-streams */
+        return NULL;
+    }
     _PDCLIB_close( stream->handle );
+    /* TODO: It is not nice to do this on a stream we just closed.
+       It does not matter with the current implementation of clearerr(),
+       but it might start to matter if someone replaced that implementation.
+    */
     clearerr( stream );
-    /* FIXME: Copy filename into the FILE structure. */
-    /* FIXME: filename cannot reside in "big block" memory */
+    /* The new filename might not fit the old buffer */
     if ( filename == NULL )
     {
+        /* Use previous filename */
         filename = stream->filename;
     }
+    else if ( ( stream->filename != NULL ) && ( strlen( stream->filename ) >= strlen( filename ) ) )
+    {
+        /* Copy new filename into existing buffer */
+        strcpy( stream->filename, filename );
+    }
+    else
+    {
+        /* Allocate new buffer */
+        if ( ( stream->filename = (char *)malloc( strlen( filename ) ) ) == NULL )
+        {
+            return NULL;
+        }
+        strcpy( stream->filename, filename );
+    }
     if ( ( mode == NULL ) || ( filename[0] == '\0' ) )
     {
         return NULL;
index 014052bda5f4451883f586f8c2e530248f67b00b..b9a02249a717be07a28dd09fffdd9dd8c667de10 100644 (file)
@@ -162,7 +162,9 @@ FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restr
    identified by the given filename with the given mode (equivalent to fopen()),
    and associate it with the given stream. If filename is a NULL pointer,
    attempt to change the mode of the given stream.
-   This implementation allows the following mode changes: TODO
+   This implementation allows any mode changes on "real" files, and associating
+   of the standard streams with files. It does *not* support mode changes on
+   standard streams.
    (Primary use of this function is to redirect stdin, stdout, and stderr.)
 */
 FILE * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, FILE * _PDCLIB_restrict stream );