Solved

PERL: Checking <STDIN> without actually waiting on it.

Posted on 2004-04-01
21
1,548 Views
Last Modified: 2013-12-25
I want to check if there is something in the <STDIN> buffer, without actually having the system hang waiting for input.

basically:

while(true){
  $cntr=$cntr+1;
  if(<STDIN>){
    do something...
  }
}

i want to be able to run through the loop without it pausing every time to get input, and i want the 'do something' section to run only when there is something in the <STDIN> buffer, i.e. the user has typed something and pressed enter. (basically cntr keeps incrementing while waiting for input)

thanks guys,
Caleb
0
Comment
Question by:Cajones
  • 8
  • 5
  • 4
  • +2
21 Comments
 
LVL 28

Expert Comment

by:FishMonger
ID: 10732600
Do I understand you correctly, you want to get user input from STDIN, but you don't want to wait for the user to actually input anything?  What's the purpose for the counter?  Are you wanting to track the time interval inbetween the receiving of the users input or the number of times that you received input?
0
 
LVL 1

Author Comment

by:Cajones
ID: 10733035
Heh, no i want the user to input something.. but i want the while loop to be unhindered by the <STDIN> because as soon as you use that it holds the system. And im not really using the counter it was just a quick example.. im really working with the Net::AIM protocol and trying to develop an aimbot. and i have this control loop for my shell

while($cmd ne 'exit'){
      print ">> ";
      $aim->do_one_loop;
      $line=<STDIN>;chomp($line);
      @lv=split(/ /,$line);
      $cmd=$lv[0];
      if($cmd eq "im"){&sendIM;}
}

now $aim->do_one_loop; reads from the socket, but i need that to continually read from the socket -- not only read once and wait for user input. Yet i still want to be able to get user input.. i just need a way for the loop to continue and only run the cmd parsing when there is actually something in the <STDIN> buffer... does that make sense?

thanks, Caleb
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 10733213
I've never used that module, (in fact I don't even use aim), and it's documentaion is weak, but have you tried using $aim->start() instead of $aim->do_one_loop

This is just a personal preference of mine, but here's a couple of syntax changes that I'd suggest.

chomp($line = <STDIN>);

sendIM() if ($cmd eq'im');
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 1

Author Comment

by:Cajones
ID: 10733290
well, thats just coding style suggestions, and if you use $aim->start it just starts its own infinite loop. I still want to be able to have some control after that.. like be able to send im's from the cmd line... so i need to create my own loop

do you know of a way to check if the <STDIN> buffer is full without actually trying to get anything from it, so it wont hang?
0
 
LVL 3

Expert Comment

by:rkosai
ID: 10733849
You may want to consider using fork to create two threads in this case.  Consider reading the perlfork documentation at http://www.perldoc.com/perl5.8.0/pod/perlfork.html.

my $pid = fork();
if ($pid) { #parent process
  while(1) {
    $aim->do_one_loop;
    sleep 1;
  }
} elseif (defined($pid)) {
  #child process
  while ($command = <STDIN>) {
    handle_command($command);
  }
} else {
  #fork failed, handle error
}
0
 
LVL 1

Author Comment

by:Cajones
ID: 10735261
hey, rkosai... fork just might do it.. i didnt know perl could fork... let me try it out!
thanks, Caleb
0
 
LVL 48

Expert Comment

by:Tintin
ID: 10736793
Can I ask if there is a CGI component to this question?
0
 
LVL 1

Author Comment

by:Cajones
ID: 10738463
well its PERL, and PERL is a CGI language :-D

and cgi means common gateway interface, and aim is a common gateway... sorta ;)

hey rkosai... forking the process seems to have issues.. will the $aim variable be a pointer to the original $aim object, or just a copy of it? because its yelling at me for having undefined variables in the module (i think one of the shared variables isnt getting transfered)... any ideas?

~caleb
0
 
LVL 3

Expert Comment

by:rkosai
ID: 10738970
If I recall correctly, only the parent will have the variables previously set in the script.  You'll have to use interprocess communication documented in the perlipc man page.  (http://www.perldoc.com/perl5.8.0/pod/perlipc.html)
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 10739116
AIM has nothing to do with CGI.
http://www.google.com/search?q=define:CGI
0
 
LVL 3

Expert Comment

by:rkosai
ID: 10742026
You're quite right.  This is not a CGI question.  However, this is true of many of the questions we answer in this forum.  For example, these two questions both are DBI related and don't necessarily have any relevance to CGI.  Does this mean we should question the validity of requests that only ask about Perl, and not the Common Gateway Interface specification?

