Home > Software engineering >  using gzip through pipe in c
using gzip through pipe in c

Time:10-21

i am trying to compress a file in my program using gzip. i fork() and in the parent i write the initial file to the pipe. then in the child process i use execl() to use gzip. the gzip file is being created it is being compressed however for some reason it is being created without read or write permissions the code that does this:


int main (int argc, char **argv){
    int pipe1[2];
    pid_t childpid;
    FILE *fdin;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s file\n", argv[0]);
        exit(1);
    }

    pipe(pipe1);

    // error handling
    if ((childpid = fork()) == -1){
        perror("fork");
        exit(1);
    }

    // parent load file, write to pipe1
    if (childpid != 0){
        char buf[1024];
        close(pipe1[0]);

        fdin = fopen(argv[1], "r");
        if (fdin == 0)
        {
            fprintf(stderr, "%s: failed to open file '%s'\n", argv[0], argv[1]);
            exit(1);
        }

        int nbytes = fread(buf, 1, sizeof(buf), fdin);
        if (nbytes <= 0)
        {
            fprintf(stderr, "%s: no data in file '%s'\n", argv[0], argv[1]);
            exit(1);
        }
        fclose(fdin);

        write(pipe1[1], buf, nbytes);
        close(pipe1[1]);
    }
    // child process
    else if (childpid == 0){
        close(pipe1[1]);
        dup2(pipe1[0], STDIN_FILENO);
        close(pipe1[0]);

        int fd1    = open("trovetest.gz", O_WRONLY | O_CREAT);
        dup2(fd1, 1);
        close(fd1);

        
        int i = execl("/usr/bin/gzip","/usr/bin/gzip", (char*)NULL);
        if (i<0) {
            perror("execl");
        }

        perror("/usr/bin/gzip");

        exit(EXIT_FAILURE);
    }

    // wait child
    wait(NULL);

    return 0;
}

any ideas of what i am doing incorrectly? thanks.

CodePudding user response:

When you open a file with O_CREAT you also have to pass the permissions as the third argument. Otherwise some stack garbage is used (in your case apparently 0).

The current umask is removed from these permissions to make the actual file permissions. Don't worry about umask except that it's normally 002 or 022 which prevents the file from being writable by the group (sometimes) or by everyone).

You can pass e.g. 0644 to give rw-r--r-- permissions (readable by everyone and writable only by owner):

 int fd1    = open("trovetest.gz", O_WRONLY | O_CREAT, 0644);
 //                                                    ^^^^
  • Related