corda/sgx-jvm/avian/classpath/java-nio.cpp

237 lines
4.3 KiB
C++
Raw Normal View History

2015-03-13 18:52:59 +00:00
/* Copyright (c) 2008-2015, Avian Contributors
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
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include "jni.h"
2007-10-24 17:24:19 +00:00
#include "jni-util.h"
#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
#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
#define java_nio_channels_SelectionKey_OP_READ 1L
#define java_nio_channels_SelectionKey_OP_WRITE 4L
#define java_nio_channels_SelectionKey_OP_CONNECT 8L
#define java_nio_channels_SelectionKey_OP_ACCEPT 16L
#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;
}
namespace {
2014-07-11 15:50:18 +00:00
inline jbyteArray charsToArray(JNIEnv* e, const char* s)
{
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;
}
2014-07-11 15:50:18 +00:00
inline void doClose(int socket)
{
#ifdef PLATFORM_WINDOWS
closesocket(socket);
#else
close(socket);
#endif
}
2014-07-11 15:50:18 +00:00
inline jbyteArray errorString(JNIEnv* e, int n)
2007-10-23 17:22:48 +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));
#endif
2007-10-23 17:22:48 +00:00
}
2014-07-11 15:50:18 +00:00
inline jbyteArray errorString(JNIEnv* e)
{
#ifdef PLATFORM_WINDOWS
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);
#else
2007-10-23 23:22:42 +00:00
return errorString(e, errno);
#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);
}
void throwIOException(JNIEnv* e, jbyteArray a)
2007-10-23 17:22:48 +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-23 17:22:48 +00:00
throwIOException(e, errorString(e));
}
2014-07-11 15:50:18 +00:00
inline bool einProgress(int error)
{
#ifdef PLATFORM_WINDOWS
2014-07-11 15:50:18 +00:00
return error == WSAEINPROGRESS or error == WSAEWOULDBLOCK;
#else
return error == EINPROGRESS;
#endif
}
2014-07-11 15:50:18 +00:00
bool setBlocking(JNIEnv* e, int d, bool blocking)
{
#ifdef PLATFORM_WINDOWS
u_long a = (blocking ? 0 : 1);
int r = ioctlsocket(d, FIONBIO, &a);
2007-10-23 17:22:48 +00:00
if (r != 0) {
throwIOException(e);
return false;
}
#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)));
if (r < 0) {
throwIOException(e);
return false;
}
#endif
2007-10-23 17:22:48 +00:00
return true;
}
inline bool einProgress()
{
#ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK;
#else
return errno == EINPROGRESS;
#endif
}
inline bool eagain()
{
#ifdef PLATFORM_WINDOWS
return WSAGetLastError() == WSAEINPROGRESS
or WSAGetLastError() == WSAEWOULDBLOCK;
#else
return errno == EAGAIN;
#endif
}
2014-07-11 15:50:18 +00:00
} // namespace <anonymous>
namespace {
class Pipe {
public:
2014-07-11 15:50:18 +00:00
Pipe(JNIEnv* e)
{
if (::pipe(pipe) != 0) {
throwIOException(e);
return;
}
if (setBlocking(e, pipe[0], false)) {
setBlocking(e, pipe[1], false);
}
open_ = true;
}
2014-07-11 15:50:18 +00:00
void dispose()
{
::doClose(pipe[0]);
::doClose(pipe[1]);
open_ = false;
}
2014-07-11 15:50:18 +00:00
bool connected()
{
return open_;
}
2014-07-11 15:50:18 +00:00
int reader()
{
return pipe[0];
}
2014-07-11 15:50:18 +00:00
int writer()
{
return pipe[1];
}
private:
int pipe[2];
bool open_;
};
2014-07-11 15:50:18 +00:00
} // namespace
extern "C" JNIEXPORT jboolean JNICALL
2014-07-11 15:50:18 +00:00
Java_java_nio_ByteOrder_isNativeBigEndian(JNIEnv*, jclass)
{
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
#endif // !SGX