示例#1
0
文件: jmdb.c 项目: cirnoworks/jmdb
/*
 * Class:     jmdb_DatabaseWrapper
 * Method:    cursorGet
 * Signature: (J[BII[BIII)V
 */
JNIEXPORT jlong JNICALL Java_jmdb_DatabaseWrapper_cursorGet(JNIEnv *vm,
		jclass clazz, jlong cursorL, jbyteArray keyA, jint kofs, jint klen,
		jbyteArray valueA, jint vofs, jint vlen, jint op) {
	MDB_cursor *cursorC = (MDB_cursor*) cursorL;
	enum {
		NONE, OOM, MDB, IOOB
	} result = NONE;
	jlong ret;
	jint code;
	char lenHolder[64];
	MDB_val key, value;

	jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL);
	jbyte *valueC = (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL);
	if (keyC == NULL || valueC == NULL) {
		result = OOM;
		ret = -1;
		code = 0;
	} else {
		key.mv_size = klen;
		key.mv_data = keyC + kofs;
		value.mv_size = 0;
		code = mdb_cursor_get(cursorC, &key, &value, op);
		if (code == MDB_NOTFOUND) {
			ret = -1;
		} else if (code) {
			result = MDB;
		} else if ((jlong) value.mv_size > vlen) {
			sprintf(lenHolder, "V%d/%d", (int ) value.mv_size, vlen);
			result = IOOB;
		} else if ((jlong) key.mv_size > klen) {
			sprintf(lenHolder, "K%d/%d", (int ) key.mv_size, klen);
			result = IOOB;
		} else {
			memcpy(keyC + kofs, key.mv_data, key.mv_size);
			memcpy(valueC + vofs, value.mv_data, value.mv_size);
			ret = ((((jlong) key.mv_size) & 0xffffffff) << 32)
					+ (((jlong) value.mv_size) & 0xffffffff);
		}
	}
	(*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0);
	(*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, 0);

	switch (result) {
	case NONE:
		return ret;
	case OOM:
		throwNew(vm, "java/lang/OutOfMemoryError", "");
		return -1;
	case MDB:
		throwDatabaseException(vm, code);
		return -1;
	case IOOB:
		throwNew(vm, "java/lang/IndexOutOfBoundsException", lenHolder);
		return -1;
	default:
		throwNew(vm, "java/lang/RuntimeException", "Flow control error in jni");
		return -1;
	}
}
示例#2
0
文件: jmdb.c 项目: cirnoworks/jmdb
/*
 * Class:     jmdb_DatabaseWrapper
 * Method:    get
 * Signature: (JI[BII[BII)I
 */
JNIEXPORT jint JNICALL Java_jmdb_DatabaseWrapper_get(JNIEnv *vm, jclass clazz,
		jlong txnL, jint dbi, jbyteArray keyA, jint kofs, jint klen,
		jbyteArray valueA, jint vofs, jint vlen) {
	MDB_txn *txnC = (MDB_txn*) txnL;
	enum {
		NONE, OOM, MDB, IOOB
	} result = NONE;
	jint ret;
	char lenHolder[64];
	MDB_val key, value;

	jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL);
	jbyte *valueC = (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL);
	if (keyC == NULL || valueC == NULL) {
		result = OOM;
		ret = -1;
	} else {
		key.mv_size = klen;
		key.mv_data = keyC + kofs;
		ret = mdb_get(txnC, (MDB_dbi) dbi, &key, &value);
		if (ret == MDB_NOTFOUND) {
			ret = -1;
		} else if (ret) {
			result = MDB;
		} else if ((jlong) value.mv_size > vlen) {
			sprintf(lenHolder, "V%d/%d", (int ) value.mv_size, vlen);
			result = IOOB;
		} else if ((jlong) key.mv_size > klen) {
			sprintf(lenHolder, "K%d/%d", (int ) key.mv_size, klen);
			result = IOOB;
		} else {
			memcpy(valueC + vofs, value.mv_data, value.mv_size);
			ret = value.mv_size;
		}
	}
	(*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0);
	(*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, JNI_ABORT);

	switch (result) {
	case NONE:
		return ret;
	case OOM:
		throwNew(vm, "java/lang/OutOfMemoryError", "");
		return -1;
	case MDB:
		throwDatabaseException(vm, ret);
		return -1;
	case IOOB:
		throwNew(vm, "java/lang/IndexOutOfBoundsException", lenHolder);
		return -1;
	default:
		throwNew(vm, "java/lang/RuntimeException", "Flow control error in jni");
		return -1;
	}
}
示例#3
0
文件: jmdb.c 项目: cirnoworks/jmdb
/*
 * Class:     jmdb_DatabaseWrapper
 * Method:    del
 * Signature: (JI[BII[BII)V
 */
