2015-03-13 18:52:59 +00:00
|
|
|
/* Copyright (c) 2008-2015, Avian Contributors
|
2008-02-19 18:06:52 +00:00
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2017-01-19 16:55:54 +00:00
|
|
|
#ifndef SGX
|
|
|
|
|
2007-10-05 21:32:56 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2011-06-01 19:56:03 +00:00
|
|
|
#include "jni.h"
|
2007-10-24 17:24:19 +00:00
|
|
|
#include "jni-util.h"
|
|
|
|
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2014-07-11 15:50:18 +00:00
|
|
|
#include <winsock2.h>
|
|
|
|
#include <ws2tcpip.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define snprintf sprintf_s
|
|
|
|
#else
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
2007-10-05 21:32:56 +00:00
|
|
|
#else
|
2014-07-11 15:50:18 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
#include <sys/select.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <sys/socket.h>
|
2007-10-24 17:24:19 +00:00
|
|
|
#endif
|
2007-10-05 21:32:56 +00:00
|
|
|
|
|
|
|
#define java_nio_channels_SelectionKey_OP_READ 1L
|
|
|
|
#define java_nio_channels_SelectionKey_OP_WRITE 4L
|
2009-10-08 22:26:20 +00:00
|
|
|
#define java_nio_channels_SelectionKey_OP_CONNECT 8L
|
2007-10-05 21:32:56 +00:00
|
|
|
#define java_nio_channels_SelectionKey_OP_ACCEPT 16L
|
|
|
|
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2007-10-23 17:22:48 +00:00
|
|
|
typedef int socklen_t;
|
|
|
|
#endif
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
inline void* operator new(size_t, void* p) throw()
|
|
|
|
{
|
|
|
|
return p;
|
|
|
|
}
|
2008-10-10 17:49:07 +00:00
|
|
|
|
2007-10-05 21:32:56 +00:00
|
|
|
namespace {
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
inline jbyteArray charsToArray(JNIEnv* e, const char* s)
|
2007-10-05 21:32:56 +00:00
|
|
|
{
|
2007-10-23 17:22:48 +00:00
|
|
|
unsigned length = strlen(s);
|
|
|
|
jbyteArray a = e->NewByteArray(length + 1);
|
|
|
|
e->SetByteArrayRegion(a, 0, length + 1, reinterpret_cast<const jbyte*>(s));
|
|
|
|
return a;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
inline void doClose(int socket)
|
2009-08-27 00:26:44 +00:00
|
|
|
{
|
2010-06-05 00:45:13 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2009-08-27 00:26:44 +00:00
|
|
|
closesocket(socket);
|
2010-06-05 00:45:13 +00:00
|
|
|
#else
|
|
|
|
close(socket);
|
2009-08-27 00:26:44 +00:00
|
|
|
#endif
|
2010-06-05 00:45:13 +00:00
|
|
|
}
|
2009-08-27 00:26:44 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
inline jbyteArray errorString(JNIEnv* e, int n)
|
2007-10-23 17:22:48 +00:00
|
|
|
{
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
const unsigned size = 128;
|
|
|
|
char buffer[size];
|
|
|
|
strerror_s(buffer, size, n);
|
|
|
|
return charsToArray(e, buffer);
|
|
|
|
#else
|
2007-10-23 17:22:48 +00:00
|
|
|
return charsToArray(e, strerror(n));
|
2009-08-27 00:26:44 +00:00
|
|
|
#endif
|
2007-10-23 17:22:48 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
inline jbyteArray errorString(JNIEnv* e)
|
2007-10-05 21:32:56 +00:00
|
|
|
{
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2007-10-05 21:32:56 +00:00
|
|
|
const unsigned size = 64;
|
|
|
|
char buffer[size];
|
|
|
|
snprintf(buffer, size, "wsa code: %d", WSAGetLastError());
|
2007-10-23 17:22:48 +00:00
|
|
|
return charsToArray(e, buffer);
|
2007-10-05 21:32:56 +00:00
|
|
|
#else
|
2007-10-23 23:22:42 +00:00
|
|
|
return errorString(e, errno);
|
2007-10-05 21:32:56 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void throwIOException(JNIEnv* e, const char* s)
|
2007-10-23 17:22:48 +00:00
|
|
|
{
|
|
|
|
throwNew(e, "java/io/IOException", s);
|
|
|
|
}
|
|
|
|
|
2014-04-24 21:10:35 +00:00
|
|
|
void throwIOException(JNIEnv* e, jbyteArray a)
|
2007-10-23 17:22:48 +00:00
|
|
|
{
|
2014-04-24 21:10:35 +00:00
|
|
|
size_t length = e->GetArrayLength(a);
|
|
|
|
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
|
|
|
|
if (buf) {
|
|
|
|
e->GetByteArrayRegion(a, 0, length, reinterpret_cast<jbyte*>(buf));
|
|
|
|
throwIOException(e, reinterpret_cast<const char*>(buf));
|
|
|
|
free(buf);
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
2007-10-23 17:22:48 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void throwIOException(JNIEnv* e)
|
2007-10-05 21:32:56 +00:00
|
|
|
{
|
2007-10-23 17:22:48 +00:00
|
|
|
throwIOException(e, errorString(e));
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
inline bool einProgress(int error)
|
2009-10-12 15:28:04 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
2014-07-11 15:50:18 +00:00
|
|
|
return error == WSAEINPROGRESS or error == WSAEWOULDBLOCK;
|
2009-10-12 15:28:04 +00:00
|
|
|
#else
|
|
|
|
return error == EINPROGRESS;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
bool setBlocking(JNIEnv* e, int d, bool blocking)
|
2007-10-05 21:32:56 +00:00
|
|
|
{
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2009-08-03 14:58:56 +00:00
|
|
|
u_long a = (blocking ? 0 : 1);
|
2007-10-05 21:32:56 +00:00
|
|
|
int r = ioctlsocket(d, FIONBIO, &a);
|
2007-10-23 17:22:48 +00:00
|
|
|
if (r != 0) {
|
|
|
|
throwIOException(e);
|
|
|
|
return false;
|
|
|
|
}
|
2007-10-05 21:32:56 +00:00
|
|
|
#else
|
2014-07-11 15:50:18 +00:00
|
|
|
int r = fcntl(d,
|
|
|
|
F_SETFL,
|
|
|
|
(blocking ? (fcntl(d, F_GETFL) & (~O_NONBLOCK))
|
|
|
|
: (fcntl(d, F_GETFL) | O_NONBLOCK)));
|
2007-10-05 21:32:56 +00:00
|
|
|
if (r < 0) {
|
|
|
|
throwIOException(e);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
2007-10-23 17:22:48 +00:00
|
|
|
return true;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2017-11-21 17:06:18 +00:00
|
|
|
inline bool einProgress()
|
2007-10-05 21:32:56 +00:00
|
|
|
{
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2017-11-21 17:06:18 +00:00
|
|
|
return WSAGetLastError() == WSAEINPROGRESS
|
|
|
|
or WSAGetLastError() == WSAEWOULDBLOCK;
|
2007-10-05 21:32:56 +00:00
|
|
|
#else
|
2017-11-21 17:06:18 +00:00
|
|
|
return errno == EINPROGRESS;
|
2007-10-05 21:32:56 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-11-21 17:06:18 +00:00
|
|
|
inline bool eagain()
|
2007-10-05 21:32:56 +00:00
|
|
|
{
|
2009-08-27 00:26:44 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2017-11-21 17:06:18 +00:00
|
|
|
return WSAGetLastError() == WSAEINPROGRESS
|
|
|
|
or WSAGetLastError() == WSAEWOULDBLOCK;
|
2007-10-05 21:32:56 +00:00
|
|
|
#else
|
2017-11-21 17:06:18 +00:00
|
|
|
return errno == EAGAIN;
|
2007-10-05 21:32:56 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace <anonymous>
|
2007-10-05 21:32:56 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class Pipe {
|
|
|
|
public:
|
2014-07-11 15:50:18 +00:00
|
|
|
Pipe(JNIEnv* e)
|
|
|
|
{
|
2007-10-05 21:32:56 +00:00
|
|
|
if (::pipe(pipe) != 0) {
|
|
|
|
throwIOException(e);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-08-03 14:58:56 +00:00
|
|
|
if (setBlocking(e, pipe[0], false)) {
|
|
|
|
setBlocking(e, pipe[1], false);
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
2009-10-05 15:23:53 +00:00
|
|
|
|
|
|
|
open_ = true;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void dispose()
|
|
|
|
{
|
2010-06-05 00:45:13 +00:00
|
|
|
::doClose(pipe[0]);
|
|
|
|
::doClose(pipe[1]);
|
2009-10-05 15:23:53 +00:00
|
|
|
open_ = false;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
bool connected()
|
|
|
|
{
|
2009-10-05 15:23:53 +00:00
|
|
|
return open_;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int reader()
|
|
|
|
{
|
2007-10-05 21:32:56 +00:00
|
|
|
return pipe[0];
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int writer()
|
|
|
|
{
|
2007-10-05 21:32:56 +00:00
|
|
|
return pipe[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int pipe[2];
|
2009-10-05 15:23:53 +00:00
|
|
|
bool open_;
|
2007-10-05 21:32:56 +00:00
|
|
|
};
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace
|
2007-10-05 21:32:56 +00:00
|
|
|
|
2012-11-11 05:04:11 +00:00
|
|
|
extern "C" JNIEXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Java_java_nio_ByteOrder_isNativeBigEndian(JNIEnv*, jclass)
|
2012-11-11 05:04:11 +00:00
|
|
|
{
|
|
|
|
union {
|
|
|
|
uint32_t i;
|
|
|
|
char c[4];
|
|
|
|
} u = {0x01020304};
|
|
|
|
|
|
|
|
if (u.c[0] == 1)
|
|
|
|
return JNI_TRUE;
|
|
|
|
return JNI_FALSE;
|
|
|
|
}
|
2017-01-19 16:55:54 +00:00
|
|
|
|
2017-11-21 17:06:18 +00:00
|
|
|
#endif // !SGX
|