コード例 #1
0
ファイル: colib.lj.c プロジェクト: jamjr/Helios-NG
ptr CreateCo(VoidFnPtr function, WORD size)
{ Coroutine		*newco;
  struct sigaction	 act_save, act_new;
  struct sigstack	 stack_save, stack_new;
  sigset_t		 set_save, set_new;
  void			(*fn)(int);

  newco = (Coroutine *) malloc (sizeof(Coroutine));
  if (newco == NULL) return (NULL);

  Dbg(("CreateCo: new coroutine is at %x", newco));
  Dbg(("CreateCo: saving current state in %x", CurrentCo->JmpBuf));
  
  if (sigsetjmp((sigjmp_buf *) CurrentCo->JmpBuf, 1) == 0)
   { 
     newco->Parent = CurrentCo;
     CurrentCo = newco;

	/* Block all signals except SIGUSR1	*/
     sigfillset(&set_new);
     sigdelset(&set_new, SIGUSR1);
     sigprocmask(SIG_SETMASK, &set_new, &set_save);

	/* Set up the coroutine stack as the signal handling stack	*/
     stack_new.ss_sp	  = (caddr_t) &(newco->Stack[STK_SIZE - sizeof(int)]);
     stack_new.ss_onstack = 0;
     sigstack(&stack_new, &stack_save);

	/* Install the signal handling routine.				*/
     sigaction(SIGUSR1, NULL, &act_save);
     act_new.sa_handler	  = createco_aux;
     act_new.sa_mask	  = act_save.sa_mask;
     act_new.sa_flags	  = act_save.sa_flags | SA_ONSTACK;
     sigaction(SIGUSR1, &act_new, NULL);

     Dbg(("CreateCo: raising signal to activate new coroutine %x", newco));
	/* Now get the coroutine running.				*/
     raise(SIGUSR1);
   }
  else
   {	/* createco_aux has done the siglongjmp...			*/
 	/* switch back to default signal stack				*/
     sigstack(&stack_save, NULL);
	/* restore the signal handler.					*/
     sigaction(SIGUSR1, &act_save, NULL);
	/* and unblock the various signals.				*/
     sigprocmask(SIG_SETMASK, &set_save, NULL);

     	/* restore CurrentCo						*/
     CurrentCo = CurrentCo->Parent;
     Dbg(("CreateCo: new coroutine has been initialised, CurrentCo %x", CurrentCo));
   }

  Dbg(("CreateCo: returning new coroutine %x", newco));
  return(newco);
}
コード例 #2
0
ファイル: tc.os.c プロジェクト: tcsh-org/tcsh
void
osinit(void)
{
#ifdef OREO
    set42sig();
    setcompat(getcompat() & ~COMPAT_EXEC);
    signal(SIGIO, SIG_IGN);		/* ignore SIGIO */
#endif /* OREO */

#ifdef aiws
    {
	struct sigstack inst;
	inst.ss_sp = xmalloc(4192) + 4192;
	inst.ss_onstack = 0;
	sigstack(&inst, NULL);
    }
#endif /* aiws */

#ifdef apollo
    (void) isapad();
#endif

#ifdef _SX
    /* 
     * kill(SIGCONT) problems, don't know what this syscall does
     * [[email protected]]
     */
    syscall(151, getpid(), getpid());
#endif /* _SX */
}
コード例 #3
0
ファイル: sig_unix.cpp プロジェクト: cthulhuology/self
void SignalInterface::init_signal_stack() {
  // ensure generic val is enough for ppc
  signal_stack_size = max(1 << 15, SIGSTKSZ); // 32K should be enough
  signal_stack = (char*)valloc(signal_stack_size);
  struct sigstack ss;
  ss.ss_sp = signal_stack + signal_stack_size;     // stack grows downwards
  ss.ss_onstack = false;
  if (sigstack(&ss, NULL) == -1) {
   perror("sigstack");
  fatal("cannot install signal stack");
  }
}
コード例 #4
0
ファイル: signal_test_01.c プロジェクト: AbhiramiP/ltp
/*---------------------------------------------------------------------+
|                               main ()                                |
| ==================================================================== |
|                                                                      |
| Function:  Main program  (see prolog for more details)               |
|                                                                      |
+---------------------------------------------------------------------*/
int main(int argc, char **argv)
{
	sigset_t mask,		/* Initial process signal mask */
	 newmask,		/* Second process signal mask */
	 oldmask;		/* Signal mask returned by sigblock */
	pid_t pid = getpid();	/* Process ID (of this process) */

	/* Print out program header */
	printf("%s: IPC Signals TestSuite program\n\n", *argv);

	/*
	 * Establish signal handler for each signal & reset "valid signals"
	 * array, and setup alternative stack for processing signals
	 */
	init_sig_vec();
	reset_valid_sig();
#ifdef _LINUX_
	// sigstack function is obsolete, use sigaltstack instead
	if (sigaltstack(&stack, NULL) < 0)
		sys_error("sigaltstack failed", __LINE__);
#else
	if (sigstack(&stack, NULL) < 0)
		sys_error("sigstack failed", __LINE__);
#endif
	/*
	 * Send SIGILL, SIGALRM & SIGIOT signals to this process:
	 *
	 * First indicate which signals the signal handler should expect
	 * by setting the corresponding valid_sig[] array fields.
	 *
	 * Then send the signals to this process.
	 *
	 * And finally verify that the signals were caught by the signal
	 * handler by checking to see if the corresponding valid_sig[] array
	 * fields were reset.
	 */
	printf("\tSend SIGILL, SIGALRM, SIGIOT signals to process\n");
	valid_sig[SIGILL] = 1;
	valid_sig[SIGALRM] = 1;
	valid_sig[SIGIOT] = 1;

	kill(pid, SIGILL);
	kill(pid, SIGALRM);
	kill(pid, SIGIOT);

	if (valid_sig[SIGILL])
		error("failed to receive SIGILL signal!", __LINE__);
	if (valid_sig[SIGALRM])
		error("failed to receive SIGALRM signal!", __LINE__);
	if (valid_sig[SIGIOT])
		error("failed to receive SIGIOT signal!", __LINE__);

	/*
	 * Block SIGILL, SIGALRM & SIGIOT signals:
	 *
	 * First create the process signal mask by ORing together the
	 * signal values.
	 *
	 * Then change the process signal mask with sigsetmask ().
	 *
	 * Verify that the desired signals are blocked from interrupting the
	 * process, by sending both blocked and unblocked signals to the
	 * process. Only the unblocked signals should interrupt the process.
	 */
	printf("\n\tBlock SIGILL, SIGALRM, SIGIOT signals, "
	       "and resend signals + others\n");
	sigemptyset(&mask);
	sigaddset(&mask, SIGILL);
	sigaddset(&mask, SIGALRM);
	sigaddset(&mask, SIGIOT);
#ifdef _LINUX_
	sigprocmask(SIG_SETMASK, &mask, NULL);
#else
	if (sigsetmask(mask) < 0)
		sys_error("setsigmask failed", __LINE__);
#endif
	valid_sig[SIGFPE] = 1;
	valid_sig[SIGTERM] = 1;
	valid_sig[SIGINT] = 1;

	kill(pid, SIGILL);
	kill(pid, SIGALRM);
	kill(pid, SIGIOT);
	kill(pid, SIGFPE);
	kill(pid, SIGTERM);
	kill(pid, SIGINT);

	if (valid_sig[SIGFPE])
		error("failed to receive SIGFPE signal!", __LINE__);
	if (valid_sig[SIGTERM])
		error("failed to receive SIGTERM signal!", __LINE__);
	if (valid_sig[SIGINT])
		error("failed to receive SIGINT signal!", __LINE__);

	/*
	 * Block additional SIGFPE, SIGTERM & SIGINT signals:
	 *
	 * Create a signal mask containing the additional signals to block.
	 *
	 * Change the process signal mask to block the additional signals
	 * with the sigprocmask () function.
	 *
	 * Verify that all of the desired signals are now blocked from
	 * interrupting the process.  None of the specified signals should
	 * interrupt the process until the process signal mask is changed.
	 */
	printf("\n\tBlock rest of signals\n");
	sigemptyset(&newmask);
	sigaddset(&newmask, SIGFPE);
	sigaddset(&newmask, SIGTERM);
	sigaddset(&newmask, SIGINT);
	sigemptyset(&oldmask);
	if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
		perror("sigprocmask failed");
		exit(-1);
	}
	if (memcmp(&mask, &oldmask, sizeof(mask)) != 0)
		error("value returned by sigblock () does not match the "
		      "old signal mask", __LINE__);

	kill(pid, SIGILL);
	kill(pid, SIGALRM);
	kill(pid, SIGIOT);
	kill(pid, SIGFPE);
	kill(pid, SIGTERM);
	kill(pid, SIGINT);

	/* Wait two seconds just to make sure that none of the specified
	 * signals interrupt the process (They should all be blocked).
	 */
	sleep(2);

	/* Change the process signal mask:
	 *
	 * Now allow the SIGINT signal to interrupt the process.
	 * Thus by using sigpause (), force the process to suspend
	 * execution until delivery of an unblocked signal (here SIGINT).
	 *
	 * Additionally, verify that the SIGINT signal was received.
	 */
	valid_sig[SIGINT] = 1;

	printf
	    ("\n\tChange signal mask & wait until signal interrupts process\n");
	if (sigpause(SIGINT) != -1 || errno != 4)
		sys_error("sigpause failed", __LINE__);

	if (valid_sig[SIGINT])
		error("failed to receive SIGINT signal!", __LINE__);

	/* Program completed successfully -- exit */
	printf("\nsuccessful!\n");

	return (0);
}
コード例 #5
0
ファイル: pcl.c プロジェクト: amyznikov/libpcl
static int co_set_context(co_ctx_t *ctx, void *func, char *stkbase, long stksiz)
{
	struct sigaction sa;
	struct sigaction osa;
	sigset_t osigs;
	sigset_t sigs;
#if defined(CO_HAS_SIGSTACK)
	struct sigstack ss;
	struct sigstack oss;
#elif defined(CO_HAS_SIGALTSTACK)
	struct sigaltstack ss;
	struct sigaltstack oss;
#else
#error "PCL: Unknown context stack type"
#endif

	/*
	 * Preserve the SIGUSR1 signal state, block SIGUSR1,
	 * and establish our signal handler. The signal will
	 * later transfer control onto the signal stack.
	 */
	sigemptyset(&sigs);
	sigaddset(&sigs, SIGUSR1);
	sigprocmask(SIG_BLOCK, &sigs, &osigs);
	sa.sa_handler = co_ctx_trampoline;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_ONSTACK;
	if (sigaction(SIGUSR1, &sa, &osa) != 0)
		return -1;

	/*
	 * Set the new stack.
	 *
	 * For sigaltstack we're lucky [from sigaltstack(2) on
	 * FreeBSD 3.1]: ``Signal stacks are automatically adjusted
	 * for the direction of stack growth and alignment
	 * requirements''
	 *
	 * For sigstack we have to decide ourself [from sigstack(2)
	 * on Solaris 2.6]: ``The direction of stack growth is not
	 * indicated in the historical definition of struct sigstack.
	 * The only way to portably establish a stack pointer is for
	 * the application to determine stack growth direction.''
	 */
#if defined(CO_HAS_SIGALTSTACK)
	ss.ss_sp = stkbase;
	ss.ss_size = stksiz - sizeof(long);
	ss.ss_flags = 0;
	if (sigaltstack(&ss, &oss) < 0)
		return -1;
#elif defined(CO_HAS_SIGSTACK)
	if (co_ctx_stackdir() < 0)
		ss.ss_sp = (stkbase + stksiz - sizeof(long));
	else
		ss.ss_sp = stkbase;
	ss.ss_onstack = 0;
	if (sigstack(&ss, &oss) < 0)
		return -1;
#else
#error "PCL: Unknown context stack type"
#endif

	/*
	 * Now transfer control onto the signal stack and set it up.
	 * It will return immediately via "return" after the setjmp()
	 * was performed. Be careful here with race conditions.  The
	 * signal can be delivered the first time sigsuspend() is
	 * called.
	 */
	ctx_called = 0;
	kill(getpid(), SIGUSR1);
	sigfillset(&sigs);
	sigdelset(&sigs, SIGUSR1);
	while (!ctx_called)
		sigsuspend(&sigs);

	/*
	 * Inform the system that we are back off the signal stack by
	 * removing the alternative signal stack. Be careful here: It
	 * first has to be disabled, before it can be removed.
	 */
#if defined(CO_HAS_SIGALTSTACK)
	sigaltstack(NULL, &ss);
	ss.ss_flags = SS_DISABLE;
	if (sigaltstack(&ss, NULL) < 0)
		return -1;
	sigaltstack(NULL, &ss);
	if (!(ss.ss_flags & SS_DISABLE))
		return -1;
	if (!(oss.ss_flags & SS_DISABLE))
		sigaltstack(&oss, NULL);
#elif defined(CO_HAS_SIGSTACK)
	if (sigstack(&oss, NULL))
		return -1;
#else
#error "PCL: Unknown context stack type"
#endif

	/*
	 * Restore the old SIGUSR1 signal handler and mask
	 */
	sigaction(SIGUSR1, &osa, NULL);
	sigprocmask(SIG_SETMASK, &osigs, NULL);

	/*
	 * Set creation information.
	 */
	ctx_creating = ctx;
	ctx_creating_func = func;
	memcpy(&ctx_creating_sigs, &osigs, sizeof(sigset_t));

	/*
	 * Now enter the trampoline again, but this time not as a signal
	 * handler. Instead we jump into it directly.
	 */
	if (setjmp(ctx_caller.cc) == 0)
		longjmp(ctx_trampoline.cc, 1);

	return 0;
}
コード例 #6
0
ファイル: pexpr.c プロジェクト: AllardJ/Tomato
void
setup_error_handler (void)
{
#if HAVE_SIGACTION
  struct sigaction act;
  act.sa_handler = cleanup_and_exit;
  sigemptyset (&(act.sa_mask));
#define SIGNAL(sig)  sigaction (sig, &act, NULL)
#else
  struct { int sa_flags; } act;
#define SIGNAL(sig)  signal (sig, cleanup_and_exit)
#endif
  act.sa_flags = 0;

  /* Set up a stack for signal handling.  A typical cause of error is stack
     overflow, and in such situation a signal can not be delivered on the
     overflown stack.  */
#if HAVE_SIGALTSTACK
  {
    /* AIX uses stack_t, MacOS uses struct sigaltstack, various other
       systems have both. */
#if HAVE_STACK_T
    stack_t s;
#else
    struct sigaltstack s;
#endif
    s.ss_sp = malloc (SIGSTKSZ);
    s.ss_size = SIGSTKSZ;
    s.ss_flags = 0;
    if (sigaltstack (&s, NULL) != 0)
      perror("sigaltstack");
    act.sa_flags = SA_ONSTACK;
  }
#else
#if HAVE_SIGSTACK
  {
    struct sigstack s;
    s.ss_sp = malloc (SIGSTKSZ);
    if (stack_downwards_p ())
      s.ss_sp += SIGSTKSZ;
    s.ss_onstack = 0;
    if (sigstack (&s, NULL) != 0)
      perror("sigstack");
    act.sa_flags = SA_ONSTACK;
  }
#else
#endif
#endif

#ifdef LIMIT_RESOURCE_USAGE
  {
    struct rlimit limit;

    limit.rlim_cur = limit.rlim_max = 0;
    setrlimit (RLIMIT_CORE, &limit);

    limit.rlim_cur = 3;
    limit.rlim_max = 4;
    setrlimit (RLIMIT_CPU, &limit);

    limit.rlim_cur = limit.rlim_max = 16 * 1024 * 1024;
    setrlimit (RLIMIT_DATA, &limit);

    getrlimit (RLIMIT_STACK, &limit);
    limit.rlim_cur = 4 * 1024 * 1024;
    setrlimit (RLIMIT_STACK, &limit);

    SIGNAL (SIGXCPU);
  }
#endif /* LIMIT_RESOURCE_USAGE */

  SIGNAL (SIGILL);
  SIGNAL (SIGSEGV);
#ifdef SIGBUS /* not in mingw */
  SIGNAL (SIGBUS);
#endif
  SIGNAL (SIGFPE);
  SIGNAL (SIGABRT);
}
コード例 #7
0
ファイル: prog_stacksetup.c プロジェクト: RockyMeadow/simgrid
int main(int argc, char *argv[])
{
  FILE *f;
  char *skaddr;
  char *skbuf;
  int sksize;
  char result[1024];
  int i;
  sksize = 32768;
  skbuf = (char *) malloc(sksize * 2 + 2 * sizeof(union alltypes));
  if (skbuf == NULL)
    exit(1);
  for (i = 0; i < sksize * 2 + 2 * sizeof(union alltypes); i++)
    skbuf[i] = 'A';
  skaddr = skbuf + sizeof(union alltypes);
#if defined(TEST_sigstack) || defined(TEST_sigaltstack)
  {
    struct sigaction sa;
#if defined(TEST_sigstack)
    struct sigstack ss;
#elif defined(TEST_sigaltstack) && defined(HAVE_STACK_T)
    stack_t ss;
#else
    struct sigaltstack ss;
#endif
#if defined(TEST_sigstack)
    ss.ss_sp = (void *) (skaddr + sksize);
    ss.ss_onstack = 0;
    if (sigstack(&ss, NULL) < 0)
      exit(1);
#elif defined(TEST_sigaltstack)
    ss.ss_sp = (void *) (skaddr + sksize);
    ss.ss_size = sksize;
    ss.ss_flags = 0;
    if (sigaltstack(&ss, NULL) < 0)
      exit(1);
#endif
    memset((void *) &sa, 0, sizeof(struct sigaction));
    sa.sa_handler = handler;
    sa.sa_flags = SA_ONSTACK;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGUSR1, &sa, NULL);
    kill(getpid(), SIGUSR1);
    while (!handler_done)
      /*nop */ ;
  }
