Home | History | Annotate | Download | only in syscall
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     23 
     24 
     25 /*
     26  * Copyright 1994-2003 Sun Microsystems, Inc.  All rights reserved.
     27  * Use is subject to license terms.
     28  */
     29 
     30 #pragma ident	"@(#)sigprocmask.c	1.6	05/06/08 SMI"
     31 
     32 #include <sys/param.h>
     33 #include <sys/types.h>
     34 #include <sys/sysmacros.h>
     35 #include <sys/systm.h>
     36 #include <sys/errno.h>
     37 #include <sys/proc.h>
     38 #include <sys/fault.h>
     39 #include <sys/signal.h>
     40 #include <sys/schedctl.h>
     41 #include <sys/debug.h>
     42 
     43 int64_t
     44 lwp_sigmask(int how, uint_t bits0, uint_t bits1)
     45 {
     46 	kthread_t *t = curthread;
     47 	proc_t *p = ttoproc(t);
     48 	rval_t rv;
     49 
     50 	mutex_enter(&p->p_lock);
     51 	schedctl_finish_sigblock(t);
     52 
     53 	bits0 &= (FILLSET0 & ~CANTMASK0);
     54 	bits1 &= (FILLSET1 & ~CANTMASK1);
     55 
     56 	rv.r_val1 = t->t_hold.__sigbits[0];
     57 	rv.r_val2 = t->t_hold.__sigbits[1];
     58 
     59 	switch (how) {
     60 	case SIG_BLOCK:
     61 		t->t_hold.__sigbits[0] |= bits0;
     62 		t->t_hold.__sigbits[1] |= bits1;
     63 		break;
     64 	case SIG_UNBLOCK:
     65 		t->t_hold.__sigbits[0] &= ~bits0;
     66 		t->t_hold.__sigbits[1] &= ~bits1;
     67 		if (sigcheck(p, t))
     68 			t->t_sig_check = 1;
     69 		break;
     70 	case SIG_SETMASK:
     71 		t->t_hold.__sigbits[0] = bits0;
     72 		t->t_hold.__sigbits[1] = bits1;
     73 		if (sigcheck(p, t))
     74 			t->t_sig_check = 1;
     75 		break;
     76 	}
     77 
     78 	mutex_exit(&p->p_lock);
     79 	return (rv.r_vals);
     80 }
     81 
     82 /*
     83  * This system call is no longer called from libc.
     84  * It exists solely for the benefit of statically-linked
     85  * binaries from the past.  It should be eliminated.
     86  */
     87 int
     88 sigprocmask(int how, sigset_t *setp, sigset_t *osetp)
     89 {
     90 	sigset_t set;
     91 	k_sigset_t kset;
     92 	rval_t rv;
     93 
     94 	/*
     95 	 * User's oset and set might be the same address, so copyin first and
     96 	 * save before copying out.
     97 	 */
     98 	if (setp) {
     99 		switch (how) {
    100 		case SIG_BLOCK:
    101 		case SIG_UNBLOCK:
    102 		case SIG_SETMASK:
    103 			break;
    104 		default:
    105 			return (set_errno(EINVAL));
    106 		}
    107 		if (copyin((caddr_t)setp, (caddr_t)&set, sizeof (sigset_t)))
    108 			return (set_errno(EFAULT));
    109 		sigutok(&set, &kset);
    110 	} else {
    111 		/* none of SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK equals 0 */
    112 		how = 0;
    113 		sigemptyset(&kset);
    114 	}
    115 
    116 	rv.r_vals = lwp_sigmask(how, kset.__sigbits[0], kset.__sigbits[1]);
    117 
    118 	if (osetp) {
    119 		kset.__sigbits[0] = rv.r_val1;
    120 		kset.__sigbits[1] = rv.r_val2;
    121 		sigktou(&kset, &set);
    122 		if (copyout((caddr_t)&set, (caddr_t)osetp, sizeof (sigset_t)))
    123 			return (set_errno(EFAULT));
    124 	}
    125 
    126 	return (0);
    127 }
    128