From: solar Date: Sat, 20 Nov 2010 08:53:56 +0000 (+0000) Subject: Fixed broken filename handling in freopen(). X-Git-Tag: v0.5~33 X-Git-Url: https://pd.if.org/git/?p=pdclib;a=commitdiff_plain;h=71712a8bb92d6a10218e3356c6d26554dc2633dd Fixed broken filename handling in freopen(). --- diff --git a/functions/stdio/fclose.c b/functions/stdio/fclose.c index 5c1e4d4..456acc1 100644 --- a/functions/stdio/fclose.c +++ b/functions/stdio/fclose.c @@ -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 ); } diff --git a/functions/stdio/freopen.c b/functions/stdio/freopen.c index a2c0ada..482b820 100644 --- a/functions/stdio/freopen.c +++ b/functions/stdio/freopen.c @@ -12,14 +12,8 @@ #include <_PDCLIB_glue.h> #include +#include -/* 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; diff --git a/includes/stdio.h b/includes/stdio.h index 014052b..b9a0224 100644 --- a/includes/stdio.h +++ b/includes/stdio.h @@ -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 );