From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12700 invoked by alias); 13 May 2008 14:17:34 -0000 Received: (qmail 12675 invoked by uid 367); 13 May 2008 14:17:33 -0000 Date: Tue, 13 May 2008 14:17:00 -0000 Message-ID: <20080513141733.12660.qmail@sourceware.org> From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Draft translation of Fork.cxx. X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 469c9c97c59f507101aad8250ab9332ce054d50c X-Git-Newrev: a72d896b75eab570ea1125186d52e5ad59799024 Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2008-q2/txt/msg00230.txt.bz2 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 Date: Tue May 13 10:16:15 2008 -0400 Draft translation of Fork.cxx. frysk-sys/frysk/jnixx/ChangeLog 2008-05-13 Andrew Cagney * 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 * 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 + + * 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 * 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); extern ::jnixx::array 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 + + * jni/Fork.cxx: Implement. + 2008-05-10 Andrew Cagney * 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 +#include +#include +#include +#include +#include + +#include + +#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 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 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 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 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 args, + jlong environ) { + return ::spawn(env, exe, in, out, err, args, environ, DAEMON); +} hooks/post-receive -- frysk system monitor/debugger