<commit_before>#include "math.h"
#include "stdlib.h"
#include "sys/time.h"
#include "time.h"
#include "time.h"
#include "string.h"
#include "stdio.h"
#include "stdint.h"
#include "jni.h"
#include "jni-util.h"
#include "errno.h"
#include "fcntl.h"
#include "unistd.h"

#ifdef WIN32
#  include "windows.h"
#  include "winbase.h"
#  include "io.h"
#  include "tchar.h"
#  define SO_PREFIX ""
#else
#  define SO_PREFIX "lib"
#include "sys/wait.h"
#endif

#ifdef __APPLE__
#  define SO_SUFFIX ".jnilib"
#elif defined WIN32
#  define SO_SUFFIX ".dll"
#else
#  define SO_SUFFIX ".so"
#endif

namespace {
#ifdef WIN32
  char* getErrorStr(DWORD err){
    // The poor man's error string, just print the error code 
    char * errStr = (char*) malloc(9 * sizeof(char));
    snprintf(errStr, 9, "%d", (int) err);
    return errStr;
    
    // The better way to do this, if I could figure out how to convert LPTSTR to char*
    //char* errStr;
    //LPTSTR s;
    //if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
    //                 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, &s, 0, NULL) == 0)
    //{
    //  errStr.Format("Unknown error occurred (%08x)", err);
    //} else {
    //  errStr = s;
    //}
    //return errStr;
  }

  void makePipe(JNIEnv* e, HANDLE p[2])
  {
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = 1;
    sa.lpSecurityDescriptor = 0;
  
    BOOL success = CreatePipe(p, p + 1, &sa, 0);
    if (not success) {
      throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    }
  }
  
  int descriptor(JNIEnv* e, HANDLE h)
  {
    int fd = _open_osfhandle(reinterpret_cast<long>(h), 0);
    if (fd == -1) {
      throwNew(e, "java/io/IOException", strerror(errno));
    }
    return fd;
  }
#else
  void makePipe(JNIEnv* e, int p[2])
  {
    if(pipe(p) != 0) {
      throwNew(e, "java/io/IOException", strerror(errno));
    }
  }
  
  void safeClose(int &fd)
  {
    if(fd != -1) close(fd);
    fd = -1;
  }
  
  void close(int p[2])
  {
    ::close(p[0]);
    ::close(p[1]);
  }
  
  void clean(JNIEnv* e, jobjectArray command, char** p)
  {
    int i = 0;
    for(char** x = p; *x; ++x, ++i){
      jstring element = (jstring) e->GetObjectArrayElement(command, i);
      e->ReleaseStringUTFChars(element, *x);
    }
    free(p);
  }
#endif  
}

