• How to use 'dup' from TclX

    From Helmut Giese@21:1/5 to All on Mon Aug 28 00:02:29 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Helmut Giese on Mon Aug 28 02:01:43 2023
    Helmut Giese <[email protected]> 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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Leitgeb@21:1/5 to Rich on Mon Aug 28 17:18:14 2023
    Rich <[email protected]d> wrote:
    Helmut Giese <[email protected]> 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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Giese@21:1/5 to All on Tue Aug 29 14:53:05 2023
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)