JNIEXPORT jboolean JNICALL Java_jmdb_DatabaseWrapper_del(JNIEnv *vm,
		jclass clazz, jlong txnL, jint dbi, jbyteArray keyA, jint kofs,
		jint klen, jbyteArray valueA, jint vofs, jint vlen) {
	MDB_txn *txnC = (MDB_txn*) txnL;
	enum {
		NONE, OOM, MDB
	} result = NONE;
	jint ret;
	MDB_val key, value;

	jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL);
	jbyte *valueC =
			valueA ? (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL) : NULL;
	if (keyC == NULL || (valueA && valueC == NULL)) {
		result = OOM;
		ret = 0; //make gcc happy
	} else {
		key.mv_size = klen;
		key.mv_data = keyC + kofs;
		if (valueA) {
			value.mv_size = vlen;
			value.mv_data = valueC + vofs;
			ret = mdb_del(txnC, (MDB_dbi) dbi, &key, &value);
		} else {
			ret = mdb_del(txnC, (MDB_dbi) dbi, &key, NULL);
		}
		if (ret == MDB_NOTFOUND) {
			ret = 0;
		} else if (ret) {
			result = MDB;
		} else {
			ret = 1;
		}
	}
	if (valueA) {
		(*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0);
	}
	(*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, JNI_ABORT);

	switch (result) {
	case NONE:
		return ret;
	case OOM:
		throwNew(vm, "java/lang/OutOfMemoryError", "");
		return 0;
	case MDB:
		throwDatabaseException(vm, ret);
		return 0;
	default:
		throwNew(vm, "java/lang/RuntimeException", "Flow control error in jni");
		return 0;
	}
}
示例#4
0
SOCKET accept(JNIEnv* e, SOCKET sock, long* client_addr, short* client_port)
{
  sockaddr_in adr;
  SOCKET client_socket = ::accept(sock, (sockaddr*)&adr, NULL);
  if (INVALID_SOCKET == client_socket) {
    char buf[255];
    sprintf(buf,
            "Can't accept the incoming connection. System error: %d",
            last_socket_error());
    throwNew(e, "java/io/IOException", buf);
    return INVALID_SOCKET;
  }

  if (client_addr != NULL) {
#ifdef PLATFORM_WINDOWS
    *client_addr = ntohl(adr.sin_addr.S_un.S_addr);
#else
    *client_addr = ntohl(adr.sin_addr.s_addr);
#endif
  }

  if (client_port != NULL) {
    *client_port = ntohs(adr.sin_port);
  }

  return client_socket;
}
示例#5
0
文件: jmdb.c 项目: cirnoworks/jmdb
/*
 * Class:     jmdb_DatabaseWrapper
 * Method:    envInfo
 * Signature: (JLjava/nio/ByteBuffer;)V
 */
JNIEXPORT void JNICALL Java_jmdb_DatabaseWrapper_envInfo(JNIEnv *vm,
		jclass clazz, jlong envL, jobject buf) {
	MDB_env *envC = (MDB_env*) envL;
	MDB_envinfo info;
	jsize size = (*vm)->GetArrayLength(vm, buf);
	jlong *bufC;
	if (size < JMDB_INFO_SIZE) {
		throwNew(vm, "java/lang/IndexOutOfBoundsException",
				"info[]'s length is less than MDB_info's entries");
		return;
	}
	int code = mdb_env_info(envC, &info);
	if (code) {
		throwDatabaseException(vm, code);
		return;
	}
	bufC = (*vm)->GetPrimitiveArrayCritical(vm, buf, NULL);
	bufC[0] = (jlong) info.me_mapaddr;
	bufC[1] = (jlong) info.me_mapsize;
	bufC[2] = (jlong) info.me_last_pgno;
	bufC[3] = (jlong) info.me_last_txnid;
	bufC[4] = (jlong) info.me_maxreaders;
	bufC[5] = (jlong) info.me_numreaders;
	(*vm)->ReleasePrimitiveArrayCritical(vm, buf, bufC, 0);
}
示例#6
0
文件: jmdb.c 项目: cirnoworks/jmdb
/*
 * Class:     jmdb_DatabaseWrapper
 * Method:    stat
 * Signature: (JILjava/nio/ByteBuffer;)V
 */
