Это домашнее задание. Задача состоит в том, чтобы повторить команду: ls | wc -l
в программе C, используя execlp
, fork
и каналы.
Мой подход
I думаю, что проблему можно решить следующим образом:
- Создайте файл канала:
pipe.txt
- Создайте дочерний процесс, используя
fork()
- Сопоставьте
stdout
дочернего процесса в pipe.txt
- Выполнить
ls
, используя execlp
- Это помещает вывод
ls
в pipe.txt
- Внутри родительского процесса
- Сопоставить
stdin
родительского процесса с pipe.txt
- Выполнить
wc -l
, используя execlp
без предоставления каких-либо дополнительных аргументов, поэтому он читает из stdin вместо этого - Поскольку
stdout
этого родительского процесса все еще является самим терминалом, поэтому он должен распечатать количество строк на терминале
Мой код
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
int main() {
int pipefds[2];
int returnstatus;
int pid;
char argArr[30] = {'\n'};
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
int file_desc = open("pipe.txt", O_RDWR | O_APPEND | O_CREAT);
pid = fork();
if (pid == 0) {
int copy_desc = dup2(file_desc, 1);
execlp("ls", "ls", NULL);
} else {
int copy_desc = dup2(file_desc, 0);
close(copy_desc);
execlp("wc", "wc", "-l", NULL);
}
return 0;
}
Фактический вывод
main.cpp blabla.cpp main pipe.txt
>
Проблемы
Две вещи, которые неправильно с этим:
Он начинает ждать, пока пользователь предоставит ввод? Разве он не должен получать данные из файла канала вместо пользователя?
Ожидаемый результат
5
*, если имеется 5 файлов в текущем каталоге
Tried Solutions
- Использование только канала: (Получена ошибка дескриптора файла)
int main() {
int pipefds[2];
int returnstatus;
int pid;
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
pid = fork();
if (pid == 0) {
dup2(pipefds[0], 1);
close(pipefds[1]);
execlp("ls", "ls", NULL);
} else {
dup2(pipefds[1], 0);
close(pipefds[0]);
execlp("wc", "wc", "-l", NULL);
}
return 0;
}