...

Text file src/pkg/runtime/cgo/gcc_sigaction.c

     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	// +build linux,amd64 linux,arm64
     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.
    18	typedef 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 GNU/Linux i386/amd64 specific.
    27	#ifndef SA_RESTORER
    28	#define SA_RESTORER 0x4000000
    29	#endif
    30	
    31	int32_t
    32	x_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, i+1);
    53				}
    54			}
    55			act.sa_flags = goact->flags & ~SA_RESTORER;
    56		}
    57	
    58		ret = sigaction(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, i+1) == 1) {
    74					oldgoact->mask |= (uint64_t)(1)<<i;
    75				}
    76			}
    77			oldgoact->flags = oldact.sa_flags;
    78		}
    79	
    80		_cgo_tsan_release();
    81		return ret;
    82	}

View as plain text