Plan 9 from Bell Labs’s /usr/web/sources/contrib/cinap_lenrek/old/linuxemu.old/signal.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <ureg.h>
#include "linuxsys.h"
#include "linux.h"

static struct {
	char	*msg;	/* just check prefix */
	int	num;
} sigtab[] = {
	{"hangup",					SIGHUP},
	{"interrupt",					SIGINT},
	{"quit",						SIGQUIT},
	{"alarm",						SIGALRM},
	{"sys: trap: illegal instruction",		SIGILL},
	{"sys: trap: reserved instruction",	SIGILL},
	{"sys: trap: reserved",			SIGILL},
	{"sys: trap: arithmetic overflow",	SIGFPE},
	{"abort",						SIGABRT},
	{"sys: fp:",						SIGFPE},
	{"exit",						SIGKILL},
	{"die",						SIGKILL},
	{"kill",						SIGKILL},
	{"sys: trap: bus error",			SIGSEGV},
	{"sys: trap: address error",		SIGSEGV},
	{"sys: trap: TLB",				SIGSEGV},
	{"sys: write on closed pipe",		SIGPIPE},
	{"alarm",						SIGALRM},
	{"term",						SIGTERM},
	{"usr1",						SIGUSR1},
	{"usr2",						SIGUSR2},

	{"rt1",						SIGRT1},
	{"rt2",						SIGRT2},
	{"rt3",						SIGRT3},
	{"rt4",						SIGRT4},
	{"rt5",						SIGRT5},
	{"rt6",						SIGRT6},
	{"rt7",						SIGRT7},
	{"rt8",						SIGRT8},

	{"tstp",						SIGTSTP},
	{"ttin",						SIGTTIN},
	{"ttou",						SIGTTOU},
	{"stop",						SIGSTOP},
	{"start",						SIGCONT},
};
#define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0])))

int
stringsig(char *msg)
{
	int i;
	for(i=0; i<NSIGTAB; i++){
		if(strncmp(msg, sigtab[i].msg, strlen(sigtab[i].msg)) == 0)
			return sigtab[i].num;
	}	
	return 0;
}

char*
sigstring(int sig)
{
	int i;
	for(i=0; i<NSIGTAB; i++){
		if(sigtab[i].num == sig)
			return sigtab[i].msg;
	}
	return nil;
}

static void
dosig(Sigstate *ss, int sig, void *info, uvlong rblocked)
{
	void *h;

	USED(info);

	h = ss->action[sig-1].handler;
	if((ulong)h > 2){
		ss->blocked |= ss->action[sig-1].blocked;
		callsignal(sig, h);
		ss->blocked = rblocked;
	}
}

static int
sigenqueue(Sigqueue *q, int sig, void *info)
{
	int a, i;

	a = i = q->wp;

	i = (i + 1) & (SIGQUEUESIZE - 1);
	if(i == q->rp)
		return 0;

	assert(q->e[a].sig == 0);

	q->e[a].sig = sig;
	q->e[a].info = info;

	q->wp = i;

	return 1;
}

static int
sigdequeue(Sigqueue *q, int *psig, void **pinfo, uvlong blocked)
{
	int i, a;

	a = i = q->rp;

	for(;;){
		if(i == q->wp)
			return 0;

		if(!((1LL << (q->e[i].sig-1)) & blocked))
			break;

		i = (i + 1) & (SIGQUEUESIZE - 1);
	}

	if(psig)
		*psig = q->e[i].sig;
	if(pinfo)
		*pinfo = q->e[i].info;

	q->e[i].sig = 0;

	if(i == a)
		q->rp = (i + 1) & (SIGQUEUESIZE - 1);
	return 1;
}

static uvlong
sigpeekqueue(Sigqueue *q)
{
	int i;
	uvlong m;

	m = 0LL;
	for(i = q->rp; i != q->wp; i = (i + 1) & (SIGQUEUESIZE - 1))
		m |= 1LL << (q->e[i].sig-1);
	return m;
}

void sigprocess(Sigstate *ss)
{
	int sig;
	void *info;
	uvlong rblocked;

	if(ss->level)
		return;

	for(sig=1; sig<=32; sig++){
		ulong m;

		m = 1 << (sig-1);
		if((m & ss->pending) == 0)
			continue;

		rblocked = ss->blocked;
		if(m & rblocked)
			continue;
		info = ss->info[sig-1];
		ss->pending &= ~m;

		dosig(ss, sig, info, rblocked);
	}

	for(;;){
		rblocked = ss->blocked;
		if(!sigdequeue(&ss->rtsq, &sig, &info, rblocked))
			break;
		dosig(ss, sig, info, rblocked);
	}
}

uvlong
sigpending(Sigstate *ss)
{
	uvlong m;
	m = (uvlong)ss->pending;
	m |= sigpeekqueue(&ss->rtsq);
	return m;
}

void
sigclearall(Sigstate *ss)
{
	ss->pending = 0;
	ss->rtsq.rp = ss->rtsq.wp = 0;
}

void sigdisable(Sigstate *ss)
{
	_xinc(&ss->level);
}

void sigenable(Sigstate *ss)
{
	if(!_xdec(&ss->level))
		sigprocess(ss);
}

int
signote(Sigstate *ss, char *msg)
{
	int sig;
	void *info;

	if((sig = stringsig(msg)) < 1)
		return 0;

	info = nil;

	if(sig <= 32){
		ulong m;

		m = 1<<(sig-1);
		if(m & ss->pending){
			fprint(2, "signal %d lost!\n", sig);
			return 1;
		}
		ss->info[sig-1] = info;
		ss->pending |= m;
	} else {
		if(!sigenqueue(&ss->rtsq, sig, info))
			fprint(2, "rt signal %d lost!\n", sig);
	}
	return 1;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.