Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
4.2 kB
1
Indexable
Never
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main (int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Please give exactly 1 argument!\n");
        /* Different errors return different values. */
        return 1; 
    }
    int fds[2];
    pid_t pid;
    /* Create a pipe. File descriptors for the two ends of the pipe are placed in fds. */
    if(pipe (fds) == -1) {
        /* If pipe() returns -1 then something went wrong. */
        fprintf(stderr, "Error creating a pipe: %s\n", strerror(errno));
        return 2;
    }
    /* Fork a child process. */
    pid = fork ();
    if(pid == -1) {
        /* If fork() returns -1 then something went wrong. */
        fprintf(stderr, "Error creating a child process: %s\n", strerror(errno));
        return 3;
    }
    if (pid == (pid_t) 0) {
        /* This is the child process. Close our copy of the write end of the file descriptor. */
        if(close (fds[1]) == -1) {
            /* If close() returns -1 then something went wrong. */
            fprintf(stderr, "Error closing a file descriptor: %s\n", strerror(errno));
            return 4;
        }
        /* Connect the read end of the pipe to standard input. */
        if(dup2 (fds[0], STDIN_FILENO) == -1) {
            /* If dup2() returns -1 then something went wrong. */
            fprintf(stderr, "Error duplicating a file descriptor: %s\n", strerror(errno));
            return 5;
        }
        FILE* outStream = fopen(argv[1], "w");
        if(outStream == NULL) {
            /* If fopen() returns NULL then something went wrong. */
            fprintf(stderr, "Error opening a file: %s\n", strerror(errno));
            return 6;
        }
        int outStrFD = fileno(outStream);
        /* Connect the output file to standard output. */
        if(dup2 (outStrFD, STDOUT_FILENO) == -1) {
            /* If dup2() returns -1 then something went wrong. */
            fprintf(stderr, "Error duplicating a file descriptor: %s\n", strerror(errno));
            return 5;
        }
        /* Replace the child process with the "sort” program. */
        if(execlp ("sort", "sort", NULL) == -1) {
            /* If execlp() returns -1 then something went wrong. */
            fprintf(stderr, "Error replacing the current process: %s\n", strerror(errno));
            return 7;
        }
    } else {
        /* This is the parent process. */
        FILE* stream;
        /* Close our copy of the read end of the file descriptor. */
        if(close (fds[0]) == -1) {
            /* If close() returns -1 then something went wrong. */
            fprintf(stderr, "Error closing a file descriptor: %s\n", strerror(errno));
            return 4;
        }
        /* Convert the write file descriptor to a FILE object, and write to it. */
        stream = fdopen (fds[1], "w");
        if(stream == NULL) {
            /* If fdopen() returns NULL then something went wrong. */
            fprintf(stderr, "Error associating a stream with a file descriptor: %s\n", strerror(errno));
            return 8;
        }
        fprintf (stream, "This is a test.\n");
        fprintf (stream, "Hello, world.\n");
        fprintf (stream, "My dog has fleas.\n");
        fprintf (stream, "This program is great.\n");
        fprintf (stream, "One fish, two fish.\n");
        if(fflush (stream) == EOF) {
            /* If fflush() returns EOF then something went wrong. */
            fprintf(stderr, "Error flushing output: %s\n", strerror(errno));
            return 9;
        }
        if(close (fds[1]) == -1) {
            /* If dup2() returns -1 then something went wrong. */
            fprintf(stderr, "Error closing a file descriptor: %s\n", strerror(errno));
            return 4;
        }
        /* Wait for the child process to finish. */
        if(waitpid (pid, NULL, 0) == -1) {
            /* If waitpid() returns -1 then something went wrong. */
            fprintf(stderr, "Error waiting for a process: %s\n", strerror(errno));
            return 10;
        }
    }
    return 0;
}