/* source: xiosigchld.c */
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
/* Published under the GNU General Public License V.2, see file COPYING */

/* this is the source of the extended child signal handler */


#include "xiosysincludes.h"
#include "xioopen.h"


/*!! with socat, at most 4 exec children exist */
pid_t diedunknown[NUMUNKNOWN];	/* children that died before they were registered */
int   statunknown[NUMUNKNOWN]; 	/* exit state of unknown dead child */
size_t nextunknown;
int engine_result = EXIT_SUCCESS;


/* register for a xio filedescriptor a callback (handler).
   when a SIGCHLD occurs, the signal handler will ??? */
int xiosetsigchild(xiofile_t *xfd, int (*callback)(struct single *)) {
   if (xfd->tag != XIO_TAG_DUAL) {
      xfd->stream.sigchild = callback;
   } else {
      xfd->dual.stream[0]->sigchild = callback;
      xfd->dual.stream[1]->sigchild = callback;
   }
   return 0;
}

/* exec'd child has died, perform appropriate changes to descriptor */
/* is async-signal-safe */
static int sigchld_stream(struct single *file) {
   /*!! call back to application */
   file->para.exec.pid = 0;
   if (file->sigchild) {
      return (*file->sigchild)(file);
   }
   return 0;
}

/* return 0 if socket is not responsible for deadchild */
static int xio_checkchild(xiofile_t *socket, int socknum, pid_t deadchild) {
   int retval;
   if (socket != NULL) {
      if (socket->tag != XIO_TAG_DUAL) {
	 if ((socket->stream.howtoend == END_KILL ||
	      socket->stream.howtoend == END_CLOSE_KILL ||
	      socket->stream.howtoend == END_SHUTDOWN_KILL) &&
	     socket->stream.para.exec.pid == deadchild) {
	    Info2("exec'd process %d on socket %d terminated",
		  socket->stream.para.exec.pid, socknum);
	    sigchld_stream(&socket->stream);	/* is async-signal-safe */
	    return 1;
	 }
      } else {
	 if (retval = xio_checkchild((xiofile_t *)socket->dual.stream[0], socknum, deadchild))
	    return retval;
	 else
	    return xio_checkchild((xiofile_t *)socket->dual.stream[1], socknum, deadchild);
      }
   }
   return 0;
}

/* this is the "physical" signal handler for SIGCHLD */
/* the current socat/xio implementation knows two kinds of children:
   exec/system addresses perform a fork: these children are registered and
   there death influences the parents flow;
   listen-socket with fork children: these children are "anonymous" and their
   death does not affect the parent process (now; maybe we have a child
   process counter later) */
void childdied(int signum) {
   pid_t pid;
   int _errno;
   int status = 0;
   bool wassig = false;
   int i;

   _errno = errno;	/* save current value; e.g., select() on Cygwin seems
			   to set it to EINTR _before_ handling the signal, and
			   then passes the value left by the signal handler to
			   the caller of select(), accept() etc. */
   diag_in_handler = 1;
   Notice1("childdied(): handling signal %d", signum);
   Info1("childdied(signum=%d)", signum);
   do {
      pid = Waitpid(-1, &status, WNOHANG);
      if (pid == 0) {
	 Msg(wassig?E_INFO:E_WARN,
	     "waitpid(-1, {}, WNOHANG): no child has exited");
	 Info("childdied() finished");
	 diag_in_handler = 0;
	 errno = _errno;
	 return;
      } else if (pid < 0 && errno == EINTR) {
	 Info1("childdied(): %s", strerror(errno));
      } else if (pid < 0 && errno == ECHILD) {
	 Msg(wassig?E_INFO:E_NOTICE,
	      "waitpid(-1, {}, WNOHANG): "F_strerror);
	 Info("childdied() finished");
	 diag_in_handler = 0;
	 errno = _errno;
	 return;
      }
      wassig = true;
      if (pid < 0) {
	 Warn1("waitpid(-1, {%d}, WNOHANG): "F_strerror, status);
	 Info("childdied() finished");
	 diag_in_handler = 0;
	 errno = _errno;
	 return;
      }
   /*! indent */
   if (num_child) {
      num_child--;
      Info1("number of children decreased to %d", num_child);
   }
   /* check if it was a registered child process */
   i = 0;
   while (i < XIO_MAXSOCK) {
      if (xio_checkchild(sock[i], i, pid))  break;
      ++i;
   }
   if (i == XIO_MAXSOCK) {
	 Info2("childdied(%d): cannot identify child %d", signum, pid);
	 if (num_child) num_child--;
	 if (nextunknown == NUMUNKNOWN) {
	    nextunknown = 0;
	 }
	 diedunknown[nextunknown] = pid;
	 statunknown[nextunknown++] = WEXITSTATUS(status);
	 Debug1("saving pid in diedunknown"F_Zu,
		nextunknown/*sic, for compatibility*/);
      }

   if (WIFEXITED(status)) {
      if (WEXITSTATUS(status) == 0) {
	 Info2("waitpid(): child %d exited with status %d",
	       pid, WEXITSTATUS(status));
      } else {
	 if (i == XIO_MAXSOCK) {
	    Info2("waitpid(): child %d exited with status %d",
		   pid, WEXITSTATUS(status));
	 } else {
	    Warn2("waitpid(): child %d exited with status %d",
		   pid, WEXITSTATUS(status));
	    engine_result = 1;
	 }
      }
   } else if (WIFSIGNALED(status)) {
      if (i == XIO_MAXSOCK) {
	 Info2("waitpid(): child %d exited on signal %d",
	       pid, WTERMSIG(status));
      } else {
	 Warn2("waitpid(): child %d exited on signal %d",
	       pid, WTERMSIG(status));
	 engine_result = 1;
      }
   } else if (WIFSTOPPED(status)) {
      Info2("waitpid(): child %d stopped on signal %d",
	    pid, WSTOPSIG(status));
   } else {
      Warn1("waitpid(): cannot determine status of child %d", pid);
   }

#if !HAVE_SIGACTION
   /* we might need to re-register our handler */
   if (Signal(SIGCHLD, childdied) == SIG_ERR) {
      Warn("signal(SIGCHLD, childdied): "F_strerror);
   }
#endif /* !HAVE_SIGACTION */
  } while (1);
   Info("childdied() finished");
   diag_in_handler = 0;
   errno = _errno;
}


int xiosetchilddied(void) {
#if HAVE_SIGACTION
   struct sigaction act;
   memset(&act, 0, sizeof(struct sigaction));
   act.sa_flags   = SA_NOCLDSTOP/*|SA_RESTART*/
#ifdef SA_NOMASK
      |SA_NOMASK
#endif
      ;
   act.sa_handler = childdied;
   sigfillset(&act.sa_mask);
   if (Sigaction(SIGCHLD, &act, NULL) < 0) {
      /*! man does not say that errno is defined */
      Warn2("sigaction(SIGCHLD, %p, NULL): %s", childdied, strerror(errno));
   }
#else /* HAVE_SIGACTION */
   if (Signal(SIGCHLD, childdied) == SIG_ERR) {
      Warn2("signal(SIGCHLD, %p): %s", childdied, strerror(errno));
   }
#endif /* !HAVE_SIGACTION */
   return 0;
}
