Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login




Remember Me
Forgot Password?
Join Us!

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • 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!

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

Donate Today!

Do you enjoy these
technical forums?
Donate Today! Click Here

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.
Jobs from Indeed

Link To This Forum!

Partner Button
Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

Bidirectional Pipe Problem

cptk (TechnicalUser) (OP)
30 Jan 04 17:29
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!!!!
ulis (Programmer)
30 Jan 04 18:43
Try to verify the braces balancing: if the braces mismatch the offending instruction can be out of the scope of the variable.

HTH

ulis
cptk (TechnicalUser) (OP)
30 Jan 04 22:02
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.

cptk (TechnicalUser) (OP)
30 Jan 04 23:27
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
cmds
set fid [open "|cprgm" "r+"]
fconfigure $fid -buffering line

outside any function, but I try to use the variable
fid

in a function, I need to define the fid
variable as
global in the function?
ulis (Programmer)
31 Jan 04 5:48
YES!
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.

HTH

ulis
cptk (TechnicalUser) (OP)
2 Feb 04 11:03
UPDATE ...

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?
marsd (IS/IT--Management)
2 Feb 04 11:18

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

Works for me.
cptk (TechnicalUser) (OP)
2 Feb 04 11:47
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????

marsd (IS/IT--Management)
2 Feb 04 12:24
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.


C CODE:

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



#define iterations 12

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

int main(void) {
int xx = 0;

     srand(time(NULL));
     while (xx < iterations) {
           mysleep(2);
           printf("%s\n", randline());
           fflush(stdout);
           xx++;
     }
     return 0;
}

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

          time(&start);
          current = (time_t)start + val;

              while (start < current) {
                    time(&start);
              }
}

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


TCL CODE
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

HTH
cptk (TechnicalUser) (OP)
3 Feb 04 17:45
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?

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!

Back To Forum

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