/* Linuxthreads - a simple clone()-based implementation of Posix        */
/* threads for Linux.                                                   */
/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
/*                                                                      */
/* This program is free software; you can redistribute it and/or        */
/* modify it under the terms of the GNU Library 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 Library General Public License for more details.                 */

/* Handling of signals */

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include <bits/sigcontextinfo.h>

/* mods for uClibc: __libc_sigaction is not in any standard headers */
extern __typeof(sigaction) __libc_sigaction;

int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask)
{
  sigset_t mask;

  if (newmask != NULL) {
    mask = *newmask;
    /* Don't allow __pthread_sig_restart to be unmasked.
       Don't allow __pthread_sig_cancel to be masked. */
    switch(how) {
    case SIG_SETMASK:
      sigaddset(&mask, __pthread_sig_restart);
      sigdelset(&mask, __pthread_sig_cancel);
      if (__pthread_sig_debug > 0)
	sigdelset(&mask, __pthread_sig_debug);
      break;
    case SIG_BLOCK:
      sigdelset(&mask, __pthread_sig_cancel);
      if (__pthread_sig_debug > 0)
	sigdelset(&mask, __pthread_sig_debug);
      break;
    case SIG_UNBLOCK:
      sigdelset(&mask, __pthread_sig_restart);
      break;
    }
    newmask = &mask;
  }
  if (sigprocmask(how, newmask, oldmask) == -1)
    return errno;
  else
    return 0;
}

int pthread_kill(pthread_t thread, int signo)
{
  pthread_handle handle = thread_handle(thread);
  int pid;

  __pthread_lock(&handle->h_lock, NULL);
  if (invalid_handle(handle, thread)) {
    __pthread_unlock(&handle->h_lock);
    return ESRCH;
  }
  pid = handle->h_descr->p_pid;
  __pthread_unlock(&handle->h_lock);
  if (kill(pid, signo) == -1)
    return errno;
  else
    return 0;
}

/* User-provided signal handlers */
typedef void (*arch_sighandler_t) __PMT ((int, SIGCONTEXT));
static union
{
  arch_sighandler_t old;
  void (*rt) (int, struct siginfo *, struct ucontext *);
} sighandler[NSIG];

/* The wrapper around user-provided signal handlers */
static void pthread_sighandler(int signo, SIGCONTEXT ctx)
{
  pthread_descr self = thread_self();
  char * in_sighandler;
  /* If we're in a sigwait operation, just record the signal received
     and return without calling the user's handler */
  if (THREAD_GETMEM(self, p_sigwaiting)) {
    THREAD_SETMEM(self, p_sigwaiting, 0);
    THREAD_SETMEM(self, p_signal, signo);
    return;
  }
  /* Record that we're in a signal handler and call the user's
     handler function */
  in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
  if (in_sighandler == NULL)
    THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
  sighandler[signo].old(signo, SIGCONTEXT_EXTRA_ARGS ctx);
  if (in_sighandler == NULL)
    THREAD_SETMEM(self, p_in_sighandler, NULL);
}

/* The same, this time for real-time signals.  */
static void pthread_sighandler_rt(int signo, struct siginfo *si,
				  struct ucontext *uc)
{
  pthread_descr self = thread_self();
  char * in_sighandler;
  /* If we're in a sigwait operation, just record the signal received
     and return without calling the user's handler */
  if (THREAD_GETMEM(self, p_sigwaiting)) {
    THREAD_SETMEM(self, p_sigwaiting, 0);
    THREAD_SETMEM(self, p_signal, signo);
    return;
  }
  /* Record that we're in a signal handler and call the user's
     handler function */
  in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
  if (in_sighandler == NULL)
    THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
  sighandler[signo].rt(signo, si, uc);
  if (in_sighandler == NULL)
    THREAD_SETMEM(self, p_in_sighandler, NULL);
}

/* The wrapper around sigaction.  Install our own signal handler
   around the signal. */
