|
40 | 40 | #endif |
41 | 41 | #ifdef __APPLE__ |
42 | 42 | #include <serial/ioss.h>//Needed for IOSSIOSPEED in Mac OS X (Non standard baudrate) |
43 | | -#elif !defined(HAVE_POLL) |
44 | | - // Seems as poll has some portability issues on OsX (Search for "poll" in |
45 | | - // "https://cr.yp.to/docs/unixport.html"). So we only make use of poll on |
46 | | - // all platforms except "__APPLE__". |
47 | | - // If you want to force usage of 'poll', pass "-DHAVE_POLL=1" to gcc. |
48 | | - #define HAVE_POLL 1 |
49 | 43 | #endif |
50 | 44 |
|
51 | | -#if HAVE_POLL == 0 |
52 | | - #include <sys/select.h> |
53 | | -#else |
54 | | - #include <poll.h> |
55 | | -#endif |
| 45 | +#include <sys/select.h> |
56 | 46 |
|
57 | 47 | #include <jni.h> |
58 | 48 | #include <jssc_SerialNativeInterface.h> |
@@ -527,15 +517,23 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR |
527 | 517 | */ |
528 | 518 | JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes |
529 | 519 | (JNIEnv *env, jobject, jlong portHandle, jbyteArray buffer){ |
530 | | - jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); |
| 520 | + jbyte* jBuffer = NULL; |
531 | 521 | jint bufferSize = env->GetArrayLength(buffer); |
532 | 522 | fd_set write_fd_set; |
533 | 523 | int byteRemains = bufferSize; |
534 | 524 | struct timeval timeout; |
535 | 525 | int result; |
536 | 526 | jclass threadClass = env->FindClass("java/lang/Thread"); |
537 | 527 | jmethodID areWeInterruptedMethod = env->GetStaticMethodID(threadClass, "interrupted", "()Z"); |
538 | | - |
| 528 | + |
| 529 | + if (portHandle < 0 || portHandle > FD_SETSIZE) { |
| 530 | + char msg[95]; |
| 531 | + snprintf(msg, sizeof msg, "select(): file descriptor %ld outside expected range 0..%d", portHandle, FD_SETSIZE); |
| 532 | + return env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), msg); |
| 533 | + } |
| 534 | + |
| 535 | + jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); |
| 536 | + |
539 | 537 | while(byteRemains > 0) { |
540 | 538 |
|
541 | 539 | // Check if the java thread has been interrupted, and if so, throw the exception |
@@ -576,70 +574,29 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes |
576 | 574 | return JNI_TRUE; //result == bufferSize ? JNI_TRUE : JNI_FALSE; |
577 | 575 | } |
578 | 576 |
|
579 | | -/** |
580 | | - * Waits until 'read()' has something to tell for the specified filedescriptor. |
581 | | - */ |
582 | | -/* |
583 | | -static void awaitReadReady(JNIEnv*, jlong fd){ |
584 | | -#if HAVE_POLL == 0 |
585 | | - // Alternative impl using 'select' as 'poll' isn't available (or broken). |
586 | | -
|
587 | | - //assert(fd < FD_SETSIZE); // <- Might help when hunting SEGFAULTs. |
588 | | - fd_set readFds; |
589 | | - while(true) { |
590 | | - FD_ZERO(&readFds); |
591 | | - FD_SET(fd, &readFds); |
592 | | - int result = select(fd + 1, &readFds, NULL, NULL, NULL); |
593 | | - if(result < 0){ |
594 | | - // man select: On error, -1 is returned, and errno is set to indicate the error |
595 | | - // TODO: Maybe a candidate to raise a java exception. But won't do |
596 | | - // yet for backward compatibility. |
597 | | - continue; |
598 | | - } |
599 | | - // Did wait successfully. |
600 | | - break; |
601 | | - } |
602 | | - FD_CLR(fd, &readFds); |
603 | | -
|
604 | | -#else |
605 | | - // Default impl using 'poll'. This is more robust against fd>=1024 (eg |
606 | | - // SEGFAULT problems). |
607 | | -
|
608 | | - struct pollfd fds[1]; |
609 | | - fds[0].fd = fd; |
610 | | - fds[0].events = POLLIN; |
611 | | - while(true){ |
612 | | - int result = poll(fds, 1, -1); |
613 | | - if(result < 0){ |
614 | | - // man poll: On error, -1 is returned, and errno is set to indicate the error. |
615 | | - // TODO: Maybe a candidate to raise a java exception. But won't do |
616 | | - // yet for backward compatibility. |
617 | | - continue; |
618 | | - } |
619 | | - // Did wait successfully. |
620 | | - break; |
621 | | - } |
622 | 577 |
|
623 | | -#endif |
624 | | -} |
625 | | -*/ |
626 | | - |
627 | | -/* OK */ |
628 | 578 | /* |
629 | 579 | * Reading data from the port |
630 | | - * |
631 | | - * Rewritten to use poll() instead of select() to handle fd>=1024 |
632 | 580 | */ |
633 | 581 | JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes |
634 | 582 | (JNIEnv *env, jobject, jlong portHandle, jint byteCount){ |
635 | 583 | fd_set read_fd_set; |
636 | | - jbyte *lpBuffer = new jbyte[byteCount]; |
| 584 | + jbyte *lpBuffer = NULL; |
637 | 585 | int byteRemains = byteCount; |
638 | 586 | struct timeval timeout; |
639 | 587 | int result; |
640 | 588 | jclass threadClass = env->FindClass("java/lang/Thread"); |
641 | 589 | jmethodID areWeInterruptedMethod = env->GetStaticMethodID(threadClass, "interrupted", "()Z"); |
642 | | - |
| 590 | + |
| 591 | + if (portHandle < 0 || portHandle > FD_SETSIZE) { |
| 592 | + char msg[95]; |
| 593 | + snprintf(msg, sizeof msg, "select(): file descriptor %ld outside expected range 0..%d", portHandle, FD_SETSIZE); |
| 594 | + env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), msg); |
| 595 | + return NULL; |
| 596 | + } |
| 597 | + |
| 598 | + lpBuffer = new jbyte[byteCount]; |
| 599 | + |
643 | 600 | while(byteRemains > 0) { |
644 | 601 |
|
645 | 602 | // Check if the java thread has been interrupted, and if so, throw the exception |
|
0 commit comments