Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to use 'dup' from TclX

83 views
Skip to first unread message

Helmut Giese

unread,
Aug 27, 2023, 6:02:35 PM8/27/23
to
Hello out there,
I have some data that I use to analyse the behaviour of my program.
Now I thought it would be a good idea to include this data in my
repository.
But the data is generated by using 'puts' so I would need a way to
redirect 'puts' to 'stdout'.
I found 'dup' from TclX but apparently I cannot use it correctly. Here
is my (compressed) attempt:
---
package require Tclx

proc dumpTree {data} {
puts $data
}

proc process {data} {
set fName dump.txt
if {[file exists $fName]} {
file delete $fName
}
set fd [open $fName w]
dup $fd stdout
dumpTree $data
close $fd
}
process "some data"
---
The file 'dump.txt' is generated but it is empty. Moreover running
this programm repeatedly produces the error
error deleting "dump.txt": permission denied

Any help on correcting my mistake(s) will be greatly appreciated.
Helmut

Rich

unread,
Aug 27, 2023, 10:01:50 PM8/27/23
to
Helmut Giese <hgi...@ratiosoft.com> wrote:
> Hello out there,
> But the data is generated by using 'puts' so I would need a way to
> redirect 'puts' to 'stdout'.

puts already outputs to stdout by default -- I think you meant
"redirect stdout into a file".

> I found 'dup' from TclX but apparently I cannot use it correctly.
> Here is my (compressed) attempt:

From what I read in the tclx manpage, your code looks to be using the
dup call correctly.

> proc dumpTree {data} {
> puts $data
> }

One suggestion for an alternative. Assuming you can modify the code,
write your 'dumpTree' this way:

proc dumpTree {data {fd stdout}} {
puts $fd $data
}

When you want the data to go to stdout, call it as:

dumptree $data

When you want to dump to a file:

set fd [open dump.txt {WRONLY CREAT TRUNC}]
dumptree $data $fd
close $fd

> The file 'dump.txt' is generated but it is empty. Moreover running
> this programm repeatedly produces the error
> error deleting "dump.txt": permission denied

Is the same user running it each time? This looks to be an OS
permissions issue that may have nothing to do with Tcl itself.

Andreas Leitgeb

unread,
Aug 28, 2023, 1:18:19 PM8/28/23
to
Rich <ri...@example.invalid> wrote:
> Helmut Giese <hgi...@ratiosoft.com> wrote:
>> I found 'dup' from TclX but apparently I cannot use it correctly.
>> Here is my (compressed) attempt:
> From what I read in the tclx manpage, your code looks to be using the
> dup call correctly.

I'd probably first dup the original stdout to a new filehandle (one-arg
variant of dup returns new filehandle), then dup the file onto stdout,
and finally (after "dumptree") dup the previously created filehandle
back to stdout.

set dfd [open $dumpfile w]
set origout [dup stdout]; # make backup of application's stdout
dup $fdf stdout
dumptree "Hello World!"
close stdout; close $dfd ;# I think you need to close both!
dup $origout stdout
close $origout ;# close the backup-fd of stout. no need to keep them both

try that - I think your symptom could be caused by not closing
both filedescriptors to the file (namely both stdout and the one
originally returned from open)

Whether you actually need to backup and restore the original stdout
is your decision: does your script ever need to output something to
stdout after the call to "dumptree" ?

PS: another maybe-caveat: if the application is on Windows and
actually opening a window (using Tk, or maybe even just tclsh's
"console") then all the stdout-handling might be just screwed,
so that even redirecting a file-fd to stdout might just not work.
I don't have any experience with Tclx on Windows.

Helmut Giese

unread,
Aug 29, 2023, 8:53:11 AM8/29/23
to
Hi Rich and Andreas,
many thanks to both of you.
>
>I'd probably first dup the original stdout to a new filehandle (one-arg
>variant of dup returns new filehandle), then dup the file onto stdout,
>and finally (after "dumptree") dup the previously created filehandle
>back to stdout.
>
> set dfd [open $dumpfile w]
> set origout [dup stdout]; # make backup of application's stdout
> dup $fdf stdout
> dumptree "Hello World!"
> close stdout; close $dfd ;# I think you need to close both!
> dup $origout stdout
> close $origout ;# close the backup-fd of stout. no need to keep them both
>
Andreas' observation to close stdout, too, was spot on. With this
augmentation my original program works as expected.
And even preserving stdout works on Windows, albeit not within TkCon
(but that is understandable since TkCon does some magic with stdout).
Again many thanks
Helmut
0 new messages