blob: 2756203b9d3c6275d66a0724b3473271387efb56 [file] [log] [blame]
/*
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;
}