'how to use pipe and execvp in c via linux

I'm trying to use pipe command and I can't understand how to. I've a lot of versions but I can't make it work.

first of all the hierarchy: main prog - nicecmp - that will execute the child prog and print the result child prog - loopcmp - that will execute his child prog and get the returned value and send it back to the parent in nicecmp. loopcmp's childs - lencmp/lexcmp - both prog will be executed in loopcmp and return value between -1 to 2. (100% works)

shortly, I need to create a pipe and a new process that will run new program (loopcmp - added in the end of the code) using execvp, and I need to print the res of the loopcmp in the parent. I can send it directly from the prog that I executed and I can use WEXITSTATUS in the child after the end of the loopcmp. what's the right way to do so (from the progrem execution or after that I've returned from the loopcmp)

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define LINELEN (80)
#define READFROM ("./loopcmp")

typedef enum { eLexcmp, eLencmp, eNumOfCmp } eCmpstr;
const char* cmpstr[eNumOfCmp] = { "./lexcmp", "./lencmp" };


int lencmp(const char *str1, const char *str2);
int lexcmp(const char *str1, const char *str2);
char *mygets(char *buf, int len);
int mygeti();

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

    char str1[LINELEN + 1];
    char str2[LINELEN + 1];
    int index, rc, status, res;
    
    int pfd[2];/* Pipe file descriptors */

        if (pipe(pfd) == -1) /* Create pipe */
            exit(-2); // pipe failed !

    char* myargs[4];
    myargs[0]=strdup(READFROM);
    while (1)
    {
        printf("Please enter first string:\n");
        if (mygets(str1, LINELEN) == NULL)
            break;
        printf("Please enter second string:\n");
        if (mygets(str2, LINELEN) == NULL)
            break;
        myargs[2] = strdup(str1);
        myargs[3] = strdup(str2);
        do {
            printf("Please choose:\n");
            for (int i = 0; i < eNumOfCmp; i++)
                printf("%d - %s\n", i, cmpstr[i]);
            index = mygeti();

        } while ((index < 0) || (index >= eNumOfCmp));

        myargs[1] = strdup(cmpstr[index]);
        
        rc = fork();
        if (rc < 0)             // fork failed !
        {
            printf("fork failed\n");
            return -2;
        }
        else if (rc == 0) { // child !
              if (close(pfd[1]) == -1)                    /* Write end is unused */
            exit(-2);

        /* Duplicate stdin on read end of pipe; close duplicated descriptor */

        if (pfd[0] != STDIN_FILENO) {               /* Defensive check */
            if (dup2(pfd[0], STDIN_FILENO) == -1)
                exit(-2);
            if (close(pfd[0]) == -1)
                exit(-2);
        }

                execvp(myargs[0],myargs);   

            }       

        else { // parent
             if (close(pfd[1]) == -1)                    /* Write end is unused */
            exit(-2);

        /* Duplicate stdin on read end of pipe; close duplicated descriptor */

        if (pfd[0] != STDIN_FILENO) {               /* Defensive check */
            if (dup2(pfd[0], STDIN_FILENO) == -1)
                exit(-2);
            if (close(pfd[0]) == -1)
                exit(-2);
        }
            read(pfd[0], &res, sizeof(int));
            printf("%d\n", res);
            if (close(pfd[0]) == -1)
                exit(-2);
        }
    }
    return 0;

}

loopcmp ->

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

    int status,rc,res = 0;
    
    if (argc != 4)
    {
        return -1;
    }
    char* myargs[3];
    for(int i=0;i<3;i++){
        myargs[i]=argv[i+1];
        }

        rc = fork();
        if (rc < 0) //fork failed
        { 
            return -2;
        }
        else if (rc == 0) //I'm the child
        {
            
            if(execvp(myargs[1], myargs)==-1)
                return -2;
        }
        else // parent
        {
            wait(&status);
            res = WEXITSTATUS(status);
            if(res ==254) // invalid file path ! (254== -2)
            return -2 ;
        }
        write(fileno(stdout),&res,sizeof(int));
    return res;
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source