Is it possible to timeout an ipstream process after a defined period? I am issuing a lpd print queue command and if there is not a response within 5 seconds I want to stop the ipstream process and then call an error routine.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
PStreams doesn't currently provide a way of setting a timeout, but you can use an alarm signal to interrupt the process while it's waiting for data. I hope this program demonstrates the idea:
If getline() does not return before the alarm it will be interrupted, timed_out will be set, control will return to the main function and the error handling will be run.
I hadn't planned to make PStreams include this functionality as it might interfere with other signal handling in the program, but since using it would be optional I will reconsider it.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I should add that the example program is incomplete. In a real program you would have to reset the alarm to prevent it timing out after a successful read. You should also restore the default action for the SIGALRM signal.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
A successful qchk command displays soething similar to the following:
qchk -P R1129
Queue Dev Status Job Files User PP % Blks Cp Rnk
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
R1129 hp4mv READY
R1129: JetDirect lpd: no jobs queued on the port Auto
A failed qchk command looks similar to the following:
qchk -P Q1111
Queue Dev Status Job Files User PP % Blks Cp Rnk
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
Q1111 hp4si READY
: (WARNING) 0781-375 Connection to server failed.
rembak: errno = 81: A route to the remote host is not available.
Q1111 queue HOST_DOWN
Is it possible to timeout an ipstream process after a defined period? I am issuing a lpd print queue command and if there is not a response within 5 seconds I want to stop the ipstream process and then call an error routine.
PStreams doesn't currently provide a way of setting a timeout, but you can use an alarm signal to interrupt the process while it's waiting for data. I hope this program demonstrates the idea:
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <pstream.h>
// whether we timed out or not
volatile sig_atomic_t timed_out = 0;
void signal_handler(int)
{
timed_out = 1;
}
int main()
{
using namespace redi;
sigset_t block_mask;
sigemptyset(&block_mask);
struct sigaction action;
action.sa_handler = signal_handler;
action.sa_mask = block_mask;
action.sa_flags = 0;
// set signal handler for SIGALRM
sigaction(SIGALRM, &action, 0);
srand(time(0));
int timeout = rand() % 4 + 1;
std::cout << "Time out in " << timeout << " seconds" << std::endl;
ipstream child("sleep 2 && echo finished");
alarm(timeout); // raise SIGALRM after timeout seconds
std::string s;
std::getline(child, s);
if (timed_out)
{
std::cerr << "Timed out\n";
child.rdbuf()->kill();
return EXIT_FAILURE;
}
else
{
std::cout << s << std::endl;
return EXIT_SUCCESS;
}
}
If getline() does not return before the alarm it will be interrupted, timed_out will be set, control will return to the main function and the error handling will be run.
I hadn't planned to make PStreams include this functionality as it might interfere with other signal handling in the program, but since using it would be optional I will reconsider it.
I should add that the example program is incomplete. In a real program you would have to reset the alarm to prevent it timing out after a successful read. You should also restore the default action for the SIGALRM signal.
Thanks for the response. A further question:
I am using AIX and its qchk command.
A successful qchk command displays soething similar to the following:
qchk -P R1129
Queue Dev Status Job Files User PP % Blks Cp Rnk
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
R1129 hp4mv READY
R1129: JetDirect lpd: no jobs queued on the port Auto
A failed qchk command looks similar to the following:
qchk -P Q1111
Queue Dev Status Job Files User PP % Blks Cp Rnk
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
Q1111 hp4si READY
: (WARNING) 0781-375 Connection to server failed.
rembak: errno = 81: A route to the remote host is not available.
Q1111 queue HOST_DOWN
I use the following code to get the output:
ipstream qchk("qchk -P Q1111");
string buffer;
while ( getline(qchk, buffer) ) {
cout << buffer << endl;
}
A failed qchk command immediately displays:
qchk -P Q1111
Queue Dev Status Job Files User PP % Blks Cp Rnk
------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
Q1111 hp4si READY
and then after 45 seconds displays the remainder of the text (: (WARNING) ... ).
The following code still waits 45 seconds (the remaining code is identical to that which you provided):
...
...
while ( getline(qchk, buffer) )
{
if (timed_out)
{
cerr << "Timed out\n";
qchk.rdbuf()->kill(9);
}
else
{
qchkVct.push_back (buffer);
}
}
if (! timed_out)
{
copy(qchkVct.begin(), qchkVct.end(), ostream_iterator<string>(cout, "\n"));
}
Would you know why it still waiting the 45 seconds?
Hi Brian,
I've never tested PStreams on AIX, so although it *should* work exactly the same I can't guarantee it.
I'm not sure why your program is still pausing, but I'll think about it and see if I can figure it out...
jon