JNIEXPORT void JNICALL Java_jmdb_DatabaseWrapper_stat(JNIEnv *vm, jclass clazz,
		jlong txnL, jint dbi, jobject buf) {
	MDB_txn *txnC = (MDB_txn*) txnL;
	MDB_stat stat;
	jsize size = (*vm)->GetArrayLength(vm, buf);
	jlong *bufC;
	if (size < JMDB_STAT_SIZE) {
		throwNew(vm, "java/lang/IndexOutOfBoundsException",
				"stat[]'s length is less than MDB_stat's entries");
		return;
	}
	int code = mdb_stat(txnC, (MDB_dbi) dbi, &stat);
	if (code) {
		throwDatabaseException(vm, code);
		return;
	}
	bufC = (*vm)->GetPrimitiveArrayCritical(vm, buf, NULL);
	bufC[0] = stat.ms_psize;
	bufC[1] = stat.ms_depth;
	bufC[2] = stat.ms_branch_pages;
	bufC[3] = stat.ms_leaf_pages;
	bufC[4] = stat.ms_overflow_pages;
	bufC[5] = stat.ms_entries;
	(*vm)->ReleasePrimitiveArrayCritical(vm, buf, bufC, 0);
}
示例#7
0
extern "C" JNIEXPORT void JNICALL
    Java_java_util_zip_Deflater_deflate(JNIEnv* e,
                                        jclass,
                                        jlong peer,
                                        jbyteArray input,
                                        jint inputOffset,
                                        jint inputLength,
                                        jbyteArray output,
                                        jint outputOffset,
                                        jint outputLength,
                                        jboolean finish,
                                        jintArray results)
{
  z_stream* s = reinterpret_cast<z_stream*>(peer);

  jbyte* in = static_cast<jbyte*>(malloc(inputLength));
  if (in == 0) {
    throwNew(e, "java/lang/OutOfMemoryError", 0);
    return;
  }

  jbyte* out = static_cast<jbyte*>(malloc(outputLength));
  if (out == 0) {
    free(in);
    throwNew(e, "java/lang/OutOfMemoryError", 0);
    return;
  }

  e->GetByteArrayRegion(input, inputOffset, inputLength, in);

  s->next_in = reinterpret_cast<Bytef*>(in);
  s->avail_in = inputLength;
  s->next_out = reinterpret_cast<Bytef*>(out);
  s->avail_out = outputLength;

  int r = deflate(s, finish ? Z_FINISH : Z_NO_FLUSH);
  jint resultArray[3] = {r,
                         static_cast<jint>(inputLength - s->avail_in),
                         static_cast<jint>(outputLength - s->avail_out)};

  free(in);

  e->SetByteArrayRegion(output, outputOffset, resultArray[2], out);
  free(out);

  e->SetIntArrayRegion(results, 0, 3, resultArray);
}
示例#8
0
void abort(JNIEnv* e, SOCKET sock)
{
  if (SOCKET_ERROR == ::closesocket(sock)) {
    char buf[255];
    sprintf(
        buf, "Can't close the socket. System error: %d", last_socket_error());
    throwNew(e, "java/io/IOException", buf);
  }
}
示例#9
0
void send(JNIEnv* e, SOCKET sock, const char* buff_ptr, int buff_size)
{
  if (SOCKET_ERROR == ::send(sock, buff_ptr, buff_size, 0)) {
    char buf[255];
    sprintf(buf,
            "Can't send data through the socket. System error: %d",
            last_socket_error());
    throwNew(e, "java/io/IOException", buf);
    return;
  }
}
示例#10
0
文件: java-lang.cpp 项目: dscho/avian
extern "C" JNIEXPORT jint JNICALL
    Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  DWORD exitCode;
  WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
  BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
  if (not success) {
    throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
  }

  CloseHandle(reinterpret_cast<HANDLE>(pid));
  CloseHandle(reinterpret_cast<HANDLE>(tid));

  return exitCode;
#else
  throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
  return -1;
