Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Example of how to intercept messages to stdout/stderr
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#if defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X, 4096, O_BINARY)
#define fileno _fileno
#define dup _dup
#define dup2 _dup2
#define read _read
#include "uv.h"
uv_thread_t stdout_thread;
uv_thread_t stderr_thread;
static bool process_alive_ = true;
static void stdio_dup(void* arg) {
FILE* std_io = static_cast<FILE*>(arg);
char buf[256];
int fds[2];
int res;
int saved_stdio = dup(fileno(std_io));
res = pipe(fds);
assert(res == 0);
res = dup2(fds[1], fileno(std_io));
assert(res != -1);
// Windows does not buffer calls.
#if defined(__unix__) || defined(__unix) || \
(defined(__APPLE__) && defined(__MACH__))
setvbuf(std_io, nullptr, _IONBF, 0);
while (process_alive_) {
res = read(fds[0], buf, sizeof(buf) - 1);
assert(res >= 0 && res < sizeof(buf));
buf[res] = '\0';
dprintf(saved_stdio, "buf => %s\n", buf);
if (!process_alive_) break;
dup2(saved_stdio, fileno(std_io));
// TODO(trevnorris): Restore vbuf settings for std_io.
int main() {
uv_thread_create(&stdout_thread, stdio_dup, stdout);
uv_thread_create(&stderr_thread, stdio_dup, stderr);
printf("sleep 1");
printf("sleep 2");
printf("sleep 3");
process_alive_ = false;
printf("\nbye stdout");
fprintf(stderr, "\nbye stderr");
printf("all done\n");
return 0;

This comment has been minimized.

Copy link

commented Feb 24, 2017

Good job @trevnorris!

But two threads? It's not like you're having to deal with Java or something ... ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.