I need the main prog to get two strings from the user and an argument for the other program, call fork() and then in child process I need to write the strings into pipe and send them to the other program which returns an int which I want to pass to parent so I'm trying to use another pipe for it but every time it stops right after inserting the strings.
So the main program: (EDITED)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/wait.h>
#define LINELEN (80)
char *mygets(char *buf, int len);
int mygeti();
int main(int argc, char *argv[])
{
char *cmpstr[] = {"lexcmp", "lencmp"};
int veclen = sizeof(cmpstr)/sizeof(char *);
char str1[LINELEN + 1];
char str2[LINELEN + 1];
int index;
int pid[2];
int pfd[4][2];
for(int i = 0; i < 4; i++)
{
if(pipe(pfd[i]) < 0)
{
perror("pipe");
return -2;
}
}
pid[0] = fork();
if(pid[0] == 0) // child a
{
close(pfd[0][1]);
close(pfd[2][0]);
dup2(pfd[0][0], STDIN_FILENO);
dup2(pfd[2][1], STDOUT_FILENO);
char *myargs[3];
myargs[0] = "./loopcmp";
myargs[1] = "lexcmp";
myargs[2] = NULL;
if(execvp(myargs[0], myargs) == -1)
{
perror("exec");
return -2;
}
close(pfd[0][0]);
close(pfd[2][1]);
}
else
{
pid[1] = fork();
if(pid[1] == 0) //child b
{
close(pfd[1][1]);
close(pfd[3][0]);
dup2(pfd[1][0], STDIN_FILENO);
dup2(pfd[3][1], STDOUT_FILENO);
char *myargs[3];
myargs[0] = "./loopcmp";
myargs[1] = "lencmp";
myargs[2] = NULL;
if(execvp(myargs[0], myargs) == -1)
{
perror("exec");
return -2;
}
close(pfd[1][0]);
close(pfd[3][1]);
}
else // parent
{
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;
do {
printf("Please choose:\n");
for (int i=0 ; i < veclen ; i++)
printf("%d - %s\n", i, cmpstr[i]);
index = mygeti();
} while ((index < 0) || (index >= veclen));
close(pfd[index][0]);
if(write(pfd[index][1], str1, strlen(str1)) == -1)
{
perror("writeToPipe");
return -2;
}
if(write(pfd[index][1], str2, strlen(str2)) == -1)
{
perror("writeToPipe");
return -2;
}
if(index == 0)
{
close(pfd[2][1]);
char rbuf[1];
while(read(pfd[2][0], &rbuf, 1) > 0)
{
write(STDOUT_FILENO, &rbuf, 1);
}
}
if(index == 1)
{
close(pfd[3][1]);
char rbuf[1];
while(read(pfd[3][0], &rbuf, 1) > 0)
{
write(STDOUT_FILENO, &rbuf, 1);
}
}
}
}
}
return 0;
}
char *mygets(char *buf, int len)
{
char *retval;
retval = fgets(buf, len, stdin);
buf[len] = '\0';
if (buf[strlen(buf) - 1] == 10) /* trim \r */
buf[strlen(buf) - 1] = '\0';
else if (retval)
while (getchar() != '\n'); /* get to eol */
return retval;
}
int mygeti()
{
int ch;
int retval=0;
while(isspace(ch=getchar()));
while(isdigit(ch))
{
retval = retval * 10 + ch - '0';
ch = getchar();
}
while (ch != '\n')
ch = getchar();
return retval;
}
The other program - loopcmp: (Here I shouldn't change anything)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINELEN (80)
int lencmp(const char *str1, const char *str2);
int lexcmp(const char *str1, const char *str2);
char *mygets(char *buf, int len);
int main(int argc, char *argv[])
{
int(*cmpfunc)(const char *, const char *) = NULL;
char str1[LINELEN + 1];
char str2[LINELEN + 1];
if (argc != 2)
return -1;
if (!strcmp(argv[1], "lexcmp"))
cmpfunc = lexcmp;
else if (!strcmp(argv[1], "lencmp"))
cmpfunc = lencmp;
else
return -1;
while (1)
{
if (mygets(str1, LINELEN) == NULL)
break;
if (mygets(str2, LINELEN) == NULL)
break;
printf("%d\n", cmpfunc(str1, str2));
fflush(stdout);
}
return 0;
}
int lencmp(const char *str1, const char *str2)
{
int val;
val = strlen(str1) - strlen(str2);
if (val < 0)
return 1;
if (val > 0)
return 2;
return 0;
}
int lexcmp(const char *str1, const char *str2)
{
int val;
val = strcmp(str1, str2);
if (val < 0)
return 1;
if (val > 0)
return 2;
return 0;
}
char *mygets(char *buf, int len)
{
char *retval;
retval = fgets(buf, len, stdin);
buf[len] = '\0';
if (buf[strlen(buf) - 1] == 10) /* trim \r */
buf[strlen(buf) - 1] = '\0';
else if (retval) while (getchar() != '\n'); /* get to eol */
return retval;
}
This is what I get: Picture
and what I actually need it to print the interger returned from the exec of the child and then start again and get new two strings and so on till the user exits. what am I doing wrong? I can only modify the main program (the first one)