...

Text file src/runtime/cgo/gcc_freebsd_sigaction.c

     1	// Copyright 2018 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build freebsd,amd64
     6	
     7	#include <errno.h>
     8	#include <stddef.h>
     9	#include <stdint.h>
    10	#include <string.h>
    11	#include <signal.h>
    12	
    13	#include "libcgo.h"
    14	
    15	// go_sigaction_t is a C version of the sigactiont struct from
    16	// os_freebsd.go.  This definition — and its conversion to and from struct
    17	// sigaction — are specific to freebsd/amd64.
    18	typedef struct {
    19	        uint32_t __bits[_SIG_WORDS];
    20	} go_sigset_t;
    21	typedef struct {
    22		uintptr_t handler;
    23		int32_t flags;
    24		go_sigset_t mask;
    25	} go_sigaction_t;
    26	
    27	int32_t
    28	x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) {
    29		int32_t ret;
    30		struct sigaction act;
    31		struct sigaction oldact;
    32		size_t i;
    33	
    34		_cgo_tsan_acquire();
    35	
    36		memset(&act, 0, sizeof act);
    37		memset(&oldact, 0, sizeof oldact);
    38	
    39		if (goact) {
    40			if (goact->flags & SA_SIGINFO) {
    41				act.sa_sigaction = (void(*)(int, siginfo_t*, void*))(goact->handler);
    42			} else {
    43				act.sa_handler = (void(*)(int))(goact->handler);
    44			}
    45			sigemptyset(&act.sa_mask);
    46			for (i = 0; i < 8 * sizeof(goact->mask); i++) {
    47				if (goact->mask.__bits[i/32] & ((uint32_t)(1)<<(i&31))) {
    48					sigaddset(&act.sa_mask, i+1);
    49				}
    50			}
    51			act.sa_flags = goact->flags;
    52		}
    53	
    54		ret = sigaction(signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
    55		if (ret == -1) {
    56			// runtime.sigaction expects _cgo_sigaction to return errno on error.
    57			_cgo_tsan_release();
    58			return errno;
    59		}
    60	
    61		if (oldgoact) {
    62			if (oldact.sa_flags & SA_SIGINFO) {
    63				oldgoact->handler = (uintptr_t)(oldact.sa_sigaction);
    64			} else {
    65				oldgoact->handler = (uintptr_t)(oldact.sa_handler);
    66			}
    67			for (i = 0 ; i < _SIG_WORDS; i++) {
    68				oldgoact->mask.__bits[i] = 0;
    69			}
    70			for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) {
    71				if (sigismember(&oldact.sa_mask, i+1) == 1) {
    72					oldgoact->mask.__bits[i/32] |= (uint32_t)(1)<<(i&31);
    73				}
    74			}
    75			oldgoact->flags = oldact.sa_flags;
    76		}
    77	
    78		_cgo_tsan_release();
    79		return ret;
    80	}

View as plain text