#endif
}
示例#11
0
void close_output(JNIEnv* e, SOCKET sock)
{
  if (SOCKET_ERROR == ::shutdown(sock, SD_SEND)) {
    int errcode = last_socket_error();
    if (errcode != ENOTCONN) {
      char buf[255];
      sprintf(buf, "Can't shutdown the socket. System error: %d", errcode);
      throwNew(e, "java/io/IOException", buf);
    }
  }
}
JNIEXPORT void JNICALL Java_quickfix_SocketAcceptor_start
( JNIEnv *pEnv, jobject obj )
{ QF_STACK_TRY

  JVM::set( pEnv );
  try
  {
    getCPPSocketAcceptor( obj ) ->start();
  }
  catch( FIX::ConfigError &e )
  {
    throwNew( "Lquickfix/ConfigError;", e.what() );
  }
  catch( FIX::RuntimeError &e )
  {
    throwNew( "Lquickfix/RuntimeError;", e.what() );
  }

  QF_STACK_CATCH
}
示例#13
0
extern "C" JNIEXPORT jlong JNICALL
    Java_java_util_zip_Inflater_make(JNIEnv* e, jclass, jboolean nowrap)
{
  z_stream* s = static_cast<z_stream*>(malloc(sizeof(z_stream)));
  if (s == 0) {
    throwNew(e, "java/lang/OutOfMemoryError", 0);
    return 0;
  }

  memset(s, 0, sizeof(z_stream));

  int r = inflateInit2(s, (nowrap ? -15 : 15));
  if (r != Z_OK) {
    free(s);
    throwNew(e, "java/lang/RuntimeException", zError(r));
    return 0;
  }

  return reinterpret_cast<jlong>(s);
}
JNIEXPORT void JNICALL Java_quickfix_ThreadedSocketInitiator_block
( JNIEnv *pEnv, jobject obj )
{ QF_STACK_TRY

  JVM::set( pEnv );
  try
  {
    getCPPThreadedSocketInitiator( obj ) ->block();
  }
  catch( FIX::ConfigError &e )
  {
    throwNew( "Lquickfix/ConfigError;", e.what() );
  }
  catch( FIX::RuntimeError &e )
  {
    throwNew( "Lquickfix/RuntimeError;", e.what() );
  }

  QF_STACK_CATCH
}
JNIEXPORT jboolean JNICALL Java_quickfix_ThreadedSocketInitiator_poll
( JNIEnv *pEnv, jobject obj )
{ QF_STACK_TRY

  JVM::set( pEnv );
  try
  {
    return getCPPThreadedSocketInitiator( obj ) ->poll();
  }
  catch( FIX::ConfigError &e )
  {
    throwNew( "Lquickfix/ConfigError;", e.what() );
  }
  catch( FIX::RuntimeError &e )
  {
    throwNew( "Lquickfix/RuntimeError;", e.what() );
  }
  return false;

  QF_STACK_CATCH
}
示例#16
0
SOCKET create(JNIEnv* e)
{
  SOCKET sock;
  if (INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) {
    char buf[255];
    sprintf(
        buf, "Can't create a socket. System error: %d", last_socket_error());
    throwNew(e, "java/io/IOException", buf);
    return 0;  // This doesn't matter cause we have risen an exception
  }
  return sock;
}
示例#17
0
int recv(JNIEnv* e, SOCKET sock, char* buff_ptr, int buff_size)
{
  int length = ::recv(sock, buff_ptr, buff_size, 0);
  if (SOCKET_ERROR == length) {
    char buf[255];
    sprintf(buf,
            "Can't receive data through the socket. System error: %d",
            last_socket_error());
    throwNew(e, "java/io/IOException", buf);
    return 0;  // This doesn't matter cause we have risen an exception
  }
  return length;
}
示例#18
0
void init(JNIEnv* ONLY_ON_WINDOWS(e))
{
#ifdef PLATFORM_WINDOWS
  static bool wsaInitialized = false;
  if (not wsaInitialized) {
    WSADATA data;
    int r = WSAStartup(MAKEWORD(2, 2), &data);
    if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) {
      throwNew(e, "java/io/IOException", "WSAStartup failed");
    } else {
      wsaInitialized = true;
    }
  }
#endif
}
示例#19
0
extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
  DWORD exitCode;
  WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
  BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
  if(not success){
    throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
  }

  CloseHandle(reinterpret_cast<HANDLE>(pid));
  CloseHandle(reinterpret_cast<HANDLE>(tid));

  return exitCode;
}
示例#20
0
extern "C" JNIEXPORT jlong JNICALL
Java_java_nio_channels_SocketSelector_natInit(JNIEnv* e, jclass)
{
  void *mem = malloc(sizeof(SelectorState));
  if (mem) {
    SelectorState *s = new (mem) SelectorState(e);
    if (e->ExceptionCheck()) return 0;

    if (s) {
      FD_ZERO(&(s->read));
      FD_ZERO(&(s->write));
      FD_ZERO(&(s->except));
      return reinterpret_cast<jlong>(s);
    }
  }
  throwNew(e, "java/lang/OutOfMemoryError", 0);
  return 0;
}
示例#21
0
void bind(JNIEnv* e, SOCKET sock, long addr, short port)
{
  sockaddr_in adr;
  adr.sin_family = AF_INET;
#ifdef PLATFORM_WINDOWS
  adr.sin_addr.S_un.S_addr = htonl(addr);
#else
  adr.sin_addr.s_addr = htonl(addr);
#endif
  adr.sin_port = htons(port);

  if (SOCKET_ERROR == ::bind(sock, (sockaddr*)&adr, sizeof(adr))) {
    char buf[255];
    sprintf(buf, "Can't bind a socket. System error: %d", last_socket_error());
    throwNew(e, "java/io/IOException", buf);
    return;
  }
}
JNIEXPORT void JNICALL Java_quickfix_ThreadedSocketInitiator_create
( JNIEnv *pEnv, jobject obj )
{ QF_STACK_TRY

  JVM::set( pEnv );
  JVMObject jobject( obj );

  JavaLogFactory* pLogFactory = 0;
  try
  { pLogFactory = &createLogFactory( jobject ); }
  catch ( JVMException& ) {}

  FIX::Initiator* pInitiator = 0;

  try
  {
    if ( pLogFactory )
    {
      pInitiator = new FIX::ThreadedSocketInitiator(
                    createApplication( jobject ),
                    createFactory( jobject ),
                    getSettings( jobject ),
                    *pLogFactory );
    }
    else
    {
      pInitiator = new FIX::ThreadedSocketInitiator(
                    createApplication( jobject ),
                    createFactory( jobject ),
                    getSettings( jobject ));
    }
  }
  catch( FIX::ConfigError& e )
  {
    throwNew( "Lquickfix/ConfigError;", e.what() );
    return;
  }

  jobject.setLong( "cppPointer", ( long ) pInitiator );

  QF_STACK_CATCH
}
示例#23
0
文件: jmdb.c 项目: cirnoworks/jmdb
/*
 * Class:     jmdb_DatabaseWrapper
 * Method:    cursorPut
 * Signature: (J[BII[BIII)V
 */
