Проверка аргумента программы
Чтобы убедиться, что указан параметр имени файла, вы можете проверить следующее:
if (argc < 2) {
fprintf(stderr, "usage: progname <filename>");
exit(EXIT_FAILURE);
}
Открытие файла
Предположительно, имеет смысл проверить, успешно ли работает fopen.
Вы можете сделать проверку, например, так:
if ((fptr = fopen(argv[1], "r")) == NULL) {
perror("error opening file");
exit(EXIT_FAILURE);
}
Также как упомянуто @ В комментариях этот код можно переместить к ребенку.
Чтение файла
Чтение файла можно сделать так:
while (fgets(singleLine, sizeof(singleLine), fptr)) {
write(pipefds[1], singleLine, strlen(singleLine));
}
Как упоминал Джонатан Леффлер в комментариях, не следует проверять заранее. Также важно отметить, что вы не хотите записывать sizeof (singleLine) байтов, потому что строки могут иметь переменный размер и быть короче размера буфера, поэтому лучше использовать strlen(singleLine)
здесь.
Чтение данных
Чтение данных должно происходить в течение всего oop - до тех пор, пока данные доступны. Вызов read
возвращает количество прочитанных байтов.
ssize_t n;
while ((n = read(pipefds[0], buffer, sizeof(buffer) - 1)) > 0) {
buffer[n] = '\0';
printf("%s", buffer);
}
Чтобы не сохранять данные за пределами буфера, вы можете использовать sizeof(buffer) - 1
в качестве третьего аргумента вызова чтения.
Программа
Таким образом, ваша программа, слегка измененная с учетом вышеуказанных пунктов, может выглядеть так:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
int pipefds[2];
char buffer[100];
if (argc < 2) {
fprintf(stderr, "usage: progname <filename>");
exit(EXIT_FAILURE);
}
if (pipe(pipefds) == -1) {
perror("PIPE ERROR");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid == 0) {
FILE *fptr;
if ((fptr = fopen(argv[1], "r")) == NULL) {
perror("error opening file");
exit(EXIT_FAILURE);
}
char singleLine[150];
close(pipefds[0]);
while (fgets(singleLine, sizeof(singleLine), fptr)) {
write(pipefds[1], singleLine, strlen(singleLine));
}
int error = ferror(fptr);
fclose(fptr);
if (error) {
perror("error reading file");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
} else if (pid > 0) {
close(pipefds[1]);
ssize_t n;
while ((n = read(pipefds[0], buffer, sizeof(buffer) - 1)) > 0) {
buffer[n] = '\0';
printf("%s", buffer);
}
close(pipefds[0]);
}
return 0;
}