Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Jul 2001 18:53:55 +0200
From:      Gabriel Ambuehl <gabriel_ambuehl@buz.ch>
To:        questions@freebsd.org
Subject:   popen() with bidirectional pipes?
Message-ID:  <64111861237.20010716185355@buz.ch>

next in thread | raw e-mail | index | archive | help
-----BEGIN PGP SIGNED MESSAGE-----

Hello,
I'm trying to get popen() with bidirectional pipes working in C++,
but
somehow, I don't seem to be very lucky at it:

I popen() the following code (which should simply print a line about
it self, then the data written to the pipe and finally a line stating
it's done)
- -----
#include <iostream>
#include <unistd.h>
#include <stdio.h>
int main()
{
  char buffer[1024];
  int counter;
  cout << "Test method starts...." << endl;
  while (!feof(stdin))
    {
      fread((void *) &buffer, (size_t) 1024 , (size_t) 1, stdin);
      cout << buffer << flush;
      cerr << "buffer: " << buffer << endl;
    }
    cout << "\ndone"<< endl;

   return 0;
}
- ----

(This works perfectly well when used with echo | on the cli)

and the following one to do the actual popen() call:

- ----
    pid_t pid;

    if ( (pid=fork()) == 0)
      {
        char buffer;
        cout << "child pid: " << getpid() << endl;
        string data;
        FILE * process;
        process=popen((const char *) this->cli_call.data(), (const
char *) &"r+");
        fwrite((const void *) this->stdin_call.data(), (size_t)
this->stdin_call.size(), (size_t) 1, process);

        sleep(2);
        cout << ">>>Child (pid: " << getpid() << ") reports:\n ";
        while (!feof(process))
        {
            fread(&buffer, (size_t) 1, (size_t) 1, process);
            cout << buffer;
        }
         cout << data << endl;

        pclose(process);
        //spreadclose(process);
        _exit(0);


        //cout << "child exits..." << endl;

      }
- -----

According to the popen() man page, the last argument should be r for
reading only pipes, w for writing only and r+ for bidirectional ones.


Now if put r in there, I get the data the test program will output
the stuff it would without any stdin data which makes sense as there
isn't anything on it's stdin to print. If I use w, then stdout will
go
to the console and the data that was written to stdin gets integrated
as it should but if I use r+ (which I need), the program gets loaded
and the caller simply gets back the data that is printed everytime,
so like I'd call it with r instead of r+. What am I doing wrong?


Also, I wonder about the following: the first piece of code works
without any problems with a buffer of 1024 bytes and reads all the
data there is, whereas the second one will be caught in an endless
loop (I suppose, as it won't exit anymore) as soon as I use a buffer
of more than a single char. A bigger buffer would be a good thing as
this would speed up things dramatically.

Best regards,
 Gabriel

PS: How big is the buffer of a pipe in FreeBSD?

-----BEGIN PGP SIGNATURE-----
Version: PGP 6.5i

iQEVAwUBO1MOGMZa2WpymlDxAQFzQwgAptLov8qyCffmARJcCfIugRDbBapgsRjU
bze/xivNr8PAL3QcuDulXS6esvhmkYMwjg81HKKxF+vvFhU8lXVisg0Q1G3861wI
Im1o8zzF4SAMTyxET9sSAJMj2zpIyph5UL6Ong/oxPkmW49Iq3J/nymv1ChwbOxj
Rv3ALRVObuE097j1p2YdiomXqTtc7cp0EBwfL+YmN2sZjLnGB7ET/a5cx6JuDZMw
JAfAnssjjKwWI+nVx3IVfTXtUt34heQ0vvgHI+/sv21KrqLlZBPpVwtdNB5onabL
nyP6eOwEEZWNADODJuZNXZCktucNS79F992ob1lch9VstInjtYWJQQ==
=gEV+
-----END PGP SIGNATURE-----


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?64111861237.20010716185355>