The branch, master has been updated via a72d896b75eab570ea1125186d52e5ad59799024 (commit) from 469c9c97c59f507101aad8250ab9332ce054d50c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit a72d896b75eab570ea1125186d52e5ad59799024 Author: Andrew Cagney <cagney@redhat.com> Date: Tue May 13 10:16:15 2008 -0400 Draft translation of Fork.cxx. frysk-sys/frysk/jnixx/ChangeLog 2008-05-13 Andrew Cagney <cagney@redhat.com> * PrintDeclarations.java: Generate a parameterless constructor. * jnixx.hxx (jnixx::env::env()): New. * JniBindings.java: Add Object.!=. * chars.hxx (class StringArrayChars): New. (class StringChars): New. frysk-sys/frysk/sys/ChangeLog 2008-05-13 Andrew Cagney <cagney@redhat.com> * jni/Fork.cxx: Implement. ----------------------------------------------------------------------- Summary of changes: frysk-sys/frysk/jnixx/ChangeLog | 8 + frysk-sys/frysk/jnixx/JniBindings.java | 8 + frysk-sys/frysk/jnixx/PrintDeclarations.java | 6 + frysk-sys/frysk/jnixx/chars.hxx | 48 +++++++ frysk-sys/frysk/jnixx/jnixx.hxx | 3 + frysk-sys/frysk/sys/ChangeLog | 4 + frysk-sys/frysk/sys/jni/Fork.cxx | 184 +++++++++++++++++++++++++- 7 files changed, 259 insertions(+), 2 deletions(-) First 500 lines of diff: diff --git a/frysk-sys/frysk/jnixx/ChangeLog b/frysk-sys/frysk/jnixx/ChangeLog index 60f9c78..00fe601 100644 --- a/frysk-sys/frysk/jnixx/ChangeLog +++ b/frysk-sys/frysk/jnixx/ChangeLog @@ -1,3 +1,11 @@ +2008-05-13 Andrew Cagney <cagney@redhat.com> + + * PrintDeclarations.java: Generate a parameterless constructor. + * jnixx.hxx (jnixx::env::env()): New. + * JniBindings.java: Add Object.!=. + * chars.hxx (class StringArrayChars): New. + (class StringChars): New. + 2008-05-12 Andrew Cagney <cagney@redhat.com> * JniBindings.java: Generate primitive array methods. diff --git a/frysk-sys/frysk/jnixx/JniBindings.java b/frysk-sys/frysk/jnixx/JniBindings.java index 53804d0..9605d86 100644 --- a/frysk-sys/frysk/jnixx/JniBindings.java +++ b/frysk-sys/frysk/jnixx/JniBindings.java @@ -187,6 +187,14 @@ class JniBindings { new Object[] { "return this->_object == _object;", }) + .put(Object.class, false, + "bool", "operator!=", + new String[] { + "jobject", "_object", + }, + new Object[] { + "return this->_object != _object;", + }) // DeleteLocalRef .put(Object.class, false, null, "DeleteLocalRef", diff --git a/frysk-sys/frysk/jnixx/PrintDeclarations.java b/frysk-sys/frysk/jnixx/PrintDeclarations.java index c028391..b9f9ab8 100644 --- a/frysk-sys/frysk/jnixx/PrintDeclarations.java +++ b/frysk-sys/frysk/jnixx/PrintDeclarations.java @@ -171,6 +171,12 @@ class PrintDeclarations extends ClassWalker { p.print("(jobject _object) : "); p.printGlobalCxxName(parent); p.println("(_object) { }"); + // Empty constructor. + p.print("public: "); + p.printUnqualifiedCxxName(klass); + p.print("() : "); + p.printGlobalCxxName(parent); + p.println("(NULL) { }"); } // Explicit cast operator. p.print("public: static "); diff --git a/frysk-sys/frysk/jnixx/chars.hxx b/frysk-sys/frysk/jnixx/chars.hxx index 02ee457..5c44b81 100644 --- a/frysk-sys/frysk/jnixx/chars.hxx +++ b/frysk-sys/frysk/jnixx/chars.hxx @@ -40,3 +40,51 @@ extern char** strings2chars(::jnixx::env, ::jnixx::array<java::lang::String>); extern ::jnixx::array<java::lang::String> chars2strings(::jnixx::env, char**); + +class StringChars { +private: + ::java::lang::String string; + ::jnixx::env env; +public: + const char* p; + StringChars(::jnixx::env env, ::java::lang::String string) { + this->string = string; + this->env = env; + if (string != NULL) { + this->p = string.GetStringUTFChars(env); + } else { + this->p = NULL; + } + } + void free() { + if (p != NULL) { + string.ReleaseStringUTFChars(env, p); + p = NULL; + } + } + ~StringChars() { + free(); + } +}; + +class StringArrayChars { +public: + char** p; + StringArrayChars(::jnixx::env env, + ::jnixx::array< ::java::lang::String> strings) { + if (strings != NULL) { + p = strings2chars(env, strings); + } else { + p = NULL; + } + } + void free() { + if (p != NULL) { + delete p; + p = NULL; + } + } + ~StringArrayChars() { + free(); + } +}; diff --git a/frysk-sys/frysk/jnixx/jnixx.hxx b/frysk-sys/frysk/jnixx/jnixx.hxx index d8051fa..d77e5ed 100644 --- a/frysk-sys/frysk/jnixx/jnixx.hxx +++ b/frysk-sys/frysk/jnixx/jnixx.hxx @@ -62,6 +62,9 @@ namespace jnixx { env(JNIEnv* _jni) { this->_jni = _jni; } + env() { + this->_jni = NULL; + } // Version Information diff --git a/frysk-sys/frysk/sys/ChangeLog b/frysk-sys/frysk/sys/ChangeLog index 01f3ea6..1922e23 100644 --- a/frysk-sys/frysk/sys/ChangeLog +++ b/frysk-sys/frysk/sys/ChangeLog @@ -1,3 +1,7 @@ +2008-05-13 Andrew Cagney <cagney@redhat.com> + + * jni/Fork.cxx: Implement. + 2008-05-10 Andrew Cagney <cagney@redhat.com> * Fork.java (NO_TRACE, PTRACE, UTRACE): Delete. diff --git a/frysk-sys/frysk/sys/jni/Fork.cxx b/frysk-sys/frysk/sys/jni/Fork.cxx index b358932..8705196 100644 --- a/frysk-sys/frysk/sys/jni/Fork.cxx +++ b/frysk-sys/frysk/sys/jni/Fork.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2007, 2008, Red Hat Inc. // // FRYSK is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by @@ -37,4 +37,184 @@ // version and license this file solely under the GPL without // exception. -#include "jni.hxx" +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/ptrace.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <jni.hxx> + +#include "frysk/jnixx/chars.hxx" +#include "frysk/jnixx/exceptions.hxx" + +using namespace java::lang; + +enum tracing { + DAEMON, + NO_TRACE, + PTRACE, + UTRACE, +}; + +static void +reopen(const char* file, const char* mode, FILE *stream) { + if (file == NULL) + return; + errno = 0; + ::freopen(file, mode, stream); + if (errno != 0) { + // Should not happen! + ::perror("freopen"); + ::_exit(errno); + } +} + +/** + * Spawn a child, return the PID or the -ERROR. + */ +static int +spawn(const char* exePath, + const char* inPath, const char* outPath, const char* errPath, + int argc, char** argv, char** environ, tracing trace) { + + if (trace == DAEMON) { + // Do a vfork(), fork(), exec() which lets the top level process + // capture the middle level fork()'s return value in a volatile. + volatile int pid = -1; + register int v; + errno = 0; + v = vfork (); + switch (v) { + case 0: + // This is executed by the child with the parent blocked, the + // final process id ends up in PID. + pid = ::spawn(exePath, inPath, outPath, errPath, argc, argv, 0, NO_TRACE); + _exit (0); + case -1: + // This is executed after a vfork barfs. + return -errno; + default: + // This is executed after the child has set PID with a FORK and + // then exited (which helps guarentee that the waitpid, below, + // doesn't block. + if (pid < 0) + return -errno; + // Consume the middle players wait. + int status; + errno = 0; + if (waitpid (v, &status, 0) < 0) + return -errno; + return pid; + } + } + + // Fork/exec + errno = 0; + pid_t pid = fork (); + switch (pid) { + case -1: // Fork failed. + return -errno; + default: // Parent + return pid; + case 0: // Child + // Scrub the signal mask. + sigset_t mask; + sigfillset(&mask); + ::sigprocmask(SIG_UNBLOCK, &mask, NULL); + // Redirect stdio. + reopen(inPath, "r", stdin); + reopen(outPath, "w", stdout); + reopen(errPath, "w", stderr); + switch (trace) { + case PTRACE: + errno = 0; + ::ptrace((enum __ptrace_request) PTRACE_TRACEME, 0, 0, 0); + if (errno != 0) { + ::perror ("ptrace.traceme"); + ::_exit(errno); + } + break; + case UTRACE: + fprintf(stderr, "\n\n>>>>> in spawn(...utrace)\n\n"); + break; + case NO_TRACE: + break; + case DAEMON: + break; + } + if (environ != NULL) { + ::execve(exePath, argv, environ); + } else + ::execv(exePath, argv); + // This should not happen. + ::perror("execvp"); + ::_exit (errno); + } +} + +/** + * Convert convert to native and then spawn. + */ +static int +spawn(jnixx::env env, java::io::File exe, + String in, String out, String err, + ::jnixx::array<String> args, jlong environ, tracing trace) { + String exeFile = exe.getPath(env); + StringChars exePath = StringChars(env, exeFile); + StringChars inPath = StringChars(env, in); + StringChars outPath = StringChars(env, out); + StringChars errPath = StringChars(env, err); + int argc = args.GetLength(env); + StringArrayChars argv = StringArrayChars(env, args); + int pid = ::spawn(exePath.p, inPath.p, outPath.p, errPath.p, + argc, argv.p, (char**)environ, trace); + argv.free(); + exePath.free(); + inPath.free(); + outPath.free(); + errPath.free(); + if (pid < 0) { + switch (trace) { + case NO_TRACE: + errnoException(env, -pid, "fork/exec"); + case DAEMON: + errnoException(env, -pid, "vfork/wait"); + case PTRACE: + errnoException(env, -pid, "fork/ptrace/exec"); + case UTRACE: + errnoException(env, -pid, "utrace"); + } + } + return pid; +} + +jint +frysk::sys::Fork::spawn(::jnixx::env env, java::io::File exe, + String in, String out, String err, + ::jnixx::array<String> args, jlong environ) { + return ::spawn(env, exe, in, out, err, args, environ, NO_TRACE); +} + +jint +frysk::sys::Fork::ptrace(::jnixx::env env, java::io::File exe, + String in, String out, String err, + ::jnixx::array<String> args, jlong environ) { + return ::spawn(env, exe, in, out, err, args, environ, PTRACE); +} + +jint +frysk::sys::Fork::utrace(::jnixx::env env, java::io::File exe, + String in, String out, String err, + ::jnixx::array<String> args, jlong environ) { + return ::spawn(env, exe, in, out, err, args, environ, UTRACE); +} + +jint +frysk::sys::Fork::daemon (::jnixx::env env, java::io::File exe, + String in, String out, String err, + ::jnixx::array<String> args, + jlong environ) { + return ::spawn(env, exe, in, out, err, args, environ, DAEMON); +} hooks/post-receive -- frysk system monitor/debugger