Ejemplo n.º 1
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals that
 * the kernel can handle, and then we build all the user-level signal handling
 * stack-frames in one go after that.
 */
static void do_signal(struct pt_regs *regs, int in_syscall)
{
	struct ksignal ksig;

#ifdef DEBUG_SIG
	pr_info("do signal: %p %d\n", regs, in_syscall);
	pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
			regs->r12, current_thread_info()->flags);
#endif

	if (get_signal(&ksig)) {
		/* Whee! Actually deliver the signal. */
		if (in_syscall)
			handle_restart(regs, &ksig.ka, 1);
		handle_signal(&ksig, regs);
		return;
	}

	if (in_syscall)
		handle_restart(regs, NULL, 0);

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 2
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals that
 * the kernel can handle, and then we build all the user-level signal handling
 * stack-frames in one go after that.
 */
static void do_signal(struct pt_regs *regs, int in_syscall)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
#ifdef DEBUG_SIG
	pr_info("do signal: %p %d\n", regs, in_syscall);
	pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
			regs->r12, current_thread_info()->flags);
#endif

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee! Actually deliver the signal. */
		if (in_syscall)
			handle_restart(regs, &ka, 1);
		handle_signal(signr, &ka, &info, regs);
		return;
	}

	if (in_syscall)
		handle_restart(regs, NULL, 0);

	/*
	 * If there's no signal to deliver, we just put the saved sigmask
	 * back.
	 */
	restore_saved_sigmask();
}
Ejemplo n.º 3
0
/*
 * OK, we're invoking a handler
 */
static int
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
	      sigset_t *oldset, struct pt_regs *regs)
{
	int ret;

	/* are we from a system call? to see pt_regs->orig_p0 */
	if (regs->orig_p0 >= 0)
		/* If so, check system call restarting.. */
		handle_restart(regs, ka, 1);

	/* set up the stack frame */
	ret = setup_rt_frame(sig, ka, info, oldset, regs);

	if (ret == 0) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked, &current->blocked,
			  &ka->sa.sa_mask);
		if (!(ka->sa.sa_flags & SA_NODEFER))
			sigaddset(&current->blocked, sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
	return ret;
}
Ejemplo n.º 4
0
Archivo: signal.c Proyecto: 7LK/McWRT
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 */
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
	struct k_sigaction ka;
	siginfo_t info;
	int signr;

	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (!user_mode(regs))
		return 1;

	if (!oldset)
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &ka, &info, oldset, regs);
		return 1;
	}

	/* Did we come from a system call? */
	if (regs->frame_type == -1) {
		/* Restart the system call - no handlers present */
		handle_restart(regs, NULL, 0);
	}

	return 0;
}
Ejemplo n.º 5
0
/*
 * OK, we're invoking a handler
 */
static void
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs *regs)
{
	/* are we from a system call? */
	if (regs->orig_er0 >= 0)
		/* If so, check system call restarting.. */
		handle_restart(regs, ka, 1);

	/* set up the stack frame */
	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame(sig, ka, info, oldset, regs);
	else
		setup_frame(sig, ka, oldset, regs);

	if (ka->sa.sa_flags & SA_ONESHOT)
		ka->sa.sa_handler = SIG_DFL;

	if (!(ka->sa.sa_flags & SA_NODEFER)) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}
}
Ejemplo n.º 6
0
/*
 * OK, we're invoking a handler
 */
static void
handle_signal(struct ksignal *ksig, struct pt_regs *regs)
{
	sigset_t *oldset = sigmask_to_save();
	int ret;
	/* are we from a system call? */
	if (regs->orig_er0 >= 0)
		handle_restart(regs, &ksig->ka);

	ret = setup_rt_frame(ksig, oldset, regs);

	signal_setup_done(ret, ksig, 0);
}
Ejemplo n.º 7
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals that
 * the kernel can handle, and then we build all the user-level signal handling
 * stack-frames in one go after that.
 */
int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
#ifdef DEBUG_SIG
	printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall);
	printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
			regs->r12, current_thread_info()->flags);
#endif
	/*
	 * We want the common case to go fast, which
	 * is why we may in certain cases get here from
	 * kernel mode. Just return without doing anything
	 * if so.
	 */
	if (kernel_mode(regs))
		return 1;

	if (!oldset)
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee! Actually deliver the signal. */
		if (in_syscall)
			handle_restart(regs, &ka, 1);
		handle_signal(signr, &ka, &info, oldset, regs);
		return 1;
	}

	if (in_syscall)
		handle_restart(regs, NULL, 0);

	/* Did we come from a system call? */
	return 0;
}
Ejemplo n.º 8
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals
 * that the kernel can handle, and then we build all the user-level signal
 * handling stack-frames in one go after that.
 */
asmlinkage void do_signal(struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;
	sigset_t *oldset;

	current->thread.esp0 = (unsigned long)regs;

	if (try_to_freeze())
		goto no_signal;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
			/* a signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);

			tracehook_signal_handler(signr, &info, &ka, regs,
				test_thread_flag(TIF_SINGLESTEP));
		}

		return;
	}

 no_signal:
	/* Did we come from a system call? */
	if (regs->orig_p0 >= 0)
		/* Restart the system call - no handlers present */
		handle_restart(regs, NULL, 0);

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}
Ejemplo n.º 9
0
Archivo: signal.c Proyecto: 4atty/linux
/*
 * OK, we're invoking a handler
 */
static void
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
	      struct pt_regs *regs)
{
	/* are we from a system call? to see pt_regs->orig_p0 */
	if (regs->orig_p0 >= 0)
		/* If so, check system call restarting.. */
		handle_restart(regs, ka, 1);

	/* set up the stack frame */
	if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
		force_sigsegv(sig, current);
	else 
		signal_delivered(sig, info, ka, regs,
				test_thread_flag(TIF_SINGLESTEP));
}
Ejemplo n.º 10
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 */
static void do_signal(struct pt_regs *regs)
{
	struct ksignal ksig;

	current->thread.esp0 = (unsigned long) regs;

	if (get_signal(&ksig)) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(&ksig, regs);
		return;
	}
	/* Did we come from a system call? */
	if (regs->orig_er0 >= 0)
		handle_restart(regs, NULL);

	/* If there's no signal to deliver, we just restore the saved mask.  */
	restore_saved_sigmask();
}
Ejemplo n.º 11
0
/*
 * OK, we're invoking a handler
 */
static int
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
	      sigset_t *oldset, struct pt_regs *regs)
{
	int ret;

	/* are we from a system call? to see pt_regs->orig_p0 */
	if (regs->orig_p0 >= 0)
		/* If so, check system call restarting.. */
		handle_restart(regs, ka, 1);

	/* set up the stack frame */
	ret = setup_rt_frame(sig, ka, info, oldset, regs);

	if (ret == 0)
		block_sigmask(ka, sig);

	return ret;
}
Ejemplo n.º 12
0
Archivo: signal.c Proyecto: 4atty/linux
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals
 * that the kernel can handle, and then we build all the user-level signal
 * handling stack-frames in one go after that.
 */
