Cannot detect the end of file.

In the following UNIX code the “fdout_eof” flag never gets set.

/* Read and buffer any available stdout data from the program. */
if (!fdout_eof && FD_ISSET(fdout, readset))
{
len = read(fdout, buf, sizeof(buf));
if (len <= 0)
fdout_eof = 1;
else
{
buffer_append(&stdout_buffer, buf, len);
fdout_bytes += len;
}
}

Does that mean that select() never marks an empty file as ready for
reading?
The “else” branch works fine. Surrounding the “len = read…” with “if
(!eof(fdout))” breaks the other logic of the UNIX program, the flag is set
immediatelly.
Is there any QNX4 specific with “select()”?

Tony.

Tony <mts.spb.suxx@mail.ru> wrote:

In the following UNIX code the “fdout_eof” flag never gets set.

What is fdout?

/* Read and buffer any available stdout data from the program. */
if (!fdout_eof && FD_ISSET(fdout, readset))
{
len = read(fdout, buf, sizeof(buf));
if (len <= 0)
fdout_eof = 1;
else
{
buffer_append(&stdout_buffer, buf, len);
fdout_bytes += len;
}
}

Does that mean that select() never marks an empty file as ready for
reading?

My little test program shows that it does.

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/select.h>

void main( void )
{
int fd1;
fd_set rfd;
int n;
char buf[1000];

fd1 = open("/tmp/blah1", O_RDONLY );

if( fd1 == -1 )
{
perror( “open” );
exit( EXIT_FAILURE );
}

n = read( fd1, buf, 1000);
printf(“read %d bytes\n”);

/*

  • Clear the set of read file descriptors, and
  • add the two we just got from the open calls.
    */
    FD_ZERO( &rfd );
    FD_SET( fd1, &rfd );

switch ( n = select( 1 + fd1,
&rfd, 0, 0, 0 ) ) {
case -1:
perror( “select” );
exit( EXIT_FAILURE );
case 0:
puts( “select timed out” );
break;
default:
printf( “%d descriptors ready …\n”, n );
if( FD_ISSET( fd1, &rfd ) )
puts( " – fd1 descriptor has data pending" );
}
exit( EXIT_SUCCESS );
}

Running this prints:
read 0 bytes
1 descriptors ready …
– fd1 descriptor has data pending

As expected - operating on:
-rw-rw-r-- 1 dagibbs techies 0 Jan 12 15:32 /tmp/blah1

The “else” branch works fine. Surrounding the “len = read…” with “if
(!eof(fdout))” breaks the other logic of the UNIX program, the flag is set
immediatelly.
Is there any QNX4 specific with “select()”?

Oh, probably lots of bits – but I don’t think this is one of them, at
least not for regular files.

What does fdout point to?

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

On 12 Jan 2005 20:34:54 GMT, David Gibbs <dagibbs@qnx.com> wrote:

What does fdout point to?
It’s the file descriptor of the copy of the controlling tty to the child

process (/dev/ptyp0). The unusual about it is the fact it is “dup()”'ed
from the actual master pseudo tty.
The code snipped from the server side i.e. parent process…

The authors comment on this “dup()”'ing that it simplifies some code in
the child.

Tony.

Tony <mts.spb.suxx@mail.ru> wrote:

On 12 Jan 2005 20:34:54 GMT, David Gibbs <> dagibbs@qnx.com> > wrote:

What does fdout point to?
It’s the file descriptor of the copy of the controlling tty to the child
process (/dev/ptyp0). The unusual about it is the fact it is “dup()”'ed
from the actual master pseudo tty.

Ok, it’s an fd to a pty.

In that case, I wouldn’t expect it to select() for read unless there
was actual data to be read. Files are special… but, in general,
a successful select() for read implies that there should be 1 or
more “units” (usually bytes, sometimes blocks) of data available
to be read.

The other times they might select for read, but read() return
0 or -1 is on some sort of disconnect – if this is the master,
read() might select(), but give no data is there is no longer
a process associated with the slave side of the pty.

So, looking at the code, I would never expect that eof flag to
get set, except in the exceptional/cleanup case.

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com

David Gibbs wrote:

Tony <> mts.spb.suxx@mail.ru> > wrote:
It’s the file descriptor of the copy of the controlling tty to the child
process (/dev/ptyp0). The unusual about it is the fact it is “dup()”'ed
from the actual master pseudo tty.

Ok, it’s an fd to a pty.

In that case, I wouldn’t expect it to select() for read unless there
was actual data to be read. Files are special… but, in general,
a successful select() for read implies that there should be 1 or
more “units” (usually bytes, sometimes blocks) of data available
to be read.

A select() on a character device is supposed to return on an EOF, but I
think the problem is that under QNX4 the master end of a pty never
generates an EOF. Try this:

Start “cat /dev/ptyp9” in a pterm.
Then, run “echo Hello > /dev/ttyp9” in another pterm.

Under QNX6 (and, I presume, other Unixes), the cat blocks on read, then
prints out “Hello”, and then gets an EOF and exits. Under QNX4, cat
never gets an EOF – you can run the echo again and again, and cat with
say Hello again and again.

On 12 Jan 2005 21:50:48 GMT, David Gibbs <dagibbs@qnx.com> wrote:

Ok, it’s an fd to a pty.

So, looking at the code, I would never expect that eof flag to get set,
except in the exceptional/cleanup case.
Is it true for other UNIXes too?

Then it must be some glitch in ssh-1.2.33 code, left by the authors…
One can cleanly disconnect only if all file descriptors are closed but the
cleanup process DOES CHECK if “fdout_eof” flag is set…

Thank you for the help!

Tony.

PS
I’ve found a place to hack the flag out and now the ssh client logouts
from the server. But the exit code is -1. Usually, ssh returns the code
from the last process executed.
As a reference I use the telnetd, when I logout from it - the exit code is
+1.
How do I check what exit code “/bin/ksh” returns on executing
“/bin/logout” program?

On Wed, 12 Jan 2005 17:36:35 -0500, Wojtek Lerch <Wojtek_L@yahoo.ca> wrote:

A select() on a character device is supposed to return on an EOF, but I
think the problem is that under QNX4 the master end of a pty never
generates an EOF. Try this:

Start “cat /dev/ptyp9” in a pterm.
Then, run “echo Hello > /dev/ttyp9” in another pterm.
Yes, your example does the trick.

Is it /bin/Dev32.pty v4.23G error or something deeper still?
(QNX v4.25G)

Tony.

On Wed, 12 Jan 2005 17:36:35 -0500, Wojtek Lerch <Wojtek_L@yahoo.ca> wrote:

Under QNX6 (and, I presume, other Unixes), the cat blocks on read, then
prints out “Hello”, and then gets an EOF and exits. Under QNX4, cat
never gets an EOF – you can run the echo again and again, and cat with
say Hello again and again.

Seems, the next QNX4 patch is going to be released soon (I hope).
Will this Dev.pty [mis]feature be addressed there as well?

Tony.

On Thu, 13 Jan 2005 00:50:48 +0300, David Gibbs <dagibbs@qnx.com> wrote:

So, looking at the code, I would never expect that eof flag to get set,
except in the exceptional/cleanup case.

Seems, the next QNX4 patch is going to be released really soon.
Are there any chances this Dev.pty [mis]feature be addressed there as well?

I’d like it to behave more UNIX-like - to return EOF on the other side
close event.

Tony.

Alas… Silence was reply.

Is it possible to have an “experimental” version of Dev.pty that would
return EOF on the other side detach event?

Tony.