...

Text file src/runtime/cgo/gcc_sigaction.c

Documentation: runtime/cgo

     1// Copyright 2016 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 linux && (amd64 || arm64 || ppc64le)
     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// defs_linux_amd64.go.  This definition — and its conversion to and from struct
    17// sigaction — are specific to linux/amd64.
    18typedef struct {
    19	uintptr_t handler;
    20	uint64_t flags;
    21	uintptr_t restorer;
    22	uint64_t mask;
    23} go_sigaction_t;
    24
    25// SA_RESTORER is part of the kernel interface.
    26// This is Linux i386/amd64 specific.
    27#ifndef SA_RESTORER
    28#define SA_RESTORER 0x4000000
    29#endif
    30
    31int32_t
    32x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) {
    33	int32_t ret;
    34	struct sigaction act;
    35	struct sigaction oldact;
    36	size_t i;
    37
    38	_cgo_tsan_acquire();
    39
    40	memset(&act, 0, sizeof act);
    41	memset(&oldact, 0, sizeof oldact);
    42
    43	if (goact) {
    44		if (goact->flags & SA_SIGINFO) {
    45			act.sa_sigaction = (void(*)(int, siginfo_t*, void*))(goact->handler);
    46		} else {
    47			act.sa_handler = (void(*)(int))(goact->handler);
    48		}
    49		sigemptyset(&act.sa_mask);
    50		for (i = 0; i < 8 * sizeof(goact->mask); i++) {
    51			if (goact->mask & ((uint64_t)(1)<<i)) {
    52				sigaddset(&act.sa_mask, (int)(i+1));
    53			}
    54		}
    55		act.sa_flags = (int)(goact->flags & ~(uint64_t)SA_RESTORER);
    56	}
    57
    58	ret = sigaction((int)signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
    59	if (ret == -1) {
    60		// runtime.rt_sigaction expects _cgo_sigaction to return errno on error.
    61		_cgo_tsan_release();
    62		return errno;
    63	}
    64
    65	if (oldgoact) {
    66		if (oldact.sa_flags & SA_SIGINFO) {
    67			oldgoact->handler = (uintptr_t)(oldact.sa_sigaction);
    68		} else {
    69			oldgoact->handler = (uintptr_t)(oldact.sa_handler);
    70		}
    71		oldgoact->mask = 0;
    72		for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) {
    73			if (sigismember(&oldact.sa_mask, (int)(i+1)) == 1) {
    74				oldgoact->mask |= (uint64_t)(1)<<i;
    75			}
    76		}
    77		oldgoact->flags = (uint64_t)oldact.sa_flags;
    78	}
    79
    80	_cgo_tsan_release();
    81	return ret;
    82}

View as plain text