Всем привет! Вот такая проблема, создаю трубу, потом потомка, из потомка перевожу стандартный вывод на эту трубу и запускаю cat чарез execl, из родителя читаю всё что появится в трубе. Проблема заключается в том, что когда cat всё выведет в трубу и завершиться, труба не рушиться, хотя потомка уже нет среди процессов... где может быть промах?ps: ловил сигнал sigpipe, его не возникает. Конечно не воникнет, в труду надо записать сначала, и если её нет, то оно возникнет.
>Всем привет! Вот такая проблема, создаю трубу, потом потомка, из потомка перевожу
>стандартный вывод на эту трубу и запускаю cat чарез execl, из
>родителя читаю всё что появится в трубе. Проблема заключается в том,
>что когда cat всё выведет в трубу и завершиться, труба не
>рушиться, хотя потомка уже нет среди процессов... где может быть промах?С точки зрения читателя, достигается "конец файла", т.е. read
возвращает 0. Никакой другой индикации нет (и не нужно).>ps: ловил сигнал sigpipe, его не возникает. Конечно не воникнет, в труду
>надо записать сначала, и если её нет, то оно возникнет.Правильно, sigpipe доставляется при *записи* в закрытый канал.
>Всем привет! Вот такая проблема, создаю трубу, потом потомка, из потомка перевожу
>стандартный вывод на эту трубу и запускаю cat чарез execl, из
>родителя читаю всё что появится в трубе. Проблема заключается в том,
>что когда cat всё выведет в трубу и завершиться, труба не
>рушиться, хотя потомка уже нет среди процессов... где может быть промах?
>
>
>ps: ловил сигнал sigpipe, его не возникает. Конечно не воникнет, в труду
>надо записать сначала, и если её нет, то оно возникнет.Hi
1)
Probably problem is that you did not close "unused" pipe's descriptors in parent and child... You should do something like this (please be aware that I did not compile/run code below):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>#define BUFF_SZ 1024
int main( int argc, char** argv )
{
/* pseudo code not tested at all */
int pd[ 2 ]; /* pipe's descriptors */
pid_t child_pid;
long recieved = 0L;
char* buffer = NULL;
int res;pipe( pd );
if ( argc < 3 ) {
printf( "USAGE: ttt command_with_full_path file_to_be_processed\n" );
exit( 1 );
}
if( ( child_pid = fork() ) == -1 ) {
perror( "fork failed!!!" );
exit(1);
}if( child_pid == 0 ) {
printf( "Child entry\n" );
/* our child */
close( pd[ 0 ] ); /* close pipe's input */
dup2( pd[ 1 ], 1 ); /* stdout -> pipe's output */
res = execv( argv[ 1 ], argv + 1 );
if ( res != 0 )
perror( "execv failed!!!" );printf( "Child exit\n" );
exit( 0 );
}
else {
/* parent */
printf( "Parent \"entry\"\n" );
close( pd[ 1 ] ); /* close pipe's output */
buffer = (char*)malloc( BUFF_SZ );
for ( ; ; ) {
recieved = read( pd[ 0 ], buffer, BUFF_SZ );
printf( "Recieved=%ld\n", recieved );
if ( recieved == 0 )
break;
buffer[ recieved - 1 ] = '\0';
printf( "Buffer=[%s]\n", buffer );
}
free( buffer );
printf( "Parent \"exit\"\n" );
}return 0;
}
This code is just for example. No real error checks etc performed...Thanks
--- Sas
А вот ещё вопрос в догонку:Как мне в моем исходнике построить цепочку string mydata > prog1 | prog2 | ....
... > mydatabis
Вариант с одним потомком и двумя трубами у меня работает, а вот цепь никак
не могу приладить!
>А вот ещё вопрос в догонку:
>
>Как мне в моем исходнике построить цепочку string mydata > prog1 | prog2 | ....
>... > mydatabis
>Вариант с одним потомком и двумя трубами у меня работает, а вот
>цепь никак
>не могу приладить!Hi
Did not understand question. What are you trying to accomplish?
Where? Inside program or from shell?Thanks
--- sas
>>А вот ещё вопрос в догонку:
>>
>>Как мне в моем исходнике построить цепочку string mydata > prog1 | prog2 | ....
>>... > mydatabis
>>Вариант с одним потомком и двумя трубами у меня работает, а вот
>>цепь никак
>>не могу приладить!
>
>Hi
>
>Did not understand question. What are you trying to accomplish?
>Where? Inside program or from shell?
>
>Thanks
>--- sasВ общем, в cgi (C++ + cgicc) конвертирую пришедшие картинки и делаю тамбнэйл. Как сами понимаете,
париться над библиотеками не очень хочется, вот и прогоняю пришедшую
лабуду через трубу (djpeg | pnmscale | ppmtojpeg). Собственно, на данный
момент задача реализована, вот только одного понять не могу (код приводить
не буду, чтобы не вызывать всеобщег недоумения :))) : создаю четыре канала,
трех потомков, преренаправяляю ввод-вывод, закрываю лишние дескрипторы, пишу в первый канал, читаю из
последнего - все вроде как надо, только вот если читаю не по одному байту (fread(buf, 1000, 1, pipe))
то получается, что данные "где-то" пропадают, то есть получаю из трубы меньше,
чем в шеле. Но если читаю по одному байту - все чики-пики! И конечно раздражает
скорость операции! Нельзя ли прояснить где грабли?
PS> Why elglish? Many of us are sure been confused!
>>>А вот ещё вопрос в догонку:
>>>
>>>Как мне в моем исходнике построить цепочку string mydata > prog1 | prog2 | ....
>>>... > mydatabis
>>>Вариант с одним потомком и двумя трубами у меня работает, а вот
>>>цепь никак
>>>не могу приладить!
>>
>>Hi
>>
>>Did not understand question. What are you trying to accomplish?
>>Where? Inside program or from shell?
>>
>>Thanks
>>--- sas
>Hi,
Sorry for delay with the answer.
>В общем, в cgi (C++ + cgicc) конвертирую пришедшие картинки и делаю
>тамбнэйл. Как сами понимаете,
>париться над библиотеками не очень хочется, вот и прогоняю пришедшую
>лабуду через трубу (djpeg | pnmscale | ppmtojpeg). Собственно, на данный
>момент задача реализована, вот только одного понять не могу (код приводить
>не буду, чтобы не вызывать всеобщег недоумения :))) : создаю четыре канала,
>
>трех потомков, преренаправяляю ввод-вывод, закрываю лишние дескрипторы, пишу в первый канал, читаю
>из
>последнего - все вроде как надо, только вот если читаю не по
>одному байту (fread(buf, 1000, 1, pipe))
>то получается, что данные "где-то" пропадают, то есть получаю из трубы меньше,
>
>чем в шеле. Но если читаю по одному байту - все чики-пики!Without code it is impossible to find an exact problem. I would suggest to try with normal buffered read with 2 pipes and see. Then add one new pipe and check etc.
I think that may be you have a problem because you are trying to use standard i/o library where stdin/stdout are fully buffered streams (fopen/fwrite/fread/fclose). Try to rewrite application using open/close/write/read I/O functions.
Also why not use only one child which calls shell script with all your transformations and just return final result? I understand that you are want to dig deeper into the problem, but still...
>И конечно раздражает
>скорость операции! Нельзя ли прояснить где грабли?Obviously one byte read will be very slow.
>PS> Why elglish? Many of us are sure been confused!
1. On luchshe latinici. Ya i sam ee chiata' ne lublu i drugim ne gelaju.
2. Krome togo kak uge pisal, ya dumaju chto kagdii kto programmirovaniem zanimaetsya dolgen umet' chitat' angliiskie tehnicheskie texti
3. Moy angliiskii nastol'ko primitiven (k sogaleniju), chto ego dolgen ponyat' i perevesti luboy chelovek.
Thanks
--- Alex
Of course everyone at sysconsole MUST read, etc...
Думаю, это действительно проблема с буферизацией...
What about flush() ?:)
>>>>А вот ещё вопрос в догонку:
>>>>
>>>>Как мне в моем исходнике построить цепочку string mydata > prog1 | prog2 | ....
>>>>... > mydatabis
>>>>Вариант с одним потомком и двумя трубами у меня работает, а вот
>>>>цепь никак
>>>>не могу приладить!
>>>
>>>Hi
>>>
>>>Did not understand question. What are you trying to accomplish?
>>>Where? Inside program or from shell?
>>>
>>>Thanks
>>>--- sas
>>
>
>Hi,
>
>Sorry for delay with the answer.
>
>>В общем, в cgi (C++ + cgicc) конвертирую пришедшие картинки и делаю
>>тамбнэйл. Как сами понимаете,
>>париться над библиотеками не очень хочется, вот и прогоняю пришедшую
>>лабуду через трубу (djpeg | pnmscale | ppmtojpeg). Собственно, на данный
>>момент задача реализована, вот только одного понять не могу (код приводить
>>не буду, чтобы не вызывать всеобщег недоумения :))) : создаю четыре канала,
>>
>>трех потомков, преренаправяляю ввод-вывод, закрываю лишние дескрипторы, пишу в первый канал, читаю
>>из
>>последнего - все вроде как надо, только вот если читаю не по
>>одному байту (fread(buf, 1000, 1, pipe))
>>то получается, что данные "где-то" пропадают, то есть получаю из трубы меньше,
>>
>>чем в шеле. Но если читаю по одному байту - все чики-пики!
>
>Without code it is impossible to find an exact problem. I would
>suggest to try with normal buffered read with 2 pipes and
>see. Then add one new pipe and check etc.
>
>I think that may be you have a problem because you are
>trying to use standard i/o library where stdin/stdout are fully buffered
>streams (fopen/fwrite/fread/fclose). Try to rewrite application using open/close/write/read I/O functions.
>
>Also why not use only one child which calls shell script with
>all your transformations and just return final result? I understand that
>you are want to dig deeper into the problem, but still...
>
>
>
>>И конечно раздражает
>>скорость операции! Нельзя ли прояснить где грабли?
>
>Obviously one byte read will be very slow.
>
>>PS> Why elglish? Many of us are sure been confused!
>
>1. On luchshe latinici. Ya i sam ee chiata' ne lublu i
>drugim ne gelaju.
>2. Krome togo kak uge pisal, ya dumaju chto kagdii kto programmirovaniem
>zanimaetsya dolgen umet' chitat' angliiskie tehnicheskie texti
>3. Moy angliiskii nastol'ko primitiven (k sogaleniju), chto ego dolgen ponyat' i
>perevesti luboy chelovek.
>
>
>Thanks
>--- Alex