changing I/O channels
From: Eric Smith (eric-no-spam-for-me_at_brouhaha.com)
Date: 02/28/04
- Next message: Donal K. Fellows: "Re: Use "foreach i [range ...], not "for"?"
- Previous message: marvin: "Re: xotcl accessing member variable from inside a tcl proc"
- Next in thread: Marco Maggi: "Re: changing I/O channels"
- Reply: Marco Maggi: "Re: changing I/O channels"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 27 Feb 2004 15:04:08 -0800
I'm embedding Tcl as a debugger language into a simulator, similar to what
I've done in the Altogether simulator for the Xerox Alto:
http://altogether.brouhaha.com/
In this simulator, Tcl runs in its own thread. I need the Tcl stdin,
stdout, and stderr channels to be directed to a PTY, but the PTY is on
file descriptors other than 0, 1, and 2. I can't play games with
rearranging the Unix file descriptors, because it would interfere with
standard I/O in my other two threads.
I tried the code below, but it segfaults in the call to Tcl_RegisterChannel().
I also wasn't sure whether Tcl_UnregisterChannel() was the right thing to
call. Initially I tried Tcl_Close(), but that complained "called Tcl_Close
on channel with refCount > 0".
I'm also somewhat confused by the documentation for Tcl_MakeFileChannel().
The man page says that you have to register the channel with
Tcl_RegisterChannel. It also says that if one of the stnadard channels
was previously closed, the act of creating the channel also assigns it as
a replacement. But surely it must be the act of registering the channel,
not the act of creating it, that assigns it as the replacement?
Thanks!
Eric Smith
[To reply by private email, please remove the obvious spam-proofing from
my email address.]
Tcl_Channel tcl_reopen (Tcl_Interp *interp, char *name, int fd, int rw)
{
Tcl_Channel chan;
chan = Tcl_GetChannel (interp, name, NULL);
if (chan)
{
if (Tcl_UnregisterChannel (interp, chan) != TCL_OK)
fprintf (stderr, "error unregistering Tcl %s channel\n", name);
}
else
fprintf (stderr, "error getting Tcl %s channel\n", name);
chan = Tcl_MakeFileChannel ((void *) fd, rw);
Tcl_RegisterChannel (interp, chan);
/* need to register? */
return (chan);
}
void init_tcl (dbg_t *dbg)
{
cmd_entry *ce;
dbg->tcl_interp = Tcl_CreateInterp ();
dbg->tcl_stdin = tcl_reopen (dbg->tcl_interp,
"stdin",
dbg->slave_pty,
TCL_READABLE);
dbg->tcl_stdout = tcl_reopen (dbg->tcl_interp,
"stdout",
dbg->slave_pty,
TCL_WRITABLE);
dbg->tcl_stderr = tcl_reopen (dbg->tcl_interp,
"stderr",
dbg->slave_pty,
TCL_WRITABLE);
for (ce = & cmd_table [0]; ce->name != NULL; ce++)
Tcl_CreateCommand (dbg->tcl_interp,
ce->name,
ce->handler,
dbg,
NULL);
}
- Next message: Donal K. Fellows: "Re: Use "foreach i [range ...], not "for"?"
- Previous message: marvin: "Re: xotcl accessing member variable from inside a tcl proc"
- Next in thread: Marco Maggi: "Re: changing I/O channels"
- Reply: Marco Maggi: "Re: changing I/O channels"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|