Solved

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

Posted on 2004-04-01
21
1,533 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 1

Author Comment

by:Cajones
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Can I ask if there is a CGI component to this question?
0
 
LVL 1

Author Comment

by:Cajones
Comment Utility
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
Comment Utility
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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 28

Expert Comment

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

Expert Comment

by:rkosai
Comment Utility
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
Comment Utility
"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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
yeah, basically im trying to write a cmd line aim
0
 
LVL 3

Assisted Solution

by:rkosai
rkosai earned 41 total points
Comment Utility
"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
Comment Utility
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
Comment Utility
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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

The following is a collection of cases for strange behaviour when using advanced techniques in DOS batch files. You should have some basic experience in batch "programming", as I'm assuming some knowledge and not further explain the basics. For some…
Introduction This tutorial will give you a fast look what you can do with WhizBase. I expect you already know how to work with HTML at least, and that you understand the basics of the internet and how the internet works. WhizBase is a server-s…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

762 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now