Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here


Bidirectional Pipe Problem

Bidirectional Pipe Problem

Bidirectional Pipe Problem

I have ...
set fid [open "|cprgm" "r+"]
fconfigure $fid -buffering line
puts $fid "1"
gets $fid c_return

Where cprgm is a C program that basically sits in an infinite loop, waits for input with the scanf cmd,
then takes the input and goes through a switch/case
cmd based on the value of the input.
The C program runs fine by itself (i.e. - standalone),
however when I run it with the above tcl code, it gives the following error:

Can't read "fid": no such variable.

When I look at the stack trace for error, it fails at the
puts line above.

Could it be it can't find the cprgm file (even though I've tried using the absolute path in the open cmd).
I'm stumped.  Thanks for any help!!!!

RE: Bidirectional Pipe Problem

Try to verify the braces balancing: if the braces mismatch the offending instruction can be out of the scope of the variable.



RE: Bidirectional Pipe Problem

I don't see where the braces are off-balanced. Do you mean
within the tcl/tk script?  If so, I'm pretty sure that's ok - in fact, I have these commands outside of any function/procedure.  They reside at the global level, near the beginning.  Could this be the problem?

Other notes: The problem, although I've stated occurs with the put cmd, it's actually with the set fid [open "|cprgm" "r+"] cmd. It doesn't seem recognize something in the open cmd.

To be safe, I did chmod the cprgm to 777.

RE: Bidirectional Pipe Problem

Some more thoughts ...
Could the problem be:
1.) I have the r+ in quotes (i.e. - set fid [open "|cprgm" "r+"]
2.) I'm rusty on this, but since I defined the
set fid [open "|cprgm" "r+"]
fconfigure $fid -buffering line

outside any function, but I try to use the variable

in a function, I need to define the fid
variable as
global in the function?

RE: Bidirectional Pipe Problem

You have to add a global fid in the script of the  proc and before any use of fid.

Alternatively you can use the :: notation for referencing fid: fconfigure $::fid -buffering line.

What happens is that the vars environment of a proc does'nt include the surrounding namespace env (the global one for you). This is different of the procs environment that includes the surrounding namespace env.

One more thing: the same occurs for the scripts in the callbacks (fileevent script for example). You don't have to worry with that if you don't 'code' in the script but only call a proc.



RE: Bidirectional Pipe Problem


My problem, as I suspected, was that I didn't define the fileid as global in the proc.  The issue of whether or not to quote the "r+" is a non-issue ... it doesn't matter.

But now I'm having buffering problems to work out ... I'm fflushing the stdout from the c program, but the front-end tcl script is only seeing one input line at a time -- I have many lines coming in from the c prgrm.  
How do I loop the "gets" cmd efficently in the tcl script?

RE: Bidirectional Pipe Problem

while {[gets $fd line] > -1} {
      #do stuff with $line

Works for me.

RE: Bidirectional Pipe Problem

marsd: For some reason, the stmt
while {[gets $fd line] > -1} it's not working for me.

For example ...
Using a very simple tcl script, I click on a button in the tcl prgm, it executes a proc that sends a puts $fid "1" to c program.  The c program, which waits for input, takes the value "1" via a switch cmd, and executes a printf line 3 times.

In  the same proc as the "puts" cmd, I use the gets $fid retval cmd.  By itself (without the gets in a while loop) the gets works fine. When I put three of these gets statements in succession, it works fine.  When I put the forth gets line in, it obviuosly hangs (waiting for input).

Thus, when I try to use the gets in a while loop, it hangs. Anotherwords, it doesn't know to exit when there's no more data to read in.

What am I missing here????

RE: Bidirectional Pipe Problem

Somehow eof is being missed.
I would strongly suspect the C program here or
your fconfigure options.  

I'm on a windows machine today so my options are
limited but I created a working scenario with
source for comparison sake.


#include <stdlib.h>
#include <time.h>

#define iterations 12

void mysleep(int val);
char *randline(void);

int main(void) {
int xx = 0;

     while (xx < iterations) {
           printf("%s\n", randline());
     return 0;

void mysleep(int val) {
time_t start, current;

          current = (time_t)start + val;

              while (start < current) {

char *randline(void) {
int p;
char *new = malloc(iterations * sizeof(char));

      for (p=0 ; p < iterations ; p++) {
           new[p] = (char)(1 + rand() % 128);
      return new;

proc openprog {pname} {
      if {![file exists $pname]} {error "Could not find $pname"}
      set popen [open "|$pname" r]
      fconfigure $popen -buffering line
      while {[gets $popen line] > -1} {
              puts "read from $popen: $line"
      catch {close $popen}

Output of openprog:

openprog c:/lcc/lcc1/slow_out.exe
read from fileb154e8: $'l.g.3
read from fileb154e8: }.1
read from fileb154e8: S.eZX6EvX/
read from fileb154e8: (qm"uT!.P2)
read from fileb154e8: at$jF    
read from fileb154e8: /w
read from fileb154e8: idj'v'$/z"P
read from fileb154e8: Q{8p
read from fileb154e8: jsH-
read from fileb154e8: Bh:''~_:"2_
read from fileb154e8: h;i~QOd'Do
read from fileb154e8: ]wku:16Y
read from fileb154e8: 5
read from fileb154e8: w!GMkBW9_x;
read from fileb154e8: ;W*p;4+S
read from fileb154e8: "
read from fileb154e8: 8'xU?1?nv


RE: Bidirectional Pipe Problem

I played around with some options and found that if I use
fconfigure $fid -blocking no,
it works.

By the way, the data coming in from the c program comes in via the following cmd:

fprintf(stdout, "%d %s ...etc.", var1 var2 ...etc);
also, I do fflush(stdout); after each
fprintf cmd.

So, what's this no blocking doing for me?  Can I get into trouble with this cmd?

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close