public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Prototype jni/PseudoTerminal.
@ 2008-05-21 18:41 cagney
  0 siblings, 0 replies; only message in thread
From: cagney @ 2008-05-21 18:41 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  bca04cf8014a6ab4995b3af8abef6e2bf0d5a797 (commit)
       via  68963650f864c770ab27f1f8caae53f07c33c974 (commit)
      from  ac46ba63440998b66f7038c8fe0efad8036186ff (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit bca04cf8014a6ab4995b3af8abef6e2bf0d5a797
Author: Andrew Cagney <cagney@redhat.com>
Date:   Wed May 21 14:40:14 2008 -0400

    Prototype jni/PseudoTerminal.
    
    frysk-sys/frysk/sys/ChangeLog
    2008-05-21  Andrew Cagney  <cagney@redhat.com>
    
    	* cni/Fork.cxx (class redirect_stdio): Fix typo out->err.
    	* jni/PseudoTerminal.cxx: Implement.
    	* jni/Fork.hxx: New.
    	* jni/Fork.cxx: Merge in cni/Fork.cxx changes.

commit 68963650f864c770ab27f1f8caae53f07c33c974
Author: Andrew Cagney <cagney@redhat.com>
Date:   Tue May 20 21:24:08 2008 -0400

    Re-implement PseudoTerminal using Fork.
    
    frysk-sys/frysk/sys/ChangeLog
    2008-05-20  Andrew Cagney  <cagney@redhat.com>
    
    	* cni/PseudoTerminal.cxx (PseudoTerminal::child): Implement.
    	(PseudoTerminal::daemon): Implement.
    	* cni/Fork.hxx: New.
    	* PseudoTerminal.java (RedirectStdio): Delete.
    	(addChild, addDaemon): Implement as natives.
    	* cni/Fork.cxx (spawn): New.

-----------------------------------------------------------------------

Summary of changes:
 frysk-sys/frysk/sys/ChangeLog                      |   12 ++
 frysk-sys/frysk/sys/PseudoTerminal.java            |   36 +----
 frysk-sys/frysk/sys/cni/Fork.cxx                   |  127 +++++++---------
 .../sys/{jni/PseudoTerminal.cxx => cni/Fork.hxx}   |   72 +++++++---
 frysk-sys/frysk/sys/cni/PseudoTerminal.cxx         |  140 ++++++++++-------
 frysk-sys/frysk/sys/jni/Fork.cxx                   |  159 +++++++++-----------
 .../frysk/sys/jni/{PseudoTerminal.cxx => Fork.hxx} |   79 ++++++++---
 frysk-sys/frysk/sys/jni/PseudoTerminal.cxx         |  138 ++++++++++++++++-
 8 files changed, 474 insertions(+), 289 deletions(-)
 copy frysk-sys/frysk/sys/{jni/PseudoTerminal.cxx => cni/Fork.hxx} (64%)
 copy frysk-sys/frysk/sys/jni/{PseudoTerminal.cxx => Fork.hxx} (58%)

First 500 lines of diff:
diff --git a/frysk-sys/frysk/sys/ChangeLog b/frysk-sys/frysk/sys/ChangeLog
index c6f46b9..4a39196 100644
--- a/frysk-sys/frysk/sys/ChangeLog
+++ b/frysk-sys/frysk/sys/ChangeLog
@@ -1,10 +1,22 @@
 2008-05-21  Andrew Cagney  <cagney@redhat.com>
 
+	* cni/Fork.cxx (class redirect_stdio): Fix typo out->err.
+	* jni/PseudoTerminal.cxx: Implement.
+	* jni/Fork.hxx: New.
+	* jni/Fork.cxx: Merge in cni/Fork.cxx changes.
+
 	* jni/Fork.cxx (spawn): Use elements(), not .p.
 	* jni/Signal.cxx-sh (frysk): Ditto.
 
 2008-05-20  Andrew Cagney  <cagney@redhat.com>
 
+	* cni/PseudoTerminal.cxx (PseudoTerminal::child): Implement.
+	(PseudoTerminal::daemon): Implement.
+	* cni/Fork.hxx: New.
+	* PseudoTerminal.java (RedirectStdio): Delete.
+	(addChild, addDaemon): Implement as natives.
+	* cni/Fork.cxx (spawn): New.
+
 	* jni/Signal.cxx-sh: Don't leak JNI string pointers.
 
 	* jni/DaemonFactory.cxx: Implement.
diff --git a/frysk-sys/frysk/sys/PseudoTerminal.java b/frysk-sys/frysk/sys/PseudoTerminal.java
index d53457b..8f3262d 100755
--- a/frysk-sys/frysk/sys/PseudoTerminal.java
+++ b/frysk-sys/frysk/sys/PseudoTerminal.java
@@ -77,51 +77,25 @@ public class PseudoTerminal extends FileDescriptor {
     /**
      * Return the path of the pseudo-terminal's slave.
      */
-    public File getFile ()
-    {
+    public File getFile() {
 	return file;
     }
 
     /**
-     * Redirect stdin, stdout, and stderr to this PseudoTerminal.
-     *
-     * The file descriptors are created in the parent process so that
-     * child does not need to run the risk of running out of
-     * descriptors et.al. and recover from that.
-     */
-    static private class RedirectStdio
-	extends Redirect
-    {
-	protected final String name;
-	RedirectStdio (String name)
-	{
-	    this.name = name;
-	}
-	/**
-	 * Execute in context of child.
-	 */
-	public native void reopen ();
-	/**
-	 * Executed in context of parent.
-	 */
-	public void close ()
-	{
-	}
-    }
-
-    /**
      * Convenience method, adds a child process bound to this
      * pseudo-terminal.
      */
     public ProcessIdentifier addChild(String[] args) {
-	return ChildFactory.create(new RedirectStdio (name), new Exec (args));
+	return ProcessIdentifierFactory.create(child(args[0], args, name));
     }
+    private static native int child(String exe, String[] args, String name);
 
     /**
      * Convenience method, adds a daemon process bound to this
      * pseudo-terminal.
      */
     public ProcessIdentifier addDaemon(String[] args) {
-	return DaemonFactory.create(new RedirectStdio (name), new Exec (args));
+	return ProcessIdentifierFactory.create(daemon(args[0], args, name));
     }
+    private static native int daemon(String exe, String[] args, String name);
 }
diff --git a/frysk-sys/frysk/sys/cni/Fork.cxx b/frysk-sys/frysk/sys/cni/Fork.cxx
index 74db54c..d8806e2 100644
--- a/frysk-sys/frysk/sys/cni/Fork.cxx
+++ b/frysk-sys/frysk/sys/cni/Fork.cxx
@@ -49,38 +49,15 @@
 #include "java/io/File.h"
 #include "frysk/sys/Fork.h"
 #include "frysk/sys/cni/Errno.hxx"
-
+#include "frysk/sys/cni/Fork.hxx"
 #include "frysk/sys/ProcessIdentifier.h"
 #include "frysk/sys/ProcessIdentifierFactory.h"
 
-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.
+ * Spawn a child, return the PID or throw 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) {
-
+int
+spawn(tracing trace, redirect& redirection, exec& execute) {
   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.
@@ -92,22 +69,24 @@ spawn(const char* exePath,
     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);
+      pid = ::spawn(CHILD, redirection, execute);
       _exit (0);
     case -1:
       // This is executed after a vfork barfs.
-      return -errno;
+      throwErrno(errno, "vfork");
     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;
+      if (pid < 0) {
+	throwErrno(errno, "vfork/fork");
+      }
       // Consume the middle players wait.
       int status;
       errno = 0;
-      if (waitpid (v, &status, 0) < 0)
-	return -errno;
+      if (waitpid(v, &status, 0) < 0) {
+	throwErrno(errno, "waitpid");
+      }
       return pid;
     }
   }
@@ -117,7 +96,7 @@ spawn(const char* exePath,
   pid_t pid = fork ();
   switch (pid) {
   case -1: // Fork failed.
-    return -errno;
+    throwErrno(errno, "fork");
   default: // Parent
     return pid;
   case 0: // Child
@@ -126,9 +105,7 @@ spawn(const char* exePath,
     sigfillset(&mask);
     ::sigprocmask(SIG_UNBLOCK, &mask, NULL);
     // Redirect stdio.
-    reopen(inPath, "r", stdin);
-    reopen(outPath, "w", stdout);
-    reopen(errPath, "w", stderr);
+    redirection.reopen();
     switch (trace) {
     case PTRACE:
       errno = 0;
@@ -141,21 +118,50 @@ spawn(const char* exePath,
     case UTRACE:
       fprintf(stderr, "\n\n>>>>> in spawn(...utrace)\n\n");
       break;
-    case NO_TRACE:
+    case CHILD:
       break;
     case DAEMON:
       break;
     }
-    if (environ != NULL) {
-      ::execve(exePath, argv, environ);
-    } else
-      ::execv(exePath, argv);
-    // This should not happen.
-    ::perror("execvp");
-    ::_exit (errno);
+    execute.execute();
+    ::_exit(errno);
   }
 }
 
+class redirect_stdio : public redirect {
+private:
+  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);
+    }
+  }
+  char* in;
+  char* out;
+  char* err;
+public:
+  redirect_stdio(jstring in, jstring out, jstring err) {
+    this->in = MALLOC_STRING(in);
+    this->out = MALLOC_STRING(out);
+    this->err = MALLOC_STRING(err);
+  }
+  void reopen() {
+    reopen(in, "r", stdin);
+    reopen(out, "w", stdout);
+    reopen(err, "w", stderr);
+  }
+  ~redirect_stdio() {
+    JvFree(in);
+    JvFree(out);
+    JvFree(err);
+  }
+};
+
 /**
  * Convert convert to native and then spawn.
  */
