// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin freebsd linux openbsd netbsd

#include <sys/time.h>

#include "runtime.h"
#include "defs.h"
#include "signal_unix.h"

extern SigTab runtime_sigtab[];

void
runtime_initsig(void)
{
	int32 i;
	SigTab *t;

	// First call: basic setup.
	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
		t = &runtime_sigtab[i];
		if((t->flags == 0) || (t->flags & SigDefault))
			continue;

		// For some signals, we respect an inherited SIG_IGN handler
		// rather than insist on installing our own default handler.
		// Even these signals can be fetched using the os/signal package.
		switch(t->sig) {
		case SIGHUP:
		case SIGINT:
			if(runtime_getsig(i) == GO_SIG_IGN) {
				t->flags = SigNotify | SigIgnored;
				continue;
			}
		}

		t->flags |= SigHandling;
		runtime_setsig(i, runtime_sighandler, true);
	}
}

void
runtime_sigenable(uint32 sig)
{
	int32 i;
	SigTab *t;

	t = nil;
	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
		if(runtime_sigtab[i].sig == (int32)sig) {
			t = &runtime_sigtab[i];
			break;
		}
	}

	if(t == nil)
		return;

	if((t->flags & SigNotify) && !(t->flags & SigHandling)) {
		t->flags |= SigHandling;
		if(runtime_getsig(i) == GO_SIG_IGN)
			t->flags |= SigIgnored;
		runtime_setsig(i, runtime_sighandler, true);
	}
}

void
runtime_sigdisable(uint32 sig)
{
	int32 i;
	SigTab *t;

	t = nil;
	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
		if(runtime_sigtab[i].sig == (int32)sig) {
			t = &runtime_sigtab[i];
			break;
		}
	}

	if(t == nil)
		return;

	if((t->flags & SigNotify) && (t->flags & SigHandling)) {
		t->flags &= ~SigHandling;
		if(t->flags & SigIgnored)
			runtime_setsig(i, GO_SIG_IGN, true);
		else
			runtime_setsig(i, GO_SIG_DFL, true);
	}
}

void
runtime_resetcpuprofiler(int32 hz)
{
	struct itimerval it;

	runtime_memclr((byte*)&it, sizeof it);
	if(hz == 0) {
		runtime_setitimer(ITIMER_PROF, &it, nil);
		runtime_setprof(false);
	} else {
		it.it_interval.tv_sec = 0;
		it.it_interval.tv_usec = 1000000 / hz;
		it.it_value = it.it_interval;
		runtime_setitimer(ITIMER_PROF, &it, nil);
		runtime_setprof(true);
	}
	runtime_m()->profilehz = hz;
}

void
os_sigpipe(void)
{
	int32 i;

	for(i = 0; runtime_sigtab[i].sig != -1; i++)
		if(runtime_sigtab[i].sig == SIGPIPE)
			break;
	runtime_setsig(i, GO_SIG_DFL, false);
	runtime_raise(SIGPIPE);
}

void
runtime_crash(void)
{
	int32 i;

#ifdef GOOS_darwin
	// OS X core dumps are linear dumps of the mapped memory,
	// from the first virtual byte to the last, with zeros in the gaps.
	// Because of the way we arrange the address space on 64-bit systems,
	// this means the OS X core file will be >128 GB and even on a zippy
	// workstation can take OS X well over an hour to write (uninterruptible).
	// Save users from making that mistake.
	if(sizeof(void*) == 8)
		return;
#endif

	for(i = 0; runtime_sigtab[i].sig != -1; i++)
		if(runtime_sigtab[i].sig == SIGABRT)
			break;
	runtime_setsig(i, GO_SIG_DFL, false);
	runtime_raise(SIGABRT);
}

void
runtime_raise(int32 sig)
{
	raise(sig);
}
