Curses and getch problem

G

Guest

Hello,
I'm experiencing problems with getch() from Curses. If I want to proces
standard input first with <>, takes all cpu time for, as it seems,
nothing except looping. Here is an example:

#!/usr/bin/perl
use Curses;
1 while <>;
initscr();
while (1) {
if (getch() eq 'q') {
endwin();
exit;
}
}

If you run it like "script.pl < somefile", pressing 'q' doesn't do
anything, whereas if you run it like "script.pl somefile", it works as
expected.

Ideas? Thanks,

andrej
 
M

Michele Dondi

1 while <>; [snip]
If you run it like "script.pl < somefile", pressing 'q' doesn't do
anything, whereas if you run it like "script.pl somefile", it works as
expected.

^D (or ^Z).

Nothing actually to do with Curses, BTW.


Michele
 
G

Guest

1 while <>;
initscr();

Upon examining urlview, which also processes standard input first, I've
found this interesting piece of code:

/* if we piped a file we can't use initscr() because it assumes
`stdin' */
fp = reopen_tty ? fopen ("/dev/tty", "r") : stdin;
scr = newterm (NULL, stdout, fp);
set_term (scr);

But for me it still doesn't work:
[...]
1 while <>
open(TTYI, "/dev/tty") or die $!;
$scr = newterm(undef, STDOUT, TTYI) or die $!;
set_term($scr);
[...]

Please, does anyone know how to make it work?

andrej
 
G

Guest

open(TTYI, "/dev/tty") or die $!;
$scr = newterm(undef, STDOUT, TTYI) or die $!;
set_term($scr);

Okay, at last, here's the solution:


close(STDIN);
^^^^^^^^^^^^^
open(TTYI, "</dev/tty");
$scr = newterm("linux", STDOUT, TTYI) or die $!;
set_term($scr);

I only have to figure out what to pass as the first argument to newterm
or whatever it is that garbles up the screen after usage.

andrej
 
M

Michele Dondi

But for me it still doesn't work:
[...]
1 while <>

If you do not supply args on the cmdline, this will wait for STDIN
forever unless you close it (^D - or ^Z), and Curses or not, the code
that follows will never be reached.
open(TTYI, "/dev/tty") or die $!;
$scr = newterm(undef, STDOUT, TTYI) or die $!;
set_term($scr);
[...]

Please, does anyone know how to make it work?

As I wrote in my followup this has nothing to do with Curses: does the
following "work"?

1 while <>;
die "done!";


HTH,
Michele
 
M

Michele Dondi

Please elaborate; I fail to see what solution you were proposing.

It was kind of a hint. You must read about @ARGV and <> in the docs.
Your program is waiting for input from STDIN. If you give it eof, the
program will pass to the next instructions...


HTH,
Michele
 
G

Guest

Michele said:
It was kind of a hint. You must read about @ARGV and <> in the docs.
Your program is waiting for input from STDIN. If you give it eof, the
program will pass to the next instructions...

It seems like you haven't noticed the following from my first post:
-----
If you run it like "script.pl < somefile", pressing 'q' doesn't do
anything, whereas if you run it like "script.pl somefile", it works as
expected.
----

You could have also tried it out to see what I meant. Anyway, I've
already posted the solution. Looks to me to be curses-related after
all.

Thanks for your input,
andrej
 
G

Guest

Now, the final solution. It's enough to do the following:
open(STDIN, "/dev/tty");

and it will work just perfect.

Bye,
andrej
 
M

Michele Dondi

^
^

Aren't you missing something here?!?
If you do not supply args on the cmdline, this will wait for STDIN
forever unless you close it (^D - or ^Z), and Curses or not, the code
that follows will never be reached.

Incidentally the code you shown doesn't even compile. Mind you: it's
always recommended to paste rather than retype.


Michele
 
M

Michele Dondi

^^^^^^^^^
^^^^^^^^^

Okay, at last, here's the solution:


close(STDIN);
^^^^^^^^^^^^^

I've not tested my guess, but it seems quite reasonable that "here's
the solution" is a side effect of closing STDIN for when <> tries to
access it, it will silently fail, period.

Thinking of it better, it's not too hard to test it:

$ perl -e 'close STDIN; 1 while <>; die "Done"'
Done at -e line 1.

I wouldn't call this "a solution". I'd call it a clumsy workaround.
open(TTYI, "</dev/tty");

Do a favour to yourself and die here too! (No pun intended...)

Do a favour to yourself and use lexical fhs.

Do a favour to yourself and use the three args form of open().
I only have to figure out what to pass as the first argument to newterm
or whatever it is that garbles up the screen after usage.

I can't help you on this. But I can _help_ you recommending you not to
spread clumsy code.


Michele
 
M

Michele Dondi

It seems like you haven't noticed the following from my first post:
-----
If you run it like "script.pl < somefile", pressing 'q' doesn't do
anything, whereas if you run it like "script.pl somefile", it works as
expected.
----

Sorry, I misread your post.


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,124
Latest member
JuniorPell
Top