@@ -163,39 +169,16 @@ static int
 spawn(java::io::File* exe,
       jstring in, jstring out, jstring err,
       jstringArray args, jlong environ, tracing trace) {
-  char* exePath = MALLOC_STRING(exe->getPath());
-  char* inPath = MALLOC_STRING(in);
-  char* outPath = MALLOC_STRING(out);
-  char* errPath = MALLOC_STRING(err);
-  int argc = args->length;
-  char** argv = MALLOC_ARGV(args);
-  int pid = ::spawn(exePath, inPath, outPath, errPath,
-		    argc, argv, (char**)environ, trace);
-  JvFree(exePath);
-  JvFree(inPath);
-  JvFree(outPath);
-  JvFree(errPath);
-  JvFree(argv);
-  if (pid < 0) {
-    switch (trace) {
-    case NO_TRACE:
-      throwErrno(-pid, "fork/exec");
-    case DAEMON:
-      throwErrno(-pid, "vfork/wait");
-    case PTRACE:
-      throwErrno(-pid, "fork/ptrace/exec");
-    case UTRACE:
-      throwErrno(-pid, "utrace");
-    }
-  }
-  return pid;
+  redirect_stdio io = redirect_stdio(in, out, err);
+  exec_program program = exec_program(exe->getPath(), args, environ);
+  return ::spawn(trace, io, program);
 }
 
 jint
 frysk::sys::Fork::spawn(java::io::File* exe,
 			jstring in, jstring out, jstring err,
 			jstringArray args, jlong environ) {
-  return ::spawn(exe, in, out, err, args, environ, NO_TRACE);
+  return ::spawn(exe, in, out, err, args, environ, CHILD);
 }
 
 jint
