diff options
Diffstat (limited to '')
-rw-r--r-- | common/estream.c | 89 |
1 files changed, 86 insertions, 3 deletions
diff --git a/common/estream.c b/common/estream.c index 3a17910f7..56e362d68 100644 --- a/common/estream.c +++ b/common/estream.c @@ -211,6 +211,7 @@ struct estream_internal void *cookie; /* Cookie. */ void *opaque; /* Opaque data. */ unsigned int modeflags; /* Flags for the backend. */ + char *printable_fname; /* Malloced filename for es_fname_get. */ off_t offset; es_cookie_read_function_t func_read; es_cookie_write_function_t func_write; @@ -227,6 +228,7 @@ struct estream_internal unsigned int is_stdstream:1; /* This is a standard stream. */ unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */ unsigned int print_err: 1; /* Error in print_fun_writer. */ + unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */ int print_errno; /* Errno from print_fun_writer. */ size_t print_ntotal; /* Bytes written from in print_fun_writer. */ FILE *print_fp; /* Stdio stream used by print_fun_writer. */ @@ -266,8 +268,12 @@ static unsigned char custom_std_fds_valid[3]; #endif - +/* Local prototypes. */ +static void fname_set_internal (estream_t stream, const char *fname, int quote); + + + /* Macros. */ /* Calculate array dimension. */ @@ -1275,6 +1281,8 @@ es_initialize (estream_t stream, stream->intern->is_stdstream = 0; stream->intern->stdstream_fd = 0; stream->intern->deallocate_buffer = 0; + stream->intern->printable_fname = NULL; + stream->intern->printable_fname_inuse = 0; stream->data_len = 0; stream->data_offset = 0; @@ -1314,7 +1322,10 @@ es_deinitialize (estream_t stream) if (func_close) SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie)); - + mem_free (stream->intern->printable_fname); + stream->intern->printable_fname = NULL; + stream->intern->printable_fname_inuse = 0; + return err; } @@ -2190,6 +2201,9 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) if (err) goto out; + if (stream && path) + fname_set_internal (stream, path, 1); + out: if (err && create_called) @@ -2467,6 +2481,9 @@ _es_get_std_stream (int fd) stream->intern->stdstream_fd = fd; if (fd == 2) es_set_buffering (stream, NULL, _IOLBF, 0); + fname_set_internal (stream, + fd == 0? "[stdin]" : + fd == 1? "[stdout]" : "[stderr]", 0); } ESTREAM_LIST_UNLOCK; return stream; @@ -2515,7 +2532,11 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, stream = NULL; } else - ESTREAM_UNLOCK (stream); + { + if (stream && path) + fname_set_internal (stream, path, 1); + ESTREAM_UNLOCK (stream); + } } else { @@ -3407,6 +3428,68 @@ es_opaque_get (estream_t stream) return opaque; } + +static void +fname_set_internal (estream_t stream, const char *fname, int quote) +{ + if (stream->intern->printable_fname + && !stream->intern->printable_fname_inuse) + { + mem_free (stream->intern->printable_fname); + stream->intern->printable_fname = NULL; + } + if (stream->intern->printable_fname) + return; /* Can't change because it is in use. */ + + if (*fname != '[') + quote = 0; + else + quote = !!quote; + + stream->intern->printable_fname = mem_alloc (strlen (fname) + quote + 1); + if (fname) + { + if (quote) + stream->intern->printable_fname[0] = '\\'; + strcpy (stream->intern->printable_fname+quote, fname); + } +} + + +/* Set the filename attribute of STREAM. There is no error return. + as long as STREAM is valid. This function is called internally by + functions which open a filename. */ +void +es_fname_set (estream_t stream, const char *fname) +{ + if (fname) + { + ESTREAM_LOCK (stream); + fname_set_internal (stream, fname, 1); + ESTREAM_UNLOCK (stream); + } +} + + +/* Return the filename attribute of STREAM. In case no filename has + been set, "[?]" will be returned. The returned file name is valid + as long as STREAM is valid. */ +const char * +es_fname_get (estream_t stream) +{ + const char *fname; + + ESTREAM_LOCK (stream); + fname = stream->intern->printable_fname; + if (fname) + stream->intern->printable_fname_inuse = 1; + ESTREAM_UNLOCK (stream); + if (!fname) + fname = "[?]"; + return fname; +} + + /* Print a BUFFER to STREAM while replacing all control characters and the characters in DELIMITERS by standard C escape sequences. Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL |