+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement: This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software. Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#)kern_sig.c 7.23 (Berkeley) 6/28/90
+ */
+
+#include "param.h"
+#include "systm.h"
+#include "user.h"
+#include "vnode.h"
+#include "proc.h"
+#include "timeb.h"
+#include "times.h"
+#include "buf.h"
+#include "text.h"
+#include "seg.h"
+#include "vm.h"
+#include "acct.h"
+#include "uio.h"
+#include "file.h"
+#include "kernel.h"
+#include "wait.h"
+#include "ktrace.h"
+
+#include "machine/reg.h"
+#include "machine/pte.h"
+#include "machine/psl.h"
+#include "machine/mtpr.h"
+
+#define ttystopsigmask (sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU))
+#define stopsigmask (sigmask(SIGSTOP)|ttystopsigmask)
+#define defaultignmask (sigmask(SIGCONT)|sigmask(SIGIO)|sigmask(SIGURG)| \
+ sigmask(SIGCHLD)|sigmask(SIGWINCH)|sigmask(SIGINFO))
+
+/*
+ * Can process p send the signal signo to process q?
+ */
+#define CANSIGNAL(p, q, signo) \
+ ((p)->p_uid == 0 || \
+ (p)->p_ruid == (q)->p_ruid || (p)->p_uid == (q)->p_ruid || \
+ (p)->p_ruid == (q)->p_uid || (p)->p_uid == (q)->p_uid || \
+ ((signo) == SIGCONT && (q)->p_session == (p)->p_session))
+
+/* ARGSUSED */
+sigaction(p, uap, retval)
+ struct proc *p;
+ register struct args {
+ int signo;
+ struct sigaction *nsa;
+ struct sigaction *osa;
+ } *uap;
+ int *retval;
+{
+ struct sigaction vec;
+ register struct sigaction *sa;
+ register int sig;
+ int bit, error;
+
+ sig = uap->signo;
+ if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
+ return (EINVAL);
+ sa = &vec;
+ if (uap->osa) {
+ sa->sa_handler = u.u_signal[sig];
+ sa->sa_mask = u.u_sigmask[sig];
+ bit = sigmask(sig);
+ sa->sa_flags = 0;
+ if ((u.u_sigonstack & bit) != 0)
+ sa->sa_flags |= SA_ONSTACK;
+ if ((u.u_sigintr & bit) == 0)
+ sa->sa_flags |= SA_RESTART;
+ if (p->p_flag & SNOCLDSTOP)
+ sa->sa_flags |= SA_NOCLDSTOP;
+ if (error = copyout((caddr_t)sa, (caddr_t)uap->osa,
+ sizeof (vec)))
+ return (error);
+ }
+ if (uap->nsa) {
+ if (error = copyin((caddr_t)uap->nsa, (caddr_t)sa,
+ sizeof (vec)))
+ return (error);
+ setsigvec(p, sig, sa);
+ }
+ return (0);
+}
+
+setsigvec(p, sig, sa)
+ register struct proc *p;
+ int sig;
+ register struct sigaction *sa;