I just recently wanted to something very similar. This is what I came
up with (using tcl 8.4).
The basic idea is that you'll want to define callbacks to handle the
data when it is going to be written to stdout. At that point you can
do whatever you like with it including saving it away.
/** handle channel closed */
static int LogCloseProc(ClientData clientData, Tcl_Interp *interp)
{
return TCL_OK;
}
/** handle output */
static int LogOutputProc(ClientData clientData, const char *buf, int
toWrite, int *errorCodePtr)
{
Tcl_Channel outChannel;
int result;
/* the original channel was set to clientData with Tcl_StackChannel
below */
outChannel = (Tcl_Channel) clientData;
/* really write to the stdout channel */
result = Tcl_WriteRaw(outChannel, buf, toWrite);
*errorCodePtr = (result == -1) ? EAGAIN : 0;
if (result > 0) {
/*
* Your code here
*/
}
return result;
}
/*
* Structure used to define the logging channel that
* logs any data written to stdout (i.e. puts etc.)
*
*/
static Tcl_ChannelType LogChannel = {
"log",
TCL_CHANNEL_VERSION_4,
LogCloseProc,
NULL,
LogOutputProc
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
{ /* ... */
/*
* Create a stacked channel to capture stdout
*
* By default, Tcl does crlf translation on output data on UNIX.
* It doesn't seem matter to a tty but it add ^M to log files.
* We'll turn that off.
*/
outChannel = Tcl_GetStdChannel(TCL_STDOUT);
Tcl_SetChannelOption(interp, outChannel, "-translation", "auto");
Tcl_StackChannel(interp, &LogChannel, outChannel, TCL_WRITABLE,
outChannel);
/* do the same as above for TCL_STDERR */
}
Received on Sun Apr 30 02:27:58 2006