io-redir.c

DownloadView Raw

/**
 * io-redir.c
 *
 * Demonstrates redirecting I/O with dup2.
 *
 * Compile: gcc -g -Wall io-redir.c -o io-redir
 * Run: ./io-redir
 */

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(void)
{
    /* First, let's find the FDs of our input/output streams: */
    printf("stdout fileno: %d\n", fileno(stdout));
    printf("stdin fileno: %d\n", fileno(stdin));
    printf("stderr fileno: %d\n", fileno(stderr));


    /* ----> Next: Let's redirect all output to a file: log.txt */


    /**
     * For a list of flags, see man 2 open:
     *
     * - O_RDWR - open for reading and writing (we could get by with O_WRONLY
     *            instead)
     * - O_CREAT - create file if it does not exist
     * - O_TRUNC - truncate size to 0
     */
    int open_flags = O_RDWR | O_CREAT | O_TRUNC;

    /**
     * These are the file permissions we see when doing an `ls -l`: we can
     * restrict access to the file. 0644 is octal notation for allowing the user
     * to read and write the file, while everyone else can only read it.
     */
    int open_perms = 0644;

    int fd = open("log.txt", open_flags, open_perms);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    if (dup2(fd, fileno(stdout)) == -1) {
        perror("dup2");
        return 1;
    }
    /* Note: after this call to dup2, the original stdout stream is closed */

    printf("This is going to go to the file!\n");
    printf("Amazing stuff, right? We can just redirect everything\n");
    printf("going to stdout somewhere else with this.\n");
    /* Note: the printfs up at the top of main() WILL print to stdout */

    fprintf(stderr, "This is headed to stderr though... Will it print?\n");
    fprintf(stderr, "Yup!\n");

    fprintf(stdout, "Printing back to stdout... Goodbye!\n");

    return 0;
}