Skip to content
Advertisement

C: Trying to implement unnamed pipes

I’m trying to make a program that simlutates the terminal’s nameless pipes. For example, if I want to run the command:

ls –l | grep ‘10’

would be:

./pipes ls -l – grep ’10’

(I use – instead of |).

However, my program doesn’t work because execvp fails (bad adress). This seems impossible to me. What am I doing wrong? Any help would be welcome!

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

 void np_exec(char* cmd, char** argv)
 {
    int fd[2];

    while(*(++argv) != NULL)
    {
            pipe(fd);

            int pid = fork(); //parent executes
            if(pid < 0)
            {
                    printf("Error forking");
                    exit(1);
            }

            if(pid != 0) // parent
            {
                    dup2(fd[1],1);
                    close(fd[0]);  

                    if (execvp(cmd, *argv) == -1)
                    {
                            perror("execvp failed");
                    }
            }
            else
            {
                    dup2(fd[0],0); 
                    close(fd[1]);
            }
    }
}

int main(int argc, char** argv)
{
    assert(strcmp(argv[argc-1], "-"));

    int i;
    for (i = 1; i < argc; ++i) {
            if (!strcmp(argv[i], "-"))
            {
                    argv[i] = NULL;
                    np_exec(argv[1], &argv[1]);
                    argv = &argv[i];
                    argc -= i;
                    i = 0;
            }
    }

    char* args[argc];
    args[argc-1] = NULL;

    for (i = 1; i < argc; ++i) {
            args[i-1] = argv[i];
    }

    if (execvp(args[0], args) == -1)
            perror("execvp failed");

    return;
}

Advertisement

Answer

Replace:

                   if (execvp(cmd, *argv) == -1)

by:

               if (execvp(cmd, argv) == -1)

Notes:

a) is the warnign level you use high enough?

b) you must add a “#include” for “execvp”. In this way, the compiler will find by itself this error.

c) last return statement must be “return 0”. Again, compiler must warning you of this subject.

Advertisement