/* kill() for MiNT */

#include <stdlib.h>
#include <errno.h>
#include <osbind.h>
#include <signal.h>
#include <unistd.h>
#include "mintbind.h"

extern int __mint;

/* vector of signal handlers (for TOS) */
extern __Sigfunc _sig_handler[];	/* in signal.c */

/* vector giving which signals are currently blocked from delivery (for TOS) */
extern long _sigmask;			/* in signal.c */

/* which signals are pending? */
extern long _sigpending;

int
kill(pid, sig)
	int pid, sig;
{
	long r;
	__Sigfunc hndle;

	if (pid < 0) {
		errno = ERANGE;
		return -1;
	}

	if (__mint) {
		r = Pkill(pid, sig);
		if (r < 0) {
			errno = -r;
			return -1;
		}
	} else {
		if (sig < 0 || sig >= NSIG || (pid && pid != getpid())) {
			errno = ERANGE;
			return -1;
		}
		hndle = _sig_handler[sig];
		if (hndle == SIG_IGN)
			return 0;
	/* check here for masked signals */
		else if (sig != SIGKILL && (_sigmask & (1L << sig)))
			_sigpending |= (1L << sig);
		else {
			_sigpending &= ~(1L << sig);
			if (hndle == SIG_DFL) {
				switch (sig) {
				case SIGCONT:
				case SIGCHLD:
					return 0;
				default:
					exit(sig << 8);
				}
			} else {
				(*hndle)(sig);
			}
		}
	}
	return 0;
}

int
killpg(pgrp, sig)
	int pgrp, sig;
{
	long r;

	if (__mint == 0) {
		if (pgrp == 0 || pgrp == getpgrp())
			return kill(getpid(), sig);
		errno = EINVAL;
		return -1;
	}
	if (pgrp < 0) {
		errno = ERANGE;
		return -1;
	}
	r = Pkill(-pgrp, sig);
	if (__mint < 7) {	/* compensate for a bug in MiNT 0.6 */
		(void)Syield();
	}
	if (r < 0) {
		errno = -r;
		return -1;
	}
	return 0;
}