diff --git a/frysk-sys/frysk/sys/jni/PseudoTerminal.cxx b/frysk-sys/frysk/sys/cni/Fork.hxx
similarity index 64%
copy from frysk-sys/frysk/sys/jni/PseudoTerminal.cxx
copy to frysk-sys/frysk/sys/cni/Fork.hxx
index 2ae7e72..11137d8 100644
--- a/frysk-sys/frysk/sys/jni/PseudoTerminal.cxx
+++ b/frysk-sys/frysk/sys/cni/Fork.hxx
@@ -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,24 +37,60 @@
 // version and license this file solely under the GPL without
 // exception.
 
-#include <stdlib.h>
-#include <errno.h>
+enum tracing {
+  CHILD,
+  DAEMON,
+  PTRACE,
+  UTRACE,
+};
 
-#include "jni.hxx"
+/**
+ * Class to redirect a child's stdio; the destructor should clean up
+ * the parent resources.
+ */
+class redirect {
+public:
+  virtual void reopen() = 0;
+  virtual ~redirect() {
+    // where the close code goes.
+  }
+};
 
-#include "jnixx/exceptions.hxx"
+class exec {
+public:
+  virtual void execute() = 0;
+  virtual ~exec() {
+    // where the close code goes.
+  }
+};
 
-using namespace java::lang;
+class exec_program : public exec {
+  char* exePath;
+  char** argv;
+  char** environ;
+public:
+  exec_program(jstring exe, jstringArray args, jlong environ) {
+    this->exePath = MALLOC_STRING(exe);
+    this->argv = MALLOC_ARGV(args);
+    this->environ = (char**)(long)environ;
+  }
+  void execute() {
+    if (environ != NULL) {
+      ::execve(exePath, argv, environ);
+      ::perror("execve");
+    } else {
+      ::execv(exePath, argv);
+      ::perror("execv");
+    }
+    ::_exit(errno);
+  }
+  ~exec_program() {
+    JvFree(exePath);
+    JvFree(argv);
+  }
+};
 
-::String
-frysk::sys::PseudoTerminal::getName(::jnixx::env env, jint pty) {
-  const char *name = ::ptsname(pty);
-  if (name == NULL)
-    errnoException(env, errno, "ptsname");
-  return String::NewStringUTF(env, name);
-}
-
-jint
-frysk::sys::PseudoTerminal::open(::jnixx::env env, bool) {
-  return -1;
-}
+/**
+ * Spawn a child, return the PID, or throw an error.
+ */
+extern int spawn(tracing trace, redirect& redirection, exec& execute);
diff --git a/frysk-sys/frysk/sys/cni/PseudoTerminal.cxx b/frysk-sys/frysk/sys/cni/PseudoTerminal.cxx
index 7d17563..63ec20b 100755
--- a/frysk-sys/frysk/sys/cni/PseudoTerminal.cxx
+++ b/frysk-sys/frysk/sys/cni/PseudoTerminal.cxx
@@ -48,13 +48,13 @@
 
 #include <gcj/cni.h>
 