asmlinkage void do_signal(struct pt_regs *regs)
{
	siginfo_t info;
	int signr;
	struct k_sigaction ka;

	current->thread.esp0 = (unsigned long)regs;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, &info, &ka, regs);
		return;
	}

	/* Did we come from a system call? */
	if (regs->orig_p0 >= 0)
		/* Restart the system call - no handlers present */
		handle_restart(regs, NULL, 0);

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	restore_saved_sigmask();
}
Ejemplo n.º 13
0
int
do_test (int argc, char *argv[])
{
  pid_t pid;
  int status;

  /* We must have
     - one or four parameters left if called initially
       + path for ld.so		optional
       + "--library-path"	optional
       + the library path	optional
       + the application name

    if --enable-hardcoded-path-in-tests is used, just
      + the application name
  */

  if (restart)
    {
      if (argc != 1)
	{
	  printf ("Wrong number of arguments (%d) in restart\n", argc);
	  exit (EXIT_FAILURE);
	}

      return handle_restart ();
    }

  if (argc != 2 && argc != 5)
    {
      printf ("Wrong number of arguments (%d)\n", argc);
      exit (EXIT_FAILURE);
    }

  /* We want to test the `execvpe' function.  To do this we restart the
     program with an additional parameter.  */
  pid = fork ();
  if (pid == 0)
    {
      /* This is the child.  Construct the command line.  */

      /* We cast here to char* because the test itself does not modify neither
	 the argument nor the environment list.  */
      char *envs[] = { (char*)(EXECVPE_KEY "=" EXECVPE_VALUE), NULL };
      if (argc == 5)
	{
	  char *args[] = { argv[1], argv[2], argv[3], argv[4],
			   (char *) "--direct", (char *) "--restart", NULL };
	  execvpe (args[0], args, envs);
	}
      else
	{
	  char *args[] = { argv[0],
			   (char *) "--direct", (char *) "--restart", NULL };
	  execvpe (args[0], args, envs);
	}

      puts ("Cannot exec");
      exit (EXIT_FAILURE);
    }
  else if (pid == (pid_t) -1)
    {
      puts ("Cannot fork");
      return 1;
    }

  /* Wait for the child.  */
  if (waitpid (pid, &status, 0) != pid)
    {
      puts ("Wrong child");
      return 1;
    }

  if (WTERMSIG (status) != 0)
    {
      puts ("Child terminated incorrectly");
      return 1;
    }
  status = WEXITSTATUS (status);

  return status;
}
Ejemplo n.º 14
0
int
do_test (int argc, char *argv[])
{
  pid_t pid;
  int fd1;
  int fd2;
  int flags;
  int status;

  /* We must have
     - one or four parameters left if called initially
       + path for ld.so		optional
       + "--library-path"	optional
       + the library path	optional
       + the application name
     - three parameters left if called through re-execution
       + file descriptor number which is supposed to be closed
       + the open file descriptor
       + the name of the closed desriptor
  */

  if (restart)
    {
      if (argc != 4)
	error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc);

      return handle_restart (argv[1], argv[2], argv[3]);
    }

  if (argc != 2 && argc != 5)
    error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc);

  /* Prepare the test.  We are creating two files: one which file descriptor
     will be marked with FD_CLOEXEC, another which is not.  */

   /* Open our test files.   */
   fd1 = mkstemp (name1);
   if (fd1 == -1)
     error (EXIT_FAILURE, errno, "cannot open test file `%s'", name1);
   fd2 = mkstemp (name2);
   if (fd2 == -1)
     error (EXIT_FAILURE, errno, "cannot open test file `%s'", name2);

   /* Set the bit.  */
   flags = fcntl (fd1, F_GETFD, 0);
   if (flags < 0)
     error (EXIT_FAILURE, errno, "cannot get flags");
   flags |= FD_CLOEXEC;
   if (fcntl (fd1, F_SETFD, flags) < 0)
     error (EXIT_FAILURE, errno, "cannot set flags");

   /* Write something in the files.  */
   if (write (fd1, fd1string, strlen (fd1string)) != strlen (fd1string))
     error (EXIT_FAILURE, errno, "cannot write to first file");
   if (write (fd2, fd2string, strlen (fd2string)) != strlen (fd2string))
     error (EXIT_FAILURE, errno, "cannot write to second file");

  /* We want to test the `exec' function.  To do this we restart the program
     with an additional parameter.  But first create another process.  */
  pid = fork ();
  if (pid == 0)
    {
      char fd1name[18];
      char fd2name[18];

      snprintf (fd1name, sizeof fd1name, "%d", fd1);
      snprintf (fd2name, sizeof fd2name, "%d", fd2);

      /* This is the child.  Construct the command line.  */
      if (argc == 5)
	execl (argv[1], argv[1], argv[2], argv[3], argv[4], "--direct",
	       "--restart", fd1name, fd2name, name1, NULL);
      else
	execl (argv[1], argv[1], "--direct",
	       "--restart", fd1name, fd2name, name1, NULL);

      error (EXIT_FAILURE, errno, "cannot exec");
    }
  else if (pid == (pid_t) -1)
    error (EXIT_FAILURE, errno, "cannot fork");

  /* Wait for the child.  */
  if (waitpid (pid, &status, 0) != pid)
    error (EXIT_FAILURE, errno, "wrong child");

  if (WTERMSIG (status) != 0)
    error (EXIT_FAILURE, 0, "Child terminated incorrectly");
  status = WEXITSTATUS (status);

  /* Remove the test files.  */
  unlink (name1);
  unlink (name2);

  return status;
}
int
do_test (int argc, char *argv[])
{
  pid_t pid;
  int fd1;
  int fd2;
  int fd3;
  int fd4;
  int status;
  posix_spawn_file_actions_t actions;
  char fd1name[18];
  char fd2name[18];
  char fd3name[18];
  char fd4name[18];
  char *spargv[12];

  /* We must have
     - four parameters left of called initially
       + path for ld.so
       + "--library-path"
       + the library path
       + the application name
     - five parameters left if called through re-execution
       + file descriptor number which is supposed to be closed
       + the open file descriptor
       + the newly opened file descriptor
       + thhe duped second descriptor
       + the name of the closed descriptor
  */
  if (argc != (restart ? 6 : 5))
    error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc);

  if (restart)
    return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5]);

  /* Prepare the test.  We are creating two files: one which file descriptor
     will be marked with FD_CLOEXEC, another which is not.  */

   /* Open our test files.   */
   fd1 = mkstemp (name1);
   if (fd1 == -1)
     error (EXIT_FAILURE, errno, "cannot open test file `%s'", name1);
   fd2 = mkstemp (name2);
   if (fd2 == -1)
     error (EXIT_FAILURE, errno, "cannot open test file `%s'", name2);
   fd3 = mkstemp (name3);
   if (fd3 == -1)
     error (EXIT_FAILURE, errno, "cannot open test file `%s'", name3);

   /* Write something in the files.  */
   if (write (fd1, fd1string, strlen (fd1string)) != strlen (fd1string))
     error (EXIT_FAILURE, errno, "cannot write to first file");
   if (write (fd2, fd2string, strlen (fd2string)) != strlen (fd2string))
     error (EXIT_FAILURE, errno, "cannot write to second file");
   if (write (fd3, fd3string, strlen (fd3string)) != strlen (fd3string))
     error (EXIT_FAILURE, errno, "cannot write to third file");

   /* Close the third file.  It'll be opened by `spawn'.  */
   close (fd3);

   /* Tell `spawn' what to do.  */
   if (posix_spawn_file_actions_init (&actions) != 0)
     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_init");
   /* Close `fd1'.  */
   if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
   /* We want to open the third file.  */
   if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
					 O_RDONLY, 0666) != 0)
     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
   /* We dup the second descriptor.  */
   fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
   if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_adddup2");

   /* Now spawn the process.  */
   snprintf (fd1name, sizeof fd1name, "%d", fd1);
   snprintf (fd2name, sizeof fd2name, "%d", fd2);
   snprintf (fd3name, sizeof fd3name, "%d", fd3);
   snprintf (fd4name, sizeof fd4name, "%d", fd4);

   spargv[0] = argv[1];
   spargv[1] = argv[2];
   spargv[2] = argv[3];
   spargv[3] = argv[4];
   spargv[4] = (char *) "--direct";
   spargv[5] = (char *) "--restart";
   spargv[6] = fd1name;
   spargv[7] = fd2name;
   spargv[8] = fd3name;
   spargv[9] = fd4name;
   spargv[10] = name1;
   spargv[11] = NULL;

   if (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ) != 0)
     error (EXIT_FAILURE, errno, "posix_spawn");

   /* Cleanup.  */
   if (posix_spawn_file_actions_destroy (&actions) != 0)
     error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");

  /* Wait for the child.  */
  if (waitpid (pid, &status, 0) != pid)
    error (EXIT_FAILURE, errno, "wrong child");

  if (WTERMSIG (status) != 0)
    error (EXIT_FAILURE, 0, "Child terminated incorrectly");
  status = WEXITSTATUS (status);

  /* Remove the test files.  */
  unlink (name1);
  unlink (name2);
  unlink (name3);

  return status;
}
Ejemplo n.º 16
0
/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Note that we go through the signals twice: once to check the signals
 * that the kernel can handle, and then we build all the user-level signal
 * handling stack-frames in one go after that.
 */
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
	siginfo_t info;
	struct k_sigaction *ka;

	current->thread.esp0 = (unsigned long) regs;

	if (!oldset)
		oldset = &current->blocked;

	for (;;) {
		int signr;

		signr = get_signal_to_deliver(&info, regs, NULL);

		if (!signr)
			break;

		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
			current->exit_code = signr;
			current->state = TASK_STOPPED;

			/* Did we come from a system call? */
			if (regs->orig_er0 >= 0) {
				/* Restart the system call the same way as
				   if the process were not traced.  */
				struct k_sigaction *ka =
					&current->sighand->action[signr-1];
				int has_handler =
					(ka->sa.sa_handler != SIG_IGN &&
					 ka->sa.sa_handler != SIG_DFL);
				handle_restart(regs, ka, has_handler);
			}
			notify_parent(current, SIGCHLD);
			schedule();

			/* We're back.  Did the debugger cancel the sig?  */
			if (!(signr = current->exit_code)) {
			discard_frame:
			    continue;
			}
			current->exit_code = 0;

			/* The debugger continued.  Ignore SIGSTOP.  */
			if (signr == SIGSTOP)
				goto discard_frame;

			/* Update the siginfo structure.  Is this good?  */
			if (signr != info.si_signo) {
				info.si_signo = signr;
				info.si_errno = 0;
				info.si_code = SI_USER;
				info.si_pid = current->parent->pid;
				info.si_uid = current->parent->uid;
			}

			/* If the (new) signal is now blocked, requeue it.  */
			if (sigismember(&current->blocked, signr)) {
				send_sig_info(signr, &info, current);
				continue;
			}
		}

		ka = &current->sighand->action[signr-1];
		if (ka->sa.sa_handler == SIG_IGN) {
			if (signr != SIGCHLD)
				continue;
			/* Check for SIGCHLD: it's special.  */
			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
				/* nothing */;
			continue;
		}

		if (ka->sa.sa_handler == SIG_DFL) {
			int exit_code = signr;

			if (current->pid == 1)
				continue;

			switch (signr) {
			case SIGCONT: case SIGCHLD:
			case SIGWINCH: case SIGURG:
				continue;

			case SIGTSTP: case SIGTTIN: case SIGTTOU:
				if (is_orphaned_pgrp(process_group(current)))
					continue;
				/* FALLTHRU */

			case SIGSTOP: {
				struct sighand_struct *sig;
				current->state = TASK_STOPPED;
				current->exit_code = signr;
                                sig = current->parent->sighand;
                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags 
& SA_NOCLDSTOP))
                                        notify_parent(current, SIGCHLD);
				schedule();
				continue;
			}

			case SIGQUIT: case SIGILL: case SIGTRAP:
			case SIGIOT: case SIGFPE: case SIGSEGV:
			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
				if (do_coredump(signr, exit_code, regs))
					exit_code |= 0x80;
				/* FALLTHRU */

			default:
				sigaddset(&current->pending.signal, signr);
				recalc_sigpending();
				current->flags |= PF_SIGNALED;
				do_exit(exit_code);
				/* NOTREACHED */
			}
		}

		/* Whee!  Actually deliver the signal.  */
		handle_signal(signr, ka, &info, oldset, regs);
		return 1;
	}

	/* Did we come from a system call? */
	if (regs->orig_er0 >= 0)
		/* Restart the system call - no handlers present */
		handle_restart(regs, NULL, 0);

	return 0;
}