/* This file is part of cardwords
   (c) 1998 1999 Tobias Peters
   
   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 of the License, or
   (at your option) any later version.

   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.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/

// cardwords_pipe.cc

#include "cardwords_pipe.hh"
#include <unistd.h>

#include "cardwords_exceptions.hh"
#include "cardwords_gettext.hh"
#include <assert.h>
#include <errno.h>

// construct the pipe:
CardWords_Pipe::CardWords_Pipe(unsigned int tries = 1)
{
  int FDs[2];
  int state;

  do {
    state = pipe(FDs);
    tries--;
  } while (state != 0 && (sleep(1),(tries > 0)) );

  if (state == 0) {
    good = true;
    talkFD = FDs[1];
    listenFD = FDs[0];
    talkOpen = listenOpen = true;
    my_errno = -1;
  }
  else {
    my_errno = errno;
    assert (my_errno == EMFILE || my_errno == ENFILE);
    good = false;
    talkOpen = false;
    listenOpen = false;
    throw CardWords_XLowResources(gettext("creating pipe"));
  }
}

// close one end of the line:
int CardWords_Pipe::close_talk(void)
{
  if (talkOpen == false) {
    return 0;
  }
  int retval = close (talkFD);
  talkOpen = false;
  if (retval){
    good = false;
    my_errno = errno;
  }
  return retval;
}

int CardWords_Pipe::close_listen(void)
{
  if (listenOpen == false) {
    return 0;
  }
  int retval = close (listenFD);
  listenOpen = false;
  if (retval){
    good = false;
    my_errno = errno;
  }
  return retval;
} 

// the destructor closes open FD's:
CardWords_Pipe::~CardWords_Pipe()
{
  close_talk();
  close_listen();
}
