/* Copyright (c) 1997-2004
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

#ident "$Project: polymake $$Id: pipestream.cc,v 1.2 2004/06/22 16:22:41 gawrilow Exp $"

#if defined(__GNUC__) && __GNUC_MINOR__<3 && !defined(__APPLE__) && !defined(__COMO__)
#pragma implementation
#endif

#include <stdexcept>
#include <pipestream.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/wait.h>

namespace std {

   void pipestream_base::open(const char* progname, char* const command[]) {
      int skp[2];
      if (socketpair(AF_UNIX,SOCK_STREAM,0,skp))
	 throw std::runtime_error("pipestream: socketpair() failed");
      _pid=fork();
      if (_pid<0)
	 throw std::runtime_error("pipestream: fork() failed");
      if (!_pid) {
	 // child branch
	 close(skp[0]);

	 if (dup2(skp[1],0)<0 || dup2(skp[1],1)<0) {
	    cerr << "pipestream: dup() failed" << endl;
	    exit(1);
	 }
	 close(skp[1]);
	 execvp(progname, command);
	 cerr << "pipestream: exec(" << progname << ") failed" << endl;
	 exit(1);
      }

      // parent branch goes on here
      close(skp[1]);
      _fd=skp[0];      
   }

   pipestream_base::~pipestream_base() {
      close(_fd);
      if (_pid>0) waitpid(_pid,0,0);
   }
} // end namespace std
