Graphviz  2.41.20170921.2350
gvbuffstderr.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <assert.h>
6 
7 struct buff_s {
8  int fd;
9  fpos_t pos;
10  char *template;
11 };
12 
13 /* switch stderr output to temporary file buffering
14  */
15 void *buffstderr(void)
16 {
17 #ifdef _WIN32
18  char *p;
19 #else
20  int t;
21 #endif
22  struct buff_s *b;
23 
24  assert ((b = malloc(sizeof(struct buff_s))));
25  assert ((b->template = strdup("/tmp/stderr_buffer_XXXXXX")));
26 #ifdef _WIN32
27  p = mktemp(b->template);
28  assert (p);
29 #else
30  t = mkstemp(b->template);
31  assert (t > 0);
32 #endif
33  fflush(stderr);
34  fgetpos(stderr, &(b->pos));
35  b->fd = dup(fileno(stderr));
36  freopen(b->template, "w+", stderr);
37  return (void *)b;
38 }
39 
40 /* switch stderr output back to normal,
41  * and return any buffered output in a malloc'ed buffer
42  */
43 char *unbuffstderr(struct buff_s *b)
44 {
45  long sz;
46  char *t = NULL;
47  FILE *f;
48 
49  fflush(stderr);
50  sz = ftell(stderr);
51  dup2(b->fd, fileno(stderr));
52  close(b->fd);
53  clearerr(stderr);
54  fsetpos(stderr, &(b->pos));
55 
56  if (sz) {
57  /* stderr has been restored; these asserts use normal stderr output */
58  assert((t = malloc(sz+1)));
59  assert((f = fopen(b->template, "r")));
60  assert( fread(t, 1, sz, f) == sz);
61  fclose(f);
62  t[sz]='\0';
63  }
64 
65  unlink(b->template);
66  free(b->template);
67  free(b);
68 
69  return t;
70 }
71 
72 #if 0 /* FOR TESTING */
73 int main (int argc, char *argv[]) {
74 
75  void *buff;
76  char *text;
77 
78  fprintf(stderr, "First message\n");
79 
80  buff = buffstderr();
81  fprintf(stderr, "Second message\n");
82 
83  fprintf(stderr, "Third message\n");
84 
85  text = unbuffstderr(buff);
86  fprintf(stderr, "Fourth message\n");
87 
88  if (text) {
89  fprintf(stderr, text);
90  free(text);
91  }
92 
93  return 0;
94 }
95 #endif
#define assert(x)
Definition: cghdr.h:47
void * buffstderr(void)
Definition: gvbuffstderr.c:15
char * unbuffstderr(struct buff_s *b)
Definition: gvbuffstderr.c:43
int fd
Definition: gvbuffstderr.c:8
char * template
Definition: gvbuffstderr.c:10
#define NULL
Definition: logic.h:39
fpos_t pos
Definition: gvbuffstderr.c:9
int main(int argc, char **argv)
Definition: dot.c:95