blob: 33f226791d29bc1a7db732d4848677d21afa105c [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.
*/
#include "defs.h"
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "JtuxSysVIPC.h" // generated by javah
#include "jtux_util.h"
#include "JNI_macros.h"
static bool field_jtoc_perm(JNIEnv *env, jclass cls, const char *field, jobject obj,
struct ipc_perm *perm)
{
jfieldID fid;
jclass clsperm = (*env)->FindClass(env, "jtux/USysVIPC$s_ipc_perm");
jobject objperm;
int mode;
if (cls == NULL || clsperm == NULL)
return false;
if ((fid = (*env)->GetFieldID(env, cls, field, "Ljtux/USysVIPC$s_ipc_perm;")) == NULL)
return false;
if ((objperm = (*env)->GetObjectField(env, obj, fid)) == NULL) {
JNU_ThrowByName(env, "NullPointerException", "s_ipc_perm field not initialized");
return false;
}
if (!field_jtoc_long(env, clsperm, "uid", objperm, &perm->uid))
return false;
if (!field_jtoc_long(env, clsperm, "gid", objperm, &perm->gid))
return false;
if (!field_jtoc_long(env, clsperm, "cuid", objperm, &perm->cuid))
return false;
if (!field_jtoc_long(env, clsperm, "cgid", objperm, &perm->cgid))
return false;
if (!field_jtoc_int(env, clsperm, "mode", objperm, &mode))
return false;
perm->mode = mode;
return true;
}
static bool field_ctoj_perm(JNIEnv *env, jclass cls, const char *field, jobject obj,
struct ipc_perm *perm)
{
jfieldID fid;
jclass clsperm = (*env)->FindClass(env, "jtux/USysVIPC$s_ipc_perm");
jobject objperm;
if (cls == NULL || clsperm == NULL)
return false;
if ((fid = (*env)->GetFieldID(env, cls, field, "Ljtux/USysVIPC$s_ipc_perm;")) == NULL)
return false;
if ((objperm = (*env)->GetObjectField(env, obj, fid)) == NULL) {
JNU_ThrowByName(env, "NullPointerException", "s_ipc_perm field not initialized");
return false;
}
if (!field_ctoj_long(env, clsperm, "uid", objperm, perm->uid))
return false;
if (!field_ctoj_long(env, clsperm, "gid", objperm, perm->gid))
return false;
if (!field_ctoj_long(env, clsperm, "cuid", objperm, perm->cuid))
return false;
if (!field_ctoj_long(env, clsperm, "cgid", objperm, perm->cgid))
return false;
if (!field_ctoj_int(env, clsperm, "mode", objperm, perm->mode))
return false;
return true;
}
JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_ftok(JNIEnv *env, jclass obj,
jstring path, jint id)
{
JSTR_GET_DECL(path_c, path)
key_t k;
JSTR_NULLTEST_V(path_c, -1)
JTHROW_neg1(k = ftok(path_c, id))
JSTR_REL(path_c, path)
return k;
}
JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msg_1set_1type(JNIEnv *env, jclass obj,
jlong msgtype, jbyteArray msgp)
{
void *msgp_c;
if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
return 0;
*(long *)msgp_c = (long)msgtype;
(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
return sizeof(long);
}
JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgctl(JNIEnv *env, jclass obj,
jint msqid, jint cmd, jobject data)
{
struct msqid_ds data_c;
jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_msqid_ds");
int n, r;
memset(&data_c, 0, sizeof(data_c));
if (cmd == IPC_SET) {
if (!field_jtoc_perm(env, cls, "msg_perm", data, &data_c.msg_perm))
return;
if (!field_jtoc_int(env, cls, "msg_qbytes", data, &n))
return;
data_c.msg_qbytes = n;
}
JTHROW_neg1(r = msgctl(msqid, cmd, &data_c))
if (r == -1)
return;
if (cmd == IPC_STAT) {
if (!field_ctoj_perm(env, cls, "msg_perm", data, &data_c.msg_perm))
return;
if (!field_ctoj_int(env, cls, "msg_qnum", data, data_c.msg_qnum))
return;
if (!field_ctoj_int(env, cls, "msg_qbytes", data, data_c.msg_qbytes))
return;
if (!field_ctoj_long(env, cls, "msg_lspid", data, data_c.msg_lspid))
return;
if (!field_ctoj_long(env, cls, "msg_lrpid", data, data_c.msg_lrpid))
return;
if (!field_ctoj_long(env, cls, "msg_stime", data, data_c.msg_stime))
return;
if (!field_ctoj_long(env, cls, "msg_rtime", data, data_c.msg_rtime))
return;
if (!field_ctoj_long(env, cls, "msg_ctime", data, data_c.msg_ctime))
return;
}
}
JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgget(JNIEnv *env, jclass obj,
jlong key, jint flags)
{
int msqid;
JTHROW_neg1(msqid = msgget(key, flags))
return msqid;
}
JNIEXPORT jint JNICALL Java_jtux_USysVIPC_msgrcv(JNIEnv *env, jclass obj,
jint msqid, jbyteArray msgp, jint mtextsize, jlong msgtype, jint flags)
{
void *msgp_c;
ssize_t nrcv;
if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
return -1;
JTHROW_neg1(nrcv = msgrcv(msqid, msgp_c, mtextsize, msgtype, flags))
(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
return nrcv;
}
JNIEXPORT void JNICALL Java_jtux_USysVIPC_msgsnd(JNIEnv *env, jclass obj,
jint msqid, jbyteArray msgp, jint msgsize, jint flags)
{
void *msgp_c;
if ((msgp_c = (*env)->GetByteArrayElements(env, msgp, NULL)) == NULL)
return;
JTHROW_neg1(msgsnd(msqid, msgp_c, msgsize, flags))
(*env)->ReleaseByteArrayElements(env, msgp, msgp_c, 0);
}
JNIEXPORT int JNICALL Java_jtux_USysVIPC_semctl(JNIEnv *env, jclass obj,
jint semid, jint semnum, jint cmd, jobject arg)
{
struct semid_ds data_c;
jclass cls_s_semid_ds = (*env)->FindClass(env, "jtux/USysVIPC$s_semid_ds");
jclass cls_u_semun_int = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_int");
jclass cls_u_semun_struct = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_struct");
jclass cls_u_semun_array = (*env)->FindClass(env, "jtux/USysVIPC$u_semun_array");
jfieldID fid;
jobject objds;
jshortArray array;
int r;
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} arg_c;
memset(&data_c, 0, sizeof(data_c));
switch (cmd) {
case IPC_SET:
if (cls_u_semun_struct == NULL)
return -1;
if ((fid = (*env)->GetFieldID(env, cls_u_semun_struct, "buf", "Ljtux/USysVIPC$s_semid_ds;")) == NULL)
return -1;
if ((objds = (*env)->GetObjectField(env, arg, fid)) == NULL) {
JNU_ThrowByName(env, "NullPointerException", "buf field not initialized");
return -1;
}
if (!field_jtoc_perm(env, cls_s_semid_ds, "sem_perm", objds, &data_c.sem_perm))
return -1;
/* fall through */
case IPC_STAT:
arg_c.buf = &data_c;
break;
case SETVAL:
if (!field_jtoc_int(env, cls_u_semun_int, "val", arg, &arg_c.val))
return -1;
break;
case SETALL:
case GETALL:
arg_c.buf = &data_c;
JTHROW_neg1(r = semctl(semid, 0, IPC_STAT, arg_c))
if (r == -1)
return -1;
if (cls_u_semun_array == NULL)
return -1;
if ((fid = (*env)->GetFieldID(env, cls_u_semun_array, "array", "[S")) == NULL)
return -1;
if ((array = (*env)->GetObjectField(env, arg, fid)) == NULL) {
JNU_ThrowByName(env, "NullPointerException", "array field not initialized");
return -1;
}
if ((arg_c.array = (*env)->GetShortArrayElements(env, array, NULL)) == NULL)
return -1;
}
JTHROW_neg1(r = semctl(semid, semnum, cmd, arg_c))
if (r == -1)
return r;
switch (cmd) {
case IPC_STAT:
if (cls_u_semun_struct == NULL)
return -1;
if ((fid = (*env)->GetFieldID(env, cls_u_semun_struct, "buf", "Ljtux/USysVIPC$s_semid_ds;")) == NULL)
return -1;
if ((objds = (*env)->GetObjectField(env, arg, fid)) == NULL) {
JNU_ThrowByName(env, "NullPointerException", "s_semid_ds field not initialized");
return -1;
}
if (!field_ctoj_perm(env, cls_s_semid_ds, "sem_perm", objds, &data_c.sem_perm))
return -1;
if (!field_ctoj_short(env, cls_s_semid_ds, "sem_nsems", objds, data_c.sem_nsems))
return -1;
if (!field_ctoj_long(env, cls_s_semid_ds, "sem_otime", objds, data_c.sem_otime))
return -1;
if (!field_ctoj_long(env, cls_s_semid_ds, "sem_ctime", objds, data_c.sem_ctime))
return -1;
break;
case SETALL:
(*env)->ReleaseShortArrayElements(env, array, arg_c.array, JNI_ABORT);
break;
case GETALL:
(*env)->ReleaseShortArrayElements(env, array, arg_c.array, 0);
}
return r;
}
JNIEXPORT jint JNICALL Java_jtux_USysVIPC_semget(JNIEnv *env, jclass obj,
jlong key, jint msems, jint flags)
{
int semid;
JTHROW_neg1(semid = semget(key, msems, flags))
return semid;
}
JNIEXPORT void JNICALL Java_jtux_USysVIPC_semop(JNIEnv *env, jclass obj,
jint semid, jobjectArray sops, jint nsops)
{
struct sembuf *sops_c;
int i;
jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_sembuf");
JTHROW_null(sops_c = malloc(nsops * sizeof(struct sembuf)))
if (sops_c == NULL)
return;
for (i = 0; i < nsops; i++) {
jobject sb_obj = (*env)->GetObjectArrayElement(env, sops, i);
if (sb_obj == NULL) {
free(sops_c);
return;
}
if (!field_jtoc_short(env, cls, "sem_num", sb_obj, &sops_c[i].sem_num))
return;
if (!field_jtoc_short(env, cls, "sem_op", sb_obj, &sops_c[i].sem_op))
return;
if (!field_jtoc_short(env, cls, "sem_flg", sb_obj, &sops_c[i].sem_flg))
return;
}
JTHROW_neg1(semop(semid, sops_c, nsops))
free(sops_c);
}
JNIEXPORT jlong JNICALL Java_jtux_USysVIPC_shmat(JNIEnv *env, jclass obj,
jint shmid, jlong shmaddr, jint flags)
{
intptr_t p;
JTHROW_neg1(p = (intptr_t)shmat(shmid, (const void *)(intptr_t)shmaddr, flags))
return p;
}
JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmctl(JNIEnv *env, jclass obj,
jint shmid, jint cmd, jobject data)
{
struct shmid_ds data_c;
jclass cls = (*env)->FindClass(env, "jtux/USysVIPC$s_shmid_ds");
int r;
memset(&data_c, 0, sizeof(data_c));
if (cmd == IPC_SET) {
if (!field_jtoc_perm(env, cls, "shm_perm", data, &data_c.shm_perm))
return;
}
JTHROW_neg1(r = shmctl(shmid, cmd, &data_c))
if (r == -1)
return;
if (cmd == IPC_STAT) {
if (!field_ctoj_perm(env, cls, "shm_perm", data, &data_c.shm_perm))
return;
if (!field_ctoj_int(env, cls, "shm_segsz", data, data_c.shm_segsz))
return;
if (!field_ctoj_long(env, cls, "shm_lpid", data, data_c.shm_lpid))
return;
if (!field_ctoj_long(env, cls, "shm_cpid", data, data_c.shm_cpid))
return;
if (!field_ctoj_int(env, cls, "shm_nattch", data, data_c.shm_nattch))
return;
if (!field_ctoj_long(env, cls, "shm_atime", data, data_c.shm_atime))
return;
if (!field_ctoj_long(env, cls, "shm_dtime", data, data_c.shm_dtime))
return;
if (!field_ctoj_long(env, cls, "shm_ctime", data, data_c.shm_ctime))
return;
}
}
JNIEXPORT void JNICALL Java_jtux_USysVIPC_shmdt(JNIEnv *env, jclass obj,
jlong shmaddr)
{
JTHROW_neg1(shmdt((void *)(intptr_t)shmaddr))
}
JNIEXPORT jint JNICALL Java_jtux_USysVIPC_shmget(JNIEnv *env, jclass obj,
jlong key, jint size, jint flags)
{
int shmid;
JTHROW_neg1(shmid = shmget(key, size, flags))
return shmid;
}