libpthread_hidden_proto(sigaction)
int sigaction(int sig, const struct sigaction * act,
              struct sigaction * oact)
{
  struct sigaction newact;
  struct sigaction *newactp;

#ifdef DEBUG_PT
printf(__FUNCTION__": pthreads wrapper!\n");
#endif
  if (sig == __pthread_sig_restart ||
      sig == __pthread_sig_cancel ||
      (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
    return EINVAL;
  if (act)
    {
      newact = *act;
      if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL
	  && sig > 0 && sig < NSIG)
	{
	  if (act->sa_flags & SA_SIGINFO)
	    newact.sa_handler = (__sighandler_t) pthread_sighandler_rt;
	  else
	    newact.sa_handler = (__sighandler_t) pthread_sighandler;
	}
      newactp = &newact;
    }
  else
    newactp = NULL;
  if (__libc_sigaction(sig, newactp, oact) == -1)
    return -1;
#ifdef DEBUG_PT
printf(__FUNCTION__": sighandler installed, sigaction successful\n");
#endif
  if (sig > 0 && sig < NSIG)
    {
      if (oact != NULL)
	oact->sa_handler = (__sighandler_t) sighandler[sig].old;
      if (act)
	/* For the assignment is does not matter whether it's a normal
	   or real-time signal.  */
	sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
    }
  return 0;
}
libpthread_hidden_def(sigaction)

/* A signal handler that does nothing */
static void pthread_null_sighandler(int sig attribute_unused) { }

/* sigwait -- synchronously wait for a signal */
int sigwait(const sigset_t * set, int * sig)
{
  volatile pthread_descr self = thread_self();
  sigset_t mask;
  int s;
  sigjmp_buf jmpbuf;
  struct sigaction sa;

  /* Get ready to block all signals except those in set
     and the cancellation signal.
     Also check that handlers are installed on all signals in set,
     and if not, install our dummy handler.  This is conformant to
     POSIX: "The effect of sigwait() on the signal actions for the
     signals in set is unspecified." */
  __sigfillset(&mask);
  sigdelset(&mask, __pthread_sig_cancel);
  for (s = 1; s <= NSIG; s++) {
    if (sigismember(set, s) &&
        s != __pthread_sig_restart &&
        s != __pthread_sig_cancel &&
        s != __pthread_sig_debug) {
      sigdelset(&mask, s);
      if (sighandler[s].old == NULL ||
	  sighandler[s].old == (arch_sighandler_t) SIG_DFL ||
	  sighandler[s].old == (arch_sighandler_t) SIG_IGN) {
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = pthread_null_sighandler;
        sigaction(s, &sa, NULL);
      }
    }
  }
  /* Test for cancellation */
  if (sigsetjmp(jmpbuf, 1) == 0) {
    THREAD_SETMEM(self, p_cancel_jmp, &jmpbuf);
    if (! (THREAD_GETMEM(self, p_canceled)
	   && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) {
      /* Reset the signal count */
      THREAD_SETMEM(self, p_signal, 0);
      /* Say we're in sigwait */
      THREAD_SETMEM(self, p_sigwaiting, 1);
      /* Unblock the signals and wait for them */
      sigsuspend(&mask);
    }
  }
  THREAD_SETMEM(self, p_cancel_jmp, NULL);
  /* The signals are now reblocked.  Check for cancellation */
  pthread_testcancel();
  /* We should have self->p_signal != 0 and equal to the signal received */
  *sig = THREAD_GETMEM(self, p_signal);
  return 0;
}

/* Redefine raise() to send signal to calling thread only,
   as per POSIX 1003.1c */
libpthread_hidden_proto(raise)
int raise (int sig)
{
  int retcode = pthread_kill(pthread_self(), sig);
  if (retcode == 0)
    return 0;
  else {
    errno = retcode;
    return -1;
  }
}
libpthread_hidden_def(raise)
