Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Portage & Programming
  • Search

[SOLVED] How to convert C file descriptors to C++ fstream?

Problems with emerge or ebuilds? Have a basic programming question about C, PHP, Perl, BASH or something else?
Post Reply
Advanced search
16 posts • Page 1 of 1
Author
Message
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

[SOLVED] How to convert C file descriptors to C++ fstream?

  • Quote

Post by majoron » Wed May 10, 2006 5:06 pm

Hi!
Is there a way to create a fstream object with a file descriptor as argument?
One can create in standard C++ a fstream object like this:

Code: Select all

istream infile( "foo.bar" );
but I tried (fds is a file descriptor)

Code: Select all

istream infile( fds );
and it does not work.
BTW, fds is a file descriptor associated with a pipe (so I'm trying to read from a pipe, and that's why I don't have the name of the file).

However, I have seen that there are some implementations which allow it (see this, overload 3 in ifstream constructor). I know, this is AIX, but is it not possible to have it with gcc?

This is what I have:

Code: Select all

$ g++ -v
Leyendo especificaciones de /usr/lib/gcc/i686-pc-linux-gnu/3.4.5/specs
Configurado con: /var/tmp/portage/gcc-3.4.5-r1/work/gcc-3.4.5/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/3.4.5 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.5/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.5 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.5/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.5/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.5/include/g++-v3 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --disable-libunwind-exceptions --disable-multilib --disable-libgcj --enable-languages=c,c++,f77 --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu
Modelo de hilos: posix
gcc versión 3.4.5 (Gentoo Hardened 3.4.5-r1, ssp-3.4.5-1.0, pie-8.7.9)
(sorry for the spanish)

TIA and Regards
Last edited by majoron on Fri May 12, 2006 9:15 am, edited 1 time in total.
Top
rokstar83
Guru
Guru
User avatar
Posts: 423
Joined: Sat Apr 09, 2005 6:18 am
Location: MD

  • Quote

Post by rokstar83 » Thu May 11, 2006 7:46 pm

I think you are looking for the attach method.

istream infile;

infile.attach(fs);

You may need to make sure that the correct end of the pipe is closed, though i'm not sure.
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

  • Quote

Post by majoron » Fri May 12, 2006 8:15 am

Thanks for the reply.
However it does not seem to work.
The compiler complains saying that there is no "attach" member in std::istream (neither in std::ifstream). In fact, I cannot find such method in the whole set of C++ headers.
This is the code I tried, just in case you feel curiosity:

Code: Select all

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int main() {
  int fds[2];
  pid_t pid;

  pipe( fds );

  pid = fork();

  if( pid == (pid_t) 0 ) {
    close( fds[0] );
    dup2( fds[1], STDOUT_FILENO );
    execlp( "ls", "ls", 0 );
  }
  else {
    //    FILE* stream;
    close( fds[1] );
    ifstream chorro;
    chorro.attach( fds[ 0 ] );
    //    stream = fdopen( fds[0], "r" );
    char* bufar = (char*) malloc( 1024 );
    string prev = "";
    string actu = "";
    //    while( fscanf( stream, "%s", bufar ) ) {
    while( chorro >> bufar ) {
      actu = bufar;
      if( actu == prev ) break;
      cout << "fichereres: " << actu << endl;
      prev = actu;
    }

    free( bufar );
  }
  return 0;
}
(the commented code corresponds to the lines in C which make the analogous work)

Regards
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

Solved!

  • Quote

Post by majoron » Fri May 12, 2006 9:14 am

Hi again!
I was browsing in the deep sea of libstdc++ documentation pages, and I finally found a solution.

Code: Select all

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <string>
#include <ext/stdio_filebuf.h>

using namespace std;

int main() {
  int fds[2];
  pid_t pid;

  pipe( fds );

  pid = fork();

  if( pid == (pid_t) 0 ) {
    close( fds[0] );
    dup2( fds[1], STDOUT_FILENO );
    execlp( "ls", "ls", 0 );
  }
  else {
    close( fds[1] );

    __gnu_cxx::stdio_filebuf<char> churro( fds[ 0 ], ios_base::in );
    istream cherro( &churro );

    char* bufar = (char*) malloc( 1024 );
    string prev = "";
    string actu = "";

    while( cherro >> bufar ) {
      actu = bufar;
      if( actu == prev ) break;
      cout << "fichereres: " << actu << endl;
      prev = actu;
    }

    free( bufar );
  }
  return 0;
}
It basically summarizes in: 1) define a stdio_filebuf object out of a file descriptor; and 2) define a stream object (in this case was istream) from the previously defined stdio_filebuf. Once you carry out this latter step you can read from the file using streams technology, which is basically what I was looking for.

