]> 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 */
                 remove( stream->filename );
             }
             /* Free stream */
-            if ( ! stream->status & _PDCLIB_STATIC )
+            if ( ! ( stream->status & _PDCLIB_STATIC ) )
             {
                 free( stream );
             }
             {
                 free( stream );
             }
index a2c0adade6b91908d5644c7b3dbb1e7ad66fd6b7..482b82025d225cf5d5cdbb2b1e9a2e0000177ba0 100644 (file)
 
 #include <_PDCLIB_glue.h>
 #include <stdlib.h>
 
 #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 );
 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 );
     }
     {
         _PDCLIB_flushbuffer( stream );
     }
+    if ( ( filename == NULL ) && ( stream->filename == NULL ) )
+    {
+        /* TODO: Special handling for mode changes on std-streams */
+        return NULL;
+    }
     _PDCLIB_close( stream->handle );
     _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 );
     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 )
     {
     if ( filename == NULL )
     {
+        /* Use previous filename */
         filename = stream->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;
     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.
    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 );
    (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 );