+#include "frysk/sys/cni/Errno.hxx"
+#include "frysk/sys/cni/Fork.hxx"
 #include "frysk/sys/PseudoTerminal.h"
 #include "frysk/sys/PseudoTerminal$RedirectStdio.h"
-#include "frysk/sys/cni/Errno.hxx"
 
 jint
-frysk::sys::PseudoTerminal::open (jboolean controllingTerminal)
-{
+frysk::sys::PseudoTerminal::open(jboolean controllingTerminal) {
   int master;
 
   int flags = O_RDWR | (controllingTerminal ? O_NOCTTY : 0);
@@ -80,73 +80,99 @@ frysk::sys::PseudoTerminal::open (jboolean controllingTerminal)
 }
 
 jstring
-frysk::sys::PseudoTerminal::getName(jint fd)
-{
+frysk::sys::PseudoTerminal::getName(jint fd) {
   char* pts_name = ::ptsname(fd);
   if (pts_name == NULL)
     throwErrno (errno, "ptsname");
   return JvNewStringUTF (pts_name);
 }
 
-void
-frysk::sys::PseudoTerminal$RedirectStdio::reopen ()
-{
-  // Detach from the existing controlling terminal.  NOTE: Do not use
-  // tryOpen() here, this is running in a child process.
-  int fd = ::open ("/dev/tty", O_RDWR|O_NOCTTY); // ::open ok
-  if (fd >= 0) {
-    if (::ioctl (fd, TIOCNOTTY, NULL) < 0)
-      ::perror ("ioctl (/dev/tty, TIOCNOTTY)");
-    ::close (fd);
-
-    // Verify that the detach worked, this open should fail.  NOTE: Do
-    // not use tryOpen() here, this is running in a child process.
-    fd = ::open ("/dev/tty", O_RDWR|O_NOCTTY); // ::open ok
+class redirect_tty : public redirect {
+  char* pty;
+public:
+  redirect_tty(jstring name) {
+    pty = MALLOC_STRING(name);
+  }
+  ~redirect_tty() {
+    JvFree(pty);
+  }
+  void reopen() {
+    // Detach from the existing controlling terminal.  NOTE: Do not
+    // use tryOpen() here, this is running in a child process.
+    int fd = ::open ("/dev/tty", O_RDWR|O_NOCTTY); // ::open ok
     if (fd >= 0) {
-      ::perror ("open (re-open old controlling terminal)");
-      ::exit (1);
+      if (::ioctl (fd, TIOCNOTTY, NULL) < 0)
+	::perror ("ioctl (/dev/tty, TIOCNOTTY)");
+      ::close (fd);
+
+      // Verify that the detach worked, this open should fail.  NOTE:
+      // Do not use tryOpen() here, this is running in a child
+      // process.
+      fd = ::open ("/dev/tty", O_RDWR|O_NOCTTY); // ::open ok
+      if (fd >= 0) {
+	::perror ("open (re-open old controlling terminal)");
+	::exit (1);
+      }
     }
-  }
   
-  // Make this process the session leader.
-  if (::setsid () < 0) {
-    ::perror ("setsid");
-  }
+    // Make this process the session leader.
+    if (::setsid () < 0) {
+      ::perror ("setsid");
+    }
 
-  if (::getpgrp () != ::getpid ()) {
-    perror ("grp and pid differ");
-    exit (1);
-  }
+    if (::getpgrp () != ::getpid ()) {
+      perror ("grp and pid differ");
+      exit (1);
+    }
 
-//   // Move this to the session's process group.
-//   if (::setpgid (0, getpid ()) < 0) {
-//     perror ("setpgrp");
-//   }
-
-  // Open the new pty.
-  char *pty = ALLOCA_STRING (name);
-  int tty = open (pty, O_RDWR|O_NOCTTY);
-  if (tty < 0) {
-    perror ("open.pty");
-    exit (1);
-  }
+    //   // Move this to the session's process group.
+    //   if (::setpgid (0, getpid ()) < 0) {
+    //     perror ("setpgrp");
+    //   }
 
-  // Make the pty's tty the new controlling terminal.
-  if (::ioctl (tty, TIOCSCTTY, NULL) < 0) {
-    ::perror ("ioctl.TIOSCTTY");
-    exit (1);


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-21 18:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-21 18:41 [SCM] master: Prototype jni/PseudoTerminal cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).