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 /*
     23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% 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/siginfo.h>
     41 #include <sys/debug.h>
     42 
     43 int
     44 sigaltstack(struct sigaltstack *ssp, struct sigaltstack *oss)
     45 {
     46 	klwp_t *lwp = ttolwp(curthread);
     47 	struct sigaltstack ss;
     48 
     49 	/*
     50 	 * User's oss and ss might be the same address, so copyin first and
     51 	 * save before copying out.
     52 	 */
     53 	if (ssp) {
     54 		if (lwp->lwp_sigaltstack.ss_flags & SS_ONSTACK)
     55 			return (set_errno(EPERM));
     56 		if (copyin(ssp, &ss, sizeof (ss)))
     57 			return (set_errno(EFAULT));
     58 		if (ss.ss_flags & ~SS_DISABLE)
     59 			return (set_errno(EINVAL));
     60 		if (!(ss.ss_flags & SS_DISABLE) && ss.ss_size < MINSIGSTKSZ)
     61 			return (set_errno(ENOMEM));
     62 	}
     63 
     64 	if (oss) {
     65 		if (copyout(&lwp->lwp_sigaltstack,
     66 		    oss, sizeof (struct sigaltstack)))
     67 			return (set_errno(EFAULT));
     68 	}
     69 
     70 	if (ssp)
     71 		lwp->lwp_sigaltstack = ss;
     72 
     73 	return (0);
     74 }
     75 
     76 #ifdef _LP64
     77 int
     78 sigaltstack32(struct sigaltstack32 *ssp, struct sigaltstack32 *oss)
     79 {
     80 	klwp_t *lwp = ttolwp(curthread);
     81 	struct sigaltstack   *ss;
     82 	struct sigaltstack32 ss32, oss32;
     83 
     84 	/*
     85 	 * User's oss and ss might be the same address, so copyin first and
     86 	 * save before copying out.
     87 	 */
     88 	if (ssp) {
     89 		if (lwp->lwp_sigaltstack.ss_flags & SS_ONSTACK)
     90 			return (set_errno(EPERM));
     91 		if (copyin(ssp, &ss32, sizeof (ss32)))
     92 			return (set_errno(EFAULT));
     93 		if (ss32.ss_flags & ~SS_DISABLE)
     94 			return (set_errno(EINVAL));
     95 		if (!(ss32.ss_flags & SS_DISABLE) && ss32.ss_size < MINSIGSTKSZ)
     96 			return (set_errno(ENOMEM));
     97 	}
     98 
     99 	if (oss) {
    100 		/*
    101 		 * copy to ILP32 struct before copyout.
    102 		 */
    103 		ss = &lwp->lwp_sigaltstack;
    104 		oss32.ss_sp    = (caddr32_t)(uintptr_t)ss->ss_sp;
    105 		oss32.ss_size  = (size32_t)ss->ss_size;
    106 		oss32.ss_flags = ss->ss_flags;
    107 
    108 		if (copyout(&oss32, oss, sizeof (oss32)))
    109 			return (set_errno(EFAULT));
    110 	}
    111 
    112 	if (ssp) {
    113 		ss = &lwp->lwp_sigaltstack;
    114 		ss->ss_sp = (void *)(uintptr_t)ss32.ss_sp;
    115 		ss->ss_size = (size_t)ss32.ss_size;
    116 		ss->ss_flags = ss32.ss_flags;
    117 	}
    118 
    119 	return (0);
    120 }
    121 #endif /* _LP64 */
    122