#ifdef WIN32
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;
  } 
   
  char line[size];
  char* linep = 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);
    _tcscpy(linep, s);
    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->ExceptionOccurred()) return;
  e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
  makePipe(e, out);
  SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
  jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
  if(e->ExceptionOccurred()) return;
  e->SetLongArrayRegion(process, 2, 1, &outDescriptor);
  makePipe(e, err);
  SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
  jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
  if(e->ExceptionOccurred()) return;
  e->SetLongArrayRegion(process, 3, 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) line, 0, 0, 1,
                               CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                               0, 0, &si, &pi);
  
  if (not success) {
    throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    return;
  }
  
  jlong pid = reinterpret_cast<jlong>(pi.hProcess);
  e->SetLongArrayRegion(process, 0, 1, &pid);
  
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
{
  DWORD exitCode;
  BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
  if(not success){
    throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
  } else if(exitCode == STILL_ACTIVE){
    throwNew(e, "java/lang/IllegalThreadStateException", "Process is still active");
  }
  return exitCode;
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
{
  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()));
  }
  return exitCode;
}
#else
extern "C" JNIEXPORT void JNICALL 
Java_java_lang_Runtime_exec(JNIEnv* e, jclass, 
                            jobjectArray command, jlongArray process)
{
  char** argv = static_cast<char**>(malloc((e->GetArrayLength(command) + 1) * sizeof(char*)));
  int i;
  for(i = 0; i < e->GetArrayLength(command); i++){
    jstring element = (jstring) e->GetObjectArrayElement(command, i);
    char* s = const_cast<char*>(e->GetStringUTFChars(element, 0));
    argv[i] = s;
  }
  argv[i] = 0;
  
  int in[] = { -1, -1 };
  int out[] = { -1, -1 };
  int err[] = { -1, -1 };
  int msg[] = { -1, -1 };
  
  makePipe(e, in);
  if(e->ExceptionOccurred()) return;
  jlong inDescriptor = static_cast<jlong>(in[0]);
  e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
  makePipe(e, out);
  if(e->ExceptionOccurred()) return;
  jlong outDescriptor = static_cast<jlong>(out[1]);
  e->SetLongArrayRegion(process, 1, 1, &outDescriptor);
  makePipe(e, err);
  if(e->ExceptionOccurred()) return;
  jlong errDescriptor = static_cast<jlong>(err[0]);
  e->SetLongArrayRegion(process, 1, 1, &errDescriptor);
  makePipe(e, msg);
  if(e->ExceptionOccurred()) return;
  if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) {
    throwNew(e, "java/io/IOException", strerror(errno));
    return;
  }
  
  pid_t pid = fork();
  switch(pid){
  case -1: // error
    throwNew(e, "java/io/IOException", strerror(errno));
    return;
  case 0: { // child
    // Setup stdin, stdout and stderr
    dup2(in[1], 1);
    close(in);
    dup2(out[0], 0);
    close(out);
    dup2(err[1], 2);
    close(err);
    close(msg[0]);
    
    execvp(argv[0], argv);
    
    // Error if here
    char c = errno;
    write(msg[1], &c, 1);
    exit(127);
  } break;
    
  default: { //parent
    jlong JNIPid = static_cast<jlong>(pid);
    e->SetLongArrayRegion(process, 0, 1, &JNIPid);
    
    safeClose(in[1]);
    safeClose(out[0]);
    safeClose(err[1]);
    safeClose(msg[1]);
      
    char c;
    int r = read(msg[0], &c, 1);
    if(r == -1) {
      throwNew(e, "java/io/IOException", strerror(errno));
      return;
    } else if(r) {
      throwNew(e, "java/io/IOException", strerror(c));
      return;
    }
  } break;
  }
  
  safeClose(msg[0]);
  clean(e, command, argv);
  
  fcntl(in[0], F_SETFD, FD_CLOEXEC);
  fcntl(out[1], F_SETFD, FD_CLOEXEC);
  fcntl(err[0], F_SETFD, FD_CLOEXEC);
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
{
  int status;
  pid_t returned = waitpid(pid, &status, WNOHANG);
  if(returned == 0){
    throwNew(e, "java/lang/IllegalThreadStateException", strerror(errno));
  } else if(returned == -1){
    throwNew(e, "java/lang/Exception", strerror(errno));
  } 
  
  return WEXITSTATUS(status);
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid)
{
  bool finished = false;
  int status;
  int exitCode;
  while(!finished){
    waitpid(pid, &status, 0);
    if(WIFEXITED(status)){
      finished = true;
      exitCode = WEXITSTATUS(status);
    } else if(WIFSIGNALED(status)){
      finished = true;
      exitCode = -1;
    }
  }
  
  return exitCode;
}
#endif

extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
                                  jbooleanArray found)
{
  jstring r = 0;
  const char* chars = e->GetStringUTFChars(name, 0);
  if (chars) {
#ifdef WIN32 
    if (strcmp(chars, "line.separator") == 0) {
      r = e->NewStringUTF("\r\n");
    } else if (strcmp(chars, "file.separator") == 0) {
      r = e->NewStringUTF("\\");
    } else if (strcmp(chars, "os.name") == 0) {
      r = e->NewStringUTF("windows");
    } else if (strcmp(chars, "java.io.tmpdir") == 0) {
      TCHAR buffer[MAX_PATH];
      GetTempPath(MAX_PATH, buffer);
      r = e->NewStringUTF(buffer);
    } else if (strcmp(chars, "user.home") == 0) {
      LPWSTR home = _wgetenv(L"USERPROFILE");
      r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
    }
#else
    if (strcmp(chars, "line.separator") == 0) {
      r = e->NewStringUTF("\n");
    } else if (strcmp(chars, "file.separator") == 0) {
      r = e->NewStringUTF("/");
    } else if (strcmp(chars, "os.name") == 0) {
      r = e->NewStringUTF("posix");
    } else if (strcmp(chars, "java.io.tmpdir") == 0) {
      r = e->NewStringUTF("/tmp");
    } else if (strcmp(chars, "user.home") == 0) {
      r = e->NewStringUTF(getenv("HOME"));      
    }
#endif

    e->ReleaseStringUTFChars(name, chars);
  }

  if (r) {
    jboolean v = true;
    e->SetBooleanArrayRegion(found, 0, 1, &v);
  }

  return r;
}<commit_msg>use more conventional os.name properties<commit_after>#include "math.h"
#include "stdlib.h"
#include "sys/time.h"
#include "time.h"
#include "time.h"
#include "string.h"
#include "stdio.h"
#include "stdint.h"
#include "jni.h"
#include "jni-util.h"
#include "errno.h"
#include "fcntl.h"
#include "unistd.h"