I don't know how elegant is this procedure, but I don't know any other option...

Best regards
Top
rokstar83
Guru
Guru
User avatar
Posts: 423
Joined: Sat Apr 09, 2005 6:18 am
Location: MD

  • Quote

Post by rokstar83 » Fri May 12, 2006 2:44 pm

I'm glad you found the solution but I think I figured out why it doesn't work. I think that fstream is the class that has the attach method. The derived classes, ifstream and ofstream should all have the appropriate classes. I think something like this would work.

Code: Select all

#include <fstream>
#include <stdio.h>
#include <string>
#include <iostream>

using namespace std;

int main() {
   int fd = open("somefile");
   string foo;
   ifstream infile;
   infile.attach(fd);
   foo << infile;
   cout << foo;  
}[\code]
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

  • Quote

Post by majoron » Fri May 12, 2006 3:44 pm

But, can you compile the code you wrote?
I cannot. It complains saying that 'struct std::ifstream' does not have a method called 'attach'.
I also tried doing this:

Code: Select all

  fstream infile;
and the same error occurs (substituting 'ifstream' by 'fstream').
Regards
Top
01mf02
Veteran
Veteran
User avatar
Posts: 1070
Joined: Sun Nov 21, 2004 3:14 pm
Location: Innsbruck, Austria

  • Quote

Post by 01mf02 » Fri May 12, 2006 4:22 pm

I looked in my Stroustrup, man pages and online documentation, but there is no attach() function. I'm sorry for you. :(


[EDIT]
The method that works for you is extremely unelegant (never use __ stuff!). I would really try not to use it.
Top
rokstar83
Guru
Guru
User avatar
Posts: 423
Joined: Sat Apr 09, 2005 6:18 am
Location: MD

  • Quote

Post by rokstar83 » Fri May 12, 2006 5:12 pm

http://osr5doc.sco.com:1997/cgi-bin/man ... am+C%2B%2B

is a link to some man page that I saw that on. Guess its not the right man page, SCO specific?? At any rate, the man page on my machine shows a basic constructor

explicit basic_fstream(int fd);
basic_fstream(int fd, char_type *buf, int len);

for the fstream object. I'm not sure why you are not able to access them.
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

  • Quote

Post by majoron » Fri May 12, 2006 9:39 pm

The method that works for you is extremely unelegant (never use __ stuff!). I would really try not to use it.
Thanks for the comment, but is there a better way to do it? How?
Top
markkuk
Guru
Guru
Posts: 446
Joined: Fri Nov 29, 2002 2:00 pm

  • Quote

Post by markkuk » Sat May 13, 2006 10:07 am

Standard C++ doesn't provide any way to connect streams to UNIX file descriptors. Any solution to this problem will be implementation-specific.
Top
ciaranm
Retired Dev
Retired Dev
User avatar
Posts: 1719
Joined: Sat Jul 19, 2003 11:04 pm
Location: In Hiding
Contact:
Contact ciaranm
Website

  • Quote

Post by ciaranm » Sat May 13, 2006 11:37 am

markkuk wrote:Standard C++ doesn't provide any way to connect streams to UNIX file descriptors. Any solution to this problem will be implementation-specific.
Although... There is a portable way of doing it, assuming you're also on a POSIX system. See the Streams chapter in The C++ Standard Library by Josuttis for code and an explanation. You could also take a look at the Paludis PStream class, which does what you're after to a popen()ed process.

