Ask a Question related to UNIX Programming, Design and Development.
-
ixtahdoom #1
bi-directional IPC / pipes / when to close??
Hi,
I'm writing a C program that needs to bi-directionally communicate
with with a forked/execvp'd process. Here is a sample program that
illustrates my problem. I fork 'tr' and send it a string, but it only
works if I close the pipe after the write, before the read. Any
ideas? I can't keep closing the pipe b/c I need to
read/write/read/write... etc.
I'm using redhad linux 7.2 and gcc 3.1
Thanks!!
itd
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
#define R_END 0
#define W_END 1
int
main(int argc, char *argv[])
{
fflush(stdout);
setbuf(stdout, (char*)NULL);
fflush(stderr);
setbuf(stderr, (char*)NULL);
int pid;
int pipe_a[2];
int pipe_b[2];
if (pipe(pipe_a) < 0)
return 1;
if (pipe(pipe_b) < 0)
return 1;
cout << "Pipes created, forking...\n";
pid = fork();
if (pid == 0)
{
dup2(pipe_b[R_END], STDIN_FILENO);
dup2(pipe_a[W_END], STDOUT_FILENO);
dup2(pipe_a[W_END], STDERR_FILENO);
close(pipe_a[0]);
close(pipe_b[0]);
close(pipe_a[1]);
close(pipe_b[1]);
char *args[] = {"tr", "A-Z", "a-z", 0};
execvp(args[0], args);
perror("child/fork()");
_exit(0);
}
else if (pid < 0)
{
cout << "Failed\n";
return 1;
}
// Parent reads from R_END of pipe_a
// Parent writes to W_END of pipe_b
// Child reads from R_END of pipe_b
// Child writes to W_END of pipe_a
cout << "Child process (" << pid << ")\n";
int read, write;
read = pipe_a[R_END];
write = pipe_b[W_END];
close(pipe_a[W_END]);
close(pipe_b[R_END]);
char *string = "UPPERCASE LINE\n";
cout << "Writing: " << string;
FILE *fw;
fw = fdopen(write, "w"); // w or w+ or a?
if (!fw)
{
perror("fdopen(w)");
return 1;
}
fprintf(fw, "%s", string);
// --------------------------------------
// --------------------------------------
// Doesn't work unless I comment this... why?
// fclose(fw);
// --------------------------------------
// --------------------------------------
cout << "Reading child ...\n";
FILE *fr;
char buffer[1024];
fr = fdopen(read, "r");
if (!fr)
{
perror("fdopen(r)");
return 1;
}
while (fgets(buffer, 1000, fr))
{
printf("%s", buffer);
}
fclose(fr);
cout << "Closing down child, waiting\n";
kill(pid, 9);
int return_status;
wait(&return_status);
return 0;
}
ixtahdoom Guest
-
Bidirectional pipes
Hi all, I wonder how can I open pipe to STDIN and STDOUT of a process ? Tnx. Mehmet -
Bi-Directional Encryption for classic ASP
Does anyone know if such thing exists? I am trying to find a component for classic ASP. Thanks, CK -
get rid of whitespace around pipes??
On Dec 17, LoneWolf said: Then split on /\s*\|\s*/. That regex reads "zero or more whitespace, a |, then zero or more whitespace". @fields... -
[PHP] How to achieve bi-directional communication between twoservers?
Daevid Vincent wrote: You can open a link to a "service" that is running on the client, or call some page on the client with another GET... -
Interactive directional sound
Does anyone know if this could be done using a QTVR clip (sound only) with SoundSaVR? Has anyone used SoundSaVR ( http://www.smgvr.com )? "Dan"... -
Marc Rochkind #2
Re: bi-directional IPC / pipes / when to close??
On 19 Jul 2003 14:41:28 -0700, ixtahdoom <ixtahdoom@yahoo.com> wrote:
[snip]> Hi,
>
> I'm writing a C program that needs to bi-directionally communicate
> with with a forked/execvp'd process. Here is a sample program that
> illustrates my problem. I fork 'tr' and send it a string, but it only
> works if I close the pipe after the write, before the read. Any
> ideas? I can't keep closing the pipe b/c I need to
> read/write/read/write... etc.
>
There's not a lot you can do when you're trying to interact with a command
over which you have no control, which is the case here. The command is
buffering its input, and that's causing it to be noninteractive. Closing
the pipe causes it to effectively get an EOF, but, as you say, that's
impractical if you want to keep it alive for long time.
One very complicated solution is to make the standard input of the command
that wants to buffer a terminal device instead of a pipe. For this you have
to use pseudo-terminals (ptys). Very complicated and non-portable to set
up. However, they will usually solve the problem, but even that is not
guaranteed, depending on how the command is programmed. It still might
buffer until it gets an EOF.
--Marc
Marc Rochkind Guest
-
ixtahdoom #3
Re: bi-directional IPC / pipes / when to close??
That makes sense. I thought it was related to all this
blocking/non-blocking stuff that I've read about, and can't seem to
get my head around yet. Fortunately the target program I need to
invoke as a child is a Perl script with $|=1, so I guess I can scoot
by in this case with lots of comments in the C. I wrote a version of
'tr' in perl that had unbuffered input and it worked fine. Thanks.
Marc Rochkind <rochkind@basepath.com> wrote in message news:<oprsk23tiyojfyi9@den.news.speakeasy.net>...> On 19 Jul 2003 14:41:28 -0700, ixtahdoom <ixtahdoom@yahoo.com> wrote:
>>> > Hi,
> >
> > I'm writing a C program that needs to bi-directionally communicate
> > with with a forked/execvp'd process. Here is a sample program that
> > illustrates my problem. I fork 'tr' and send it a string, but it only
> > works if I close the pipe after the write, before the read. Any
> > ideas? I can't keep closing the pipe b/c I need to
> > read/write/read/write... etc.
> >
> [snip]
>
> There's not a lot you can do when you're trying to interact with a command
> over which you have no control, which is the case here. The command is
> buffering its input, and that's causing it to be noninteractive. Closing
> the pipe causes it to effectively get an EOF, but, as you say, that's
> impractical if you want to keep it alive for long time.
>
> One very complicated solution is to make the standard input of the command
> that wants to buffer a terminal device instead of a pipe. For this you have
> to use pseudo-terminals (ptys). Very complicated and non-portable to set
> up. However, they will usually solve the problem, but even that is not
> guaranteed, depending on how the command is programmed. It still might
> buffer until it gets an EOF.
>
> --Marcixtahdoom Guest
-
Ralf Fassel #4
Re: bi-directional IPC / pipes / when to close??
* [email]ixtahdoom@yahoo.com[/email] (ixtahdoom)
| fw = fdopen(write, "w"); // w or w+ or a?
| if (!fw)
| {
| perror("fdopen(w)");
| return 1;
| }
| fprintf(fw, "%s", string);
|
| // --------------------------------------
| // --------------------------------------
| // Doesn't work unless I comment this... why?
| // fclose(fw);
Try fflush(fw) here to handle stdio buffering at your side of the pipe.
(BTW, why do you use stdio here at all if you don't want buffering?)
But, as Marc Rochkind pointed out, there might be buffering involved
in the other program, too, so this may or may not work.
R'
Ralf Fassel Guest



Reply With Quote