http://www.experts-exchange.com/Web/Web_Languages/CGI/Q_20917094.html
http://www.experts-exchange.com/Web/Web_Languages/CGI/Q_20923999.html

Just a thought.
0
 
LVL 1

Author Comment

by:Cajones
ID: 10743821
"Any piece of software can be a CGI program if it handles input and output according to the CGI standard" .. according to your definition, aim may not use the CGI standard exactly buts why i said sorta ;) however it does interact with a web server -- anyway, thats just semantics, and not why we are all here (i honestly didnt know where to place this question, and when i think CGI i think PERL, so i asked it here)
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 10745622
If you take that statment out of context, then yes, you're correct.  However 99% of the time, when refering to cgi scripts, were talking about interacting with web pages in some form or another (and have the server do something with our interaction), which is what my prior comment was refering to.  If we stretch the definition of cgi to its limits, then aim might just be in reach.

It's perfectly fine to ask your question here (some of the top Perl experts are also the top cgi experts), but the Perl section might have been better for this question.

As to your question, fork might be what you need, but it doesn't directly answer the question/problem you first stated.  We might need a little more info about what your script is supposed to do, before we can provide the best answer.
0
 
LVL 1

Author Comment

by:Cajones
ID: 10746072
fair enough, i didnt know there was a PERL section, this is the first one i saw.
Basically i want to run a shell where the user can type commands in -- like "im soandso hello" and such and concurrently wait on incoming instant messages -- both of which need an infinite loop to do. so fork seems like a good choice, although i am having problems with talking to the child, i have the child do the $aim loop, but when i send a command to the aim buffer from the parent and the child tries to send the command to the aol server the value isnt there.. and it bombs. Pipe doesnt work because i have to read from stdin and that would need some kind of loop as well defeating the purpose of splitting the process off in the first place.
i dont know if any of that makes sense.. but thats what im trying to do
0
 
LVL 28

Accepted Solution

by:
FishMonger earned 43 total points
ID: 10746629
So, as I understand it, you want to use Perl to recreate what AOL's instantant messanger program is already doing?  Is this an assignment for a programming class?

I've had too many glasses of wine tonight to write code, but you may want to look at some of the other cpan modules.  Start with these ones to see if they will help.

http://search.cpan.org/~matthewg/Net-OSCAR-1.11/OSCAR.pm
http://search.cpan.org/~elizabeth/forks-0.15/lib/forks/shared.pm
0
 
LVL 1

Author Comment

by:Cajones
ID: 10746835
yeah, basically im trying to write a cmd line aim
0
 
LVL 3

Assisted Solution

by:rkosai
rkosai earned 41 total points
ID: 10749610
"i have the child do the $aim loop, but when i send a command to the aim buffer from the parent and the child tries to send the command to the aol server the value isnt there.. and it bombs"

Did you see my comment about Interprocess Communication?  I think you're going to need to use that to have the child tell the parent to send it.

0
 
LVL 1

Author Comment

by:Cajones
ID: 10749721
hey rkosai, unless im completely nuts.. doesnt the perl IPC write to the standard in of the process you send it to? That's the impression I got and if thats so, you are still going to have to wait on STDIN in the child, does anyone happen to have an example code that sends a string to a child process and how the child process is supposed to receive it?
sorry im being so dense..
~Caleb
0
 
LVL 2

Assisted Solution

by:mishagale
mishagale earned 41 total points
ID: 10838984
I think doing multiple threads/processes here is overkill - all Caleb needs it to do non-blocking input on STDIN. According manpages (perlopentut) you can do the following to make a filehandle non-blocking:

    use Fcntl;
    fcntl(STDIN, F_SETFL, O_NONBLOCK)
        or die "can't set non blocking: $!";

After this call (once, at the begining of your script) you will be able to get data one char at a time. If there is no data, read() returns 0 and lets you get on. I think. I may be wrong about that, in which case you must use select() first to check for data. The main snag is that this won't work on windows, and since you are writing an AIM bot, I imagine thats what you are running.
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Building Windows 10 1 83
Need to learn promise API 2 51
unix purge a column in a csv file EXCEPT the first row which contains the header 4 49
Bulk Reorder File Names 4 67
This tutorial will discuss the log-in process using WhizBase. In this article I assume you already know HTML. I will write the code using WhizBase Server Pages, so you need to know some basics in WBSP (you might look at some of my other articles abo…
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to dynamically set the form action using jQuery.

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question