#c #linux #bash
#c #linux #bash
Вопрос:
Более конкретно, предполагается, что программа эмулирует команду bash cat file| grep $keyword > file
. Что я сделал: в родительском я считываю каждый символ из файла и форматирую их в строки, которые затем отправляю в именованный канал, затем в дочернем записываю строки, содержащие ключевое слово, в исходный файл.
Однако я получаю ошибку ошибки сегментации при попытке прочитать второй символ из исходного файла, что, как я предполагаю, связано с тем, что родительский элемент ожидает, что дочерний элемент запишет в исходный файл вместо чтения содержимого указанного файла.
Любая помощь с реализацией / объяснением того, почему именно возникает ошибка, была бы отличной.
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
char key[20], *c,line[40];
int fd,fd_r,fd_w,fd_fr,fd_fw,counter=0;
int main(){
pid_t pid;
mkfifo("fifo1",0777);
fgets(key,10,stdin);
int k=0;
if ((pid=fork()) < 0)
perror("err_fork");
if(pid){ //PARENT
printf("%dn",fd_r=open("prog.c",O_RDONLY));
printf("%dn",fd_fw=open("fifo1",O_WRONLY));
while(read(fd_r,c,1)){
line[k ]=(*c);
while(read(fd_r,c,1) amp;amp; ((*c)!='n'))
line[k ]=(*c);
line[k]=0;
write(fd_fw,line,strlen(line) 1);
memset(line,0,sizeof(line));
}
close(fd_r);
close(fd_fw);
}
else{ //CHILD
printf("%dn",fd_w=open("prog.c",O_WRONLY));
printf("%dn",fd_fr=open("fifo1",O_RDONLY));
while(read(fd_fr,line,sizeof(line))){
c=strstr(line,key);
if(c)
write(fd_w,line,strlen(line) 1);
}
close(fd_w);
close(fd_fr);
}
unlink("fifo1");
}
Комментарии:
1. Вы знаете, что команда bash
cat file| grep $keyword > file
принципиально не будет работать? Обычно это просто усекает файл. Я полагаю, вы можете эмулировать его прерывистость, если действительно хотите, но какой в этом смысл?2. Кроме того,
while(read(...))
это не очень хороший способ решения проблем, потому что в случае ошибкиread()
возвращает-1
значение, отличное от нуля, и, следовательно, приведет к продолжению цикла, даже еслиc
он не содержит новых данных.3. Если вам не нужно различать error и EOF, вы можете использовать
while (read(...) > 0)
4. Дочернему элементу необходимо обрезать файл, прежде чем он его закроет. В противном случае в конце файла все равно будут строки, которые не были перезаписаны.
5. @NateEldredge Это не эмулирует эту прерывистость, потому что она не используется
O_TRUNC
при открытии выходного файла.
Ответ №1:
Вы нарушаете сегментацию, потому что пытаетесь прочитать байт c
. Однако, c
является неинициализированным глобальным указателем и, следовательно, равен NULL
. Поэтому попытка считывания данных в этом месте является недопустимым использованием памяти.
Вместо этого вы объявляете
char c;
и затем
read(fd_r,amp;c,1)
Комментарии:
1. Ну, он глобальный, поэтому инициализируется значением NULL. Но на самом деле, вы не можете читать в нем.