From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16170 invoked by alias); 6 Mar 2007 16:31:18 -0000 Received: (qmail 16105 invoked by uid 22791); 6 Mar 2007 16:31:17 -0000 X-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,TW_FH X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 06 Mar 2007 16:31:06 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l26GV3LD030136 for ; Tue, 6 Mar 2007 11:31:03 -0500 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l26GV3KO014023 for ; Tue, 6 Mar 2007 11:31:03 -0500 Received: from [127.0.0.1] (sebastian-int.corp.redhat.com [172.16.52.221]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l26GV0lJ020326; Tue, 6 Mar 2007 11:31:02 -0500 Message-ID: <45ED9747.9000003@redhat.com> Date: Tue, 06 Mar 2007 16:31:00 -0000 From: Andrew Cagney User-Agent: Thunderbird 1.5.0.9 (X11/20070102) MIME-Version: 1.0 To: Stan Cox CC: Frysk List Subject: Re: fhpd References: <1172765357.27599.17.camel@multics.rdu.redhat.com> In-Reply-To: <1172765357.27599.17.camel@multics.rdu.redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2007-q1/txt/msg00180.txt.bz2 Hi Stan, I'm not sure what you mean by never regains I/O control. One key issue though is wiring the child process up to a frysk.sys.PseudoTerminal - otherwise the process and fhpd will be fighting over control of the terminal. Don't forget that there are two cases to handle: - fhpd command line where it clearly should create the PTY - UI where the pty will be part of a Terminal panel and the code should bind the created process to that The alternative approach I've seen implemented in the past is to use job-control like mechanisms where fhpd and the child alternate over who is the terminal's controlling process; similar to bash and fg/bg et.al. Since being able to direct the child's I/O to a graphical terminal is a requirement, and this alternative has no such mechanism, the approach is considered flawed. Andrew Stan Cox wrote: > This is my rather quick attempt at getting 'fhpd ' to work. > starts as a child of fhpd but fhpd never regains I/O control. > > AttachHandler > -parse > -requestCreateAttachedProc for > > ProcObserver > -new > > > > ------------------------------------------------------------------------ > > /home/scox/frysk/src /home/scox/frysk ~ > Index: frysk-core/frysk/cli/hpd/CLI.java > =================================================================== > RCS file: /cvs/frysk/frysk-core/frysk/cli/hpd/CLI.java,v > retrieving revision 1.45 > diff -u -p -r1.45 CLI.java > --- frysk-core/frysk/cli/hpd/CLI.java 27 Feb 2007 17:16:43 -0000 1.45 > +++ frysk-core/frysk/cli/hpd/CLI.java 1 Mar 2007 15:59:20 -0000 > @@ -62,13 +62,19 @@ import javax.naming.NameNotFoundExceptio > > import frysk.value.InvalidOperatorException; > import frysk.value.Variable; > +// import frysk.proc.Action; > +import frysk.proc.Action; > import frysk.proc.Host; > import frysk.proc.Manager; > import frysk.proc.Proc; > import frysk.proc.ProcId; > import frysk.proc.Task; > +import frysk.proc.TaskObserver; > import frysk.rt.RunState; > import frysk.rt.StackFrame; > +//import frysk.sys.Pid; > +import frysk.sys.Signal; > +import frysk.sys.Sig; > import frysk.rt.LineBreakpoint; > > > @@ -86,6 +92,7 @@ public class CLI > int stackLevel = 0; > static Object monitor = new Object(); > static boolean attached; > + static boolean child_created; > RunState runState; > private RunStateObserver runStateObserver; > private ActionpointTable apTable = new ActionpointTable(); > @@ -356,11 +363,13 @@ public class CLI > } > } > } > - > - class AttachHandler implements CommandHandler > + > + class AttachHandler implements CommandHandler > { > public void handle(Command cmd) throws ParseException > { > + String[] args = new String[1]; > + > refreshSymtab(); // XXX ? > ArrayList params = cmd.getParameters(); > boolean cli = true; > @@ -391,27 +400,38 @@ public class CLI > } > else if (((String)params.get(idx)).matches("[0-9]+")) > pid = Integer.parseInt((String)params.get(idx)); > + else args[0] = (String)params.get(idx); > } > > + final ProcObserver procObserver = new ProcObserver(); > if (cli) > - { > - Manager.host.requestFindProc(new ProcId(pid), new Host.FindProc() { > - > - public void procFound (ProcId procId) > - { > - > - Manager.eventLoop.requestStop(); > - } > - > - public void procNotFound (ProcId procId, Exception e) > - { > - }}); > - Manager.eventLoop.run(); > - CLIEventLoop eventLoop = new CLIEventLoop(); > - eventLoop.start(); > - } > + { > + if (pid > 0) > + { > + Manager.host.requestFindProc(new ProcId(pid), new Host.FindProc() > + { > + public void procFound (ProcId procId) > + { > + Manager.eventLoop.requestStop(); > + } > + > + public void procNotFound (ProcId procId, Exception e) > + { > + } > + }); > + } > + else > + { > + Manager.host.requestCreateAttachedProc(args, procObserver); > + child_created = true; > + } > + Manager.eventLoop.run(); > + Manager.eventLoop.start(); > + } > > - proc = Manager.host.getProc (new ProcId (pid)); > + proc = Manager.host.getProc(new ProcId(pid)); > + //Proc me = Manager.host.getProc(new ProcId(Pid.get())); > + //me.getMainTask().requestAddSignaledObserver(procObserver); > if (proc == null) > { > addMessage("The event manager is not running.", Message.TYPE_ERROR); > @@ -962,6 +982,8 @@ public class CLI > DetachHandler detachHandler = new DetachHandler(); > Command command = new Command ("detach"); > detachHandler.handle(command); > + if (child_created) > + Signal.tkill (pid, Sig.TERM); > addMessage("Quitting...", Message.TYPE_NORMAL); > } > } > @@ -1232,30 +1254,57 @@ public class CLI > } > return result; > } > - > - private static class CLIEventLoop extends Thread > + > + private class ProcObserver > + implements TaskObserver.Attached, > + TaskObserver.Terminated, > + TaskObserver.Signaled > { > - public void run() > + > + public void addedTo (Object o) > + { > + } > + > + public Action updateAttached (Task taskp) > + { > + proc = taskp.getProc(); > + taskp.requestAddTerminatedObserver(this); > + return Action.CONTINUE; > + } > + > + public void addFailed (Object observable, Throwable w) > { > - try > - { > - Manager.eventLoop.run(); > - } > - finally > - { > - synchronized (monitor) > - { > - monitor.notifyAll(); > - } > - } > } > > - public void requestStop() > + public void deletedFrom (Object o) > + { > + } > + > + public Action updateTerminated(Task task, boolean signal, int exit) > { > Manager.eventLoop.requestStop(); > + return Action.CONTINUE; > } > - } > > + public Action updateSignaled (Task task, int signal) > + { > + System.out.println("From PID: " + task.getProc().getPid() + " TID: " + task.getTid()); > + switch (signal) > + { > + case 2: > + System.out.println("SIGINT detected"); > + break; > + case 3: > + System.out.println("SIGQUIT detected"); > + break; > + case 15: > + System.out.println("SIGTERM detected"); > + break; > + } > + return Action.CONTINUE; > + } > + } > + > private class RunStateObserver implements Observer > { > public void update(Observable observable, Object arg) >