Link to home
Start Free TrialLog in
Avatar of Cajones
Cajones

asked on

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

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
Avatar of FishMonger
FishMonger
Flag of United States of America image

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?
Avatar of Cajones
Cajones

ASKER

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
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');
Avatar of Cajones

ASKER

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?
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
}
Avatar of Cajones

ASKER

hey, rkosai... fork just might do it.. i didnt know perl could fork... let me try it out!
thanks, Caleb
Can I ask if there is a CGI component to this question?
Avatar of Cajones

ASKER

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
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)
AIM has nothing to do with CGI.
http://www.google.com/search?q=define:CGI
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?

https://www.experts-exchange.com/questions/20917094/perl-Win32-ODBC-help.html
https://www.experts-exchange.com/questions/20923999/passing-an-argument-to-a-subroutine.html

Just a thought.
Avatar of Cajones

ASKER

"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)
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.
Avatar of Cajones

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of FishMonger
FishMonger
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Cajones

ASKER

yeah, basically im trying to write a cmd line aim
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Cajones

ASKER

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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial