static char rcsid[] = "@(#)$Id: posixsig.c,v 1.11 2006/04/09 07:37:05 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.11 $   $State: Exp $
 *
 *  Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                           (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  The Elm Mail System 
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/** Duplicate the old signal() call with POSIX sigaction

**/

#include "headers.h"

DEBUG_VAR(Debug,__FILE__,"signal");

#ifdef POSIX_SIGNALS

#ifndef SIG_ERR
#  ifdef BADSIG
#    define SIG_ERR BADSIG
#  else
#    define SIG_ERR -1
#  endif /* BADSIG */
#endif /* SIG_ERRR */

/*
 * This routine used to duplicate the old signal() calls
 */
SIGHAND_TYPE
#if ANSI_C && !defined(apollo)
(*posix_signal(signo, fun))(int)
	int signo;
	SIGHAND_TYPE (*fun)(int);
#else
(*posix_signal(signo, fun))()
	int signo;
	SIGHAND_TYPE (*fun)();
#endif
{
	struct sigaction act;	/* new signal action structure */
	struct sigaction oact;  /* returned signal action structure */ 

	/*   Setup a sigaction struct */

 	act.sa_handler = fun;        /* Handler is function passed */
	sigemptyset(&(act.sa_mask)); /* No signal to mask while in handler */
	act.sa_flags = 0;
#ifdef SA_INTERRUPT
	act.sa_flags |= SA_INTERRUPT;           /* SunOS */
#endif

	/* use the sigaction() system call to set new and get old action */

	sigemptyset(&oact.sa_mask);
	if(sigaction(signo, &act, &oact))
		/* If sigaction failed return -1 */
	    return(SIG_ERR);
	else
        	/* use the previous signal handler as a return value */
	    return(oact.sa_handler);
}
#endif /* POSIX_SIGNALS */

#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif       

#ifdef BACKGROUD_PROCESSES       /* We assume POSIX in here */

int my_wait (pid,statptr)
     int pid; 
#if defined(BSD_TYPE) && !defined(WEXITSTATUS)
     union wait *statptr;
#else
     int *statptr;
#endif
{
    int ret,err;

    DPRINT(Debug,10,(&Debug,
		     "my_wait(%d,...) ... with BACKGROUD_PROCESSES\n", 
		     pid));
    errno = 0;

#if POLL_METHOD
    if (have_actions()) {
	DPRINT(Debug,10,(&Debug,
			 "my_wait: have_actions ... busy waiting\n"));
	while (0 == (ret = waitpid(pid,statptr,WNOHANG))) {
	    if (!wait_for_timeout(1)) {
		DPRINT(Debug,10,(&Debug,
				 "my_wait: wait interrupted\n"));
	    }
	}
    } else
#endif
	ret = waitpid(pid,statptr,0);
    err = errno;

#if defined(BSD_TYPE) && !defined(WEXITSTATUS)
    DPRINT(Debug,10,(&Debug,
		     "my_wait(%d,*statptr=%d) = %d\n", pid,
		     statptr->w_status,ret));
#else
    DPRINT(Debug,10,(&Debug,
		     "my_wait(%d,*statptr=%d) = %d\n", pid,
		     *statptr,ret));
#endif

  if (err) {
      DPRINT(Debug,10,(&Debug,
		       " *** errno=%d (%s)\n",err,
		       error_description(err)));
  }
  errno = err;
  return ret;
}

#else

int my_wait (pid,statptr)
     int pid; 
#if defined(BSD_TYPE) && !defined(WEXITSTATUS)
     union wait *statptr;
#else
     int *statptr;
#endif
{
  int ret,err;

  DPRINT(Debug,10,(&Debug,
		   "my_wait(%d,...) ... no BACKGROUD_PROCESSES\n", pid));
  errno = 0;
  ret = 
#ifdef HASWAITPID
        waitpid(pid,statptr0)
#else
	wait(statptr);
#endif
  err = errno;

#if defined(BSD_TYPE) && !defined(WEXITSTATUS)
  DPRINT(Debug,10,(&Debug,
		   "my_wait(%d,*statptr=%d) = %d\n", pid,		   
		   statptr->w_status,ret));
#else
  DPRINT(Debug,10,(&Debug,
		   "my_wait(%d,*statptr=%d) = %d\n", pid,		   
		   *statptr,ret));
#endif

  if (err) {
      DPRINT(Debug,10,(&Debug,
		       " *** errno=%d (%s)\n",err,
		       error_description(err)));
  }
  errno = err;

  return ret;

}
#endif

int convert_status(status,exit_code) 
#if defined(BSD_TYPE) && !defined(WEXITSTATUS)
     union wait status;
#else
     int status;
#endif
     int *exit_code;
{
  int sig;

#ifdef	WEXITSTATUS
  *exit_code = WEXITSTATUS(status);
  if (WIFSIGNALED(status)) {
      sig        = WTERMSIG(status);
      DPRINT(Debug,10,(&Debug,
		      "convert_status: TERMINATED WITH SIGNAL %d\n",
		      sig));
  } else
     sig        = 0;
#else
# ifdef	BSD_TYPE
  *exit_code = status.w_retcode;
  sig        = status.w_termsig;
# else
  *exit_code = status >> 8;
  sig        = status & 128;
# endif
#endif

  DPRINT(Debug,10,(&Debug,
		   "convert_status=%d (sig): exit_code=%d\n", 
		   sig,*exit_code));

  return sig;
}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1