Pipe file bigger than 64Kb and get the size and send it to char *

169 Views Asked by At

I am trying to create a simple program using pipes, even though that are easier options for the same task (fopen(), lseek(), ftell(), etc).

First I use execve() to perform a terminal cat, and send the information through the pipe so I may be able to print the size of the file descriptor and read it to a malloc'd char pointer. My solution is this one:

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <fcntl.h>

int main (int argc, char *argv[]) {

    int fd[2], active;
    int pipe_sz = 0;
    char *name;

    pipe(fd);

    //change /bin/cat according to your system
    char *cmd[] = {"/bin/cat", "example.txt", NULL};


    if (fork() == 0) {

        //CHILD
        dup2(fd[1], STDOUT_FILENO);
        close(fd[1]);

        active = execve(cmd[0], cmd, NULL);


    } else {

        //PARENT
        wait(NULL);

        int ioctl_sz = ioctl(fd[0], FIONREAD, &pipe_sz);

        name = malloc(pipe_sz + 1);
        int result = read(fd[0], name, pipe_sz);
        name[pipe_sz] = '\0';

        printf("LEN NAME: %ld\n", strlen(name));

        close(fd[0]);
        close(fd[1]);

    }

    return 0;

}

Everything works fine as long as I keep myself inside the pipe's limits (my LINUX system is able to hold 65536 bytes). I decided to push the limits, and see what could happen. As expected, the program stays stuck when my file was above 65536 bytes.

I do not want to manually change my pipe's limits through fcntl(pipefd, F_SETPIPE_SZ, size) (since I "don't know" my file's size). Therefore, I researched, and came across the pipe2(pipefd, O_NONBLOCK) in order to avoid my pipe from stopping the reading process. Unfortunately, I received only this message:

/bin/cat: write error: Resource temporarily unavailable

I even tried a while loop read() and realloc() to see if my code could at least give the char pointer result, but I was not successful, and part of file was lost.

Is it possible to produce a code that may provide the same results as mine above with files bigger than 65536 bytes? Is there a way to interrupt the pipe if it takes too long to finish the process? Or even make a while loop to guess and resize the pipe through fcntl()?

Thanks everyone for the help!

0

There are 0 best solutions below