Header
Implementation
Simple test cases
Paludis 0.12, 127.35% Portage compatible and six times faster.
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

  • Quote

Post by majoron » Sat May 13, 2006 11:38 am

Standard C++ doesn't provide any way to connect streams to UNIX file descriptors. Any solution to this problem will be implementation-specific.
I see... I had to have figured it out because the Stroustrup book does not comment on it.
Anyway, I'm just interested in the gnu implementation, so what is the correct way to do that whitin this implementation? Or should I forget about it, and use file descriptors?
Top
ciaranm
Retired Dev
Retired Dev
User avatar
Posts: 1719
Joined: Sat Jul 19, 2003 11:04 pm
Location: In Hiding
Contact:
Contact ciaranm
Website

  • Quote

Post by ciaranm » Sat May 13, 2006 11:44 am

majoron wrote:
Standard C++ doesn't provide any way to connect streams to UNIX file descriptors. Any solution to this problem will be implementation-specific.
I see... I had to have figured it out because the Stroustrup book does not comment on it.
Anyway, I'm just interested in the gnu implementation, so what is the correct way to do that whitin this implementation? Or should I forget about it, and use file descriptors?
Wrong book. Look in Josuttis instead, and write portable code. GNU internals can and do change.
Paludis 0.12, 127.35% Portage compatible and six times faster.
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

  • Quote

Post by majoron » Sat May 13, 2006 7:37 pm

Although... There is a portable way of doing it, assuming you're also on a POSIX system. See the Streams chapter in The C++ Standard Library by Josuttis for code and an explanation.
Thanks for the advise but I do not have this book :(. I only have the one by Stroustrup and "C++ primer" by Lippman&Lajoie. So if you could give me a clue about that POSIX standard way of doing it, it would be great.
You could also take a look at the Paludis PStream class, which does what you're after to a popen()ed process.
Is this Paludis the same that "emerge -s paludis" tells about? or do I have to install it without emerge?
Wrong book. Look in Josuttis instead, and write portable code. GNU internals can and do change.
Wrong book? Why? I know it is not a primer book but looks a pretty complete reference for C++ standards, doesn't it?
About portable code... yes that would be great, but if I cannot do it or if I need to install a non-standard library for making it work, it is more or less the same as writting non-portable code, isn't it?
BTW, I only need to make that code working in systems whith the GNU compiler.

Again, thanks for the help.
Top
ciaranm
Retired Dev
Retired Dev
User avatar
Posts: 1719
Joined: Sat Jul 19, 2003 11:04 pm
Location: In Hiding
Contact:
Contact ciaranm
Website

  • Quote

Post by ciaranm » Sat May 13, 2006 8:10 pm

majoron wrote:
You could also take a look at the Paludis PStream class, which does what you're after to a popen()ed process.
Is this Paludis the same that "emerge -s paludis" tells about? or do I have to install it without emerge?
You can install it via emerge. Or you can peek at the SVN tree online using the links I provided. The latter's probably easier.
Wrong book. Look in Josuttis instead, and write portable code. GNU internals can and do change.
Wrong book? Why? I know it is not a primer book but looks a pretty complete reference for C++ standards, doesn't it?
TC++PL doesn't go into much depth on the standard library. TC++SL is the de facto reference for that.
About portable code... yes that would be great, but if I cannot do it or if I need to install a non-standard library for making it work, it is more or less the same as writting non-portable code, isn't it?
The Paludis code is easily rip-off-able, and it's GPL2ed. Just hack out the relevant bits.
BTW, I only need to make that code working in systems whith the GNU compiler.
That's the kind of attitude that leads to all sorts of things not working every time a new GCC major release is made.
Paludis 0.12, 127.35% Portage compatible and six times faster.
Top
majoron
Apprentice
Apprentice
User avatar
Posts: 243
Joined: Wed Oct 12, 2005 2:02 pm
Location: Frankfurt

  • Quote

Post by majoron » Sat May 13, 2006 9:07 pm

Thanks for the insightful comments; I still have a lot to learn about C++...
Top
Post Reply

16 posts • Page 1 of 1

Return to “Portage & Programming”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy

 

 

magic