...

Text file src/runtime/cgo/gcc_freebsd_sigaction.c

Documentation: runtime/cgo

     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//go: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.
    18typedef struct {
    19        uint32_t __bits[_SIG_WORDS];
    20} go_sigset_t;
    21typedef struct {
    22	uintptr_t handler;
    23	int32_t flags;
    24	go_sigset_t mask;
    25} go_sigaction_t;
    26
    27int32_t
    28x_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