#endif
#if defined(TEST_makecontext)
  {
    if (getcontext(&uc_handler) != 0)
      exit(1);
    uc_handler.uc_link = NULL;
    uc_handler.uc_stack.ss_sp = (void *) (skaddr + sksize);
    uc_handler.uc_stack.ss_size = sksize;
    uc_handler.uc_stack.ss_flags = 0;
    makecontext(&uc_handler, handler, 0);
    swapcontext(&uc_main, &uc_handler);
  }
#endif
  if (handler_addr == (char *) 0xDEAD)
    exit(1);
  if (handler_addr < skaddr + sksize) {
    /* stack was placed into lower area */
    if (*(skaddr + sksize) != 'A')
      sprintf(result, "(skaddr)+(sksize)-%d,(sksize)-%d",
              sizeof(union alltypes), sizeof(union alltypes));
    else
      strcpy(result, "(skaddr)+(sksize),(sksize)");
  } else {
    /* stack was placed into higher area */
    if (*(skaddr + sksize * 2) != 'A')
      sprintf(result, "(skaddr),(sksize)-%d", sizeof(union alltypes));
    else
      strcpy(result, "(skaddr),(sksize)");
  }
  if ((f = fopen("conftestval", "w")) == NULL)
    exit(1);
  fprintf(f, "%s\n", result);
  fclose(f);
  exit(0);
  return 1;
}