common: drop model_print_summary()
[c11tester.git] / common.cc
index bbb30539a8bd36710d9837614c2823b4f1ed3894..9cb7239d0a32d6bdcda8e41b1af252c190469d9e 100644 (file)
--- a/common.cc
+++ b/common.cc
 
 #define MAX_TRACE_LEN 100
 
-FILE *model_out;
-int fd_user_out; /**< @brief File descriptor from which to read user program output */
+/** @brief Model-checker output file descriptor; default to stdout until redirected */
+int model_out = STDOUT_FILENO;
 
 #define CONFIG_STACKTRACE
 /** Print a backtrace of the current program state. */
 void print_trace(void)
 {
 #ifdef CONFIG_STACKTRACE
-       print_stacktrace(stdout);
+       FILE *file = fdopen(model_out, "w");
+       print_stacktrace(file);
+       fclose(file);
 #else
        void *array[MAX_TRACE_LEN];
        char **strings;
@@ -40,14 +42,9 @@ void print_trace(void)
 #endif /* CONFIG_STACKTRACE */
 }
 
-void model_print_summary(void)
-{
-       model->print_summary();
-}
-
 void assert_hook(void)
 {
-       model_print("Add breakpoint to line %u in file %s.\n",__LINE__,__FILE__);
+       model_print("Add breakpoint to line %u in file %s.\n", __LINE__, __FILE__);
 }
 
 void model_assert(bool expr, const char *file, int line)
@@ -60,12 +57,16 @@ void model_assert(bool expr, const char *file, int line)
        }
 }
 
+#ifndef CONFIG_DEBUG
+
+static int fd_user_out; /**< @brief File descriptor from which to read user program output */
+
 /**
  * @brief Setup output redirecting
  *
  * Redirects user program's stdout to a pipe so that we can dump it
  * selectively, when displaying bugs, etc.
- * Also connects a special file 'model_out' directly to stdout, for printing
+ * Also connects a file descriptor 'model_out' directly to stdout, for printing
  * data when needed.
  *
  * The model-checker can selectively choose to print/hide the user program
@@ -77,14 +78,17 @@ void model_assert(bool expr, const char *file, int line)
  * output much data, we will need to buffer it in user-space during execution.
  * This also means that if ModelChecker decides not to print an execution, it
  * should promptly clear the pipe.
+ *
+ * This function should only be called once.
  */
 void redirect_output()
 {
-       int fd;
-
        /* Save stdout for later use */
-       fd = dup(fileno(stdout));
-       model_out = fdopen(fd, "w");
+       model_out = dup(STDOUT_FILENO);
+       if (model_out < 0) {
+               perror("dup");
+               exit(EXIT_FAILURE);
+       }
 
        /* Redirect program output to a pipe */
        int pipefd[2];
@@ -92,11 +96,17 @@ void redirect_output()
                perror("pipe");
                exit(EXIT_FAILURE);
        }
-       fd = dup2(pipefd[1], fileno(stdout)); // STDOUT_FILENO
+       if (dup2(pipefd[1], STDOUT_FILENO) < 0) {
+               perror("dup2");
+               exit(EXIT_FAILURE);
+       }
        close(pipefd[1]);
 
        /* Save the "read" side of the pipe for use later */
-       fcntl(pipefd[0], F_SETFL, O_NONBLOCK);
+       if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) < 0) {
+               perror("fcntl");
+               exit(EXIT_FAILURE);
+       }
        fd_user_out = pipefd[0];
 }
 
@@ -143,19 +153,19 @@ void print_program_output()
        fflush(stdout);
 
        /* Read program output pipe and write to (real) stdout */
-       int ret;
+       ssize_t ret;
        while (1) {
                ret = read_to_buf(fd_user_out, buf, sizeof(buf));
                if (!ret)
                        break;
                while (ret > 0) {
-                       int res = fwrite(buf, 1, ret, model_out);
+                       ssize_t res = write(model_out, buf, ret);
                        if (res < 0) {
-                               errno = ferror(model_out);
-                               perror("fwrite");
+                               perror("write");
                                exit(EXIT_FAILURE);
                        }
                        ret -= res;
                }
        }
 }
+#endif /* ! CONFIG_DEBUG */