JNIEXPORT jint JNICALL JNI_OnLoad()

in src/main/c/Posix/SerialPort_Posix.c [244:354]


JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
{
	// Retrieve the JNI environment and class
	JNIEnv *env;
	jint jniVersion = JNI_VERSION_1_2;
	if ((*jvm)->GetEnv(jvm, (void**)&env, jniVersion))
		return JNI_ERR;
	serialCommClass = (*env)->FindClass(env, "com/fazecast/jSerialComm/SerialPort");
	if (!serialCommClass) return JNI_ERR;
	jniErrorClass = (*env)->FindClass(env, "java/lang/Exception");
	if (!jniErrorClass) return JNI_ERR;

	// Cache Java fields as global references
	serialCommConstructor = (*env)->GetMethodID(env, serialCommClass, "<init>", "()V");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	serialPortFdField = (*env)->GetFieldID(env, serialCommClass, "portHandle", "J");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	vendorIdField = (*env)->GetFieldID(env, serialCommClass, "vendorID", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	productIdField = (*env)->GetFieldID(env, serialCommClass, "productID", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	serialNumberField = (*env)->GetFieldID(env, serialCommClass, "serialNumber", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	manufacturerField = (*env)->GetFieldID(env, serialCommClass, "manufacturer", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	deviceDriverField = (*env)->GetFieldID(env, serialCommClass, "deviceDriver", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	isSymlinkField = (*env)->GetFieldID(env, serialCommClass, "isPathSymlink", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	portLocationField = (*env)->GetFieldID(env, serialCommClass, "portLocation", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	autoFlushIOBuffersField = (*env)->GetFieldID(env, serialCommClass, "autoFlushIOBuffers", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	parityField = (*env)->GetFieldID(env, serialCommClass, "parity", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	flowControlField = (*env)->GetFieldID(env, serialCommClass, "flowControl", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	disableExclusiveLockField = (*env)->GetFieldID(env, serialCommClass, "disableExclusiveLock", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	requestElevatedPermissionsField = (*env)->GetFieldID(env, serialCommClass, "requestElevatedPermissions", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485ModeControlEnabledField = (*env)->GetFieldID(env, serialCommClass, "rs485ModeControlEnabled", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485EnableTerminationField = (*env)->GetFieldID(env, serialCommClass, "rs485EnableTermination", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485RxDuringTxField = (*env)->GetFieldID(env, serialCommClass, "rs485RxDuringTx", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	xonStartCharField = (*env)->GetFieldID(env, serialCommClass, "xonStartChar", "B");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	xoffStopCharField = (*env)->GetFieldID(env, serialCommClass, "xoffStopChar", "B");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	readTimeoutField = (*env)->GetFieldID(env, serialCommClass, "readTimeout", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	writeTimeoutField = (*env)->GetFieldID(env, serialCommClass, "writeTimeout", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	eventFlagsField = (*env)->GetFieldID(env, serialCommClass, "eventFlags", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;

	// Disable handling of various POSIX signals
	sigset_t blockMask;
	memset(&blockMask, 0, sizeof(blockMask));
	struct sigaction ignoreAction = { 0 };
	ignoreAction.sa_handler = SIG_IGN;
	ignoreAction.sa_mask = blockMask;
	sigaction(SIGIO, &ignoreAction, NULL);
	sigaction(SIGHUP, &ignoreAction, NULL);
	sigaction(SIGCONT, &ignoreAction, NULL);
	sigaction(SIGUSR1, &ignoreAction, NULL);
	sigaction(SIGUSR2, &ignoreAction, NULL);
	sigaction(SIGTTOU, &ignoreAction, NULL);
	sigaction(SIGTTIN, &ignoreAction, NULL);

	// Initialize the critical section lock
	pthread_mutex_init(&criticalSection, NULL);
	classInitialized = 1;
	return jniVersion;
}