Potoki w C pobranie danych z wejścia innego programu

0

Nie mogę odczytać danych przekierowanych do potoku wejściowego, oto kod:

int fd[2];
	int nbytes;
	pid_t childpid;
	char buffer[256];
	int i = 0;

	pipe(fd);

	if((childpid = fork()) == -1) {
		puts("FORK");
		perror("fork");
		exit(1);
	}

	if(childpid == 0) {
		
		// NIE DZIALA, zwraca 0 -> read(fd[0], buffer, sizeof(buffer));
		close(fd[0]);
		
		fgets(buffer, 256, stdin);
		write(fd[1], &buffer, 256);
		exit(0);

	} else {
		close(fd[1]);
		nbytes = read(fd[0], buffer, sizeof(buffer));
		printf("Received data: %s | size: %d\n", buffer, nbytes);
	
	}

Oczywiście czytanie z stdin nie ma sensu, gdyż o ile przekażemy do strumienia jakieś daje to wszystko ładnie działa. Jeśli natomiast nic nie przekażemy to mamy problem, gdyż program czeka na dane.
Zaznaczam chodzi o pobranie danych z wyjścia innego programu np. : ls -lt | ./moj_program.out

0

http://man7.org/linux/man-pages/man2/pipe.2.html
http://man7.org/linux/man-pages/man2/read.2.html
flaga O_NONBLOCK a potem łapanie błędu EAGAIN albo EWOULDBLOCK

0

To mi za dużo nie daje bo podczas odczytywania potoku nic tam nie ma.
Czyli jeśli w konsoli wydaje polecenie:
ls -lt | moj_program.out
w potoku nic nie ma.
A jeśli zrezygnuje z potoków i będę czytał z STDIN to jeśli odpalę program samodzielnie bez przekierowania strumienia to będzie odczytywał znaki z klawiatury. Tak więc lipa :(

0

No a niby z czego miałby odczytywać dane jak go odpalisz samodzielnie? o_O

0

OK, problem rozwiązałem, raczej podpinanie się pod potoki było mało sensowne.
Tak to zrobiłem w oparciu o potoki, ale w przypadku pobierania danych z stdin to mało sensowne rozwiązanie. Przerost formy nad treścią.

int fd[2];
	pid_t pid;
	char buffer[256];
	char* buff;
	int i = 0;
	size_t total = 0;
	int readed = 0;

	pipe(fd);
	pid = fork();


	switch(pid) {

		/* fork a child */
		case -1:
			perror("fork");
			exit(1);
			break;

		/* child - write to pipe */
		case 0:
			close(fd[0]);
			puts("Zapis danych do fd[1] !");
			

			while(!feof(stdin)) {
				readed = getline(&buff, &total, stdin);
				printf("...SAVING LINE... NR: %i\n", i+1);
				memcpy(buffer, buff, readed);
				write(fd[1], &buffer, readed);
				i++;
				
			}
			

			close(fd[1]);
			exit(0);
			break;

		/* parent - read from pipe */
		default:
			close(fd[1]);
			puts("Odczyt danych z potoku !");

			while( (read(fd[0], buffer, 256)) > 0 )
				printf("buffer: %s", buffer);

			putchar('\n');
			wait(NULL);
			close(fd[0]);
			exit(0);

	}

Patrzyłem w kod źródłowy cat.c http://www.opensource.apple.com/source/text_cmds/text_cmds-71/cat/cat.c i tam nikt się potokami nie bawił, tylko zwykłe podpięcie pod stdin. No cóż kombincje widocznie to moja specjalność ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1