]> granicus.if.org Git - graphviz/commitdiff
add funcions to buffer stderr - needed for displaying errors in window instead of...
authorJohn Ellson <ellson@research.att.com>
Fri, 25 Oct 2013 18:58:02 +0000 (14:58 -0400)
committerJohn Ellson <ellson@research.att.com>
Fri, 25 Oct 2013 18:58:02 +0000 (14:58 -0400)
lib/gvc/Makefile.am
lib/gvc/gvbuffstderr.c [new file with mode: 0644]

index 773c70ffd8b92f540d529415c5f2d5d95261a9ef..1bab7f082fc0490b5693840a4955cffad1f97e93 100644 (file)
@@ -34,7 +34,7 @@ pdf_DATA = gvc.3.pdf
 
 libgvc_C_la_SOURCES = gvrender.c gvlayout.c gvdevice.c gvloadimage.c \
        gvcontext.c gvjobs.c gvevent.c gvplugin.c gvconfig.c \
-       gvtextlayout.c gvusershape.c gvc.c
+       gvtextlayout.c gvusershape.c gvbuffstderr.c gvc.c
 libgvc_C_la_LIBADD = \
        $(top_builddir)/lib/pack/libpack_C.la \
        $(top_builddir)/lib/xdot/libxdot_C.la \
diff --git a/lib/gvc/gvbuffstderr.c b/lib/gvc/gvbuffstderr.c
new file mode 100644 (file)
index 0000000..b1c6eb3
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+
+struct buff_s {
+    int fd;
+    fpos_t pos;
+    char *template;
+};
+
+/* switch stderr output to temporary file buffering
+ */ 
+void *buffstderr(void)
+{
+    char *p;
+    struct buff_s *b;
+
+    assert ((b = malloc(sizeof(struct buff_s))));
+    assert ((b->template = strdup("/tmp/stderr_buffer_XXXXXX")));
+    assert ((p = mktemp(b->template)));
+    fflush(stderr);
+    fgetpos(stderr, &(b->pos));
+    b->fd = dup(fileno(stderr));
+    freopen(b->template, "w+", stderr);
+    return (void *)b;
+}
+
+/* switch stderr output back to normal,
+ *    and return any buffered output in a malloc'ed buffer
+ */
+char *unbuffstderr(struct buff_s *b)
+{
+    long sz;
+    char *t = NULL;
+    FILE *f;
+
+    fflush(stderr);
+    sz = ftell(stderr);
+    dup2(b->fd, fileno(stderr));
+    close(b->fd);
+    clearerr(stderr);
+    fsetpos(stderr, &(b->pos));
+
+    if (sz) {
+        /* stderr has been restored; these asserts use normal stderr output */
+        assert((t = malloc(sz+1)));
+        assert((f = fopen(b->template, "r")));
+        assert( fread(t, 1, sz, f) == sz);
+        fclose(f);
+        t[sz]='\0';
+    }
+
+    unlink(b->template);
+    free(b->template);
+    free(b);
+
+    return t;
+}
+
+#if 0  /* FOR TESTING */
+int main (int argc, char *argv[]) {
+
+        void *buff;
+        char *text;
+
+        fprintf(stderr, "First message\n");
+
+        buff = buffstderr();
+        fprintf(stderr, "Second message\n");
+
+        fprintf(stderr, "Third message\n");
+        
+        text = unbuffstderr(buff);
+        fprintf(stderr, "Fourth message\n");
+
+        if (text) {
+            fprintf(stderr, text);
+            free(text);
+        }
+
+        return 0;
+}
+#endif