how detect that nothing comes from stdin?

how detect that nothing comes from stdin?

Post by Uwe Boss » Fri, 16 Nov 2001 05:36:49



I want to write a small program, that works as a filter for lpr.
It  should read all command-line parameters and the standard-input
stdin,
do some accounting
and then pass all command-line parameters to lpr and pipe the stdin to
the stdin of lpr.

Now my problem is: if there is a Input at stdin all works fine with
while (cin.good()){
  ch=cin.get();
  write(fd[1],&ch,1);//ch is written to the write-side of the pipe,
which is connected to
                     // lpr
  count++;      //only fpr accounting purposes.

Quote:}

But if there isn't any input at stdin, cin.good() returns true, an my
program will
wait at ch=cin.get() forever. :-(

Is there a way to detect, that nothing comes from stdin and to give up
waiting?
Or is the only way to check the parameters whether a input from stdin is
expected or not?
(in my case, whether the last parameter is a file or not).

Thank you for any hint.

 
 
 

how detect that nothing comes from stdin?

Post by Donovan Rebbech » Fri, 16 Nov 2001 06:43:49



> Or is the only way to check the parameters whether a input from stdin is
> expected or not?
> (in my case, whether the last parameter is a file or not).

This is IMO the best strategy. Note that checking the parameters will
be much simpler if you use getopt (see the manpage)

--
Donovan

 
 
 

how detect that nothing comes from stdin?

Post by Josef M?ller » Fri, 16 Nov 2001 16:32:39



> I want to write a small program, that works as a filter for lpr.
> It  should read all command-line parameters and the standard-input
> stdin,
> do some accounting
> and then pass all command-line parameters to lpr and pipe the stdin to
> the stdin of lpr.

> Now my problem is: if there is a Input at stdin all works fine with
> while (cin.good()){
>   ch=cin.get();
>   write(fd[1],&ch,1);//ch is written to the write-side of the pipe,
> which is connected to
>                      // lpr
>   count++;      //only fpr accounting purposes.
> }
> But if there isn't any input at stdin, cin.good() returns true, an my
> program will
> wait at ch=cin.get() forever. :-(

> Is there a way to detect, that nothing comes from stdin and to give up
> waiting?
> Or is the only way to check the parameters whether a input from stdin is
> expected or not?
> (in my case, whether the last parameter is a file or not).

I'm no C++ programmer, so bear with me:

You are a little unclear by what you mean by "nothing comes from stdin".

If the input is exhausted (all data from a file has been read or the
sending process has closed its side of the pipe/connection), then you
have the "End-Of-File" condition. Under Linux (and most/all Unices),
this will result in the read() system call returning 0. C++ should
provide some means of checking this. I just borrowed the Stroustrup
book from a colleague and it seems that cin.get(ch) will return 0 in
this case, so you could write
        while (cin.good() && cin.get(ch)) {
            write(fd[1], &ch, 1);
            count++;
        }
Another possibility is the "eof" function:
        while (cin.good() && !cin.eof()) {
            ch = cin.get();
            write(fd[1], &ch, 1);
            count++;
        }
(Again, I'm no C++ person and this is absolutely untested)

If, however, you mean that no input is received within a certain amount
of time, you might want to look at the alarm() system call. Set up an
alarm for e.g. 5 seconds before trying to read a character and, if a
character is read, reset the alarm to 0, else handle the timeout
condition.
I don't know how the, rather high-level, C++-streams cooperate with
alarm.

YMMV.

HTH,
--
Josef M?llers (Pinguinpfleger bei FSC)
        If failure had no penalty success would not be a prize
                                                -- T.  Pratchett

 
 
 

how detect that nothing comes from stdin?

Post by Terran Melconi » Sat, 17 Nov 2001 15:30:17





>> Or is the only way to check the parameters whether a input from stdin is
>> expected or not?

>This is IMO the best strategy. Note that checking the parameters will
>be much simpler if you use getopt (see the manpage)

I agree.  It is entirely possible that someone would run your program
as part of a pipeline where it might not receive data for several
hours, so timing out on stdin is really not the way to go at all.
It's much better to decide whether or not to look at stdin based on
the intention of the caller, as expressed in the arguments on the
command line.
 
 
 

how detect that nothing comes from stdin?

Post by Josef M?ller » Sat, 17 Nov 2001 16:56:05






> >> Or is the only way to check the parameters whether a input from stdin is
> >> expected or not?

> >This is IMO the best strategy. Note that checking the parameters will
> >be much simpler if you use getopt (see the manpage)

> I agree.  It is entirely possible that someone would run your program
> as part of a pipeline where it might not receive data for several
> hours, so timing out on stdin is really not the way to go at all.
> It's much better to decide whether or not to look at stdin based on
> the intention of the caller, as expressed in the arguments on the
> command line.

If you cannot use the fact that when an argument is given, input is from
a file by that name and if no argument is given, input is from stdin,
there's always the "standard" way of using e.g. a dash as a filename to
denote input from stdin rather than from a file.

--
Josef M?llers (Pinguinpfleger bei FSC)
        If failure had no penalty success would not be a prize
                                                -- T.  Pratchett

 
 
 

how detect that nothing comes from stdin?

Post by Uwe Boss » Sun, 18 Nov 2001 05:29:18



> You are a little unclear by what you mean by "nothing comes from stdin".

that's right.

Quote:

> If the input is exhausted (all data from a file has been read or the
> sending process has closed its side of the pipe/connection), then you
> have the "End-Of-File" condition.

Ok, if there is any Input, at the end is a eof-byte, or when the input
is binary data (as it is the case, when raw bytes for the printer are
passed to lpr), the connection is closed and a reading access to stdin
will raise an error, which can be detected.

But if there is no input at all, then
cin.get(ch)
will not return a 0-Byte, but waits for ever for a byte to come. Please
tell me, if I am wrong.

Quote:> Another possibility is the "eof" function:
>         while (cin.good() && !cin.eof()) {

eof() is not a good idea when binary data are sent.

Quote:> If, however, you mean that no input is received within a certain amount
> of time, you might want to look at the alarm() system call. Set up an
> alarm for e.g. 5 seconds before trying to read a character and, if a
> character is read, reset the alarm to 0, else handle the timeout
> condition.

This would be an indirect solution to my problem.
Thank you for your hints.
 
 
 

how detect that nothing comes from stdin?

Post by Dave Blak » Sun, 18 Nov 2001 06:24:12



Quote:>  Ok, if there is any Input, at the end is a eof-byte, or when the input
>  is binary data (as it is the case, when raw bytes for the printer are
>  passed to lpr), the connection is closed and a reading access to stdin
>  will raise an error, which can be detected.

>  But if there is no input at all, then
>  cin.get(ch)
>  will not return a 0-Byte, but waits for ever for a byte to come. Please
>  tell me, if I am wrong.

This depends on what stdin is listening to. If it is connected
to a terminal device, the terminal is probably not returning the
read call to stdin until some number of bytes is present
(usually one).

Look into the tcsetattr and tcgetattr functions

info->libc->low level terminal

--
Dave Blake

 
 
 

how detect that nothing comes from stdin?

Post by Kasper Dupon » Sun, 18 Nov 2001 10:20:19



> Ok, if there is any Input, at the end is a eof-byte,

On Unix/Linux there is no eof-byte.

Quote:

> But if there is no input at all, then
> cin.get(ch)
> will not return a 0-Byte, but waits for ever for a byte to come.

I wouldn't expect it to sleep for ever, but I don't know  for
sure what it is going to return. I don't see why you would
expect a 0-byte at the end of the stream. If it behaves like
the getchar function it returns EOF. Notice that the return
value of getchar is not a char but an int. That is done to be
able to return 257 different values, EOF and 256 different
chars.

Quote:

> > Another possibility is the "eof" function:
> >         while (cin.good() && !cin.eof()) {

> eof() is not a good idea when binary data are sent.

Why not? I guess it is supposed to work.

--
Kasper Dupont