#ifdef WIN32
#  include "windows.h"
#  include "winbase.h"
#  include "io.h"
#  include "tchar.h"
#  define SO_PREFIX ""
#else
#  define SO_PREFIX "lib"
#include "sys/wait.h"
#endif

#ifdef __APPLE__
#  define SO_SUFFIX ".jnilib"
#elif defined WIN32
#  define SO_SUFFIX ".dll"
#else
#  define SO_SUFFIX ".so"
#endif

namespace {
#ifdef WIN32
  char* getErrorStr(DWORD err){
    // The poor man's error string, just print the error code 
    char * errStr = (char*) malloc(9 * sizeof(char));
    snprintf(errStr, 9, "%d", (int) err);
    return errStr;
    
    // The better way to do this, if I could figure out how to convert LPTSTR to char*
    //char* errStr;
    //LPTSTR s;
    //if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
    //                 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, &s, 0, NULL) == 0)
    //{
    //  errStr.Format("Unknown error occurred (%08x)", err);
    //} else {
    //  errStr = s;
    //}
    //return errStr;
  }

  void makePipe(JNIEnv* e, HANDLE p[2])
  {
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = 1;
    sa.lpSecurityDescriptor = 0;
  
    BOOL success = CreatePipe(p, p + 1, &sa, 0);
    if (not success) {
      throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    }
  }
  
  int descriptor(JNIEnv* e, HANDLE h)
  {
    int fd = _open_osfhandle(reinterpret_cast<long>(h), 0);
    if (fd == -1) {
      throwNew(e, "java/io/IOException", strerror(errno));
    }
    return fd;
  }
#else
  void makePipe(JNIEnv* e, int p[2])
  {
    if(pipe(p) != 0) {
      throwNew(e, "java/io/IOException", strerror(errno));
    }
  }
  
  void safeClose(int &fd)
  {
    if(fd != -1) close(fd);
    fd = -1;
  }
  
  void close(int p[2])
  {
    ::close(p[0]);
    ::close(p[1]);
  }
  
  void clean(JNIEnv* e, jobjectArray command, char** p)
  {
    int i = 0;
    for(char** x = p; *x; ++x, ++i){
      jstring element = (jstring) e->GetObjectArrayElement(command, i);
      e->ReleaseStringUTFChars(element, *x);
    }
    free(p);
  }
#endif  
}

