int sys_func_rval; /* Syscall entry parser's return value */
int curcol; /* Output column for this process */
FILE *outf; /* Output file for this process */
- FILE *real_outf; /* Backup for real outf while staging */
- char *memfptr;
- size_t memfloc;
+ struct staged_output_data *staged_output_data;
const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */
void *_priv_data; /* Private data for syscall decoding functions */
#include "defs.h"
+struct staged_output_data {
+ char *memfptr;
+ size_t memfloc;
+ FILE *real_outf; /* Backup for real outf while staging */
+};
+
FILE *
strace_open_memstream(struct tcb *tcp)
{
FILE *fp = NULL;
#if HAVE_OPEN_MEMSTREAM
- tcp->memfptr = NULL;
- fp = open_memstream(&tcp->memfptr, &tcp->memfloc);
+ tcp->staged_output_data = xmalloc(sizeof(*tcp->staged_output_data));
+ fp = open_memstream(&tcp->staged_output_data->memfptr,
+ &tcp->staged_output_data->memfloc);
if (!fp)
perror_msg_and_die("open_memstream");
/*
fflush(fp);
/* Store the FILE pointer for later restauration. */
- tcp->real_outf = tcp->outf;
+ tcp->staged_output_data->real_outf = tcp->outf;
tcp->outf = fp;
#endif
strace_close_memstream(struct tcb *tcp, bool publish)
{
#if HAVE_OPEN_MEMSTREAM
- if (!tcp->real_outf) {
+ if (!tcp->staged_output_data) {
debug_msg("memstream already closed");
return;
}
if (fclose(tcp->outf))
perror_msg("fclose(tcp->outf)");
- tcp->outf = tcp->real_outf;
- tcp->real_outf = NULL;
- if (tcp->memfptr) {
+ tcp->outf = tcp->staged_output_data->real_outf;
+ if (tcp->staged_output_data->memfptr) {
if (publish)
- fputs_unlocked(tcp->memfptr, tcp->outf);
+ fputs_unlocked(tcp->staged_output_data->memfptr,
+ tcp->outf);
else
- debug_msg("syscall output dropped: %s", tcp->memfptr);
- free(tcp->memfptr);
- tcp->memfptr = NULL;
+ debug_msg("syscall output dropped: %s",
+ tcp->staged_output_data->memfptr);
+
+ free(tcp->staged_output_data->memfptr);
+ tcp->staged_output_data->memfptr = NULL;
}
+ free(tcp->staged_output_data);
+ tcp->staged_output_data = NULL;
#endif
}
if (printing_tcp) {
set_current_tcp(printing_tcp);
- if (tcp->real_outf == NULL && printing_tcp->curcol != 0 &&
+ if (!tcp->staged_output_data && printing_tcp->curcol != 0 &&
(followfork < 2 || printing_tcp == tcp)) {
/*
* case 1: we have a shared log (i.e. not -ff), and last line
FILE *fp = execve_thread->outf;
execve_thread->outf = tcp->outf;
tcp->outf = fp;
- if (execve_thread->real_outf || tcp->real_outf) {
- char *memfptr;
- size_t memfloc;
-
- fp = execve_thread->real_outf;
- execve_thread->real_outf = tcp->real_outf;
- tcp->real_outf = fp;
- memfptr = execve_thread->memfptr;
- execve_thread->memfptr = tcp->memfptr;
- tcp->memfptr = memfptr;
- memfloc = execve_thread->memfloc;
- execve_thread->memfloc = tcp->memfloc;
- tcp->memfloc = memfloc;
+ if (execve_thread->staged_output_data || tcp->staged_output_data) {
+ struct staged_output_data *staged_output_data;
+
+ staged_output_data = execve_thread->staged_output_data;
+ execve_thread->staged_output_data = tcp->staged_output_data;
+ tcp->staged_output_data = staged_output_data;
}
/* And their column positions */
* "strace -ff -oLOG test/threaded_execve" corner case.
* It's the only case when -ff mode needs reprinting.
*/
- if ((followfork < 2 && printing_tcp != tcp && tcp->real_outf == NULL)
+ if ((followfork < 2 && printing_tcp != tcp && !tcp->staged_output_data)
|| (tcp->flags & TCB_REPRINT)) {
tcp->flags &= ~TCB_REPRINT;
printleader(tcp);