
Linux - čtení dat z jiného procesu pomocí fgets
Ahoj všichni! Tentokrát se snažím naučit programovat v Linuxu, resp. kombinace shell + C. Mám prográmek, který by měl vytvořit 2 potomky rodičovského procesu, v jednom potomkovi potom zavolat funkci find a tento výpis poslat do druhého potomka, který by na to měl aplikovat moji vlastní fci grep.
Problém je v tom, že se program neukončuje - pokud mám dobře nastavené waity, myslím, že je problém ve fci grep, resp. přímo v použitém fgets. Ve škole byl sice zadaný, ale myslím si, že to není správně, protože čeká na EOF, ale při čtení dat zaslaných druhým procesem na žádný nenarazí a tak zůstane "viset" a neukončí se.
Snažil jsem se tedy najít nějakou funkci, která funguje jinak, a dostal jsem se k pojmu "asynchronní I/O", který s tímto problémem nejspíše souvisí. Bohužel, z internetu jsem nepochopil, jak se nějaká z těchto nových funkcí používá, a proto bych velmi ocenil, kdyby mi někdo poradil nějaký, úplně nejjednodušší způsob, jak na to :D
Moc díky za všechny rady a tipy, Katsu
P.s.: V případě, že v terminálu spustím find | ./grep ma , tak všechno funguje jak má, program se ukončí a vypíše soubory s názvem obsahujícím "ma". To mě mate - to si to pomocí svislítka nepřeposílá přímo ale vytváří nějaký mezisoubor? :D
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#define STDIN 0
#define STDOUT 1
#define STDERR 2
#define PIPEIN 1
#define PIPEOUT 0
int main(){
int st;
int p[2];
pipe(p);
if( st = fork() ){ // rodic
int stat;
if(waitpid(st, &stat, 0) == st){
printf("Potomek 1 skoncil\n");
}
int nd;
int p2[2];
pipe(p2);
if( nd = fork() ){ // rodic
int stat2;
if(waitpid(nd, &stat2, 0) == nd){
printf("Potomek 2 skoncil\n");
}
}else{ // potomek 2
// STDIN do roury
close( p[1] );
close( 0 );
dup2( p[0], 0 );
close( p[0] );
char *arg[] = {"./grep", "-i" , "Ma", NULL};
execvp(arg[0], arg);
}
//while(wait(NULL) != -1);
}else{ // potomek 1
// STDOUT do roury
//*
close( p[0] );
close( 1 );
dup2( p[1], 1);
close( p[1] );
//*/
char *arg[] = {"find", NULL}; // vyhleda C soubory
execvp(arg[0], arg);
}
while(wait(NULL) != -1);
return 0;
}
grep.c:
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[]){
char line[1024]; // buffer
char znak;
while( fgets( line, sizeof(line), stdin ) ){
if( strcmp( argv[1], "-i") == 0 ){ // NESTACI jen argv[1]=="-i" - to by porovnavalo jen pointery, ne hodnotu stringu
if( strcasestr( line, argv[2] ) ){
printf("%s", line);
}
}else{
if( strstr( line, argv[1] ) ){
printf("%s", line);
}
}
}
printf("Konci GREP...\n");
return 0;
}