usr/src/uts/common/os/sig.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 390 ff89f8283e6c
child 2248 4609e8bb25ad
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
    22
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/bitmap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/poll_impl.h> /* only needed for kludge in sigwaiting_send() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/signal.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/siginfo.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/fault.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/ucontext.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/procfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/wait.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/class.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/mman.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/procset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <sys/prsystm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <vm/as.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/bitmap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <c2/audit.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <sys/core.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <sys/schedctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <sys/contract/process_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <sys/dtrace.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/sdt.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
				/* MUST be contiguous */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
k_sigset_t nullsmask = {0, 0};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
k_sigset_t fillset = {FILLSET0, FILLSET1};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
k_sigset_t cantmask = {CANTMASK0, CANTMASK1};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
k_sigset_t cantreset = {(sigmask(SIGILL)|sigmask(SIGTRAP)|sigmask(SIGPWR)), 0};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
k_sigset_t ignoredefault = {(sigmask(SIGCONT)|sigmask(SIGCLD)|sigmask(SIGPWR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
			|sigmask(SIGWINCH)|sigmask(SIGURG)|sigmask(SIGWAITING)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
			(sigmask(SIGLWP)|sigmask(SIGCANCEL)|sigmask(SIGFREEZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
			|sigmask(SIGTHAW)|sigmask(SIGXRES)|sigmask(SIGJVM1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
			|sigmask(SIGJVM2))};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
k_sigset_t stopdefault = {(sigmask(SIGSTOP)|sigmask(SIGTSTP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
			|sigmask(SIGTTOU)|sigmask(SIGTTIN)), 0};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
k_sigset_t coredefault = {(sigmask(SIGQUIT)|sigmask(SIGILL)|sigmask(SIGTRAP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
			|sigmask(SIGIOT)|sigmask(SIGEMT)|sigmask(SIGFPE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
			|sigmask(SIGBUS)|sigmask(SIGSEGV)|sigmask(SIGSYS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
			|sigmask(SIGXCPU)|sigmask(SIGXFSZ)), 0};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
k_sigset_t holdvfork = {(sigmask(SIGTTOU)|sigmask(SIGTTIN)|sigmask(SIGTSTP)),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
			0};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
static	int	isjobstop(int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
static	void	post_sigcld(proc_t *, sigqueue_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * Internal variables for counting number of user thread stop requests posted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 * They may not be accurate at some special situation such as that a virtually
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 * stopped thread starts to run.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
static int num_utstop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 * Internal variables for broadcasting an event when all thread stop requests
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 * are processed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
static kcondvar_t utstop_cv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
static kmutex_t thread_stop_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
void del_one_utstop(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 * Send the specified signal to the specified process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
psignal(proc_t *p, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
	sigtoproc(p, NULL, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 * Send the specified signal to the specified thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
tsignal(kthread_t *t, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
	proc_t *p = ttoproc(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	sigtoproc(p, t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
signal_is_blocked(kthread_t *t, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	return (sigismember(&t->t_hold, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	    (schedctl_sigblock(t) && !sigismember(&cantmask, sig)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 * Return true if the signal can safely be discarded on generation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 * That is, if there is no need for the signal on the receiving end.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 * The answer is true if the process is a zombie or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
 * if all of these conditions are true:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
 *	the signal is being ignored
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
 *	the process is single-threaded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
 *	the signal is not being traced by /proc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 * 	the signal is not blocked by the process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
sig_discardable(proc_t *p, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	kthread_t *t = p->p_tlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	return (t == NULL ||		/* if zombie or ... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	    (sigismember(&p->p_ignore, sig) &&	/* signal is ignored */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	    t->t_forw == t &&			/* and single-threaded */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	    !tracing(p, sig) &&			/* and no /proc tracing */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	    !signal_is_blocked(t, sig)));	/* and signal not blocked */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
 * Return true if this thread is going to eat this signal soon.
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   165
 * Note that, if the signal is SIGKILL, we force stopped threads to be
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   166
 * set running (to make SIGKILL be a sure kill), but only if the process
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   167
 * is not currently locked by /proc (the P_PR_LOCK flag).  Code in /proc
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   168
 * relies on the fact that a process will not change shape while P_PR_LOCK
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   169
 * is set (it drops and reacquires p->p_lock while leaving P_PR_LOCK set).
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   170
 * We wish that we could simply call prbarrier() below, in sigtoproc(), to
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   171
 * ensure that the process is not locked by /proc, but prbarrier() drops
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   172
 * and reacquires p->p_lock and dropping p->p_lock here would be damaging.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
eat_signal(kthread_t *t, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	int rval = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	ASSERT(THREAD_LOCK_HELD(t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	 * Do not do anything if the target thread has the signal blocked.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	if (!signal_is_blocked(t, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
		t->t_sig_check = 1;	/* have thread do an issig */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
		if (t->t_state == TS_SLEEP && (t->t_flag & T_WAKEABLE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
			setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
			rval = 1;
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   188
		} else if (t->t_state == TS_STOPPED && sig == SIGKILL &&
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   189
		    !(ttoproc(t)->p_proc_flag & P_PR_LOCK)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
			ttoproc(t)->p_stopsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
			t->t_dtrace_stop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
			t->t_schedflag |= TS_XSTART | TS_PSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
			setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
		} else if (t != curthread && t->t_state == TS_ONPROC) {
139
5b943adba575 6290459 SIGVTALRM signal delivery delayed under Solaris 10 due to t_astflag not being set
mishra
parents: 0
diff changeset
   195
			aston(t);	/* make it do issig promptly */
5b943adba575 6290459 SIGVTALRM signal delivery delayed under Solaris 10 due to t_astflag not being set
mishra
parents: 0
diff changeset
   196
			if (t->t_cpu != CPU)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
				poke_cpu(t->t_cpu->cpu_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
			rval = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		} else if (t->t_state == TS_RUN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
			rval = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	return (rval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
 * Post a signal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
 * If a non-null thread pointer is passed, then post the signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
 * to the thread/lwp, otherwise post the signal to the process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
sigtoproc(proc_t *p, kthread_t *t, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	kthread_t *tt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	int ext = !(curproc->p_flag & SSYS) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	    (curproc->p_ct_process != p->p_ct_process);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	if (sig <= 0 || sig >= NSIG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	 * Regardless of origin or directedness,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	 * SIGKILL kills all lwps in the process immediately
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	 * and jobcontrol signals affect all lwps in the process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	if (sig == SIGKILL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
		p->p_flag |= SKILLED | (ext ? SEXTKILLED : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
		t = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	} else if (sig == SIGCONT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
		 * The SSCONT flag will remain set until a stopping
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		 * signal comes in (below).  This is harmless.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
		p->p_flag |= SSCONT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		sigdelq(p, NULL, SIGSTOP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		sigdelq(p, NULL, SIGTSTP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
		sigdelq(p, NULL, SIGTTOU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
		sigdelq(p, NULL, SIGTTIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
		sigdiffset(&p->p_sig, &stopdefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
		sigdiffset(&p->p_extsig, &stopdefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
		p->p_stopsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
		if ((tt = p->p_tlist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
			do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
				sigdelq(p, tt, SIGSTOP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
				sigdelq(p, tt, SIGTSTP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
				sigdelq(p, tt, SIGTTOU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
				sigdelq(p, tt, SIGTTIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
				sigdiffset(&tt->t_sig, &stopdefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
				sigdiffset(&tt->t_extsig, &stopdefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
			} while ((tt = tt->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
		if ((tt = p->p_tlist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
			do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
				thread_lock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
				if (tt->t_state == TS_STOPPED &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
				    tt->t_whystop == PR_JOBCONTROL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
					tt->t_schedflag |= TS_XSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
					setrun_locked(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
				thread_unlock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
			} while ((tt = tt->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	} else if (sigismember(&stopdefault, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
		 * This test has a race condition which we can't fix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		 * By the time the stopping signal is received by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		 * the target process/thread, the signal handler
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		 * and/or the detached state might have changed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
		if (PTOU(p)->u_signal[sig-1] == SIG_DFL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
		    (sig == SIGSTOP || !p->p_pgidp->pid_pgorphaned))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
			p->p_flag &= ~SSCONT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
		sigdelq(p, NULL, SIGCONT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		sigdelset(&p->p_sig, SIGCONT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
		sigdelset(&p->p_extsig, SIGCONT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
		if ((tt = p->p_tlist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
			do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
				sigdelq(p, tt, SIGCONT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
				sigdelset(&tt->t_sig, SIGCONT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
				sigdelset(&tt->t_extsig, SIGCONT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
			} while ((tt = tt->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	if (sig_discardable(p, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
		DTRACE_PROC3(signal__discard, kthread_t *, p->p_tlist,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
		    proc_t *, p, int, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	if (t != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
		 * This is a directed signal, wake up the lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
		sigaddset(&t->t_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
		if (ext)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
			sigaddset(&t->t_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
		thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
		(void) eat_signal(t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
		thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
		DTRACE_PROC2(signal__send, kthread_t *, t, int, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	} else if ((tt = p->p_tlist) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
		 * Make sure that some lwp that already exists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
		 * in the process fields the signal soon.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		 * Wake up an interruptibly sleeping lwp if necessary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
		int su = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
		sigaddset(&p->p_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
		if (ext)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
			sigaddset(&p->p_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
			thread_lock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
			if (eat_signal(tt, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
				thread_unlock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
			if (sig == SIGKILL && SUSPENDED(tt))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
				su++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
			thread_unlock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
		} while ((tt = tt->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
		 * If the process is deadlocked, make somebody run and die.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
		if (sig == SIGKILL && p->p_stat != SIDL &&
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   330
		    p->p_lwprcnt == 0 && p->p_lwpcnt == su &&
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
   331
		    !(p->p_proc_flag & P_PR_LOCK)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
			thread_lock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
			p->p_lwprcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
			tt->t_schedflag |= TS_CSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
			setrun_locked(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
			thread_unlock(tt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
		DTRACE_PROC2(signal__send, kthread_t *, tt, int, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
isjobstop(int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	proc_t *p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	if (u.u_signal[sig-1] == SIG_DFL && sigismember(&stopdefault, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
		 * If SIGCONT has been posted since we promoted this signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
		 * from pending to current, then don't do a jobcontrol stop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
		if (!(p->p_flag & SSCONT) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
		    (sig == SIGSTOP || !p->p_pgidp->pid_pgorphaned) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
		    curthread != p->p_agenttp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
			sigqueue_t *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
			stop(PR_JOBCONTROL, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
			sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
			mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
			 * Only the first lwp to continue notifies the parent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
			if (p->p_pidflag & CLDCONT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
				siginfofree(sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
			else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
				p->p_pidflag |= CLDCONT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
				p->p_wcode = CLD_CONTINUED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
				p->p_wdata = SIGCONT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
				sigcld(p, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
 * Returns true if the current process has a signal to process, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
 * the signal is not held.  The signal to process is put in p_cursig.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
 * This is asked at least once each time a process enters the system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
 * (though this can usually be done without actually calling issig by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
 * checking the pending signal masks).  A signal does not do anything
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
 * directly to a process; it sets a flag that asks the process to do
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
 * something to itself.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
 * The "why" argument indicates the allowable side-effects of the call:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
 * FORREAL:  Extract the next pending signal from p_sig into p_cursig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
 * stop the process if a stop has been requested or if a traced signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
 * is pending.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
 * JUSTLOOKING:  Don't stop the process, just indicate whether or not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
 * a signal might be pending (FORREAL is needed to tell for sure).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
 * XXX: Changes to the logic in these routines should be propagated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
 * to lm_sigispending().  See bug 1201594.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
static int issig_forreal(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
static int issig_justlooking(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
issig(int why)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
	ASSERT(why == FORREAL || why == JUSTLOOKING);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
	return ((why == FORREAL)? issig_forreal() : issig_justlooking());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
issig_justlooking(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
	kthread_t *t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	klwp_t *lwp = ttolwp(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	proc_t *p = ttoproc(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	k_sigset_t set;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	 * This function answers the question:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	 * "Is there any reason to call issig_forreal()?"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	 * We have to answer the question w/o grabbing any locks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	 * because we are (most likely) being called after we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	 * put ourselves on the sleep queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	if (t->t_dtrace_stop | t->t_dtrace_sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	 * Another piece of complexity in this process.  When single-stepping a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	 * process, we don't want an intervening signal or TP_PAUSE request to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	 * suspend the current thread.  Otherwise, the controlling process will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	 * hang beacuse we will be stopped with TS_PSTART set in t_schedflag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	 * We will trigger any remaining signals when we re-enter the kernel on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	 * the single step trap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	if (lwp->lwp_pcb.pcb_flags & NORMAL_STEP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	if ((lwp->lwp_asleep && MUSTRETURN(p, t)) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	    (p->p_flag & (SEXITLWPS|SKILLED)) ||
209
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   450
	    (!lwp->lwp_nostop_r && ((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) |
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   451
		(t->t_proc_flag & TP_HOLDLWP))) ||
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   452
	    (!lwp->lwp_nostop && (p->p_stopsig | (t->t_proc_flag &
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   453
		(TP_PRSTOP|TP_CHKPT|TP_PAUSE)))) ||
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	    lwp->lwp_cursig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	if (p->p_flag & SVFWAIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
	set = p->p_sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	sigorset(&set, &t->t_sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	if (schedctl_sigblock(t))	/* all blockable signals blocked */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
		sigandset(&set, &cantmask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
		sigdiffset(&set, &t->t_hold);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	if (p->p_flag & SVFORK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		sigdiffset(&set, &holdvfork);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
	if (!sigisempty(&set)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
		int sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
		for (sig = 1; sig < NSIG; sig++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
			if (sigismember(&set, sig) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
			    (tracing(p, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
			    !sigismember(&p->p_ignore, sig))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
				 * Don't promote a signal that will stop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
				 * the process when lwp_nostop is set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
				if (!lwp->lwp_nostop ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
				    u.u_signal[sig-1] != SIG_DFL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
				    !sigismember(&stopdefault, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
					return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
issig_forreal(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	int sig = 0, ext = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	kthread_t *t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	klwp_t *lwp = ttolwp(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	proc_t *p = ttoproc(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	int toproc = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	int sigcld_found = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
	int nostop_break = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	ASSERT(t->t_state == TS_ONPROC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	schedctl_finish_sigblock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	if (t->t_dtrace_stop | t->t_dtrace_sig) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
		if (t->t_dtrace_stop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
			 * If DTrace's "stop" action has been invoked on us,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
			 * set TP_PRSTOP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
			t->t_proc_flag |= TP_PRSTOP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
		if (t->t_dtrace_sig != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
			k_siginfo_t info;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
			 * Post the signal generated as the result of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
			 * DTrace's "raise" action as a normal signal before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
			 * the full-fledged signal checking begins.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
			bzero(&info, sizeof (info));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
			info.si_signo = t->t_dtrace_sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
			info.si_code = SI_DTRACE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
			sigaddq(p, NULL, &info, KM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
			t->t_dtrace_sig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
		if (p->p_flag & (SEXITLWPS|SKILLED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
			lwp->lwp_cursig = sig = SIGKILL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
			lwp->lwp_extsig = ext = (p->p_flag & SEXTKILLED) != 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
		 * Another piece of complexity in this process.  When
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		 * single-stepping a process, we don't want an intervening
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		 * signal or TP_PAUSE request to suspend the current thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
		 * Otherwise, the controlling process will hang beacuse we will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		 * be stopped with TS_PSTART set in t_schedflag.  We will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		 * trigger any remaining signals when we re-enter the kernel on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
		 * the single step trap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		if (lwp->lwp_pcb.pcb_flags & NORMAL_STEP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
			sig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		 * Hold the lwp here for watchpoint manipulation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
		if ((t->t_proc_flag & TP_PAUSE) && !lwp->lwp_nostop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
			stop(PR_SUSPENDED, SUSPEND_PAUSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
		if (lwp->lwp_asleep && MUSTRETURN(p, t)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
			if ((sig = lwp->lwp_cursig) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
				 * Make sure we call ISSIG() in post_syscall()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
				 * to re-validate this current signal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
				t->t_sig_check = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		 * If the request is PR_CHECKPOINT, ignore the rest of signals
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		 * or requests.  Honor other stop requests or signals later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
		 * Go back to top of loop here to check if an exit or hold
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
		 * event has occurred while stopped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
		if ((t->t_proc_flag & TP_CHKPT) && !lwp->lwp_nostop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
			stop(PR_CHECKPOINT, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
		 * Honor SHOLDFORK1, SHOLDWATCH, and TP_HOLDLWP before dealing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
		 * with signals or /proc.  Another lwp is executing fork1(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		 * or is undergoing watchpoint activity (remapping a page),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
		 * or is executing lwp_suspend() on this lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		 * Again, go back to top of loop to check if an exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
		 * or hold event has occurred while stopped.
209
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   591
		 * We explicitly allow this form of stopping of one
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   592
		 * lwp in a process by another lwp in the same process,
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   593
		 * even if lwp->lwp_nostop is set, because otherwise a
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   594
		 * process can become deadlocked on a fork1().
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   595
		 * Allow this only if lwp_nostop_r is not set,
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   596
		 * to avoid a recursive call to prstop().
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
		if (((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) ||
209
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   599
		    (t->t_proc_flag & TP_HOLDLWP)) && !lwp->lwp_nostop_r) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
			stop(PR_SUSPENDED, SUSPEND_NORMAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
		 * Honor requested stop before dealing with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
		 * current signal; a debugger may change it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		 * Do not want to go back to loop here since this is a special
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
		 * stop that means: make incremental progress before the next
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
		 * stop. The danger is that returning to top of loop would most
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
		 * likely drop the thread right back here to stop soon after it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
		 * was continued, violating the incremental progress request.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
		if ((t->t_proc_flag & TP_PRSTOP) && !lwp->lwp_nostop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
			stop(PR_REQUESTED, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
		 * If a debugger wants us to take a signal it will have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
		 * left it in lwp->lwp_cursig.  If lwp_cursig has been cleared
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
		 * or if it's being ignored, we continue on looking for another
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
		 * signal.  Otherwise we return the specified signal, provided
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
		 * it's not a signal that causes a job control stop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
		 * When stopped on PR_JOBCONTROL, there is no current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
		 * signal; we cancel lwp->lwp_cursig temporarily before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		 * calling isjobstop().  The current signal may be reset
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		 * by a debugger while we are stopped in isjobstop().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
		if ((sig = lwp->lwp_cursig) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
			ext = lwp->lwp_extsig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
			lwp->lwp_cursig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
			lwp->lwp_extsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
			if (!sigismember(&p->p_ignore, sig) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
			    !isjobstop(sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
				if (p->p_flag & (SEXITLWPS|SKILLED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
					sig = SIGKILL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
					ext = (p->p_flag & SEXTKILLED) != 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
				lwp->lwp_cursig = (uchar_t)sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
				lwp->lwp_extsig = (uchar_t)ext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
			 * The signal is being ignored or it caused a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
			 * job-control stop.  If another current signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
			 * has not been established, return the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
			 * siginfo, if any, to the memory manager.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
			if (lwp->lwp_cursig == 0 && lwp->lwp_curinfo != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
				siginfofree(lwp->lwp_curinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
				lwp->lwp_curinfo = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
			 * Loop around again in case we were stopped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
			 * on a job control signal and a /proc stop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
			 * request was posted or another current signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
			 * was established while we were stopped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
		if (p->p_stopsig && !lwp->lwp_nostop &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
		    curthread != p->p_agenttp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
			 * Some lwp in the process has already stopped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
			 * showing PR_JOBCONTROL.  This is a stop in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
			 * sympathy with the other lwp, even if this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
			 * lwp is blocking the stopping signal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
			stop(PR_JOBCONTROL, p->p_stopsig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		 * Loop on the pending signals until we find a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
		 * non-held signal that is traced or not ignored.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
		 * First check the signals pending for the lwp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
		 * then the signals pending for the process as a whole.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
		for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
			k_sigset_t tsig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
			tsig = t->t_sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
			if ((sig = fsig(&tsig, t)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
				if (sig == SIGCLD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
					sigcld_found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
				toproc = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
				if (tracing(p, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
				    !sigismember(&p->p_ignore, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
					if (sigismember(&t->t_extsig, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
						ext = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
				sigdelset(&t->t_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
				sigdelset(&t->t_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
				sigdelq(p, t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
			} else if ((sig = fsig(&p->p_sig, t)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
				if (sig == SIGCLD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
					sigcld_found = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
				toproc = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
				if (tracing(p, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
				    !sigismember(&p->p_ignore, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
					if (sigismember(&p->p_extsig, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
						ext = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
				sigdelset(&p->p_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
				sigdelset(&p->p_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
				sigdelq(p, NULL, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
				/* no signal was found */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
		if (sig == 0) {	/* no signal was found */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
			if (p->p_flag & (SEXITLWPS|SKILLED)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
				lwp->lwp_cursig = SIGKILL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
				sig = SIGKILL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
				ext = (p->p_flag & SEXTKILLED) != 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
		 * If we have been informed not to stop (i.e., we are being
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
		 * called from within a network operation), then don't promote
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
		 * the signal at this time, just return the signal number.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
		 * We will call issig() again later when it is safe.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
		 * fsig() does not return a jobcontrol stopping signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
		 * with a default action of stopping the process if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
		 * lwp_nostop is set, so we won't be causing a bogus
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
		 * EINTR by this action.  (Such a signal is eaten by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
		 * isjobstop() when we loop around to do final checks.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
		if (lwp->lwp_nostop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
			nostop_break = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
		 * Promote the signal from pending to current.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
		 * Note that sigdeq() will set lwp->lwp_curinfo to NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		 * if no siginfo_t exists for this signal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
		lwp->lwp_cursig = (uchar_t)sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
		lwp->lwp_extsig = (uchar_t)ext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
		t->t_sig_check = 1;	/* so post_syscall will see signal */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
		ASSERT(lwp->lwp_curinfo == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		sigdeq(p, toproc ? NULL : t, sig, &lwp->lwp_curinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
		if (tracing(p, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
			stop(PR_SIGNALLED, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
		 * Loop around to check for requested stop before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		 * performing the usual current-signal actions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	 * If SIGCLD was dequeued, search for other pending SIGCLD's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	 * Don't do it if we are returning SIGCLD and the signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	 * handler will be reset by psig(); this enables reliable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	 * delivery of SIGCLD even when using the old, broken
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
	 * signal() interface for setting the signal handler.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	if (sigcld_found &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
	    (sig != SIGCLD || !sigismember(&u.u_sigresethand, SIGCLD)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
		sigcld_repost();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	if (sig != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
		(void) undo_watch_step(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	 * If we have been blocked since the p_lock was dropped off
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	 * above, then this promoted signal might have been handled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	 * already when we were on the way back from sleep queue, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	 * just ignore it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	 * If we have been informed not to stop, just return the signal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	 * number. Also see comments above.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	if (!nostop_break) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
		sig = lwp->lwp_cursig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
	return (sig != 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
 * Return true if the process is currently stopped showing PR_JOBCONTROL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
 * This is true only if all of the process's lwp's are so stopped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
 * If this is asked by one of the lwps in the process, exclude that lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
jobstopped(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	if ((t = p->p_tlist) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
		thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
		/* ignore current, zombie and suspended lwps in the test */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
		if (!(t == curthread || t->t_state == TS_ZOMB ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
		    SUSPENDED(t)) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
		    (t->t_state != TS_STOPPED ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
		    t->t_whystop != PR_JOBCONTROL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
			thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
	} while ((t = t->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
 * Put ourself (curthread) into the stopped state and notify tracers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
stop(int why, int what)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	kthread_t	*t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
	proc_t		*p = ttoproc(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
	klwp_t		*lwp = ttolwp(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
	kthread_t	*tx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	lwpent_t	*lep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
	int		procstop;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
	int		flags = TS_ALLSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
	hrtime_t	stoptime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
	 * Can't stop a system process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
	if (p == NULL || lwp == NULL || (p->p_flag & SSYS) || p->p_as == &kas)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	if (why != PR_SUSPENDED && why != PR_CHECKPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
		 * Don't stop an lwp with SIGKILL pending.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
		 * Don't stop if the process or lwp is exiting.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
		if (lwp->lwp_cursig == SIGKILL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
		    sigismember(&t->t_sig, SIGKILL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
		    sigismember(&p->p_sig, SIGKILL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
		    (t->t_proc_flag & TP_LWPEXIT) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
		    (p->p_flag & (SEXITLWPS|SKILLED))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
			p->p_stopsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
			t->t_proc_flag &= ~(TP_PRSTOP|TP_PRVSTOP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	 * Make sure we don't deadlock on a recursive call to prstop().
209
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   865
	 * prstop() sets the lwp_nostop_r flag and increments lwp_nostop.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
	 */
209
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   867
	if (lwp->lwp_nostop_r ||
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   868
	    (lwp->lwp_nostop &&
d02e3240ebea 4522909 automountd hangs with executable maps
cwb
parents: 139
diff changeset
   869
	    (why != PR_SUSPENDED || what != SUSPEND_NORMAL)))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
	 * Make sure the lwp is in an orderly state for inspection
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	 * by a debugger through /proc or for dumping via core().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	schedctl_finish_sigblock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	t->t_proc_flag |= TP_STOPPING;	/* must set before dropping p_lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
	stoptime = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	prstop(why, what);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	(void) undo_watch_step(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	ASSERT(t->t_state == TS_ONPROC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	switch (why) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	case PR_CHECKPOINT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
		 * The situation may have changed since we dropped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
		 * and reacquired p->p_lock. Double-check now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
		 * whether we should stop or not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		if (!(t->t_proc_flag & TP_CHKPT)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
			t->t_proc_flag &= ~TP_STOPPING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
		t->t_proc_flag &= ~TP_CHKPT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
		flags &= ~TS_RESUME;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
	case PR_JOBCONTROL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
		ASSERT(what == SIGSTOP || what == SIGTSTP ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
			what == SIGTTIN || what == SIGTTOU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
		flags &= ~TS_XSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
	case PR_SUSPENDED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
		ASSERT(what == SUSPEND_NORMAL || what == SUSPEND_PAUSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
		 * The situation may have changed since we dropped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
		 * and reacquired p->p_lock.  Double-check now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		 * whether we should stop or not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
		if (what == SUSPEND_PAUSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
			if (!(t->t_proc_flag & TP_PAUSE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
				t->t_proc_flag &= ~TP_STOPPING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
			flags &= ~TS_UNPAUSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
			if (!((t->t_proc_flag & TP_HOLDLWP) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
			    (p->p_flag & (SHOLDFORK|SHOLDFORK1|SHOLDWATCH)))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
				t->t_proc_flag &= ~TP_STOPPING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
			 * If SHOLDFORK is in effect and we are stopping
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
			 * while asleep (not at the top of the stack),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
			 * we return now to allow the hold to take effect
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
			 * when we reach the top of the kernel stack.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
			if (lwp->lwp_asleep && (p->p_flag & SHOLDFORK)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
				t->t_proc_flag &= ~TP_STOPPING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
			flags &= ~TS_CSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	default:	/* /proc stop */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
		flags &= ~TS_PSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
		 * Do synchronous stop unless the async-stop flag is set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
		 * If why is PR_REQUESTED and t->t_dtrace_stop flag is set,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
		 * then no debugger is present and we also do synchronous stop.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
		if ((why != PR_REQUESTED || t->t_dtrace_stop) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
		    !(p->p_proc_flag & P_PR_ASYNC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
			int notify;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
			for (tx = t->t_forw; tx != t; tx = tx->t_forw) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
				notify = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
				thread_lock(tx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
				if (ISTOPPED(tx) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
				    (tx->t_proc_flag & TP_PRSTOP)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
					thread_unlock(tx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
				tx->t_proc_flag |= TP_PRSTOP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
				tx->t_sig_check = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
				if (tx->t_state == TS_SLEEP &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
				    (tx->t_flag & T_WAKEABLE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
					/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
					 * Don't actually wake it up if it's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
					 * in one of the lwp_*() syscalls.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
					 * Mark it virtually stopped and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
					 * notify /proc waiters (below).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
					 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
					if (tx->t_wchan0 == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
						setrun_locked(tx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
					else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
						tx->t_proc_flag |= TP_PRVSTOP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
						tx->t_stoptime = stoptime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
						notify = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
				 * force the thread into the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
				 * if it is not already there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
				if (tx->t_state == TS_ONPROC &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
				    tx->t_cpu != CPU)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
					poke_cpu(tx->t_cpu->cpu_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
				thread_unlock(tx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
				lep = p->p_lwpdir[tx->t_dslot].ld_entry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
				if (notify && lep->le_trace)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
					prnotify(lep->le_trace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
			 * We do this just in case one of the threads we asked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
			 * to stop is in holdlwps() (called from cfork()) or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
			 * lwp_suspend().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
			cv_broadcast(&p->p_holdlwps);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	t->t_stoptime = stoptime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
	if (why == PR_JOBCONTROL || (why == PR_SUSPENDED && p->p_stopsig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
		 * Determine if the whole process is jobstopped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
		if (jobstopped(p)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
			sigqueue_t *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
			int sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
			if ((sig = p->p_stopsig) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
				p->p_stopsig = (uchar_t)(sig = what);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
			sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
			mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
			 * The last lwp to stop notifies the parent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
			 * Turn off the CLDCONT flag now so the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
			 * lwp to continue knows what to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
			p->p_pidflag &= ~CLDCONT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
			p->p_wcode = CLD_STOPPED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
			p->p_wdata = sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
			sigcld(p, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
			 * Grab p->p_lock before releasing pidlock so the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
			 * parent and the child don't have a race condition.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
			p->p_stopsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
		} else if (why == PR_JOBCONTROL && p->p_stopsig == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
			 * Set p->p_stopsig and wake up sleeping lwps
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
			 * so they will stop in sympathy with this lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
			p->p_stopsig = (uchar_t)what;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
			pokelwps(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
			 * We do this just in case one of the threads we asked
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
			 * to stop is in holdlwps() (called from cfork()) or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
			 * lwp_suspend().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
			cv_broadcast(&p->p_holdlwps);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
	if (why != PR_JOBCONTROL && why != PR_CHECKPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
		 * Do process-level notification when all lwps are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
		 * either stopped on events of interest to /proc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
		 * or are stopped showing PR_SUSPENDED or are zombies.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
		procstop = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
		for (tx = t->t_forw; procstop && tx != t; tx = tx->t_forw) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
			if (VSTOPPED(tx))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
			thread_lock(tx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
			switch (tx->t_state) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
			case TS_ZOMB:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
			case TS_STOPPED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
				/* neither ISTOPPED nor SUSPENDED? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
				if ((tx->t_schedflag &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
				    (TS_CSTART | TS_UNPAUSE | TS_PSTART)) ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
				    (TS_CSTART | TS_UNPAUSE | TS_PSTART))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
					procstop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
			case TS_SLEEP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
				/* not paused for watchpoints? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
				if (!(tx->t_flag & T_WAKEABLE) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
				    tx->t_wchan0 == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
				    !(tx->t_proc_flag & TP_PAUSE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
					procstop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
				procstop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
			thread_unlock(tx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
		if (procstop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
			/* there must not be any remapped watched pages now */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
			ASSERT(p->p_mapcnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
			if (p->p_proc_flag & P_PR_PTRACE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
				/* ptrace() compatibility */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
				mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
				mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
				p->p_wcode = CLD_TRAPPED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
				p->p_wdata = (why == PR_SIGNALLED)?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
				    what : SIGTRAP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
				cv_broadcast(&p->p_parent->p_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
				 * Grab p->p_lock before releasing pidlock so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
				 * parent and child don't have a race condition.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
				mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
				mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
			if (p->p_trace)			/* /proc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
				prnotify(p->p_trace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
			cv_broadcast(&pr_pid_cv[p->p_slot]); /* pauselwps() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
			cv_broadcast(&p->p_holdlwps);	/* holdwatch() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
		if (why != PR_SUSPENDED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
			lep = p->p_lwpdir[t->t_dslot].ld_entry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
			if (lep->le_trace)		/* /proc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
				prnotify(lep->le_trace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
			 * Special notification for creation of the agent lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
			if (t == p->p_agenttp &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
			    (t->t_proc_flag & TP_PRSTOP) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
			    p->p_trace)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
				prnotify(p->p_trace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
			 * The situation may have changed since we dropped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
			 * and reacquired p->p_lock. Double-check now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
			 * whether we should stop or not.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
			if (!(t->t_proc_flag & TP_STOPPING)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
				if (t->t_proc_flag & TP_PRSTOP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
					t->t_proc_flag |= TP_STOPPING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
			t->t_proc_flag &= ~(TP_PRSTOP|TP_PRVSTOP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
			prnostep(lwp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
	if (why == PR_SUSPENDED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
		 * We always broadcast in the case of SUSPEND_PAUSE.  This is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
		 * because checks for TP_PAUSE take precedence over checks for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
		 * SHOLDWATCH.  If a thread is trying to stop because of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
		 * SUSPEND_PAUSE and tries to do a holdwatch(), it will be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
		 * waiting for the rest of the threads to enter a stopped state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
		 * If we are stopping for a SUSPEND_PAUSE, we may be the last
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
		 * lwp and not know it, so broadcast just in case.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
		if (what == SUSPEND_PAUSE ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
		    --p->p_lwprcnt == 0 || (t->t_proc_flag & TP_HOLDLWP))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
			cv_broadcast(&p->p_holdlwps);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
	 * Need to do this here (rather than after the thread is officially
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	 * stopped) because we can't call mutex_enter from a stopped thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	if (why == PR_CHECKPOINT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
		del_one_utstop();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
	thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
	ASSERT((t->t_schedflag & TS_ALLSTART) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
	t->t_schedflag |= flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
	t->t_whystop = (short)why;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
	t->t_whatstop = (short)what;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	CL_STOP(t, why, what);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	(void) new_mstate(t, LMS_STOPPED);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
	thread_stop(t);			/* set stop state and drop lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
	if (why != PR_SUSPENDED && why != PR_CHECKPOINT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
		 * We may have gotten a SIGKILL or a SIGCONT when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
		 * we released p->p_lock; make one last check.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
		 * Also check for a /proc run-on-last-close.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
		if (sigismember(&t->t_sig, SIGKILL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
		    sigismember(&p->p_sig, SIGKILL) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
		    (t->t_proc_flag & TP_LWPEXIT) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
		    (p->p_flag & (SEXITLWPS|SKILLED))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
			p->p_stopsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
			thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
			t->t_schedflag |= TS_XSTART | TS_PSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
			setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
			thread_unlock_nopreempt(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
		} else if (why == PR_JOBCONTROL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
			if (p->p_flag & SSCONT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
				 * This resulted from a SIGCONT posted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
				 * while we were not holding p->p_lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
				p->p_stopsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
				thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
				t->t_schedflag |= TS_XSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
				setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
				thread_unlock_nopreempt(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
		} else if (!(t->t_proc_flag & TP_STOPPING)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
			 * This resulted from a /proc run-on-last-close.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
			thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
			t->t_schedflag |= TS_PSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
			setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
			thread_unlock_nopreempt(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
	t->t_proc_flag &= ~TP_STOPPING;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
	swtch();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	setallwatch();	/* reestablish any watchpoints set while stopped */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
	prbarrier(p);	/* barrier against /proc locking */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
/* Interface for resetting user thread stop count. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
utstop_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
	mutex_enter(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
	num_utstop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
	mutex_exit(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
/* Interface for registering a user thread stop request. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
add_one_utstop(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	mutex_enter(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
	num_utstop++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	mutex_exit(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
/* Interface for cancelling a user thread stop request */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
del_one_utstop(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
	mutex_enter(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	num_utstop--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
	if (num_utstop == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
		cv_broadcast(&utstop_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
	mutex_exit(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
/* Interface to wait for all user threads to be stopped */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
utstop_timedwait(clock_t ticks)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
	mutex_enter(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
	if (num_utstop > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		(void) cv_timedwait(&utstop_cv, &thread_stop_lock,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
		    ticks + lbolt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
	mutex_exit(&thread_stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
 * Perform the action specified by the current signal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
 * The usual sequence is:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
 * 	if (issig())
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
 * 		psig();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
 * The signal bit has already been cleared by issig(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
 * the current signal number has been stored in lwp_cursig,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
 * and the current siginfo is now referenced by lwp_curinfo.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
psig(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
	kthread_t *t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
	proc_t *p = ttoproc(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
	klwp_t *lwp = ttolwp(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
	void (*func)();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
	int sig, rc, code, ext;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
	pid_t pid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	id_t ctid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
	zoneid_t zoneid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
	sigqueue_t *sqp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
	schedctl_finish_sigblock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
	code = CLD_KILLED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	if (p->p_flag & SEXITLWPS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
		lwp_exit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
		return;			/* not reached */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
	sig = lwp->lwp_cursig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
	ext = lwp->lwp_extsig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
	ASSERT(sig < NSIG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	 * Re-check lwp_cursig after we acquire p_lock.  Since p_lock was
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	 * dropped between issig() and psig(), a debugger may have cleared
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	 * lwp_cursig via /proc in the intervening window.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	if (sig == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
		if (lwp->lwp_curinfo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
			siginfofree(lwp->lwp_curinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
			lwp->lwp_curinfo = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
		if (t->t_flag & T_TOMASK) {	/* sigsuspend or pollsys */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
			t->t_flag &= ~T_TOMASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
			t->t_hold = lwp->lwp_sigoldmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
	func = u.u_signal[sig-1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
	 * The signal disposition could have changed since we promoted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
	 * this signal from pending to current (we dropped p->p_lock).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
	 * This can happen only in a multi-threaded process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	if (sigismember(&p->p_ignore, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
	    (func == SIG_DFL && sigismember(&stopdefault, sig))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
		lwp->lwp_cursig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
		lwp->lwp_extsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
		if (lwp->lwp_curinfo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
			siginfofree(lwp->lwp_curinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
			lwp->lwp_curinfo = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		if (t->t_flag & T_TOMASK) {	/* sigsuspend or pollsys */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
			t->t_flag &= ~T_TOMASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
			t->t_hold = lwp->lwp_sigoldmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
	 * We check lwp_curinfo first since pr_setsig can actually
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
	 * stuff a sigqueue_t there for SIGKILL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
	if (lwp->lwp_curinfo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		sqp = lwp->lwp_curinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
	} else if (sig == SIGKILL && p->p_killsqp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
		sqp = p->p_killsqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
	if (sqp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
		if (SI_FROMUSER(&sqp->sq_info)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
			pid = sqp->sq_info.si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
			ctid = sqp->sq_info.si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
			zoneid = sqp->sq_info.si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
		 * If we have a sigqueue_t, its sq_external value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
		 * trumps the lwp_extsig value.  It is theoretically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
		 * possible to make lwp_extsig reflect reality, but it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
		 * would unnecessarily complicate things elsewhere.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
		ext = sqp->sq_external;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	if (func == SIG_DFL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
		DTRACE_PROC3(signal__handle, int, sig, k_siginfo_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
		    NULL, void (*)(void), func);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
		k_siginfo_t *sip = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
		 * If DTrace user-land tracing is active, give DTrace a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
		 * chance to defer the signal until after tracing is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
		 * complete.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
		if (t->t_dtrace_on && dtrace_safe_defer_signal()) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
		 * save siginfo pointer here, in case the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
		 * the signal's reset bit is on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
		 * The presence of a current signal prevents paging
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
		 * from succeeding over a network.  We copy the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
		 * signal information to the side and cancel the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
		 * signal so that sendsig() will succeed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
		if (sigismember(&p->p_siginfo, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
			if (sqp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
				bcopy(&sqp->sq_info, &lwp->lwp_siginfo,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
				    sizeof (k_siginfo_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
				sip = &lwp->lwp_siginfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
			} else if (sig == SIGPROF &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
			    t->t_rprof != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
			    t->t_rprof->rp_anystate &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
			    lwp->lwp_siginfo.si_signo == SIGPROF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
				sip = &lwp->lwp_siginfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
		if (t->t_flag & T_TOMASK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
			t->t_flag &= ~T_TOMASK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
			lwp->lwp_sigoldmask = t->t_hold;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
		sigorset(&t->t_hold, &u.u_sigmask[sig-1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
		if (!sigismember(&u.u_signodefer, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
			sigaddset(&t->t_hold, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
		if (sigismember(&u.u_sigresethand, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
			setsigact(sig, SIG_DFL, nullsmask, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
		DTRACE_PROC3(signal__handle, int, sig, k_siginfo_t *,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
		    sip, void (*)(void), func);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
		lwp->lwp_cursig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
		lwp->lwp_extsig = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
		if (lwp->lwp_curinfo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
			/* p->p_killsqp is freed by freeproc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
			siginfofree(lwp->lwp_curinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
			lwp->lwp_curinfo = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		lwp->lwp_ru.nsignals++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
		if (p->p_model == DATAMODEL_NATIVE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
			rc = sendsig(sig, sip, func);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
			rc = sendsig32(sig, sip, func);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
#endif	/* _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
		if (rc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
		sig = lwp->lwp_cursig = SIGSEGV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
		ext = 0;	/* lwp_extsig was set above */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
		pid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
		ctid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	if (sigismember(&coredefault, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
		 * Terminate all LWPs but don't discard them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
		 * If another lwp beat us to the punch by calling exit(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
		 * evaporate now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
		 */
390
ff89f8283e6c 6272865 race condition between SIGKILL and /proc PCAGENT
raf
parents: 209
diff changeset
  1429
		proc_is_exiting(p);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
		if (exitlwps(1) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
			lwp_exit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
		/* if we got a SIGKILL from anywhere, no core dump */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
		if (p->p_flag & SKILLED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
			sig = SIGKILL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
			ext = (p->p_flag & SEXTKILLED) != 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
#ifdef C2_AUDIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
			if (audit_active)		/* audit core dump */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
				audit_core_start(sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
			if (core(sig, ext) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
				code = CLD_DUMPED;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
#ifdef C2_AUDIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
			if (audit_active)		/* audit core dump */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
				audit_core_finish(code);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
	if (ext)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
		contract_process_sig(p->p_ct_process, p, sig, pid, ctid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
		    zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
	exit(code, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
 * Find next unheld signal in ssp for thread t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
fsig(k_sigset_t *ssp, kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	proc_t *p = ttoproc(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
	user_t *up = PTOU(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
	k_sigset_t temp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
	 * Don't promote any signals for the parent of a vfork()d
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
	 * child that hasn't yet released the parent's memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	if (p->p_flag & SVFWAIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
	temp = *ssp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
	sigdiffset(&temp, &t->t_hold);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
	 * Don't promote stopping signals (except SIGSTOP) for a child
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	 * of vfork() that hasn't yet released the parent's memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	if (p->p_flag & SVFORK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
		sigdiffset(&temp, &holdvfork);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	 * Don't promote a signal that will stop
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	 * the process when lwp_nostop is set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
	if (ttolwp(t)->lwp_nostop) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
		sigdelset(&temp, SIGSTOP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
		if (!p->p_pgidp->pid_pgorphaned) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
			if (up->u_signal[SIGTSTP-1] == SIG_DFL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
				sigdelset(&temp, SIGTSTP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
			if (up->u_signal[SIGTTIN-1] == SIG_DFL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
				sigdelset(&temp, SIGTTIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
			if (up->u_signal[SIGTTOU-1] == SIG_DFL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
				sigdelset(&temp, SIGTTOU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
	 * Choose SIGKILL and SIGPROF before all other pending signals.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
	 * The rest are promoted in signal number order.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
	if (sigismember(&temp, SIGKILL))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
		return (SIGKILL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
	if (sigismember(&temp, SIGPROF))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
		return (SIGPROF);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
	for (i = 0; i < sizeof (temp) / sizeof (temp.__sigbits[0]); i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
		if (temp.__sigbits[i])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
			return ((i * NBBY * sizeof (temp.__sigbits[0])) +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
			    lowbit(temp.__sigbits[i]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
setsigact(int sig, void (*disp)(), k_sigset_t mask, int flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	proc_t *p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	u.u_signal[sig - 1] = disp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	 * Honor the SA_SIGINFO flag if the signal is being caught.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	 * Force the SA_SIGINFO flag if the signal is not being caught.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
	 * This is necessary to make sigqueue() and sigwaitinfo() work
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	 * properly together when the signal is set to default or is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	 * being temporarily ignored.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
	if ((flags & SA_SIGINFO) || disp == SIG_DFL || disp == SIG_IGN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
		sigaddset(&p->p_siginfo, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
		sigdelset(&p->p_siginfo, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	if (disp != SIG_DFL && disp != SIG_IGN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
		sigdelset(&p->p_ignore, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
		u.u_sigmask[sig - 1] = mask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
		if (!sigismember(&cantreset, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
			if (flags & SA_RESETHAND)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
				sigaddset(&u.u_sigresethand, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
				sigdelset(&u.u_sigresethand, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
		if (flags & SA_NODEFER)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
			sigaddset(&u.u_signodefer, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
			sigdelset(&u.u_signodefer, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
		if (flags & SA_RESTART)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
			sigaddset(&u.u_sigrestart, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
			sigdelset(&u.u_sigrestart, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
		if (flags & SA_ONSTACK)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
			sigaddset(&u.u_sigonstack, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
			sigdelset(&u.u_sigonstack, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
	} else if (disp == SIG_IGN ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	    (disp == SIG_DFL && sigismember(&ignoredefault, sig))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
		 * Setting the signal action to SIG_IGN results in the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
		 * discarding of all pending signals of that signal number.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
		 * Setting the signal action to SIG_DFL does the same *only*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
		 * if the signal's default behavior is to be ignored.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
		sigaddset(&p->p_ignore, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
		sigdelset(&p->p_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
		sigdelset(&p->p_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
		sigdelq(p, NULL, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
		t = p->p_tlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
		do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
			sigdelset(&t->t_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
			sigdelset(&t->t_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
			sigdelq(p, t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
		} while ((t = t->t_forw) != p->p_tlist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
		 * The signal action is being set to SIG_DFL and the default
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
		 * behavior is to do something: make sure it is not ignored.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
		sigdelset(&p->p_ignore, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
	if (sig == SIGCLD) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
		if (flags & SA_NOCLDWAIT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
			p->p_flag |= SNOWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
			p->p_flag &= ~SNOWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
		if (flags & SA_NOCLDSTOP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
			p->p_flag &= ~SJCTL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
			p->p_flag |= SJCTL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
		if (p->p_flag & SNOWAIT || disp == SIG_IGN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
			proc_t *cp, *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
			mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
			for (cp = p->p_child; cp != NULL; cp = tp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
				tp = cp->p_sibling;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
				if (cp->p_stat == SZOMB)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
					freeproc(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
 * Set all signal actions not already set to SIG_DFL or SIG_IGN to SIG_DFL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
 * Called from exec_common() for a process undergoing execve()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
 * and from cfork() for a newly-created child of vfork().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
 * In the vfork() case, 'p' is not the current process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
 * In both cases, there is only one thread in the process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
sigdefault(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	kthread_t *t = p->p_tlist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	struct user *up = PTOU(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
	int sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
	for (sig = 1; sig < NSIG; sig++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
		if (up->u_signal[sig - 1] != SIG_DFL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
		    up->u_signal[sig - 1] != SIG_IGN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
			up->u_signal[sig - 1] = SIG_DFL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
			sigemptyset(&up->u_sigmask[sig - 1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
			if (sigismember(&ignoredefault, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
				sigdelq(p, NULL, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
				sigdelq(p, t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
			if (sig == SIGCLD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
				p->p_flag &= ~(SNOWAIT|SJCTL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
	sigorset(&p->p_ignore, &ignoredefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
	sigfillset(&p->p_siginfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
	sigdiffset(&p->p_siginfo, &cantmask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
	sigdiffset(&p->p_sig, &ignoredefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	sigdiffset(&p->p_extsig, &ignoredefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
	sigdiffset(&t->t_sig, &ignoredefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
	sigdiffset(&t->t_extsig, &ignoredefault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
sigcld(proc_t *cp, sigqueue_t *sqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
	proc_t *pp = cp->p_parent;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	switch (cp->p_wcode) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
	case CLD_EXITED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	case CLD_DUMPED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
	case CLD_KILLED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
		ASSERT(cp->p_stat == SZOMB);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
		 * The broadcast on p_srwchan_cv is a kludge to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
		 * wakeup a possible thread in uadmin(A_SHUTDOWN).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
		cv_broadcast(&cp->p_srwchan_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
		 * Add to newstate list of the parent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
		add_ns(pp, cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
		cv_broadcast(&pp->p_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
		if ((pp->p_flag & SNOWAIT) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
		    (PTOU(pp)->u_signal[SIGCLD - 1] == SIG_IGN))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
			freeproc(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
		else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
			post_sigcld(cp, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
			sqp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	case CLD_STOPPED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
	case CLD_CONTINUED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
		cv_broadcast(&pp->p_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
		if (pp->p_flag & SJCTL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
			post_sigcld(cp, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
			sqp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
	if (sqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
		siginfofree(sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
 * Common code called from sigcld() and issig_forreal()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
 * Give the parent process a SIGCLD if it does not have one pending,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
 * else mark the child process so a SIGCLD can be posted later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
post_sigcld(proc_t *cp, sigqueue_t *sqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
	proc_t *pp = cp->p_parent;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
	void (*handler)() = PTOU(pp)->u_signal[SIGCLD - 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
	k_siginfo_t info;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
	mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
	 * If a SIGCLD is pending, or if SIGCLD is not now being caught,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
	 * then just mark the child process so that its SIGCLD will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
	 * be posted later, when the first SIGCLD is taken off the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
	 * queue or when the parent is ready to receive it, if ever.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
	if (handler == SIG_DFL || handler == SIG_IGN ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
	    sigismember(&pp->p_sig, SIGCLD))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
		cp->p_pidflag |= CLDPEND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
		cp->p_pidflag &= ~CLDPEND;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
		if (sqp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
			 * This can only happen when the parent is init.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
			 * (See call to sigcld(q, NULL) in exit().)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
			 * Use KM_NOSLEEP to avoid deadlock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
			ASSERT(pp == proc_init);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
			winfo(cp, &info, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
			sigaddq(pp, NULL, &info, KM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
			winfo(cp, &sqp->sq_info, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
			sigaddqa(pp, NULL, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
			sqp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
	mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
	if (sqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
		siginfofree(sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
 * Search for a child that has a pending SIGCLD for us, the parent.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
 * The queue of SIGCLD signals is implied by the list of children.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
 * We post the SIGCLD signals one at a time so they don't get lost.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
 * When one is dequeued, another is enqueued, until there are no more.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
sigcld_repost()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
	proc_t *pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	proc_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
	void (*handler)() = PTOU(pp)->u_signal[SIGCLD - 1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
	sigqueue_t *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
	 * Don't bother if SIGCLD is not now being caught.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
	if (handler == SIG_DFL || handler == SIG_IGN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
	sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
	for (cp = pp->p_child; cp; cp = cp->p_sibling) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
		if (cp->p_pidflag & CLDPEND) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
			post_sigcld(cp, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
			mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
	kmem_free(sqp, sizeof (sigqueue_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
 * count number of sigqueue send by sigaddqa()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
sigqsend(int cmd, proc_t *p, kthread_t *t, sigqueue_t *sigqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
	sigqhdr_t *sqh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	sqh = (sigqhdr_t *)sigqp->sq_backptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	ASSERT(sqh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	mutex_enter(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
	sqh->sqb_sent++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
	if (cmd == SN_SEND)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
		sigaddqa(p, t, sigqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
		siginfofree(sigqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
sigsendproc(proc_t *p, sigsend_t *pv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	struct cred *cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	proc_t *myprocp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
	if (p->p_pid == 1 && pv->sig && sigismember(&cantmask, pv->sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
		return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	cr = CRED();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	if (pv->checkperm == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
	    (pv->sig == SIGCONT && p->p_sessp == myprocp->p_sessp) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	    prochasprocperm(p, myprocp, cr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
		pv->perm++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
		if (pv->sig) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
			/* Make sure we should be setting si_pid and friends */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
			ASSERT(pv->sicode <= 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
			if (SI_CANQUEUE(pv->sicode)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
				sigqueue_t *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
				mutex_enter(&myprocp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
				sqp = sigqalloc(myprocp->p_sigqhdr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
				mutex_exit(&myprocp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
				if (sqp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
					return (EAGAIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
				sqp->sq_info.si_signo = pv->sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
				sqp->sq_info.si_code = pv->sicode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
				sqp->sq_info.si_pid = myprocp->p_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
				sqp->sq_info.si_ctid = PRCTID(myprocp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
				sqp->sq_info.si_zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
				sqp->sq_info.si_uid = crgetruid(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
				sqp->sq_info.si_value = pv->value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
				mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
				sigqsend(SN_SEND, p, NULL, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
				mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
				k_siginfo_t info;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
				bzero(&info, sizeof (info));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
				info.si_signo = pv->sig;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
				info.si_code = pv->sicode;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
				info.si_pid = myprocp->p_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
				info.si_ctid = PRCTID(myprocp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
				info.si_zoneid = getzoneid();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
				info.si_uid = crgetruid(cr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
				mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
				 * XXX: Should be KM_SLEEP but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
				 * we have to avoid deadlock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
				sigaddq(p, NULL, &info, KM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
				mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
sigsendset(procset_t *psp, sigsend_t *pv)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	error = dotoprocs(psp, sigsendproc, (char *)pv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	if (error == 0 && pv->perm == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
		return (EPERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
 * Dequeue a queued siginfo structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
 * If a non-null thread pointer is passed then dequeue from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
 * the thread queue, otherwise dequeue from the process queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
sigdeq(proc_t *p, kthread_t *t, int sig, sigqueue_t **qpp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
	sigqueue_t **psqp, *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
	*qpp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	if (t != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
		sigdelset(&t->t_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
		sigdelset(&t->t_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
		psqp = &t->t_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
		sigdelset(&p->p_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
		sigdelset(&p->p_extsig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
		psqp = &p->p_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
		if ((sqp = *psqp) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
		if (sqp->sq_info.si_signo == sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
			psqp = &sqp->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
	*qpp = sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	*psqp = sqp->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
	for (sqp = *psqp; sqp; sqp = sqp->sq_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
		if (sqp->sq_info.si_signo == sig) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
			if (t != (kthread_t *)NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
				sigaddset(&t->t_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
				t->t_sig_check = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
				sigaddset(&p->p_sig, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
				set_proc_ast(p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
 * Delete a queued SIGCLD siginfo structure matching the k_siginfo_t argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
sigcld_delete(k_siginfo_t *ip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	proc_t *p = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
	int another_sigcld = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
	sigqueue_t **psqp, *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	ASSERT(ip->si_signo == SIGCLD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	if (!sigismember(&p->p_sig, SIGCLD)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	psqp = &p->p_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
		if ((sqp = *psqp) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
		if (sqp->sq_info.si_signo == SIGCLD) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
			if (sqp->sq_info.si_pid == ip->si_pid &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
			    sqp->sq_info.si_code == ip->si_code &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
			    sqp->sq_info.si_status == ip->si_status)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
			another_sigcld = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
		psqp = &sqp->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
	*psqp = sqp->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
	siginfofree(sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
	for (sqp = *psqp; !another_sigcld && sqp; sqp = sqp->sq_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
		if (sqp->sq_info.si_signo == SIGCLD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
			another_sigcld = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
	if (!another_sigcld) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
		sigdelset(&p->p_sig, SIGCLD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
		sigdelset(&p->p_extsig, SIGCLD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
 * Delete queued siginfo structures.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
 * If a non-null thread pointer is passed then delete from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
 * the thread queue, otherwise delete from the process queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
sigdelq(proc_t *p, kthread_t *t, int sig)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	sigqueue_t **psqp, *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
	 * We must be holding p->p_lock unless the process is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
	 * being reaped or has failed to get started on fork.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
	ASSERT(MUTEX_HELD(&p->p_lock) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
	    p->p_stat == SIDL || p->p_stat == SZOMB);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
	if (t != (kthread_t *)NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
		psqp = &t->t_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
		psqp = &p->p_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
	while (*psqp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
		sqp = *psqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
		if (sig == 0 || sqp->sq_info.si_signo == sig) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
			*psqp = sqp->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
			siginfofree(sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
			psqp = &sqp->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
 * Insert a siginfo structure into a queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
 * If a non-null thread pointer is passed then add to the thread queue,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
 * otherwise add to the process queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
 * The function sigaddqins() is called with sigqueue already allocated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
 * It is called from sigaddqa() and sigaddq() below.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
 * The value of si_code implicitly indicates whether sigp is to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
 * explicitly queued, or to be queued to depth one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
sigaddqins(proc_t *p, kthread_t *t, sigqueue_t *sigqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
	sigqueue_t **psqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
	int sig = sigqp->sq_info.si_signo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
	sigqp->sq_external = (curproc != &p0) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
	    (curproc->p_ct_process != p->p_ct_process);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
	 * issig_forreal() doesn't bother dequeueing signals if SKILLED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
	 * is set, and even if it did, we would want to avoid situation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
	 * (which would be unique to SIGKILL) where one thread dequeued
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
	 * the sigqueue_t and another executed psig().  So we create a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
	 * separate stash for SIGKILL's sigqueue_t.  Because a second
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	 * SIGKILL can set SEXTKILLED, we overwrite the existing entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
	 * if (and only if) it was non-extracontractual.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
	if (sig == SIGKILL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
		if (p->p_killsqp == NULL || !p->p_killsqp->sq_external) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
			if (p->p_killsqp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
				siginfofree(p->p_killsqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
			p->p_killsqp = sigqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
			sigqp->sq_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
			siginfofree(sigqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
	ASSERT(sig >= 1 && sig < NSIG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
	if (t != NULL)	/* directed to a thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
		psqp = &t->t_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
	else 		/* directed to a process */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
		psqp = &p->p_sigqueue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
	if (SI_CANQUEUE(sigqp->sq_info.si_code) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
	    sigismember(&p->p_siginfo, sig)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
		for (; *psqp != NULL; psqp = &(*psqp)->sq_next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
				;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
		for (; *psqp != NULL; psqp = &(*psqp)->sq_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
			if ((*psqp)->sq_info.si_signo == sig) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
				siginfofree(sigqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
				return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
	*psqp = sigqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
	sigqp->sq_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
 * The function sigaddqa() is called with sigqueue already allocated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
 * If signal is ignored, discard but guarantee KILL and generation semantics.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
 * It is called from sigqueue() and other places.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
sigaddqa(proc_t *p, kthread_t *t, sigqueue_t *sigqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
	int sig = sigqp->sq_info.si_signo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
	ASSERT(sig >= 1 && sig < NSIG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
	if (sig_discardable(p, sig))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
		siginfofree(sigqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
		sigaddqins(p, t, sigqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
	sigtoproc(p, t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
 * Allocate the sigqueue_t structure and call sigaddqins().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
sigaddq(proc_t *p, kthread_t *t, k_siginfo_t *infop, int km_flags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
	sigqueue_t *sqp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
	int sig = infop->si_signo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
	ASSERT(sig >= 1 && sig < NSIG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
	 * If the signal will be discarded by sigtoproc() or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
	 * if the process isn't requesting siginfo and it isn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
	 * blocking the signal (it *could* change it's mind while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
	 * the signal is pending) then don't bother creating one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
	if (!sig_discardable(p, sig) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
	    (sigismember(&p->p_siginfo, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
	    (curproc->p_ct_process != p->p_ct_process) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
	    (sig == SIGCLD && SI_FROMKERNEL(infop))) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
	    ((sqp = kmem_alloc(sizeof (sigqueue_t), km_flags)) != NULL)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
		bcopy(infop, &sqp->sq_info, sizeof (k_siginfo_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
		sqp->sq_func = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
		sqp->sq_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
		sigaddqins(p, t, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
	sigtoproc(p, t, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
 * Handle stop-on-fault processing for the debugger.  Returns 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
 * if the fault is cleared during the stop, nonzero if it isn't.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
stop_on_fault(uint_t fault, k_siginfo_t *sip)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
	proc_t *p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
	klwp_t *lwp = ttolwp(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
	ASSERT(prismember(&p->p_fltmask, fault));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
	 * Record current fault and siginfo structure so debugger can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
	 * find it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
	lwp->lwp_curflt = (uchar_t)fault;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
	lwp->lwp_siginfo = *sip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
	stop(PR_FAULTED, fault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
	fault = lwp->lwp_curflt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
	lwp->lwp_curflt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
	return (fault);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
sigorset(k_sigset_t *s1, k_sigset_t *s2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
	s1->__sigbits[0] |= s2->__sigbits[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
	s1->__sigbits[1] |= s2->__sigbits[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
sigandset(k_sigset_t *s1, k_sigset_t *s2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	s1->__sigbits[0] &= s2->__sigbits[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	s1->__sigbits[1] &= s2->__sigbits[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
sigdiffset(k_sigset_t *s1, k_sigset_t *s2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	s1->__sigbits[0] &= ~(s2->__sigbits[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
	s1->__sigbits[1] &= ~(s2->__sigbits[1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
 * Return non-zero if curthread->t_sig_check should be set to 1, that is,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
 * if there are any signals the thread might take on return from the kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
 * If ksigset_t's were a single word, we would do:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
 *	return (((p->p_sig | t->t_sig) & ~t->t_hold) & fillset);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
sigcheck(proc_t *p, kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
	sc_shared_t *tdp = t->t_schedctl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	 * If signals are blocked via the schedctl interface
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	 * then we only check for the unmaskable signals.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
	if (tdp != NULL && tdp->sc_sigblock)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
		return ((p->p_sig.__sigbits[0] | t->t_sig.__sigbits[0]) &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
		    CANTMASK0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
	return (((p->p_sig.__sigbits[0] | t->t_sig.__sigbits[0]) &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
		    ~t->t_hold.__sigbits[0]) |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
		(((p->p_sig.__sigbits[1] | t->t_sig.__sigbits[1]) &
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
		    ~t->t_hold.__sigbits[1]) & FILLSET1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
/* ONC_PLUS EXTRACT START */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
sigintr(k_sigset_t *smask, int intable)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
	proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
	int owned;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
	k_sigset_t lmask;		/* local copy of cantmask */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
	klwp_t *lwp = ttolwp(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
	 * Mask out all signals except SIGHUP, SIGINT, SIGQUIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
	 *    and SIGTERM. (Preserving the existing masks).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
	 *    This function supports the -intr nfs and ufs mount option.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	 * don't do kernel threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	if (lwp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
	 * get access to signal mask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
	p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
	owned = mutex_owned(&p->p_lock);	/* this is filthy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
	if (!owned)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
		mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
	 * remember the current mask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
	schedctl_finish_sigblock(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
	*smask = curthread->t_hold;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
	 * mask out all signals
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
	sigfillset(&curthread->t_hold);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
	 * Unmask the non-maskable signals (e.g., KILL), as long as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
	 * they aren't already masked (which could happen at exit).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
	 * The first sigdiffset sets lmask to (cantmask & ~curhold).  The
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
	 * second sets the current hold mask to (~0 & ~lmask), which reduces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
	 * to (~cantmask | curhold).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
	lmask = cantmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
	sigdiffset(&lmask, smask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
	sigdiffset(&curthread->t_hold, &lmask);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
	 * Re-enable HUP, QUIT, and TERM iff they were originally enabled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
	 * Re-enable INT if it's originally enabled and the NFS mount option
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
	 * nointr is not set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
	if (!sigismember(smask, SIGHUP))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
		sigdelset(&curthread->t_hold, SIGHUP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
	if (!sigismember(smask, SIGINT) && intable)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
		sigdelset(&curthread->t_hold, SIGINT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
	if (!sigismember(smask, SIGQUIT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
		sigdelset(&curthread->t_hold, SIGQUIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
	if (!sigismember(smask, SIGTERM))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
		sigdelset(&curthread->t_hold, SIGTERM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
	 * release access to signal mask
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
	if (!owned)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
		mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
	 * Indicate that this lwp is not to be stopped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
	lwp->lwp_nostop++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
/* ONC_PLUS EXTRACT END */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
sigunintr(k_sigset_t *smask)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
	proc_t *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
	int owned;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
	klwp_t *lwp = ttolwp(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
	 * Reset previous mask (See sigintr() above)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
	if (lwp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
		lwp->lwp_nostop--;	/* restore lwp stoppability */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
		p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
		owned = mutex_owned(&p->p_lock);	/* this is filthy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
		if (!owned)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
		curthread->t_hold = *smask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
		/* so unmasked signals will be seen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
		curthread->t_sig_check = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
		if (!owned)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
sigreplace(k_sigset_t *newmask, k_sigset_t *oldmask)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
	proc_t	*p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	int owned;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
	 * Save current signal mask in oldmask, then
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
	 * set it to newmask.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
	if (ttolwp(curthread) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
		p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
		owned = mutex_owned(&p->p_lock);	/* this is filthy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
		if (!owned)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
			mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
		schedctl_finish_sigblock(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
		if (oldmask != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
			*oldmask = curthread->t_hold;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
		curthread->t_hold = *newmask;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
		curthread->t_sig_check = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
		if (!owned)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
			mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
 * Return true if the signal number is in range
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
 * and the signal code specifies signal queueing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
sigwillqueue(int sig, int code)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
	if (sig >= 0 && sig < NSIG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
		switch (code) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
		case SI_QUEUE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
		case SI_TIMER:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
		case SI_ASYNCIO:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
		case SI_MESGQ:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
#ifndef	UCHAR_MAX
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
#define	UCHAR_MAX	255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
 * The entire pool (with maxcount entries) is pre-allocated at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
 * the first sigqueue/signotify call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
sigqhdr_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
sigqhdralloc(size_t size, uint_t maxcount)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
	size_t i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
	sigqueue_t *sq, *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
	sigqhdr_t *sqh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
	i = (maxcount * size) + sizeof (sigqhdr_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
	ASSERT(maxcount <= UCHAR_MAX && i <= USHRT_MAX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
	sqh = kmem_alloc(i, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
	sqh->sqb_count = (uchar_t)maxcount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
	sqh->sqb_maxcount = (uchar_t)maxcount;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
	sqh->sqb_size = (ushort_t)i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
	sqh->sqb_pexited = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
	sqh->sqb_sent = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
	sqh->sqb_free = sq = (sigqueue_t *)(sqh + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
	for (i = maxcount - 1; i != 0; i--) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
		next = (sigqueue_t *)((uintptr_t)sq + size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
		sq->sq_next = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
		sq = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
	sq->sq_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
	mutex_init(&sqh->sqb_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
	return (sqh);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
static void sigqrel(sigqueue_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
 * allocate a sigqueue/signotify structure from the per process
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
 * pre-allocated pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
sigqueue_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
sigqalloc(sigqhdr_t *sqh)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
	sigqueue_t *sq = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
	ASSERT(MUTEX_HELD(&curproc->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
	if (sqh != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
		mutex_enter(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
		if (sqh->sqb_count > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
			sqh->sqb_count--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
			sq = sqh->sqb_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
			sqh->sqb_free = sq->sq_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
			mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
			bzero(&sq->sq_info, sizeof (k_siginfo_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
			sq->sq_backptr = sqh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
			sq->sq_func = sigqrel;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
			sq->sq_next = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
			sq->sq_external = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
			mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
	return (sq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
 * Return a sigqueue structure back to the pre-allocated pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
sigqrel(sigqueue_t *sq)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
	sigqhdr_t *sqh;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
	/* make sure that p_lock of the affected process is held */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
	sqh = (sigqhdr_t *)sq->sq_backptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
	mutex_enter(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
	if (sqh->sqb_pexited && sqh->sqb_sent == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
		mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
		mutex_destroy(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
		kmem_free(sqh, sqh->sqb_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
		sqh->sqb_count++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
		sqh->sqb_sent--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
		sq->sq_next = sqh->sqb_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
		sq->sq_backptr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
		sqh->sqb_free = sq;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
		mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
 * Free up the pre-allocated sigqueue headers of sigqueue pool
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
 * and signotify pool, if possible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
 * Called only by the owning process during exec() and exit().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
sigqfree(proc_t *p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
	ASSERT(MUTEX_HELD(&p->p_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
	if (p->p_sigqhdr != NULL) {	/* sigqueue pool */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
		sigqhdrfree(p->p_sigqhdr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
		p->p_sigqhdr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
	if (p->p_signhdr != NULL) {	/* signotify pool */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
		sigqhdrfree(p->p_signhdr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
		p->p_signhdr = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
 * Free up the pre-allocated header and sigq pool if possible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
sigqhdrfree(sigqhdr_t *sqh)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
	mutex_enter(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
	if (sqh->sqb_sent == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
		mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
		mutex_destroy(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
		kmem_free(sqh, sqh->sqb_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
		sqh->sqb_pexited = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
		mutex_exit(&sqh->sqb_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
 * Free up a single sigqueue structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
 * No other code should free a sigqueue directly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
siginfofree(sigqueue_t *sqp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	if (sqp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
		if (sqp->sq_func != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
			(sqp->sq_func)(sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
			kmem_free(sqp, sizeof (sigqueue_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
 * Generate a synchronous signal caused by a hardware
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
 * condition encountered by an lwp.  Called from trap().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
trapsig(k_siginfo_t *ip, int restartable)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
	proc_t *p = ttoproc(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
	int sig = ip->si_signo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
	sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
	ASSERT(sig > 0 && sig < NSIG);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
	if (curthread->t_dtrace_on)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
		dtrace_safe_synchronous_signal();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
	mutex_enter(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
	schedctl_finish_sigblock(curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
	 * Avoid a possible infinite loop if the lwp is holding the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
	 * signal generated by a trap of a restartable instruction or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
	 * if the signal so generated is being ignored by the process.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
	if (restartable &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
	    (sigismember(&curthread->t_hold, sig) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
	    p->p_user.u_signal[sig-1] == SIG_IGN)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
		sigdelset(&curthread->t_hold, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
		p->p_user.u_signal[sig-1] = SIG_DFL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
		sigdelset(&p->p_ignore, sig);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
	bcopy(ip, &sqp->sq_info, sizeof (k_siginfo_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
	sigaddqa(p, curthread, sqp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
	mutex_exit(&p->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
 * It's tricky to transmit a sigval between 32-bit and 64-bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
 * process, since in the 64-bit world, a pointer and an integer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
 * are different sizes.  Since we're constrained by the standards
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
 * world not to change the types, and it's unclear how useful it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
 * to send pointers between address spaces this way, we preserve
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
 * the 'int' interpretation for 32-bit processes interoperating
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
 * with 64-bit processes.  The full semantics (pointers or integers)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
 * are available for N-bit processes interoperating with N-bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
 * processes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
siginfo_kto32(const k_siginfo_t *src, siginfo32_t *dest)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
	bzero(dest, sizeof (*dest));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
	 * The absolute minimum content is si_signo and si_code.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
	dest->si_signo = src->si_signo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
	if ((dest->si_code = src->si_code) == SI_NOINFO)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
	 * A siginfo generated by user level is structured
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
	 * differently from one generated by the kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
	if (SI_FROMUSER(src)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
		dest->si_pid = src->si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
		dest->si_ctid = src->si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
		dest->si_zoneid = src->si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
		dest->si_uid = src->si_uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
		if (SI_CANQUEUE(src->si_code))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
			dest->si_value.sival_int =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
				(int32_t)src->si_value.sival_int;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
	dest->si_errno = src->si_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
	switch (src->si_signo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
		dest->si_pid = src->si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
		dest->si_ctid = src->si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
		dest->si_zoneid = src->si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
		dest->si_uid = src->si_uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
		dest->si_value.sival_int = (int32_t)src->si_value.sival_int;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
	case SIGCLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
		dest->si_pid = src->si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
		dest->si_ctid = src->si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
		dest->si_zoneid = src->si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
		dest->si_status = src->si_status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
		dest->si_stime = src->si_stime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
		dest->si_utime = src->si_utime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
	case SIGSEGV:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
	case SIGBUS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
	case SIGILL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
	case SIGTRAP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
	case SIGFPE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
	case SIGEMT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
		dest->si_addr = (caddr32_t)(uintptr_t)src->si_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
		dest->si_trapno = src->si_trapno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
		dest->si_pc = (caddr32_t)(uintptr_t)src->si_pc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
	case SIGPOLL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
	case SIGXFSZ:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
		dest->si_fd = src->si_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
		dest->si_band = src->si_band;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
	case SIGPROF:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
		dest->si_faddr = (caddr32_t)(uintptr_t)src->si_faddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
		dest->si_tstamp.tv_sec = src->si_tstamp.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
		dest->si_tstamp.tv_nsec = src->si_tstamp.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
		dest->si_syscall = src->si_syscall;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
		dest->si_nsysarg = src->si_nsysarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
		dest->si_fault = src->si_fault;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
siginfo_32tok(const siginfo32_t *src, k_siginfo_t *dest)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
	bzero(dest, sizeof (*dest));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
	 * The absolute minimum content is si_signo and si_code.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
	dest->si_signo = src->si_signo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
	if ((dest->si_code = src->si_code) == SI_NOINFO)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
	 * A siginfo generated by user level is structured
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
	 * differently from one generated by the kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
	if (SI_FROMUSER(src)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
		dest->si_pid = src->si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
		dest->si_ctid = src->si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
		dest->si_zoneid = src->si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
		dest->si_uid = src->si_uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
		if (SI_CANQUEUE(src->si_code))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
			dest->si_value.sival_int =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
				(int)src->si_value.sival_int;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
	dest->si_errno = src->si_errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
	switch (src->si_signo) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
		dest->si_pid = src->si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
		dest->si_ctid = src->si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
		dest->si_zoneid = src->si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
		dest->si_uid = src->si_uid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
		dest->si_value.sival_int = (int)src->si_value.sival_int;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
	case SIGCLD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
		dest->si_pid = src->si_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
		dest->si_ctid = src->si_ctid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
		dest->si_zoneid = src->si_zoneid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
		dest->si_status = src->si_status;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
		dest->si_stime = src->si_stime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
		dest->si_utime = src->si_utime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
	case SIGSEGV:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
	case SIGBUS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	case SIGILL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
	case SIGTRAP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2657
	case SIGFPE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2658
	case SIGEMT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2659
		dest->si_addr = (void *)(uintptr_t)src->si_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2660
		dest->si_trapno = src->si_trapno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2661
		dest->si_pc = (void *)(uintptr_t)src->si_pc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2662
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2663
	case SIGPOLL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2664
	case SIGXFSZ:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2665
		dest->si_fd = src->si_fd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2666
		dest->si_band = src->si_band;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2667
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2668
	case SIGPROF:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2669
		dest->si_faddr = (void *)(uintptr_t)src->si_faddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2670
		dest->si_tstamp.tv_sec = src->si_tstamp.tv_sec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2671
		dest->si_tstamp.tv_nsec = src->si_tstamp.tv_nsec;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2672
		dest->si_syscall = src->si_syscall;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2673
		dest->si_nsysarg = src->si_nsysarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2674
		dest->si_fault = src->si_fault;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2675
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2676
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2677
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2679
#endif /* _SYSCALL32_IMPL */