#ifdef WIN32
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;
  } 
   
  char line[size];
  char* linep = 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);
    _tcscpy(linep, s);
    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->ExceptionOccurred()) return;
  e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
  makePipe(e, out);
  SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
  jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
  if(e->ExceptionOccurred()) return;
  e->SetLongArrayRegion(process, 2, 1, &outDescriptor);
  makePipe(e, err);
  SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
  jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
  if(e->ExceptionOccurred()) return;
  e->SetLongArrayRegion(process, 3, 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) line, 0, 0, 1,
                               CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                               0, 0, &si, &pi);
  
  if (not success) {
    throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    return;
  }
  
  jlong pid = reinterpret_cast<jlong>(pi.hProcess);
  e->SetLongArrayRegion(process, 0, 1, &pid);
  
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
{
  DWORD exitCode;
  BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
  if(not success){
    throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
  } else if(exitCode == STILL_ACTIVE){
    throwNew(e, "java/lang/IllegalThreadStateException", "Process is still active");
  }
  return exitCode;
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
{
  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()));
  }
  return exitCode;
}
#else
extern "C" JNIEXPORT void JNICALL 
Java_java_lang_Runtime_exec(JNIEnv* e, jclass, 
                            jobjectArray command, jlongArray process)
{
  char** argv = static_cast<char**>(malloc((e->GetArrayLength(command) + 1) * sizeof(char*)));
  int i;
  for(i = 0; i < e->GetArrayLength(command); i++){
    jstring element = (jstring) e->GetObjectArrayElement(command, i);
    char* s = const_cast<char*>(e->GetStringUTFChars(element, 0));
    argv[i] = s;
  }
  argv[i] = 0;
  
  int in[] = { -1, -1 };
  int out[] = { -1, -1 };
  int err[] = { -1, -1 };
  int msg[] = { -1, -1 };
  
  makePipe(e, in);
  if(e->ExceptionOccurred()) return;
  jlong inDescriptor = static_cast<jlong>(in[0]);
  e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
  makePipe(e, out);
  if(e->ExceptionOccurred()) return;
  jlong outDescriptor = static_cast<jlong>(out[1]);
  e->SetLongArrayRegion(process, 1, 1, &outDescriptor);
  makePipe(e, err);
  if(e->ExceptionOccurred()) return;
  jlong errDescriptor = static_cast<jlong>(err[0]);
  e->SetLongArrayRegion(process, 1, 1, &errDescriptor);
  makePipe(e, msg);
  if(e->ExceptionOccurred()) return;
  if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) {
    throwNew(e, "java/io/IOException", strerror(errno));
    return;
  }
  
  pid_t pid = fork();
  switch(pid){
  case -1: // error
    throwNew(e, "java/io/IOException", strerror(errno));
    return;
  case 0: { // child
    // Setup stdin, stdout and stderr
    dup2(in[1], 1);
    close(in);
    dup2(out[0], 0);
    close(out);
    dup2(err[1], 2);
    close(err);
    close(msg[0]);
    
    execvp(argv[0], argv);
    
    // Error if here
    char c = errno;
    write(msg[1], &c, 1);
    exit(127);
  } break;
    
  default: { //parent
    jlong JNIPid = static_cast<jlong>(pid);
    e->SetLongArrayRegion(process, 0, 1, &JNIPid);
    
    safeClose(in[1]);
    safeClose(out[0]);
    safeClose(err[1]);
    safeClose(msg[1]);
      
    char c;
    int r = read(msg[0], &c, 1);
    if(r == -1) {
      throwNew(e, "java/io/IOException", strerror(errno));
      return;
    } else if(r) {
      throwNew(e, "java/io/IOException", strerror(c));
      return;
    }
  } break;
  }
  
  safeClose(msg[0]);
  clean(e, command, argv);
  
  fcntl(in[0], F_SETFD, FD_CLOEXEC);
  fcntl(out[1], F_SETFD, FD_CLOEXEC);
  fcntl(err[0], F_SETFD, FD_CLOEXEC);
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
{
  int status;
  pid_t returned = waitpid(pid, &status, WNOHANG);
  if(returned == 0){
    throwNew(e, "java/lang/IllegalThreadStateException", strerror(errno));
  } else if(returned == -1){
    throwNew(e, "java/lang/Exception", strerror(errno));
  } 
  
  return WEXITSTATUS(status);
}

extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid)
{
  bool finished = false;
  int status;
  int exitCode;
  while(!finished){
    waitpid(pid, &status, 0);
    if(WIFEXITED(status)){
      finished = true;
      exitCode = WEXITSTATUS(status);
    } else if(WIFSIGNALED(status)){
      finished = true;
      exitCode = -1;
    }
  }
  
  return exitCode;
}
#endif

extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
                                  jbooleanArray found)
{
  jstring r = 0;
  const char* chars = e->GetStringUTFChars(name, 0);
  if (chars) {
#ifdef WIN32 
    if (strcmp(chars, "line.separator") == 0) {
      r = e->NewStringUTF("\r\n");
    } else if (strcmp(chars, "file.separator") == 0) {
      r = e->NewStringUTF("\\");
    } else if (strcmp(chars, "os.name") == 0) {
      r = e->NewStringUTF("Windows");
    } else if (strcmp(chars, "java.io.tmpdir") == 0) {
      TCHAR buffer[MAX_PATH];
      GetTempPath(MAX_PATH, buffer);
      r = e->NewStringUTF(buffer);
    } else if (strcmp(chars, "user.home") == 0) {
      LPWSTR home = _wgetenv(L"USERPROFILE");
      r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
    }
#else
    if (strcmp(chars, "line.separator") == 0) {
      r = e->NewStringUTF("\n");
    } else if (strcmp(chars, "file.separator") == 0) {
      r = e->NewStringUTF("/");
    } else if (strcmp(chars, "os.name") == 0) {
#ifdef __APPLE__
      r = e->NewStringUTF("Mac OS X");
#else
      r = e->NewStringUTF("Linux");
#endif
    } else if (strcmp(chars, "java.io.tmpdir") == 0) {
      r = e->NewStringUTF("/tmp");
    } else if (strcmp(chars, "user.home") == 0) {
      r = e->NewStringUTF(getenv("HOME"));      
    }
#endif

    e->ReleaseStringUTFChars(name, chars);
  }

  if (r) {
    jboolean v = true;
    e->SetBooleanArrayRegion(found, 0, 1, &v);
  }

  return r;
}
{'fraction_non_alphanumeric': 0.1658677851008588, 'fraction_numerical': 0.014180147793089674, 'mean_word_length': 3.2614893617021274, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 118, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2323137', 'n_tokens_mistral': 7914, 'n_tokens_neox': 7629, 'n_words': 1640}