/*
Ниже небольшая тестовая программа на СИ. Она в принципе работает.
И заглушка утилиты.
Замечу следующее.
Запись в pipe делается, если там есть свободное место, если не ошибаюсь 512 байт.
Если в утилите построчная буферизация, то скорее всего и будете получать построчно.
Если там другая буферизация или строки длиннее 512, то будете получать разными
кусками. Тогда к этому нужно быть готовым.
*/ // ТЕСТОВАЯ ПРОГРАММА
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
// c:\СИ\all_funk\forum.c
// cd /usr/home/test3test/all_funk/tar/
// gcc forum.c -o forum.cgi
// ./forum.cgi
//------------------------------ call_util --------------------------------
int call_util()
{
int k, n;
int pipesin[2], pipesout[2];
pid_t pid, status=0;
char buf[100];
pipesin[0] = -1;
pipesin[1] = -1;
pipesout[0] = -1;
pipesout[1] = -1;
k=pipe(pipesin);
if(k<0){ printf("k=pipe(pipesin)=%d\n", k); goto ERR;}
k=pipe(pipesout);
if(k<0){ printf("k=pipe(pipesout)=%d\n", k); goto ERR;}
pid=fork();
if(pid<0){ printf("pid=fork()=%d\n", (int)pid); goto ERR;}
if(pid==0){
//this is child process
char *args[] = {"forum_util.cgi", "-c" ,NULL};
int in, out;
close(pipesin[1]);
close(pipesout[0]);
close(1);//close stdout
k=dup(pipesout[1]);
if(k!=1) exit(1);
close(pipesout[1]); // это все так делают
close(0); //close stdin
k=dup(pipesin[0]);
if(k!=0) exit(1);
close(pipesin[0]); // это все так делают
k=execvp("./forum_util.cgi", args);
printf("k=execvp()=%d: %s\n", k, strerror(errno));
exit(2);
}
//this is parent process
signal(SIGPIPE, SIG_IGN); // это чтоб не завалить главный процесс
close(pipesin[0]);
pipesin[0]=-1;
close(pipesout[1]);
pipesout[1]=-1;
n=0;
while(n<4){
snprintf(buf, sizeof(buf), "n=%d\n", n);
k=write(pipesin[1], buf, strlen(buf));
fflush(stdout);
if(k<0){ printf("k=write(pipesin[1])=%d\n", k); goto ERR;}
printf(">>> %s\n", buf);
k=read(pipesout[0], buf, sizeof(buf)-1);
if(k<=0){ printf("k=read(pipesout[0])=%d\n", k); goto ERR;}
buf[k]=0;
printf("<<< %s\n", buf);
n++;
}
if(pipesin[0] >= 0) close(pipesin[0]);
if(pipesin[1] >= 0) close(pipesin[1]);
if(pipesout[0] >= 0) close(pipesout[0]);
if(pipesout[1] >= 0) close(pipesout[1]);
wait(&status); // борьба с зомби
printf("status=0xX\n", status);
return(0);
ERR:
if(pipesin[0] >= 0) close(pipesin[0]);
if(pipesin[1] >= 0) close(pipesin[1]);
if(pipesout[0] >= 0) close(pipesout[0]);
if(pipesout[1] >= 0) close(pipesout[1]);
wait(&status); // борьба с зомби
printf("status=0xX\n", status);
return(-1);
}
//-------------------------- main ---------------------------------
int main()
{
int k;
k=call_util();
printf("k=call_util()=%d\n\n", k);
exit(0);
}
//=====================================================================
// ЗАГЛУШКА УТИЛИТЫ
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// c:\СИ\all_funk\forum_util.c
// cd /usr/home/test3test/all_funk/tar/
// gcc forum_util.c -o forum_util.cgi
// ./forum_util.cgi
//----------------- main ------------------
int main(int argc, char *argv[])
{
char *ptr, buf[100];
alarm(10);
while(1){
ptr=fgets(buf, sizeof(buf), stdin);
if(ptr==NULL) exit(9);
printf("%s", buf);
fflush(stdout);
}
exit(10);
}