* fhpd <program>
@ 2007-03-01 16:15 Stan Cox
2007-03-06 16:31 ` Andrew Cagney
0 siblings, 1 reply; 4+ messages in thread
From: Stan Cox @ 2007-03-01 16:15 UTC (permalink / raw)
To: Frysk List
[-- Attachment #1: Type: text/plain, Size: 236 bytes --]
This is my rather quick attempt at getting 'fhpd <program>' to work.
<program> starts as a child of fhpd but fhpd never regains I/O control.
AttachHandler
-parse <program>
-requestCreateAttachedProc for <program>
ProcObserver
-new
[-- Attachment #2: ,cvsdiff --]
[-- Type: text/plain, Size: 5272 bytes --]
/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)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: fhpd <program>
2007-03-01 16:15 fhpd <program> Stan Cox
@ 2007-03-06 16:31 ` Andrew Cagney
2007-03-07 13:43 ` Tim Moore
0 siblings, 1 reply; 4+ messages in thread
From: Andrew Cagney @ 2007-03-06 16:31 UTC (permalink / raw)
To: Stan Cox; +Cc: Frysk List
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 <program>' to work.
> <program> starts as a child of fhpd but fhpd never regains I/O control.
>
> AttachHandler
> -parse <program>
> -requestCreateAttachedProc for <program>
>
> 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)
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: fhpd <program>
2007-03-06 16:31 ` Andrew Cagney
@ 2007-03-07 13:43 ` Tim Moore
2007-03-07 21:51 ` Andrew Cagney
0 siblings, 1 reply; 4+ messages in thread
From: Tim Moore @ 2007-03-07 13:43 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Stan Cox, Frysk List
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Andrew Cagney wrote:
> 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:
I checked in changes that implement the "run" command in the CLI command
line. It will be quite easy to adapt the fhpd program to pass an
argument to run a program named in its arguments. This works well for
our simple looping test cases, but I also didn't think about the
terminal issue.
>
> - fhpd command line where it clearly should create the PTY
What should the other side of the pty be bound to? An xterm?
> - UI where the pty will be part of a Terminal panel and the code should
> bind the created process to that
Tim
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iD8DBQFF7sGEeDhWHdXrDRURAkSCAKCmIQytNY8hY7bbvWLOBQ65iEgarACfc/3x
HfdWe0wEDL53GNbmNkNQrT0=
=PsgH
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: fhpd <program>
2007-03-07 13:43 ` Tim Moore
@ 2007-03-07 21:51 ` Andrew Cagney
0 siblings, 0 replies; 4+ messages in thread
From: Andrew Cagney @ 2007-03-07 21:51 UTC (permalink / raw)
To: Tim Moore; +Cc: Stan Cox, Frysk List
Tim Moore wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Andrew Cagney wrote:
>
>> 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:
>>
> I checked in changes that implement the "run" command in the CLI command
> line. It will be quite easy to adapt the fhpd program to pass an
> argument to run a program named in its arguments. This works well for
> our simple looping test cases, but I also didn't think about the
> terminal issue.
>
>> - fhpd command line where it clearly should create the PTY
>>
> What should the other side of the pty be bound to? An xterm?
>
Good question.
For the text only case, it could start a terminal (there's a gtk object
accessable to frysk for doing that) but I would expect a user running
just the command line to be doing so because they do not want to use X
and do not want or have access to an X based terminal. Instead the
controlling-pty would be managed by the HPD. That will allow the HPD to
control the child's output - say only displaying it when there is no HPD
command input, and, when specified, switching all I/O to the child. The
HPD spec discusses this.
I would expect that just that mode will prove sufficient - it covers the
common case of a program doing printf level I/O. For a program
attempting complex terminal manipulations, graphics, or modes (e.x.,
vi), a dedicated terminal is a requirement (saving all terminal state is
not technically possible). In that senario, it will be better to direct
the user towards a gnome interface where a dedicated terminal is
provided. An option like <<frysk --hpd>>, to start the HPD under GNOME,
might be useful.
Andrew
>> - UI where the pty will be part of a Terminal panel and the code should
>> bind the created process to that
>>
>
> Tim
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
> Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
>
> iD8DBQFF7sGEeDhWHdXrDRURAkSCAKCmIQytNY8hY7bbvWLOBQ65iEgarACfc/3x
> HfdWe0wEDL53GNbmNkNQrT0=
> =PsgH
> -----END PGP SIGNATURE-----
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-03-07 21:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-01 16:15 fhpd <program> Stan Cox
2007-03-06 16:31 ` Andrew Cagney
2007-03-07 13:43 ` Tim Moore
2007-03-07 21:51 ` Andrew 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).