I am trying to do a multiple grep using c language. Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char** argv)
{
int pid1, pid2;
int stdout = 1;
int pipefd[2];
char* name = malloc(sizeof(char) * 100);
char* year = malloc(sizeof(char) * 100);
bzero(name, sizeof(name));
bzero(year, sizeof(year));
pid1 = fork();
if(pid1 == 0){
strcpy(name, "Jack");
strcpy(year, "2018");
close(1);
if(pipe(pipefd) == -1){
perror("pipe");
exit(-1);
}
pid2 = fork();
dup(pipefd[1]);
close(pipefd[1]);
execlp("grep", "grep", year, "file.txt", (char*)NULL);
if(pid2 == 0){
read(pipefd[0], &stdout, sizeof(stdout));
int a = dup2(pipefd[0], 0);
close(pipefd[0]);
execlp("grep", "grep", name, a, (char*)NULL);
}
} else if (pid1 < 0){
printf("pid error\n");
}
}
So basically it gives me error in the first exec, saying that the file descriptor is invalid. I didn't find a solution to pass the result of the first exec to the second fork.
Your program behaves like this (I only look at fork
and exec
calls):
fork
: you have 2 processes: A(parent) and B(child)fork
: you have 2 processes B and C its childexec
a grep command.grep
processes.But, you were not far to a solution.
What you have to do is:
create the second child
wait for child to end.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char **argv)
{
int pid1, pid2;
int stdout = 1;
int pipefd[2];
/* patterns to search */
char name[] = "Jack";
char year[] = "2018";
/* pipe creation */
if (pipe(pipefd) == -1) {
perror("pipe");
exit(-1);
}
/* create first child */
pid1 = fork();
if (pid1 == 0) {
close(pipefd[0]);
dup2(pipefd[1], 1);
close(pipefd[1]);
execlp("grep", "grep", year, "file.txt", (char *) NULL);
}
/* second child */
pid2 = fork();
if (pid2 == 0) {
close(pipefd[1]);
dup2(pipefd[0], 0);
close(pipefd[0]);
execlp("grep", "grep", name, "-", (char *) NULL);
}
/* close pipe to prevent child hang up */
close(pipefd[0]);
close(pipefd[1]);
while (1) {
pid_t cid = wait(NULL);
if (-1 == cid)
break;
printf("process %d terminated\n", cid);
}
}