changing I/O channels

From: Eric Smith (eric-no-spam-for-me_at_brouhaha.com)
Date: 02/28/04


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);
}



Relevant Pages

  • Re: Fedora Linux and Tcl/Tk problems
    ... translation and encoding configuration on the $fileID ... nicely by some shortcuts modern Tcl supports for binary channels. ... which signals at the time you open the channel that you ... look at the time stamps, that note was answered BEFORE it was ...
    (comp.lang.tcl)
  • TIP #219: Tcl Channel Reflection API
    ... TIP #219: TCL CHANNEL REFLECTION API ... command') and also an independent companion to the forthcoming TIPs on ...
    (comp.lang.tcl)
  • tcl, cell simulator, and simos
    ... simulator (mambo), and some tcl related uses. ... Mambo itself seems to be based on a powerpc simulator ... unwritten page for SimOS on Larry Virden's page. ...
    (comp.lang.tcl)
  • Re: readable callback blocking invoked when theres nothing to read
    ... I'm not a proficient TCL ... the buffering layer matters. ... Fortunately, in Tcl things are different, because all channel ... TCL socket protocol didn't use the callback mechanism. ...
    (comp.lang.tcl)
  • Re: Simulation of VHDL in xilinx from a C program?
    ... I'd like to be able to drive the simulator in ISE from a C program. ... it would be a command-line C app I'd make in ... have the option anyway of doing it as a full Windows app with a gui to do ... In that case you can use Tcl to provide the ...
    (comp.lang.vhdl)