bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * CDDL HEADER START
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * The contents of this file are subject to the terms of the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Common Development and Distribution License (the "License").
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * You may not use this file except in compliance with the License.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * or http://www.opensolaris.org/os/licensing.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * See the License for the specific language governing permissions
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * and limitations under the License.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * When distributing Covered Code, include this CDDL HEADER in each
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * If applicable, add the following below this CDDL HEADER, with the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * fields enclosed by brackets "[]" replaced with your own identifying
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * information: Portions Copyright [yyyy] [name of copyright owner]
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * CDDL HEADER END
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <sys/types.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <sys/brand.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <sys/errno.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <sys/sysconfig.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <sys/ucontext.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <sys/wait.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <stdlib.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <strings.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <signal.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <s10_brand.h>
80e2ca8596e3435bc3b76f3c597833ea0a87f85e#include <brand_misc.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <s10_misc.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#include <s10_signal.h>
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sighandler_t s10_handlers[S10_NSIG - 1];
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Theory of operation:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * As of now, Solaris 10 and solaris_nevada signal numbers match all the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * way through SIGJVM2 (1 - 40) and the first 8 realtime signals (41 - 48).
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * However, solaris_nevada provides 32 realtime signals rather than 8 for S10.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We do not assume that the current range of realtime signals is
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * _SIGRTMIN - _SIGRTMAX. As a hedge against future changes,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * we obtain the realtime signal range via SIGRTMIN and SIGRTMAX.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Therefore, we must interpose on the various signal calls to translate
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * signal masks and signal handlers that deal with SIGRTMIN - SIGRTMAX to
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * refer to a potentially different range and to intercenpt any "illegal"
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * signals that might otherwise be sent to an S10 process.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * Important exception:
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * We cannot interpose on the SYS_context system call in order to deal with the
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * sigset_t contained within the ucontext_t structure because the getcontext()
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * part of this system call trap would then return an incorrect set of machine
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * registers. See the getcontext() functions in libc to get the gory details.
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * The kernel code for getcontext() and setcontext() has been made brand-aware
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * in order to deal with this.
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Simple translation is all that is required to handle most system calls,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * but signal handlers also must be interposed upon so that a user signal
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * handler sees proper signal numbers in its arguments, any passed siginfo_t
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * and in the signal mask reported in its ucontext_t.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * libc adds its own signal handler to handled signals such that the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * signal delivery mechanism looks like:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * signal ->
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * libc sigacthandler() ->
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * user signal handler()
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * With interposition, this will instead look like:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * signal ->
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * s10_sigacthandler() ->
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * libc sigacthandler() ->
8f798d3afbe38d59cc0a708261dbb729f1b6b209Roger A. Faulkner * user signal handler()
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * A little exposition on SIGRTMIN and SIGRTMAX:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * For configurability reasons, in Solaris SIGRTMIN and SIGRTMAX are actually
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * #defined to be routines:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * #define SIGRTMIN ((int)_sysconf(_SC_SIGRT_MIN))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * #define SIGRTMAX ((int)_sysconf(_SC_SIGRT_MAX))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * This means we need routines that will call the native sysconfig() system
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * call to find out what the native values for SIGRTMIN and SIGRTMAX are, and
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * those are native_sigrtmin() and native_sigrtmax(), respectively.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * To try and mitigate confusion this might cause, rather than use SIGRTMIN and
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * SIGRTMAX directly, mnemonic convenience macros are #defined to clarify the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * matter:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * S10_SIGRTMIN
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * S10_SIGRTMAX
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * NATIVE_SIGRTMIN
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * NATIVE_SIGRTMAX
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerstatic int
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknernative_sigrtmin()
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner static int sigrtmin;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sysret_t rval;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sigrtmin)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (sigrtmin);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigrtmin = __systemcall(&rval, SYS_sysconfig + 1024, _CONFIG_SIGRT_MIN)?
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner _SIGRTMIN : (int)rval.sys_rval1;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (sigrtmin);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerstatic int
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknernative_sigrtmax()
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner static int sigrtmax;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sysret_t rval;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sigrtmax)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (sigrtmax);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigrtmax = __systemcall(&rval, SYS_sysconfig + 1024, _CONFIG_SIGRT_MAX)?
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner _SIGRTMAX : (int)rval.sys_rval1;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (sigrtmax);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define NATIVE_SIGRTMIN (native_sigrtmin())
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define NATIVE_SIGRTMAX (native_sigrtmax())
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * These #defines are setup to create the SIGADDSET and SIGISMEMBER macros,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * needed because the sigaddset(3C) and sigismember(3C) calls make function
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * calls that end up being recursive in an interpositioned system call
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * environment.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define MAXBITNO (NBPW*8)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define SIGWORD(n) ((n-1)/MAXBITNO)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define BITMASK(n) (1L<<((n-1)%MAXBITNO))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define SIGADDSET(sigset, sig) \
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner ((sigset)->__sigbits[SIGWORD(sig)] |= BITMASK(sig))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner#define SIGISMEMBER(sigset, sig) \
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (((sigset)->__sigbits[SIGWORD(sig)] & BITMASK(sig)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Convert an S10 signal number to its native value.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerstatic int
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10sig_to_native(int sig)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /* signals 1 .. SIGJVM2 are the same between S10 and native */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sig <= SIGJVM2)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * If a signal is > SIGJVM2 but is < S10_SIGRTMIN, it's being used
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * for some private purpose we likely wouldn't emulate properly.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sig < S10_SIGRTMIN) /* can't happen */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (-1);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
602423772f52c941d73a9f5aa3ea7249711300fb /*
602423772f52c941d73a9f5aa3ea7249711300fb * If an app passes in a signal that is out of range, it
602423772f52c941d73a9f5aa3ea7249711300fb * expects to get back EINVAL.
602423772f52c941d73a9f5aa3ea7249711300fb */
602423772f52c941d73a9f5aa3ea7249711300fb if (sig > S10_MAXSIG)
602423772f52c941d73a9f5aa3ea7249711300fb return (-1);
602423772f52c941d73a9f5aa3ea7249711300fb
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Map S10 RT signals to their native counterparts to the degree
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * possible. If the signal would be out of the native RT signal
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * range, return an error to the caller.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sig -= S10_SIGRTMIN;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sig > (NATIVE_SIGRTMAX - NATIVE_SIGRTMIN))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (-1);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (NATIVE_SIGRTMIN + sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Convert an S10 sigset_t to its native version.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10sigset_to_native(const sigset_t *s10_set, sigset_t *native_set)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t srcset, newset;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(s10_set, &srcset, sizeof (sigset_t)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) sigemptyset(&newset);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Shortcut: we know the first 32 signals are the same in both
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * s10 and native Solaris. Just assign the first word.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner newset.__sigbits[0] = srcset.__sigbits[0];
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Copy the remainder of the initial set of common signals.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner for (sig = 33; sig <= SIGJVM2; sig++)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (SIGISMEMBER(&srcset, sig))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner SIGADDSET(&newset, sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /* convert any S10 RT signals to their native equivalents */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner for (sig = S10_SIGRTMIN; sig <= S10_SIGRTMAX; sig++) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (SIGISMEMBER(&srcset, sig) &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (nativesig = s10sig_to_native(sig)) > 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner SIGADDSET(&newset, nativesig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(&newset, native_set, sizeof (sigset_t)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Convert a native signal number to its S10 value.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknernativesig_to_s10(int sig)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /* signals 1 .. SIGJVM2 are the same between native and S10 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sig <= SIGJVM2)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We have no way to emulate native signals between (SIGJVM2 + 1) and
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * NATIVE_SIGRTMIN, so return an error to the caller.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sig < NATIVE_SIGRTMIN) /* can't happen */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (-1);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Map native RT signals to their S10 counterparts to the degree
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * possible. If the signal would be out of range for S10, return
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * an error to the caller.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sig -= NATIVE_SIGRTMIN;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sig > (S10_SIGRTMAX - S10_SIGRTMIN))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (-1);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (S10_SIGRTMIN + sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Convert a native sigset_t to its S10 version.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknernativesigset_to_s10(const sigset_t *native_set, sigset_t *s10_set)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int s10sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t srcset, newset;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(native_set, &srcset, sizeof (sigset_t)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) sigemptyset(&newset);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Shortcut: we know the first 32 signals are the same in both
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * s10 and native Solaris. Just assign the first word.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner newset.__sigbits[0] = srcset.__sigbits[0];
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Copy the remainder of the initial set of common signals.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner for (sig = 33; sig <= SIGJVM2; sig++)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (SIGISMEMBER(&srcset, sig))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner SIGADDSET(&newset, sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /* convert any RT signals to their S10 values */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner for (sig = NATIVE_SIGRTMIN; sig <= NATIVE_SIGRTMAX; sig++) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (SIGISMEMBER(&srcset, sig) &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (s10sig = nativesig_to_s10(sig)) > 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner SIGADDSET(&newset, s10sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(&newset, s10_set, sizeof (sigset_t)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * This is our interposed signal handler.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Fix up the arguments received from the kernel and jump
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * to the s10 signal handler, normally libc's sigacthandler().
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerstatic void
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigacthandler(int sig, siginfo_t *sip, void *uvp)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int s10_sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner ucontext_t *ucp;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_sig = nativesig_to_s10(sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (s10_sig <= 0) /* can't happen? */
80e2ca8596e3435bc3b76f3c597833ea0a87f85e brand_abort(sig, "Received an impossible signal");
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sip != NULL) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * All we really have to do is map the signal number,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * which changes only for the realtime signals,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * so all the rest of the siginfo structure is the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * same between s10 and native.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sip->si_signo != sig) /* can't happen? */
80e2ca8596e3435bc3b76f3c597833ea0a87f85e brand_abort(sig, "Received an impossible siginfo");
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sip->si_signo = s10_sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((ucp = uvp) != NULL &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (ucp->uc_flags & UC_SIGMASK))
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) nativesigset_to_s10(&ucp->uc_sigmask, &ucp->uc_sigmask);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_handlers[s10_sig - 1](s10_sig, sip, uvp);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_lwp_sigmask
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_lwp_sigmask(sysret_t *rval, int how, uint_t bits0, uint_t bits1)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t s10_blockset;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t native_blockset;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_blockset.__sigbits[0] = bits0;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_blockset.__sigbits[1] = bits1;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_blockset.__sigbits[2] = 0;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_blockset.__sigbits[3] = 0;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) s10sigset_to_native(&s10_blockset, &native_blockset);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner err = __systemcall(rval, SYS_lwp_sigmask + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner how,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[0],
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[1],
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[2],
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[3]);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (err != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[0] = (int)rval->sys_rval1;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[1] = (int)rval->sys_rval2;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[2] = 0;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner native_blockset.__sigbits[3] = 0;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) nativesigset_to_s10(&native_blockset, &s10_blockset);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner rval->sys_rval1 = s10_blockset.__sigbits[0];
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner rval->sys_rval2 = s10_blockset.__sigbits[1];
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigprocmask
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigprocmask(sysret_t *rval, int how, const sigset_t *set, sigset_t *oset)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t sigset_set, sigset_oset;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t *set_ptr, *oset_ptr;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner oset_ptr = (oset == NULL) ? NULL : &sigset_oset;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner set_ptr = (set == NULL) ? NULL : &sigset_set;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (set_ptr != NULL &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (err = s10sigset_to_native(set, set_ptr)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = __systemcall(rval, SYS_sigprocmask + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner how, set_ptr, oset_ptr)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (oset_ptr != NULL &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (err = nativesigset_to_s10(oset_ptr, oset)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigsuspend
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigsuspend(sysret_t *rval, const sigset_t *set)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t sigset_set;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = s10sigset_to_native(set, &sigset_set)) != 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_1(rval, SYS_sigsuspend, err, set);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_sigsuspend + 1024, &sigset_set));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigaction
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * There is a fair amount of complexity here due to the need to interpose
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * on any registered user signal handler.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * The idea is that if a user signal handler is installed, we must install
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * our own signal handler between the system and the signal handler being
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * registered. If the signal handler to be registered is SIG_DFL or SIG_IGN,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * we should remove our interpositioned handler as it's no longer needed.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * The way we do this is we set the signal handler to call s10_sigacthandler(),
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * and then store the address of the passed signal handler in a global
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * per-process array, s10_handlers[].
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We rely on the fact that the s10 libc blocks all signals during
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * its call to the sigaction() system call to guarantee atomicity.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigaction(sysret_t *rval,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int sig, const struct sigaction *act, struct sigaction *oact)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner struct sigaction sigact, osigact;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner struct sigaction *sigactp, *osigactp;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err, nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner void (*handler)();
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((nativesig = s10sig_to_native(sig)) < 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_3(rval, SYS_sigaction, EINVAL,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sig, act, oact);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EINVAL);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (act == NULL) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigactp = NULL;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner } else {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigactp = &sigact;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(act, sigactp, sizeof (struct sigaction)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = s10sigset_to_native(&sigactp->sa_mask,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner &sigactp->sa_mask)) != 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_3(rval, SYS_sigaction, err,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sig, act, oact);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner osigactp = ((oact == NULL) ? NULL : &osigact);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sigactp != NULL) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner handler = sigactp->sa_handler;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (handler != SIG_DFL && handler != SIG_IGN)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigactp->sa_handler = s10_sigacthandler;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = __systemcall(rval, SYS_sigaction + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner nativesig, sigactp, osigactp)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Translate the old signal mask if we are supposed to return the old
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * struct sigaction.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Note that we may have set the signal handler, but may return EFAULT
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * here if the oact parameter is bad.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * That's OK, because the direct system call acts the same way.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (osigactp != NULL) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner err = nativesigset_to_s10(&osigactp->sa_mask,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner &osigactp->sa_mask);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (osigactp->sa_handler == s10_sigacthandler)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner osigactp->sa_handler = s10_handlers[sig - 1];
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (err == 0 && brand_uucopy(osigactp, oact,
80e2ca8596e3435bc3b76f3c597833ea0a87f85e sizeof (struct sigaction)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner err = EFAULT;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Do not store SIG_DFL or SIG_IGN into the array of remembered
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * signal handlers. Only store bona-fide function addresses.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * This is to avoid a race condition in which some thread
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * sets the signal handler to SIG_DFL or SIG_IGN while some
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * other thread is fielding the signal but has not yet reached
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * s10_sigacthandler(). s10_sigacthandler() will unconditionally
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * call the remembered signal handler and it it calls SIG_DFL or
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * SIG_IGN, the process will incur a SIGSEGV or SIGBUS signal.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * This also allows a vfork() child to set signal handlers
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * to SIG_DFL or SIG_IGN without corrupting the parent's
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * address space.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (sigactp != NULL &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner handler != SIG_DFL && handler != SIG_IGN)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner s10_handlers[sig - 1] = handler;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigpending
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigpending(sysret_t *rval, int flag, sigset_t *set)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t sigset_set;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = __systemcall(rval, SYS_sigpending + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner flag, &sigset_set)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = nativesigset_to_s10(&sigset_set, set)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigsendsys
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigsendsys(sysret_t *rval, procset_t *psp, int sig)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((nativesig = s10sig_to_native(sig)) < 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_2(rval, SYS_sigsendsys, EINVAL,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner psp, sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EINVAL);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_sigsendsys + 1024, psp, nativesig));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Convert the siginfo_t code and status fields to an old style
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * wait status for s10_wait(), below.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerstatic int
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerwstat(int code, int status)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int stat = (status & 0377);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner switch (code) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner case CLD_EXITED:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner stat <<= 8;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner break;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner case CLD_DUMPED:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner stat |= WCOREFLG;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner break;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner case CLD_KILLED:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner break;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner case CLD_TRAPPED:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner case CLD_STOPPED:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner stat <<= 8;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner stat |= WSTOPFLG;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner break;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner case CLD_CONTINUED:
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner stat = WCONTFLG;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner break;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (stat);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_wait
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_wait(sysret_t *rval)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner siginfo_t info;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner err = s10_waitid(rval, P_ALL, 0, &info, WEXITED | WTRAPPED);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (err != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner rval->sys_rval1 = info.si_pid;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner rval->sys_rval2 = wstat(info.si_code, info.si_status);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_waitid
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_waitid(sysret_t *rval,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner idtype_t idtype, id_t id, siginfo_t *infop, int options)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err, sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner err = __systemcall(rval, SYS_waitid + 1024, idtype, id, infop, options);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (err != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * If the process being waited for terminated or stopped due to a
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * signal, translate the signal number from its native value to its
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * S10 equivalent.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * If we can't legally translate the signal number, just sort of punt
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * and leave it untranslated.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We shouldn't return EINVAL as the syscall didn't technically fail.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (infop->si_signo == SIGCLD && infop->si_code != CLD_EXITED &&
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (sig = nativesig_to_s10(infop->si_status)) > 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner infop->si_status = sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigtimedwait
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigtimedwait(sysret_t *rval,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner const sigset_t *set, siginfo_t *info, const timespec_t *timeout)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner sigset_t sigset_set;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int err, sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = s10sigset_to_native(set, &sigset_set)) != 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_3(rval, SYS_sigtimedwait, err,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner set, info, timeout);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((err = __systemcall(rval, SYS_sigtimedwait + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner &sigset_set, info, timeout)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (err);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (info != NULL) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * If we can't legally translate the signal number in the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * siginfo_t, just sort of punt and leave it untranslated.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We shouldn't return EINVAL as the syscall didn't technically
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * fail.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((sig = nativesig_to_s10(info->si_signo)) > 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner info->si_signo = sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * If we can't legally translate the signal number returned by the
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * sigtimedwait syscall, just sort of punt and leave it untranslated.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We shouldn't return EINVAL as the syscall didn't technically
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * fail.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((sig = nativesig_to_s10((int)rval->sys_rval1)) > 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner rval->sys_rval1 = sig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (0);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_sigqueue
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_sigqueue(sysret_t *rval, pid_t pid, int signo, void *value, int si_code)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((nativesig = s10sig_to_native(signo)) < 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_4(rval, SYS_sigqueue, EINVAL,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner pid, signo, value, si_code);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EINVAL);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (pid == 1)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner pid = zone_init_pid;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * The native version of this syscall takes an extra argument.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * The new last arg "block" flag should be zero. The block flag
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * is used by the Opensolaris AIO implementation, which is now
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * part of libc.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_sigqueue + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner pid, nativesig, value, si_code, 0));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_signotify
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_signotify(sysret_t *rval,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int cmd, siginfo_t *siginfo, signotify_id_t *sn_id)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner siginfo_t *infop, info;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner infop = siginfo;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /* only check for a valid siginfo pointer in the case of SN_PROC */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (cmd == SN_PROC) {
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(infop, &info, sizeof (siginfo_t)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((nativesig = s10sig_to_native(info.si_signo)) < 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_3(rval, SYS_signotify, EINVAL,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner cmd, siginfo, sn_id);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EINVAL);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner info.si_signo = nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner infop = &info;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_signotify + 1024, cmd, infop, sn_id));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_kill
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_kill(sysret_t *rval, pid_t pid, int sig)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((nativesig = s10sig_to_native(sig)) < 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_2(rval, SYS_kill, EINVAL, pid, sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EINVAL);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (pid == 1)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner pid = zone_init_pid;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_kill + 1024, pid, nativesig));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_lwp_create
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner *
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * See also the s10_lwp_create_correct_fs() function in s10_brand.c
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * for the special case of creating an lwp in a 64-bit x86 process.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_lwp_create(sysret_t *rval, ucontext_t *ucp, int flags, id_t *new_lwp)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner ucontext_t s10_uc;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(ucp, &s10_uc, sizeof (ucontext_t)) != 0)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EFAULT);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if (s10_uc.uc_flags & UC_SIGMASK)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) s10sigset_to_native(&s10_uc.uc_sigmask,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner &s10_uc.uc_sigmask);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_lwp_create + 1024,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner &s10_uc, flags, new_lwp));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner/*
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * Interposition upon SYS_lwp_kill
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulknerint
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkners10_lwp_kill(sysret_t *rval, id_t lwpid, int sig)
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner{
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner int nativesig;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner if ((nativesig = s10sig_to_native(sig)) < 0) {
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_2(rval, SYS_lwp_kill, EINVAL,
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner lwpid, sig);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (EINVAL);
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner }
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rval, SYS_lwp_kill + 1024, lwpid, nativesig));
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner}