Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

stage_output.c 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2017 Intel Corporation
  3. * Copyright (c) 2019 Paul Chaignon <paul.chaignon@gmail.com>
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: LGPL-2.1-or-later
  7. */
  8. /*
  9. * open_memstream returns a FILE stream that allows writing to a
  10. * dynamically growing buffer, that can be either copied to
  11. * tcp->outf (syscall successful) or dropped (syscall failed)
  12. */
  13. #include "defs.h"
  14. struct staged_output_data {
  15. char *memfptr;
  16. size_t memfloc;
  17. FILE *real_outf; /* Backup for real outf while staging */
  18. };
  19. FILE *
  20. strace_open_memstream(struct tcb *tcp)
  21. {
  22. FILE *fp = NULL;
  23. #if HAVE_OPEN_MEMSTREAM
  24. tcp->staged_output_data = xmalloc(sizeof(*tcp->staged_output_data));
  25. fp = open_memstream(&tcp->staged_output_data->memfptr,
  26. &tcp->staged_output_data->memfloc);
  27. if (!fp)
  28. perror_msg_and_die("open_memstream");
  29. /*
  30. * Call to fflush required to update tcp->memfptr,
  31. * see open_memstream man page.
  32. */
  33. fflush(fp);
  34. /* Store the FILE pointer for later restauration. */
  35. tcp->staged_output_data->real_outf = tcp->outf;
  36. tcp->outf = fp;
  37. #endif
  38. return fp;
  39. }
  40. void
  41. strace_close_memstream(struct tcb *tcp, bool publish)
  42. {
  43. #if HAVE_OPEN_MEMSTREAM
  44. if (!tcp->staged_output_data) {
  45. debug_msg("memstream already closed");
  46. return;
  47. }
  48. if (fclose(tcp->outf))
  49. perror_msg("fclose(tcp->outf)");
  50. tcp->outf = tcp->staged_output_data->real_outf;
  51. if (tcp->staged_output_data->memfptr) {
  52. if (publish)
  53. fputs_unlocked(tcp->staged_output_data->memfptr,
  54. tcp->outf);
  55. else
  56. debug_msg("syscall output dropped: %s",
  57. tcp->staged_output_data->memfptr);
  58. free(tcp->staged_output_data->memfptr);
  59. tcp->staged_output_data->memfptr = NULL;
  60. }
  61. free(tcp->staged_output_data);
  62. tcp->staged_output_data = NULL;
  63. #endif
  64. }