...

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

View as plain text