From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7798 invoked by alias); 13 May 2008 16:18:56 -0000 Received: (qmail 7764 invoked by uid 367); 13 May 2008 16:18:55 -0000 Date: Tue, 13 May 2008 16:18:00 -0000 Message-ID: <20080513161854.7748.qmail@sourceware.org> From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: Implement jni/ProcBuilder.cxx. X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: e62c4482adaf39915db4f42983327a7b715d316a X-Git-Newrev: d7679da2d8064a96588f719fd51ab5a511f09058 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/msg00233.txt.bz2 The branch, master has been updated via d7679da2d8064a96588f719fd51ab5a511f09058 (commit) via ee33bb63674849e5ad13a8334ab7a2fb5d7839df (commit) from e62c4482adaf39915db4f42983327a7b715d316a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit d7679da2d8064a96588f719fd51ab5a511f09058 Author: Andrew Cagney Date: Tue May 13 12:17:39 2008 -0400 Implement jni/ProcBuilder.cxx. frysk-common/ChangeLog 2008-05-13 Andrew Cagney * Makefile.gen.sh (JNIXX_CLASSES): Define. (jni.hxx, jni.cxx): Use. Depend on input java files. frysk-sys/ChangeLog 2008-05-13 Andrew Cagney * Makefile.am (JNIXX_CLASSES): Add frysk.sys.ProcessIdentifierFactory. frysk-sys/frysk/sys/proc/ChangeLog 2008-05-13 Andrew Cagney * TestProcBuilder.java: New. * jni/ProcBuilder.java: Implement. commit ee33bb63674849e5ad13a8334ab7a2fb5d7839df Author: Andrew Cagney Date: Tue May 13 11:39:09 2008 -0400 Simplify ProcBuilder. frysk-sys/frysk/sys/proc/ChangeLog 2008-05-13 Andrew Cagney * ProcBuilder.java (construct(int,Log)): Replace construct(int), make native. Throw instead of returning a boolean. (open(int), scan(RawData,int,Log), close(RawData)): Delete. * cni/ProcBuilder.cxx (ProcBuilder::construct): Update. ----------------------------------------------------------------------- Summary of changes: frysk-common/ChangeLog | 5 + frysk-common/Makefile.gen.sh | 6 +- frysk-sys/ChangeLog | 5 + frysk-sys/Makefile.am | 4 + frysk-sys/frysk/sys/proc/ChangeLog | 10 +++ frysk-sys/frysk/sys/proc/ProcBuilder.java | 30 ++----- .../{jni/ProcBuilder.cxx => TestProcBuilder.java} | 37 +++++++++- frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx | 83 +++++++++---------- frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx | 65 +++++++++++++++- 9 files changed, 175 insertions(+), 70 deletions(-) copy frysk-sys/frysk/sys/proc/{jni/ProcBuilder.cxx => TestProcBuilder.java} (71%) First 500 lines of diff: diff --git a/frysk-common/ChangeLog b/frysk-common/ChangeLog index 41ecf76..4aa7176 100644 --- a/frysk-common/ChangeLog +++ b/frysk-common/ChangeLog @@ -1,3 +1,8 @@ +2008-05-13 Andrew Cagney + + * Makefile.gen.sh (JNIXX_CLASSES): Define. + (jni.hxx, jni.cxx): Use. Depend on input java files. + 2008-05-12 Rick Moseley * version.in: Update to version 0.3. diff --git a/frysk-common/Makefile.gen.sh b/frysk-common/Makefile.gen.sh index 82cee00..05c9859 100755 --- a/frysk-common/Makefile.gen.sh +++ b/frysk-common/Makefile.gen.sh @@ -672,6 +672,7 @@ generate_jnixx_class() { local suffix=$4 local j=$(echo $(dirname $dir)/$base) if has_java_source $j ; then + echo "jni.hxx jni.cxx: $j.java" echo "${dir}/${base}.o: $j.java | jni.hxx.gch" fi } @@ -888,6 +889,7 @@ echo "" 1>&2 if automake_variable_defined lib${GEN_MAKENAME}_jni_a_SOURCES ; then cat < \$@.tmp mv \$@.tmp \$@ jni.hxx.gch: jni.hxx @@ -911,7 +913,7 @@ jni.cxx: \$(jnixx_sources) | ${GEN_DIRNAME}.jar CLASSPATH=\$(GEN_DIRNAME).jar:\$(CLASSPATH) \\ \$(JAVA) frysk.jnixx.Main \\ cxx \\ - jni.hxx ${GEN_DIRNAME}.jar \\ + jni.hxx ${GEN_DIRNAME}.jar \$(JNIXX_CLASSES) \\ > \$@.tmp mv \$@.tmp \$@ jni.o: jni.hxx | jni.hxx.gch diff --git a/frysk-sys/ChangeLog b/frysk-sys/ChangeLog index e207144..22e6cec 100644 --- a/frysk-sys/ChangeLog +++ b/frysk-sys/ChangeLog @@ -1,3 +1,8 @@ +2008-05-13 Andrew Cagney + + * Makefile.am (JNIXX_CLASSES): Add + frysk.sys.ProcessIdentifierFactory. + 2008-05-07 Andrew Cagney * Makefile.am (JniRunner): Add frysk.jnixx. diff --git a/frysk-sys/Makefile.am b/frysk-sys/Makefile.am index d0828e4..bb39422 100644 --- a/frysk-sys/Makefile.am +++ b/frysk-sys/Makefile.am @@ -70,6 +70,10 @@ lib/unwind/cni/Unwind%.cxx: lib/unwind/Unwind%.java lib/unwind/cni/UnwindH.hxx lib/unwind/Unwind%.java: lib/unwind/Unwind.java +# jnixx's auto-detect algorithm misses hidden class references, +# explicitly add them here. +JNIXX_CLASSES += frysk.sys.ProcessIdentifierFactory + # Quick hack to get a test JNI program up-and-running; as a package is # re-implemented in JNI, add it to the below. diff --git a/frysk-sys/frysk/sys/proc/ChangeLog b/frysk-sys/frysk/sys/proc/ChangeLog index f1a2b95..46377dc 100644 --- a/frysk-sys/frysk/sys/proc/ChangeLog +++ b/frysk-sys/frysk/sys/proc/ChangeLog @@ -1,3 +1,13 @@ +2008-05-13 Andrew Cagney + + * TestProcBuilder.java: New. + * jni/ProcBuilder.java: Implement. + + * ProcBuilder.java (construct(int,Log)): Replace construct(int), + make native. Throw instead of returning a boolean. + (open(int), scan(RawData,int,Log), close(RawData)): Delete. + * cni/ProcBuilder.cxx (ProcBuilder::construct): Update. + 2008-05-07 Andrew Cagney * jni/AuxvBuilder.cxx: Include jni.hxx. diff --git a/frysk-sys/frysk/sys/proc/ProcBuilder.java b/frysk-sys/frysk/sys/proc/ProcBuilder.java index b99bb81..0641dff 100644 --- a/frysk-sys/frysk/sys/proc/ProcBuilder.java +++ b/frysk-sys/frysk/sys/proc/ProcBuilder.java @@ -39,7 +39,6 @@ package frysk.sys.proc; -import gnu.gcj.RawData; import frysk.sys.ProcessIdentifier; import frysk.rsl.Log; import frysk.rsl.LogFactory; @@ -57,38 +56,25 @@ public abstract class ProcBuilder { * notifying ProcBuilder of each "interesting" entry. Use * "finally" to ensure that the directory is always closed. */ - public final boolean construct(ProcessIdentifier pid) { - return construct(pid.intValue()); - } - private boolean construct(int pid) { - RawData dir = open(pid); - if (dir == null) - return false; - try { - scan(dir, pid, warning); - } - finally { - close (dir); - } - return true; + public final void construct(ProcessIdentifier pid) { + construct(pid.intValue(), warning); } /** * Iterate over the /proc directory notifying TaskBuilder * of each "interesting" entry. */ - public final boolean construct() { - return construct(0); + public final void construct() { + construct(0, warning); } /** * Called for each process or task ID in the /proc, or * /proc/PID/task directory. */ abstract public void build(ProcessIdentifier pid); + + /** - * Private native methods for manipulating the /proc - * directory. Move to frysk.sys.Dir? + * Iterate over /proc/PID/ finding all entries. */ - private native RawData open(int pid); - private native void scan(RawData dir, int pid, Log warning); - private native void close(RawData dir); + private native void construct(int pid, Log warning); } diff --git a/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx b/frysk-sys/frysk/sys/proc/TestProcBuilder.java similarity index 71% copy from frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx copy to frysk-sys/frysk/sys/proc/TestProcBuilder.java index b358932..c01cf38 100644 --- a/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx +++ b/frysk-sys/frysk/sys/proc/TestProcBuilder.java @@ -37,4 +37,39 @@ // version and license this file solely under the GPL without // exception. -#include "jni.hxx" +package frysk.sys.proc; + +import frysk.junit.TestCase; +import frysk.sys.Pid; +import frysk.sys.Tid; +import frysk.sys.ProcessIdentifier; + +/** + * Check that this processes proc and task can be found. + */ +public class TestProcBuilder extends TestCase { + private static class FindPid extends ProcBuilder { + boolean found = false; + private final ProcessIdentifier pid; + FindPid(ProcessIdentifier pid) { + this.pid = pid; + } + public void build(ProcessIdentifier pid) { + if (this.pid.equals(pid)) { + found = true; + } + } + } + + public void testProcFound() { + FindPid finder = new FindPid(Pid.get()); + finder.construct(); + assertTrue("pid found", finder.found); + } + + public void testTaskFound() { + FindPid finder = new FindPid(Tid.get()); + finder.construct(Pid.get()); + assertTrue("pid found", finder.found); + } +} diff --git a/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx b/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx index 8aa0fa9..20c09e6 100644 --- a/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx +++ b/frysk-sys/frysk/sys/proc/cni/ProcBuilder.cxx @@ -44,6 +44,7 @@ #include #include +#include #include "frysk/sys/cni/Errno.hxx" #include "frysk/sys/proc/ProcBuilder.h" @@ -52,62 +53,56 @@ #include "frysk/rsl/Log.h" #include "frysk/rsl/cni/Log.hxx" -gnu::gcj::RawData* -frysk::sys::proc::ProcBuilder::open (jint pid) -{ - // Get the file name. - const char *file; - char tmp[FILENAME_MAX]; - if (pid > 0) { - if (::snprintf (tmp, sizeof tmp, "/proc/%d/task", (int) pid) - >= FILENAME_MAX) - throwRuntimeException ("snprintf: buffer overflow"); - file = tmp; - } - else - file = "/proc"; - return (gnu::gcj::RawData*) opendir (file); -} - void -frysk::sys::proc::ProcBuilder::scan(gnu::gcj::RawData* rawData, jint pid, - frysk::rsl::Log* warning) -{ - DIR* proc = (DIR*) rawData; - int bad = 1; // something non-ve or 0. +frysk::sys::proc::ProcBuilder::construct(jint pid, frysk::rsl::Log* warning) { + // Open the directory + DIR *proc; + { + const char *dir; + char tmp[FILENAME_MAX]; + if (pid > 0) { + if (::snprintf(tmp, sizeof tmp, "/proc/%d/task", (int) pid) + >= FILENAME_MAX) + throwRuntimeException("snprintf: buffer overflow"); + dir = tmp; + } else { + dir = "/proc"; + } + proc = ::opendir(dir); + if (proc == NULL) { + // If access isn't possible then there are no entries. + return; + } + } + // Scan the directory tree. while (true) { - // Get the dirent. - struct dirent *dirent = readdir (proc); - if (dirent == NULL) + struct dirent *dirent = readdir(proc); + if (dirent == NULL) { break; - + } // Scan the pid, skip if non-numeric. char* end = NULL; - int id = strtol (dirent->d_name, &end, 10); - if (end == dirent->d_name) + int id = strtol(dirent->d_name, &end, 10); + if (end == dirent->d_name) { continue; - + } // Seems some kernels return a dirent containing bad (e.g., 0) or // even random entries; report them and then throw an error. - if (bad <= 0) { - logf(warning, "/proc/%d/task contained bad pid: %d; skipping %d", - (int)pid, bad, id); - } else if (id <= 0) { - bad = id; - logf(warning, "/proc/%d/task contains bad pid: %d", (int)pid, id); - } else { + if (id <= 0) { + logf(warning, "/proc/%d/task contained bad pid: %d", (int)pid, id); + break; + } + + try { build(frysk::sys::ProcessIdentifierFactory::create(id)); + } catch (java::lang::RuntimeException *e) { + ::closedir(proc); + throw e; } } - if (bad <= 0) - throwRuntimeException("/proc/$$/task contains bad pid", "pid", bad); -} - -void -frysk::sys::proc::ProcBuilder::close (gnu::gcj::RawData* rawData) -{ - closedir ((DIR*) rawData); + // Open the directory. + ::closedir (proc); } diff --git a/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx b/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx index b358932..2a6a575 100644 --- a/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx +++ b/frysk-sys/frysk/sys/proc/jni/ProcBuilder.cxx @@ -1,6 +1,6 @@ // This file is part of the program FRYSK. // -// Copyright 2008, Red Hat Inc. +// Copyright 2005, 2006, 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,67 @@ // version and license this file solely under the GPL without // exception. +#include +#include +#include +#include + #include "jni.hxx" + +#include "frysk/jnixx/exceptions.hxx" +#include "frysk/rsl/jni/Log.hxx" + +void +frysk::sys::proc::ProcBuilder::construct(::jnixx::env env, jint pid, + frysk::rsl::Log warning) { + // Open the directory + DIR *proc; + { + const char *dir; + char tmp[FILENAME_MAX]; + if (pid > 0) { + if (::snprintf(tmp, sizeof tmp, "/proc/%d/task", (int) pid) + >= FILENAME_MAX) + runtimeException(env, "snprintf: buffer overflow"); + dir = tmp; + } else { + dir = "/proc"; + } + proc = ::opendir(dir); + if (proc == NULL) { + // If access isn't possible then there are no entries. + return; + } + } + + // Scan the directory tree. + while (true) { + // Get the dirent. + struct dirent *dirent = readdir(proc); + if (dirent == NULL) { + break; + } + // Scan the pid, skip if non-numeric. + char* end = NULL; + int id = strtol(dirent->d_name, &end, 10); + if (end == dirent->d_name) { + continue; + } + // Seems some kernels return a dirent containing bad (e.g., 0) or + // even random entries; report them and then throw an error. + if (id <= 0) { + logf(env, warning, "/proc/%d/task contained bad pid: %d", (int)pid, id); + break; + } + + try { + build(frysk::sys::ProcessIdentifierFactory::create(env, id)); + } catch (java::lang::RuntimeException *e) { + ::closedir(proc); + throw e; + } + } + + // Open the directory. + ::closedir (proc); +} hooks/post-receive -- frysk system monitor/debugger