/*
	Copyright 2003 by Marc J. Rochkind. All rights reserved.
	May be copied only for purposes and under conditions described
	on the Web page www.basepath.com/aup/copyright.htm.

	The Example Files are provided "as is," without any warranty;
	without even the implied warranty of merchantability or fitness
	for a particular purpose. The author and his publisher are not
	responsible for any damages, direct or incidental, resulting
	from the use or non-use of these Example Files.

	The Example Files may contain defects, and some contain deliberate
	coding mistakes that were included for educational reasons.
	You are responsible for determining if and how the Example Files
	are to be used.

*/
#ifdef SOLARIS
// needed for setegid and seteuid
#define __EXTENSIONS__
#endif

/*
	Need to prevent GNU from using the wrong prototype for functions declared in
	sys/resource.h (see comment there). As sys/wait.h (included by defs.h) brings
	in this include (on GNU systems, anyway), there is a special symbol (AUP2_SKIP_WAIT)
	used in defs.h to suppress that include. Also, we should not have to undef __USE_GNU
	(I think), we seem to have to do that as well.

	(It would have been much better if the GNU folks had not tried to improve things!)
*/

#define AUP2_SKIP_WAIT
#include "defs.h"

#ifdef _GNU_SOURCE
#define _GNU_SOURCE_WAS_DEFINED
#undef _GNU_SOURCE
#undef __USE_GNU
#endif
#include <sys/resource.h>
#ifdef _GNU_SOURCE_WAS_DEFINED
#define _GNU_SOURCE
#undef _GNU_SOURCE_WAS_DEFINED
#endif

#include <sys/wait.h> // now it is OK to bring it in
#include <sys/times.h>
#include <pthread.h>
#include "JtuxProcess.h" // generated by javah
#include "JtuxProcess$sigset_t.h" // generated by javah
#include "jtux_util.h"
#include "JNI_macros.h"

static long get_max_pathname(const char *path)
{
	long max_path;
	errno = 0;
	max_path = pathconf(path, _PC_PATH_MAX);
	if (max_path == -1) {
		if (errno == 0)
			max_path = 4096; /* guess */
		else
			max_path = 4096; /* bury the error -- return guess here, too */
	}
	return max_path + 1;
}

JNIEXPORT jint JNICALL Java_jtux_UProcess_00024sigset_1t_GetSize_1sigset_1t(JNIEnv *env, jclass obj)
{

	return sizeof(sigset_t);
}

#if 0 // all obsolete -- get rid of this stuff
static jbyteArray get_bytearray_sigset(JNIEnv *env, jclass obj)
{
	jclass sigset_t_class = (*env)->FindClass(env, "jtux/UProcess$sigset_t");
	jfieldID fid;

	if (sigset_t_class == NULL)
		return NULL;
	if ((fid = (*env)->GetFieldID(env, sigset_t_class, "set", "[B")) == NULL)
		return NULL;
	return (*env)->GetObjectField(env, obj, fid);
}

static bool get_sigset(JNIEnv *env, jclass obj, sigset_t *set)
{
	jbyteArray bytes = get_bytearray_sigset(env, obj);

	if (bytes == NULL)
		return false;
	(*env)->GetByteArrayRegion(env, bytes, 0, sizeof(sigset_t), (jbyte *)set);
	return true;
}

static bool set_sigset(JNIEnv *env, jclass obj, sigset_t *set)
{
	jbyteArray bytes = get_bytearray_sigset(env, obj);

	if (bytes == NULL)
		return false;
	(*env)->SetByteArrayRegion(env, bytes, 0, sizeof(sigset_t), (jbyte *)set);
	return true;
}

JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigaddset(JNIEnv *env, jclass obj,
  jint signum)
{
	sigset_t set;

	if (!get_sigset(env, obj, &set))
		return;
	JTHROW_neg1(sigaddset(&set, signum))
	(void)set_sigset(env, obj, &set);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigdelset(JNIEnv *env, jclass obj,
  jint signum)
{
	sigset_t set;

	if (!get_sigset(env, obj, &set))
		return;
	JTHROW_neg1(sigdelset(&set, signum))
	(void)set_sigset(env, obj, &set);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigemptyset(JNIEnv *env, jclass obj)
{
	sigset_t set;

	if (!get_sigset(env, obj, &set))
		return;
	JTHROW_neg1(sigemptyset(&set))
	(void)set_sigset(env, obj, &set);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_00024sigset_1t_sigfillset(JNIEnv *env, jclass obj)
{
	sigset_t set;

	if (!get_sigset(env, obj, &set))
		return;
	JTHROW_neg1(sigfillset(&set))
	(void)set_sigset(env, obj, &set);
}

JNIEXPORT jboolean JNICALL Java_jtux_UProcess_00024sigset_1t_sigismember(JNIEnv *env, jclass obj,
  jint signum)
{
	sigset_t set;
	int r;

	if (!get_sigset(env, obj, &set))
		return;
	JTHROW_neg1(r = sigismember(&set, signum))
	return r != 0;
}
#endif// all obsolete -- get rid of this stuff

JNIEXPORT void JNICALL Java_jtux_UProcess_abort(JNIEnv *env, jclass obj)
{
	abort();
}

JNIEXPORT void JNICALL Java_jtux_UProcess_chdir(JNIEnv *env, jclass obj, jstring s)
{
	JSTR_GET_DECL(s_c, s)

	JSTR_NULLTEST(s_c)
	JTHROW_neg1(chdir(s_c))
	JSTR_REL(s_c, s)
}

JNIEXPORT void JNICALL Java_jtux_UProcess_chroot(JNIEnv *env, jclass obj, jstring s)
{
	JSTR_GET_DECL(s_c, s)

	JSTR_NULLTEST(s_c)
	JTHROW_neg1(chroot(s_c))
	JSTR_REL(s_c, s)
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_clock(JNIEnv *env, jclass obj)
{
	clock_t c;

	errno = 0; // because SUS doesn't say it's set
	JTHROW_neg1(c = clock())
	return c;
}

/**
	Calls ::clock.
*/
/* static  clock_t UProcess::clock(void)
{
	clock_t c;

	errno = 0;
	if ((c = ::clock()) == -1) {
		if (errno == 0)
			throw Error(EINVAL);
		else
			throw Error(errno);
	}
	return c;
}*/

JNIEXPORT void JNICALL Java_jtux_UProcess_execvp(JNIEnv *env, jclass obj, jstring s, jobjectArray a)
{
	JSTR_GET_DECL(s_c, s)
	const char **argv = NULL;
	int i, argc;
	jsize array_size = (*env)->GetArrayLength(env, a);
	jobject arg;

	JSTR_NULLTEST(s_c)
	for (argc = 0; argc < array_size && (*env)->GetObjectArrayElement(env, a, argc) != NULL; argc++)
		;
	argv = malloc((argc + 1) * sizeof(char *));
	if (argv == NULL) {
		(void)setup_throw_errno(env, errno);
		return;
	}
	for (i = 0; i < argc; i++) {
		arg = (*env)->GetObjectArrayElement(env, a, i);
		if ((*env)->ExceptionCheck(env)) { // why isn't this a check on arg == NULL?
			free(argv);
			JSTR_REL(s_c, s)
			return;
		}
		argv[i] = (*env)->GetStringUTFChars(env, arg, NULL);
	}
	argv[i] = NULL;
	JTHROW_neg1(execvp(s_c, (char **)argv))
	/*
		Release arguments only when execvp fails
		************ Code is suspect -- jython complains!
	*/
	for (i = 0; i < argc; i++)
		JSTR_REL(argv[i], (*env)->GetObjectArrayElement(env, a, i))
	JSTR_REL(s_c, s)
	free(argv);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_exit(JNIEnv *env, jclass obj, jint n)
{
	exit(n);
}

JNIEXPORT void JNICALL Java_jtux_UProcess__1exit(JNIEnv *env, jclass obj, jint n)
{
	_exit(n);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_fchdir(JNIEnv *env, jclass obj, jint n)
{
	JTHROW_neg1(fchdir(n))
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_fork(JNIEnv *env, jclass obj)
{
	jlong n;
	JavaVM *vm;

	(void)(*env)->GetJavaVM(env, &vm);
	JTHROW_neg1(n = fork())
	if (n == 0) {
		JNIEnv *envnew; // not clear what to do with this
		(void)(*vm)->AttachCurrentThread(vm, (void **)&envnew, NULL);
	}
	return n;
}

JNIEXPORT void JNICALL Java_jtux_UProcess_getcwd(JNIEnv *env, jclass obj, jobject path)
{
	char *pathbuf, *r;
	long maxpath;

	JTHROW_null(pathbuf = malloc(maxpath = get_max_pathname(".")))
	if (pathbuf == NULL)
		return;
	JTHROW_null(r = getcwd(pathbuf, maxpath))
	if (r != NULL)
		(void)string_buffer_set(env, path, pathbuf);
	free(pathbuf);
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getegid(JNIEnv *env, jclass obj)
{
	return getegid();
}

JNIEXPORT jstring JNICALL Java_jtux_UProcess_getenv(JNIEnv *env, jclass obj, jstring s)
{
	JSTR_GET_DECL(s_c, s)
	char *r = NULL;

	JSTR_NULLTEST_V(s_c, NULL)
	r = getenv(s_c);
	JSTR_REL(s_c, s)
	JSTR_RETURN(r)
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_geteuid(JNIEnv *env, jclass obj)
{
	return geteuid();
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getgid(JNIEnv *env, jclass obj)
{
	return getgid();
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getpgid(JNIEnv *env, jclass obj, jlong pid)
{
	long r;

	JTHROW_neg1(r = getpgid(pid))
	return r;
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getpid(JNIEnv *env, jclass obj)
{
	return getpid();
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getppid(JNIEnv *env, jclass obj)
{
	return getppid();
}

JNIEXPORT void JNICALL Java_jtux_UProcess_getrlimit(JNIEnv *env, jclass obj,
  jint resource, jobject rl)
{
	struct rlimit rlim;
	jclass rlclass = (*env)->FindClass(env, "jtux/UProcess$s_rlimit");
	jfieldID fid;

	if (rlclass == NULL)
		return;
	JTHROW_neg1(getrlimit(resource, &rlim))
	if ((*env)->ExceptionCheck(env))
		return;
	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_cur", "J")) == NULL)
		return;
	(*env)->SetLongField(env, rl, fid, rlim.rlim_cur);
	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_max", "J")) == NULL)
		return;
	(*env)->SetLongField(env, rl, fid, rlim.rlim_max);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_getrusage(JNIEnv *env, jclass obj,
  jint who, jobject r_usage)
{
	struct rusage ru;
	jclass ruclass = (*env)->FindClass(env, "jtux/UProcess$s_rusage");
	jclass tmsclass;
	jfieldID fid, fid_tv_sec, fid_tv_usec;
	jobject objtms;

	if (ruclass == NULL)
		return;
	JTHROW_neg1(getrusage(who, &ru))
	if ((*env)->ExceptionCheck(env))
		return;
	if ((tmsclass = (*env)->FindClass(env, "jtux/UProcess$s_timeval")) == NULL)
		return;
	if ((fid_tv_sec = (*env)->GetFieldID(env, tmsclass, "tv_sec", "J")) == NULL)
		return;
	if ((fid_tv_usec = (*env)->GetFieldID(env, tmsclass, "tv_usec", "J")) == NULL)
		return;
	// set ru_utime
	if ((fid = (*env)->GetFieldID(env, ruclass, "ru_utime", "Ljtux/UProcess$s_timeval;"))
	  == NULL)
		return;
	if ((objtms = (*env)->GetObjectField(env, r_usage, fid)) == NULL)
		return;
	(*env)->SetLongField(env, objtms, fid_tv_sec, ru.ru_utime.tv_sec);
	(*env)->SetLongField(env, objtms, fid_tv_usec, ru.ru_utime.tv_usec);
	// set ru_stime
	if ((fid = (*env)->GetFieldID(env, ruclass, "ru_stime", "Ljtux/UProcess$s_timeval;"))
	  == NULL)
		return;
	if ((objtms = (*env)->GetObjectField(env, r_usage, fid)) == NULL)
		return;
	(*env)->SetLongField(env, objtms, fid_tv_sec, ru.ru_stime.tv_sec);
	(*env)->SetLongField(env, objtms, fid_tv_usec, ru.ru_stime.tv_usec);
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getsid(JNIEnv *env, jclass obj, jlong pid)
{
	long r;

	JTHROW_neg1(r = getsid(pid))
	return r;
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_getuid(JNIEnv *env, jclass obj)
{
	return getuid();
}

JNIEXPORT void JNICALL Java_jtux_UProcess_kill(JNIEnv *env, jclass obj, jlong pid, jlong signum)
{
	JTHROW_neg1(kill(pid, (int)signum))
}

JNIEXPORT void JNICALL Java_jtux_UProcess_nice(JNIEnv *env, jclass obj, jint incr)
{
	JTHROW_neg1(nice(incr))
}

JNIEXPORT void JNICALL Java_jtux_UProcess_pause(JNIEnv *env, jclass obj)
{
	JTHROW_neg1(pause());
}

/*
	See comment for sigprocmask.
*/
JNIEXPORT void JNICALL Java_jtux_UProcess_pthread_1sigmask(JNIEnv *env, jclass obj, jint how,
  jobject set, jobject oset)
{
	(void)setup_throw_errno(env, ENOSYS);
#if 0 // not redone for new sigset_t approach
	sigset_t set_c, oset_c;

	if (get_sigset(env, set, &set_c)) {
		JTHROW_rv(pthread_sigmask(how, &set_c, &oset_c))
		if (!(*env)->ExceptionCheck(env) && oset != NULL)
			(void)set_sigset(env, oset, &oset_c);
	}
#endif
}

JNIEXPORT void JNICALL Java_jtux_UProcess_putenv(JNIEnv *env, jclass obj,
  jstring string)
{
	JSTR_GET_DECL(string_c, string)

	JSTR_NULLTEST(string_c)
	JTHROW_nzero(putenv((char *)string_c))
	// Do not release string_c -- it is now in the environment
}

JNIEXPORT void JNICALL Java_jtux_UProcess_setenv(JNIEnv *env, jclass obj,
  jstring var, jstring val, jboolean overwrite)
{
#if _XOPEN_VERSION >= 600 || defined(LINUX) || defined(FREEBSD)
	JSTR_GET_DECL(var_c, var)
	JSTR_GET_DECL(val_c, val)

	JSTR_NULLTEST(var_c)
	JSTR_NULLTEST(val_c)
	JTHROW_neg1(setenv(var_c, val_c, overwrite))
	JSTR_REL(var_c, var)
	JSTR_REL(var_c, val)
#else
	(void)setup_throw_errno(env, ENOSYS);
#endif
}

JNIEXPORT void JNICALL Java_jtux_UProcess_setegid(JNIEnv *env, jclass obj, jlong gid)
{
	JTHROW_neg1(setegid(gid))
}

JNIEXPORT void JNICALL Java_jtux_UProcess_seteuid(JNIEnv *env, jclass obj, jlong uid)
{
	JTHROW_neg1(seteuid(uid))
}

JNIEXPORT void JNICALL Java_jtux_UProcess_setgid(JNIEnv *env, jclass obj, jlong gid)
{
	JTHROW_neg1(setgid(gid))
}

JNIEXPORT void JNICALL Java_jtux_UProcess_setpgid(JNIEnv *env, jclass obj, jlong pid, jlong pgid)
{
	JTHROW_neg1(setpgid(pid, pgid))
}

JNIEXPORT void JNICALL Java_jtux_UProcess_setrlimit(JNIEnv *env, jclass obj,
  jint resource, jobject rl)
{
	struct rlimit rlim;
	jclass rlclass = (*env)->FindClass(env, "jtux/UProcess$s_rlimit");
	jfieldID fid;

	if (rlclass == NULL)
		return;
	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_cur", "J")) == NULL)
		return;
	rlim.rlim_cur = (*env)->GetLongField(env, rl, fid);
	if ((fid = (*env)->GetFieldID(env, rlclass, "rlim_max", "J")) == NULL)
		return;
	rlim.rlim_max = (*env)->GetLongField(env, rl, fid);
	JTHROW_neg1(setrlimit(resource, &rlim))
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_setsid(JNIEnv *env, jclass obj)
{
	long r;

	JTHROW_neg1(r = setsid())
	return r;
}

JNIEXPORT void JNICALL Java_jtux_UProcess_setuid(JNIEnv *env, jclass obj, jlong uid)
{
	JTHROW_neg1(setuid(uid))
}

JNIEXPORT jint JNICALL Java_jtux_UProcess_sig_1get_1SIGRTMIN(JNIEnv *env, jclass obj)
{
	return SIGRTMIN;
}

JNIEXPORT jint JNICALL Java_jtux_UProcess_sig_1get_1SIGRTMAX(JNIEnv *env, jclass obj)
{
	return SIGRTMAX;
}

static JavaVM *vm;

static void fcn_handler(int signum)
{
	JNIEnv *env;
	jmethodID mid_sig;
	jclass Processclass;

	(void)write(STDOUT_FILENO, "Got signal\n", 11);
	if ((*vm)->AttachCurrentThread(vm, (void **)&env, NULL) == 0) {
		Processclass = (*env)->FindClass(env, "jtux/UProcess");
		if (Processclass == NULL) {
			return;
		}
		mid_sig = (*env)->GetStaticMethodID(env, Processclass, "CatchSignal", "(I)V");
		if (mid_sig == NULL) {
			return;
		}
		(*env)->CallStaticVoidMethod(env, Processclass, mid_sig, (jint)signum);
	}
}

static void fcn_sigaction(int signum, siginfo_t *info, void *context)
{
	JNIEnv *env;
	jmethodID mid_sig;
	jclass cls_Process;

	(void)write(STDOUT_FILENO, "fcn_sigaction got signal\n", 25);
	{
		// Just a test -- not part of the algorithm.
		JavaVM *jvmbuf[100];
		jsize nvms;
		int i;

		if (JNI_GetCreatedJavaVMs(jvmbuf, sizeof(jvmbuf), &nvms) == -1)
			printf("JNI_GetCreatedJavaVMs failed");
		for (i = 0; i < nvms; i++)
			printf("JVM #%d: 0x%lx\n", i, (long)jvmbuf[i]);
		printf("JVM passed as vm: 0x%lx\n", (long)vm);
	}
	if ((*vm)->AttachCurrentThread(vm, (void **)&env, NULL) == 0) {
		jclass cls_siginfo_t = (*env)->FindClass(env, "jtux/UProcess$siginfo_t");
		jclass cls_u_sigval_int = (*env)->FindClass(env, "jtux/UProcess$u_sigval_int");
		jmethodID mid;
		jobject si = NULL, sval;

		if (cls_u_sigval_int == NULL) {
			fprintf(stderr, "*** Jtux: fcn_sigaction -- can't get class jtux/UProcess$cls_u_sigval_int\n");
			return;
		}
		if (cls_siginfo_t == NULL) {
			fprintf(stderr, "*** Jtux: fcn_sigaction -- can't get class jtux/UProcess$siginfo_t\n");
			return;
		}
		/*
			When a NewObject is created in this signal handler, it's passed OK to the
			Java signal handler, but later in another part of the program a child process
			waiting on a semaphore (totally unrelated) gets hung up (not even in a
			sem_wait). This indicates that something is seriously amiss. Until it's
			solved, this part is disabled so a 3-arg sa_sigaction handler can't get
			the info argument as anything other than NULL.
		*/
		if (info != NULL && false /* temporary disabling*/) {
			if ((mid = (*env)->GetMethodID(env, cls_siginfo_t, "<init>", "()V")) == NULL)
				return;
			if ((si = (*env)->NewObject(env, cls_siginfo_t, mid)) == NULL)
				return;
			if ((mid = (*env)->GetMethodID(env, cls_u_sigval_int, "<init>", "()V")) == NULL)
				return;
			if ((sval = (*env)->NewObject(env, cls_u_sigval_int, mid)) == NULL)
				return;
			if (!field_ctoj_int(env, cls_siginfo_t, "si_signo", si, info->si_signo))
				return;
			if (!field_ctoj_int(env, cls_siginfo_t, "si_errno", si, info->si_errno))
				return;
			if (!field_ctoj_int(env, cls_siginfo_t, "si_code", si, info->si_code))
				return;
			if (!field_ctoj_long(env, cls_siginfo_t, "si_pid", si, info->si_pid))
				return;
			if (!field_ctoj_long(env, cls_siginfo_t, "si_uid", si, info->si_uid))
				return;
			if (!field_ctoj_long(env, cls_siginfo_t, "si_addr", si, (intptr_t)info->si_addr))
				return;
			if (!field_ctoj_int(env, cls_siginfo_t, "si_status", si, info->si_status))
				return;
			if (!field_ctoj_long(env, cls_siginfo_t, "si_band", si, info->si_band))
				return;

			//	Always assume int, since there's no way to tell if the ptr member was used
			//	anyway.
			if (!field_ctoj_int(env, cls_u_sigval_int, "sival_int", sval, info->si_value.sival_int))
				return;
			if (!field_ctoj_object(env, cls_siginfo_t, "si_value", "Ljtux/UProcess$u_sigval;", si, sval))
				return;
		}
		if ((cls_Process = (*env)->FindClass(env, "jtux/UProcess")) == NULL)
			return;
		if ((mid_sig = (*env)->GetStaticMethodID(env, cls_Process, "CatchSignal", "(ILjtux/UProcess$siginfo_t;J)V"))
		  == NULL)
			return;
		(*env)->CallStaticVoidMethod(env, cls_Process, mid_sig, (jint)signum, si, (jlong)(intptr_t)context);
	}
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigaction_1x(JNIEnv *env, jclass obj, jint signum,
  jobject act, jobject oact)
{
	jclass sclass = (*env)->FindClass(env, "jtux/UProcess$s_sigaction");
	struct sigaction sigact;
	int actiontype;

#ifdef WANT_LIST_OF_SIGNALS
{
	int n;

	for (n = 1; n <= 30; n++) {
		if (sigaction(n, NULL, &sigact) == -1)
			continue;
		if (sigact.sa_handler == SIG_IGN || sigact.sa_handler == SIG_DFL)
			printf("%s is ignored or defaulted\n", get_macrostr("signal", n, NULL));
		else
			printf("%s is caught\n", get_macrostr("signal", n, NULL));
	}
}
#endif
	memset(&sigact, 0, sizeof(sigact));
	if (!field_jtoc_int(env, sclass, "sa_actiontype", act, &actiontype))
		return;
	if (!field_jtoc_int(env, sclass, "sa_flags", act, &sigact.sa_flags))
		return;
	if (actiontype == (int)SIG_IGN || actiontype == (int)SIG_DFL)
		sigact.sa_handler = (void (*)(int))actiontype;
	else if ((sigact.sa_flags & SA_SIGINFO) == SA_SIGINFO) {
		sigact.sa_sigaction = fcn_sigaction;
}
	else {
		sigact.sa_handler = fcn_handler;
}
	//pthread_sigmask(SIG_SETMASK, &sigact.sa_mask, NULL);
	JTHROW_neg1(sigaction(signum, &sigact, NULL))

#if 0
		int sa_actiontype;
		Method sa_handler;
		sigset_t sa_mask;
		int sa_flags;
#endif
	if ((*env)->GetJavaVM(env, &vm) < 0)
		return;


#if 0
	act.sa_handler = SIG_DFL;
	JTHROW_neg1(sigaction(SIGQUIT, &act, NULL))
#endif
	//printf("signals setup\n");
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigaddset(JNIEnv *env, jclass obj,
  jobject set, jint signum)
{
	jbyteArray ba;
	jbyte *b = get_sigset(env, set, &ba);

	if (b != NULL) {
		JTHROW_neg1(sigaddset((sigset_t *)b, signum))
		release_sigset(env, ba, b);
	}
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigaltstack(JNIEnv *env, jclass obj,
  jobject stack, jobject ostack)
{
	(void)setup_throw_errno(env, ENOSYS);
}
JNIEXPORT void JNICALL Java_jtux_UProcess_sigdelset(JNIEnv *env, jclass obj,
  jobject set, jint signum)
{
	jbyteArray ba;
	jbyte *b = get_sigset(env, set, &ba);

	if (b != NULL) {
		JTHROW_neg1(sigdelset((sigset_t *)b, signum))
		release_sigset(env, ba, b);
	}
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigemptyset(JNIEnv *env, jclass obj,
  jobject set)
{
	jbyteArray ba;
	jbyte *b = get_sigset(env, set, &ba);

	if (b != NULL) {
		JTHROW_neg1(sigemptyset((sigset_t *)b))
		release_sigset(env, ba, b);
	}
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigfillset(JNIEnv *env, jclass obj,
  jobject set)
{
	jbyteArray ba;
	jbyte *b = get_sigset(env, set, &ba);

	if (b != NULL) {
		JTHROW_neg1(sigfillset((sigset_t *)b))
		release_sigset(env, ba, b);
	}
}

JNIEXPORT void JNICALL Java_jtux_UProcess_siginterrupt(JNIEnv *env, jclass obj,
  jint signum, jint on)
{
	(void)setup_throw_errno(env, ENOSYS);
}

JNIEXPORT jboolean JNICALL Java_jtux_UProcess_sigismember(JNIEnv *env, jclass obj,
  jobject set, jint signum)
{
	jbyteArray ba;
	jbyte *b = get_sigset(env, set, &ba);
	int r = 0;

	if (b != NULL) {
		JTHROW_neg1(r = sigismember((sigset_t *)b, signum))
		release_sigset(env, ba, b);
	}
	return r != 0;
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigpending(JNIEnv *env, jclass obj, jobject set)
{
	jbyteArray ba;
	jbyte *b = get_sigset(env, set, &ba);

	if (b != NULL) {
		JTHROW_neg1(sigpending((sigset_t *)b))
		release_sigset(env, ba, b);
	}
}

/*
	Ineffective because of multithreaded JVM environment. Mask affects only thread, but
	other threads (over which we have no control) with the signal unblocked will still
	get the signal.
*/
JNIEXPORT void JNICALL Java_jtux_UProcess_sigprocmask(JNIEnv *env, jclass obj, jint how,
  jobject set, jobject oset)
{
	(void)setup_throw_errno(env, ENOSYS);
#if 0 // not redone for new sigset_t approach
	sigset_t set_c, oset_c;

#if 0
{
	sigset_t s;

	if (sigemptyset(&s) == -1 ||
	  sigaddset(&s, SIGPROF) == -1 ||
	  sigprocmask(SIG_SETMASK, &s, NULL) == -1 ||
	  kill(getpid(), SIGPROF) == -1)
		printf("bad sys call in Java_jtux_UProcess_sigprocmask\n");
	else
		printf("^^^^^^^^^^^^^^^^ I am still alive.\n");
}
#endif
	if (get_sigset(env, set, &set_c)) {
		JTHROW_neg1(sigprocmask(how, &set_c, &oset_c))
		if (!(*env)->ExceptionCheck(env) && oset != NULL)
			(void)set_sigset(env, oset, &oset_c);
	}
#endif
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigqueue(JNIEnv *env, jclass obj,
  jlong pid, jint signum, jobject value)
{
	(void)setup_throw_errno(env, ENOSYS);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigsuspend(JNIEnv *env, jclass obj,
  jobject set)
{
	(void)setup_throw_errno(env, ENOSYS);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigtimedwait(JNIEnv *env, jclass obj,
  jobject set, jobject info, jobject ts)
{
	(void)setup_throw_errno(env, ENOSYS);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigwait(JNIEnv *env, jclass obj,
  jobject set, jobject signum)
{
	(void)setup_throw_errno(env, ENOSYS);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_sigwaitinfo(JNIEnv *env, jclass obj,
  jobject set, jobject info)
{
	(void)setup_throw_errno(env, ENOSYS);
}

JNIEXPORT jint JNICALL Java_jtux_UProcess_system(JNIEnv *env, jclass obj, jstring s)
{
	JSTR_GET_DECL(s_c, s)
	jint n;

	JSTR_NULLTEST_V(s_c, -1)
	JTHROW_neg1(n = system(s_c))
	JSTR_REL(s_c, s)
	return n;
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_times(JNIEnv *env, jclass obj, jobject buffer)
{
	clock_t t;
	struct tms tbuf;
	jclass tmsclass = (*env)->FindClass(env, "jtux/UProcess$s_tms");

	JTHROW_neg1(t = times(&tbuf))
	if (!field_ctoj_long(env, tmsclass, "tms_utime", buffer, tbuf.tms_utime))
		return -1;
	if (!field_ctoj_long(env, tmsclass, "tms_stime", buffer, tbuf.tms_stime))
		return -1;
	if (!field_ctoj_long(env, tmsclass, "tms_cutime", buffer, tbuf.tms_cutime))
		return -1;
	if (!field_ctoj_long(env, tmsclass, "tms_cstime", buffer, tbuf.tms_cstime))
		return -1;
	return t;
}

JNIEXPORT jint JNICALL Java_jtux_UProcess_umask(JNIEnv *env, jclass obj,
  jint cmask)
{
	return umask(cmask);
}

JNIEXPORT void JNICALL Java_jtux_UProcess_unsetenv(JNIEnv *env, jclass obj,
  jstring var)
{
#if _XOPEN_VERSION >= 600 || defined(LINUX) || defined(FREEBSD)
	JSTR_GET_DECL(var_c, var)

	JSTR_NULLTEST(var_c)
	JTHROW_neg1(unsetenv(var_c))
	JSTR_REL(var_c, var)
#else
	(void)setup_throw_errno(env, ENOSYS);
#endif
}

JNIEXPORT jlong JNICALL Java_jtux_UProcess_waitpid(JNIEnv *env, jclass obj, jlong pid,
  jobject status, jint options)
{
	pid_t rtn_pid;
	int status_c;

	JTHROW_neg1(rtn_pid = waitpid(pid, &status_c, options))
	if (rtn_pid == -1)
		return -1;
	if (status != NULL) {
		jclass ExitStatusclass;
		jmethodID mid;

		ExitStatusclass = (*env)->GetObjectClass(env, status);
		if ((mid = (*env)->GetMethodID(env, ExitStatusclass, "set", "(I)V")) == NULL)
			return -1;
		(*env)->CallIntMethod(env, status, mid, status_c);
	}
	return rtn_pid;
}