JNIEXPORT void JNICALL Java_jmdb_DatabaseWrapper_cursorPut(JNIEnv *vm,
		jclass clazz, jlong cursorL, jbyteArray keyA, jint kofs, jint klen,
		jbyteArray valueA, jint vofs, jint vlen, jint flags) {
	MDB_cursor *cursorC = (MDB_cursor*) cursorL;
	enum {
		NONE, OOM, MDB
	} result = NONE;
	jint ret;
	MDB_val key, value;

	jbyte *keyC = (*vm)->GetPrimitiveArrayCritical(vm, keyA, NULL);
	jbyte *valueC = (*vm)->GetPrimitiveArrayCritical(vm, valueA, NULL);
	if (keyC == NULL || valueC == NULL) {
		result = OOM;
		ret = -1;
	} else {
		key.mv_size = klen;
		key.mv_data = keyC + kofs;
		value.mv_size = vlen;
		value.mv_data = valueC + vofs;
		ret = mdb_cursor_put(cursorC, &key, &value, (unsigned int) flags);
		if (ret) {
			result = MDB;
		}
	}
	(*vm)->ReleasePrimitiveArrayCritical(vm, valueA, valueC, 0);
	(*vm)->ReleasePrimitiveArrayCritical(vm, keyA, keyC, JNI_ABORT);

	switch (result) {
	case NONE:
		return;
	case OOM:
		throwNew(vm, "java/lang/OutOfMemoryError", "");
		return;
	case MDB:
		throwDatabaseException(vm, ret);
		return;
	}
}
示例#24
0
extern "C" JNIEXPORT void JNICALL 
Java_java_lang_Runtime_exec(JNIEnv* e, jclass, 
                            jobjectArray command, jlongArray process)
{
  
  int size = 0;
  for (int i = 0; i < e->GetArrayLength(command); ++i){
    jstring element = (jstring) e->GetObjectArrayElement(command, i);
    size += e->GetStringUTFLength(element) + 1;
  } 
   
  RUNTIME_ARRAY(char, line, size);
  char* linep = RUNTIME_ARRAY_BODY(line);
  for (int i = 0; i < e->GetArrayLength(command); ++i) {
    if (i) *(linep++) = _T(' ');
    jstring element = (jstring) e->GetObjectArrayElement(command, i);
    const char* s =  e->GetStringUTFChars(element, 0);
#ifdef _MSC_VER
    _tcscpy_s(linep, size - (linep - RUNTIME_ARRAY_BODY(line)), s);
#else
    _tcscpy(linep, s);
#endif
    e->ReleaseStringUTFChars(element, s);
    linep += e->GetStringUTFLength(element);
  }
  *(linep++) = _T('\0');
 
  HANDLE in[] = { 0, 0 };
  HANDLE out[] = { 0, 0 };
  HANDLE err[] = { 0, 0 };
  
  makePipe(e, in);
  SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
  jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
  if(e->ExceptionCheck()) return;
  e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
  makePipe(e, out);
  SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
  jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
  if(e->ExceptionCheck()) return;
  e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
  makePipe(e, err);
  SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
  jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
  if(e->ExceptionCheck()) return;
  e->SetLongArrayRegion(process, 4, 1, &errDescriptor);
  
  PROCESS_INFORMATION pi;
  ZeroMemory(&pi, sizeof(pi));
 
  STARTUPINFO si;
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdOutput = in[1];
  si.hStdInput = out[0];
  si.hStdError = err[1];
 
  BOOL success = CreateProcess(0, (LPSTR) RUNTIME_ARRAY_BODY(line), 0, 0, 1,
                               CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                               0, 0, &si, &pi);

  CloseHandle(in[1]);
  CloseHandle(out[0]);
  CloseHandle(err[1]);
  
  if (not success) {
    throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    return;
  }
  
  jlong pid = reinterpret_cast<jlong>(pi.hProcess);
  e->SetLongArrayRegion(process, 0, 1, &pid);
  jlong tid = reinterpret_cast<jlong>(pi.hThread);  
  e->SetLongArrayRegion(process, 1, 1, &tid);
}
示例#25
0
文件: java-lang.cpp 项目: dscho/avian
extern "C" JNIEXPORT void JNICALL
    Java_java_lang_Runtime_exec(JNIEnv* e,
                                jclass,
                                jobjectArray command,
                                jlongArray process)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  int size = 0;
  for (int i = 0; i < e->GetArrayLength(command); ++i) {
    jstring element = (jstring)e->GetObjectArrayElement(command, i);
    if (element) {
      // worst case, assuming every character is '"', and we escape all of them
      size += 2 * e->GetStringUTFLength(element) + 3;
    } else {
      throwNew(e,
               "java/lang/NullPointerException",
               strdup("null string array element"));
    }
  }

  RUNTIME_ARRAY(char, line, size);
  char* linep = RUNTIME_ARRAY_BODY(line);
  for (int i = 0; i < e->GetArrayLength(command); ++i) {
    if (i)
      *(linep++) = _T(' ');
    jstring element = (jstring)e->GetObjectArrayElement(command, i);
    const char* s = e->GetStringUTFChars(element, 0);

    copyAndEscape(&linep, s, e->GetStringUTFLength(element));

    e->ReleaseStringUTFChars(element, s);
  }
  *(linep++) = _T('\0');

  HANDLE in[] = {0, 0};
  HANDLE out[] = {0, 0};
  HANDLE err[] = {0, 0};

  makePipe(e, in);
  SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
  jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
  if (e->ExceptionCheck())
    return;
  e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
  makePipe(e, out);
  SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
  jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
  if (e->ExceptionCheck())
    return;
  e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
  makePipe(e, err);
  SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
  jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
  if (e->ExceptionCheck())
    return;
  e->SetLongArrayRegion(process, 4, 1, &errDescriptor);

  PROCESS_INFORMATION pi;
  ZeroMemory(&pi, sizeof(pi));

  STARTUPINFO si;
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdOutput = in[1];
  si.hStdInput = out[0];
  si.hStdError = err[1];

  BOOL success = CreateProcess(0,
                               (LPSTR)RUNTIME_ARRAY_BODY(line),
                               0,
                               0,
                               1,
                               CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                               0,
                               0,
                               &si,
                               &pi);

  CloseHandle(in[1]);
  CloseHandle(out[0]);
  CloseHandle(err[1]);

  if (not success) {
    throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    return;
  }

  jlong pid = reinterpret_cast<jlong>(pi.hProcess);
  e->SetLongArrayRegion(process, 0, 1, &pid);
  jlong tid = reinterpret_cast<jlong>(pi.hThread);
  e->SetLongArrayRegion(process, 1, 1, &tid);
#else
  throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}