Я немного новичок в программировании Linux на C (я искал похожие темы, но ни один не помог), поэтому я застрял в следующей проблеме:C: Перенаправить дочерний процесс на другой дочерний процесс ввода и stdout
Я хочу создать оболочку в C для Linux (используя fork(), exec(), pipe(), которая получает команду с параметрами и трубами в качестве входных данных из терминала stdin (например, sort foo | uniq -c | wc -l "), он выполняет его, а затем запрашивает следующую команду и т. д.
Я отделил разные команды, их параметры и т. д., я создал 1 дочерний процесс для каждого из них, но я не могу связать вывод каждого дочернего процесса на вход следующего (и последний вывод на stdout в Терминал).
Может ли кто-нибудь помочь сделать правильный трубопровод, чтобы его запустить?
Для любой дополнительной информации, просто спросить ... Заранее спасибо
Полный код ниже:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define P_READ 0
#define P_WRITE 1
pid_t pID, chID;
char input[100];
char * params[100][100];
char * funcs[100];
char * par;
char * fun;
int i, j, k, stat, infd[2], outfd[2];
//Pipe read
void read_en(int * infd)
{
dup2(infd[P_READ], STDIN_FILENO);
close(infd[P_READ]);
close(infd[P_WRITE]);
}
//Pipe write
void write_en(int * outfd)
{
dup2(outfd[P_WRITE], STDOUT_FILENO);
close(outfd[P_READ]);
close(outfd[P_WRITE]);
}
//Fork, read from pipe, write to pipe, exec
void fork_chain(int * infd, int * outfd, int i)
{
pID = fork();
if (pID == 0)
{
if (infd != NULL)
{
read_en(infd);
}
if (outfd != NULL)
{
write_en(outfd);
}
execvp(params[i][0], params[i]);
fprintf(stderr, "Command not found!\n");
exit(1);
}
else if (pID < 0)
{
fprintf(stderr, "Fork error!\n");
exit(1);
}
else
{
chID = waitpid(-1, &stat, 0);
}
}
int main()
{
printf("\n$");
fgets(input, sizeof(input), stdin);
strtok(input, "\n");
while (strcmp(input, "exit") != 0)
{
//Separate each command
k = 0;
fun = strtok(input, "|");
while (fun != NULL)
{
funcs[k] = fun;
fun = strtok(NULL, "|");
k++;
}
//Separate each command's parameters
for (i = 0; i < k; i++)
{
j = 0;
par = strtok(funcs[i], " ");
while (par != NULL)
{
params[i][j] = par;
par = strtok(NULL, " ");
j++;
}
params[i][j] = NULL;
}
//Fork, pipe and exec for each command
for (i = 0; i < k; i++)
{
if (i == 0)
{
pipe(outfd);
fork_chain(NULL, outfd, 0);
infd[P_READ] = outfd[P_READ];
infd[P_WRITE] = outfd[P_WRITE];
}
else if (i == k-1)
{
fork_chain(infd, NULL, 1);
close(infd[P_READ]);
close(infd[P_WRITE]);
}
else
{
pipe(outfd);
fork_chain(infd, outfd, i);
close(infd[P_READ]);
close(infd[P_WRITE]);
infd[P_READ] = outfd[P_READ];
infd[P_WRITE] = outfd[P_WRITE];
}
}
//Ask for next input
printf("\n$");
fgets(input, sizeof(input), stdin);
strtok(input, "\n");
}
return (0);
}
Связанный, если не дубликат: http://stackoverflow.com/q/5060350/694576 – alk
Тема, о которой вы говорили, составляет всего 2 ребенка. Я хочу больше 2, вот в чем проблема ... – Ezlen