// <copyright>
// 
// Copyright (c) 1993-1995
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// 
// </copyright>

//<file>
//
// Name:       hgunistd.h
//
// Purpose:    syswrite, sysread, hg_signal
//
// Created:    27 Jun 94    Gerald Pani
//
// Description:
//
//
//</file>


#include "hgunistd.h"
#include <errno.h>
#include <signal.h>
#include <fcntl.h>

int syswrite( int fd, const char* buf, int nbyte) {
     register int offset = 0;
     while (nbyte) {
	  int written = ::write( fd, buf + offset, nbyte);
	  if (written < 0) {
	       if (::errno != EINTR)
		    return written;
	       else 
		    written = 0;
	  }
	  nbyte -= written;
	  offset += written;
     }
     return offset;
}

int sysread( int fd, char* buf, int nbyte) {
     register int offset = 0;
     while (nbyte) {
	  int readin = ::read( fd, buf + offset, nbyte);
	  if (readin == 0)
	       // eof
	       return offset;
	  if (readin < 0) {
	       if (::errno != EINTR)
		    return readin;
	       else 
		    readin = 0;
	  }
	  nbyte -= readin;
	  offset += readin;
     }
     return offset;
}

#ifdef ULTRIX
#  ifdef __GNUC__
     extern "C" int sigfillset(sigset_t*);
#  else
     extern "C" int sigfillset(sigset_t*);
     extern "C" int sigaction(int, struct sigaction*, struct sigaction*);
#  endif
#endif

Sigfunc* hg_signal( int sig, Sigfunc* handler) {
   static struct sigaction a, ao;
#if defined(__GNUC__)
   a.sa_handler = (void (*)(...))handler;
#elif defined(ULTRIX)
   a.sa_handler = (void (*)())handler;
#else
   a.sa_handler = handler;
#endif

// #if defined(ULTRIX) && !defined(__GNUC__)
//    a.sa_handler = (void (*)())handler;
// #else
// #if defined(SOLARIS) || defined(IRIX) || defined(BSD) && defined(SUN) && defined(__GNUC__)
//    a.sa_handler = (void (*)(...))handler;
// #else
//    a.sa_handler = handler;
// #endif
// #endif
      sigfillset(&a.sa_mask);
   if (sigaction(sig, &a, &ao) < 0)
      return (Sigfunc*)SIG_ERR;
   return (Sigfunc*)ao.sa_handler;
}




// so much for nonblocking IO/connect and POSIX !!!

//            | O_NONBLOCK     O_NDELAY
// -----------------------------------------------------------------
// HPUX       |                                                  
//            |                                                  
// connect()  | ok             ?                                
// read()     | ok             returns ZERO if no data there !!!
//            |                                                  
// -----------------------------------------------------------------
// SUN4       |                                                  
//            |                                                  
// connect()  | blocks!!!      ok                               
// read()     | ok             ok                               
//            |                                                  
// -----------------------------------------------------------------
// SUN5       |                                                  
//            |                                                  
// connect()  | ok             ?                                
// read()     | ok             ?                                
//            |                                                  
// -----------------------------------------------------------------
// LINUX      |                                                  
//            |                                                  
// connect()  | ok             ?                                
// read()     | ok             ?                                
//            |                                                  
// -----------------------------------------------------------------
// SGI        |                                                  
//            |                                                  
// connect()  | ok             ?                                
// read()     | ok             ?                                
//            |                                                  
// -----------------------------------------------------------------
// OSF1       |                                                  
//            |                                                  
// connect()  | ok             ?                                
// read()     | ok             ?                                
//            |                                                  
// -----------------------------------------------------------------
// PMAX       |           
//            |           
// connect()  | ok             ?
// read()     | ok             ?



#if (defined HPUX)
#  define NONBLOCK O_NONBLOCK

#elif (defined SUN) && (HG_OSMaj == 4)
#  define NONBLOCK O_NDELAY

#elif (defined SUN) && (HG_OSMaj == 5)
#  define NONBLOCK O_NONBLOCK

#elif (defined LINUX)
#  define NONBLOCK O_NONBLOCK

#elif (defined IRIX)
#  define NONBLOCK O_NONBLOCK

#elif (defined OSF1)
#  define NONBLOCK O_NONBLOCK

#elif (defined ULTRIX)
#  define NONBLOCK O_NONBLOCK

#elif (defined AIX)
#  define _BSD 44
#  define NONBLOCK O_NONBLOCK

#else 
have to figure this out
#endif


int set_blocking (int fd, int bl) {
   int flags = fcntl (fd, F_GETFL, 0) ;
   if (flags < 0)
      return flags ;

   if (bl)
      flags &= ~NONBLOCK ;
   else
      flags |= NONBLOCK ;

   if ((flags = fcntl (fd, F_SETFL, flags)) < 0)
      return flags ;

   return 0 ;
}

int get_blocking (int fd) {
   int flags = fcntl (fd, F_GETFL, 0);
   if (flags < 0)
      return flags ;
   return (flags & NONBLOCK) ? 0 : 1 ;
}
