How ped read a file ??

I have a resource manager providing some pseudo files with different
sizes.
If I tried to open one of these files with Ped, my resource manager
enter in my io_read function with an offset setted to a strange value if
the size of the file is bigger that 42 bytes !?! and in that case,
iofunc_attr_p->nbytes - tocb->ocb.offset is always equal to 42 !!!

It never happens with any over editors vi, Visual SlickEdit, notepad,
elvis, cat, but cat reads character by character.

Any idea?

Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

I have a resource manager providing some pseudo files with different
sizes.
If I tried to open one of these files with Ped, my resource manager
enter in my io_read function with an offset setted to a strange value if
the size of the file is bigger that 42 bytes !?! and in that case,
iofunc_attr_p->nbytes - tocb->ocb.offset is always equal to 42 !!!

It never happens with any over editors vi, Visual SlickEdit, notepad,
elvis, cat, but cat reads character by character.

Any idea?

I think ped throws some formatting/highlighting type information at or
near the end of the file. I would bet that the header/size of the
initial information it looks at to check is 42 bytes, and it expects
it to be at the end of the file.

So, it seeks to the end, then reads the last 42 bytes to check if it
has saved attribute informaton there.

Try running ped on an ordinary file in the file system, then use the
menus to change the color or font of some of the characters, then save
the file & re-open it with cat/vi/less/more or equivalent and take a
look.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
I have a resource manager providing some pseudo files with different
sizes.
If I tried to open one of these files with Ped, my resource manager
enter in my io_read function with an offset setted to a strange value if
the size of the file is bigger that 42 bytes !?! and in that case,
iofunc_attr_p->nbytes - tocb->ocb.offset is always equal to 42 !!!

It never happens with any over editors vi, Visual SlickEdit, notepad,
elvis, cat, but cat reads character by character.

Any idea?

I think ped throws some formatting/highlighting type information at or
near the end of the file. I would bet that the header/size of the
initial information it looks at to check is 42 bytes, and it expects
it to be at the end of the file.

So, it seeks to the end, then reads the last 42 bytes to check if it
has saved attribute informaton there.

Try running ped on an ordinary file in the file system, then use the
menus to change the color or font of some of the characters, then save
the file & re-open it with cat/vi/less/more or equivalent and take a
look.

-David

QNX Training Services
dagibbs@qnx.com

!!!??!! Maybe !!??!!

The last line of block styled file is:

#** PhEDIT attribute block ends (-0000163)**/

So, if the offset read index is first placed at the end of the file, rewinding
it of 42 characters place it on ‘P’ !


But I don’t understand the problem. If it works on a regular file, with or
without block syle, and it don’t works with my resource manager, I certainly
do something wrong in my replying, no?

Thanks,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

David Gibbs a ecrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
I have a resource manager providing some pseudo files with different
sizes.
If I tried to open one of these files with Ped, my resource manager
enter in my io_read function with an offset setted to a strange value if
the size of the file is bigger that 42 bytes !?! and in that case,
iofunc_attr_p->nbytes - tocb->ocb.offset is always equal to 42 !!!

Any idea?

I think ped throws some formatting/highlighting type information at or
near the end of the file. I would bet that the header/size of the
initial information it looks at to check is 42 bytes, and it expects
it to be at the end of the file.

So, it seeks to the end, then reads the last 42 bytes to check if it
has saved attribute informaton there.

!!!??!! Maybe !!??!!

The last line of block styled file is:

#** PhEDIT attribute block ends (-0000163)**/

So, if the offset read index is first placed at the end of the file,
rewinding it of 42 characters place it on ‘P’ !

But I don’t understand the problem. If it works on a regular file, with or
without block syle, and it don’t works with my resource manager, I certainly
do something wrong in my replying, no?

Probably – you didn’t mention that there was actually an error/problem
reported by ped in your initial post, just that you got a strange-looking
initial read from the file, and I was explaining why I thought that happened.
If ped is having some sort of problem/error, then probably yes you are
doing something wrong in how you reply to it, but without out more details
on what ped is complaining about, or what you are actually doing, it is
hard to diagnose.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
I have a resource manager providing some pseudo files with different
sizes.
If I tried to open one of these files with Ped, my resource manager
enter in my io_read function with an offset setted to a strange value if
the size of the file is bigger that 42 bytes !?! and in that case,
iofunc_attr_p->nbytes - tocb->ocb.offset is always equal to 42 !!!

Any idea?

I think ped throws some formatting/highlighting type information at or
near the end of the file. I would bet that the header/size of the
initial information it looks at to check is 42 bytes, and it expects
it to be at the end of the file.

So, it seeks to the end, then reads the last 42 bytes to check if it
has saved attribute informaton there.

!!!??!! Maybe !!??!!

The last line of block styled file is:

#** PhEDIT attribute block ends (-0000163)**/

So, if the offset read index is first placed at the end of the file,
rewinding it of 42 characters place it on ‘P’ !

But I don’t understand the problem. If it works on a regular file, with or
without block syle, and it don’t works with my resource manager, I certainly
do something wrong in my replying, no?

Probably – you didn’t mention that there was actually an error/problem
reported by ped in your initial post, just that you got a strange-looking
initial read from the file, and I was explaining why I thought that happened.
If ped is having some sort of problem/error, then probably yes you are
doing something wrong in how you reply to it, but without out more details
on what ped is complaining about, or what you are actually doing, it is
hard to diagnose.

-David

QNX Training Services
dagibbs@qnx.com

In fact, I don’t know if ped complains about something, what I can say is that I
see the file I want to read from my server if its size is lower than 42 bytes. In
that case everything works fine in my server. If the file size is bigger than 42
bytes, Ped is blocked and I don’t see my file in the edit window. In that case,
during the first execution of my io_read handler, offset is not set to 0 so, I
can’t do the work that I need to do correctly and I can’t reply correctly.

in my handler, I assume that the first call to io_read must be done with offset to
0, maybe I’m wrong!

this is my io_read handler:

int io_read_database(resmgr_context_t *ctp, io_read_t *msg, datas_server_ocb_t
*tocb)
{
int nbytes, nleft, nparts;
iofunc_attr_t *iofunc_attr_p = (iofunc_attr_t *)(&tocb->ocb.attr->attr);
char *reply_msg = NULL;

if (optv) {
printf("%s: in io_read_database for %s\n", progname,
basename(database_path[0]));
}

if ((status = iofunc_read_verify(ctp, msg, &tocb->ocb, NULL)) != EOK) {
return(status);
}

if (S_ISDIR(iofunc_attr_p->mode)) {
return(io_read_records_list(ctp, msg, tocb));
} else if (S_ISREG(iofunc_attr_p->mode)) {
// no special xtypes
if (msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE) {
return(ENOSYS);
}

if ((iofunc_attr_p->nbytes - tocb->ocb.offset) == 42) {
printf(" THE bug is comming back nbytes = %d, offset = %d\n",
(int)iofunc_attr_p->nbytes, (int)tocb->ocb.offset);
}

//figure out how many bytes are left
nleft = iofunc_attr_p->nbytes - tocb->ocb.offset;

// and how many bytes we can return to the client
nbytes = min(nleft, msg->i.nbytes);

if (nbytes) {
data_hash_t *data_hash;
if (tocb->record_buffer.name == NULL) {
// This is the case if we execute this function for the first time
for this access; look if we know the device
data_hash = (data_hash_t *)Tcl_GetHashValue((Tcl_HashEntry
*)((int)iofunc_attr_p->inode));
if (data_hash) {
if ((reply_msg = (char *) calloc(1, iofunc_attr_p->nbytes)) ==
NULL) {
return(errno);
}
pthread_rwlock_wrlock(&tocb->record_buffer_rwlock);
if (read_record(&tocb->record_buffer, data_hash) != 0) {
pthread_rwlock_unlock(&tocb->record_buffer_rwlock);
free(reply_msg);
reply_msg = NULL;
return(EFAULT);
}
} else {
free(reply_msg);
reply_msg = NULL;
return(EINVAL);
}
//create the output string
concatenate_database_record(&tocb->record_buffer, reply_msg);
}
SETIOV(ctp->iov, reply_msg +tocb->ocb.offset, nbytes);

_IO_SET_READ_NBYTES(ctp, nbytes);
// return it back to the client
//MsgReply(ctp->rcvid, nbytes, reply_msg + tocb->ocb.offset, nbytes);

//update flags and offset
iofunc_attr_p->flags |= IOFUNC_ATTR_ATIME | IOFUNC_ATTR_DIRTY_TIME;
tocb->ocb.offset += nbytes;

nparts = 1;
} else {
free(reply_msg);
reply_msg = NULL;
free_record_buffer(&tocb->record_buffer);

pthread_rwlock_trywrlock(&tocb->record_buffer_rwlock);
pthread_rwlock_unlock(&tocb->record_buffer_rwlock);

_IO_SET_READ_NBYTES(ctp, 0);

nparts = 0;
}

return(_RESMGR_NPARTS(nparts));
} else {
return(EBADF);
}
}

Thanks,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
I have a resource manager providing some pseudo files with different
sizes.
If I tried to open one of these files with Ped, my resource manager
enter in my io_read function with an offset setted to a strange value if
the size of the file is bigger that 42 bytes !?! and in that case,
iofunc_attr_p->nbytes - tocb->ocb.offset is always equal to 42 !!!

Any idea?

I think ped throws some formatting/highlighting type information at or
near the end of the file. I would bet that the header/size of the
initial information it looks at to check is 42 bytes, and it expects
it to be at the end of the file.

So, it seeks to the end, then reads the last 42 bytes to check if it
has saved attribute informaton there.

!!!??!! Maybe !!??!!

The last line of block styled file is:

#** PhEDIT attribute block ends (-0000163)**/

So, if the offset read index is first placed at the end of the file,
rewinding it of 42 characters place it on ‘P’ !

But I don’t understand the problem. If it works on a regular file, with or
without block syle, and it don’t works with my resource manager, I certainly
do something wrong in my replying, no?

Probably – you didn’t mention that there was actually an error/problem
reported by ped in your initial post, just that you got a strange-looking
initial read from the file, and I was explaining why I thought that happened.
If ped is having some sort of problem/error, then probably yes you are
doing something wrong in how you reply to it, but without out more details
on what ped is complaining about, or what you are actually doing, it is
hard to diagnose.

-David

QNX Training Services
dagibbs@qnx.com

In fact, I don’t know if ped complains about something, what I can say is that I
see the file I want to read from my server if its size is lower than 42 bytes. In
that case everything works fine in my server. If the file size is bigger than 42
bytes, Ped is blocked and I don’t see my file in the edit window. In that case,
during the first execution of my io_read handler, offset is not set to 0 so, I
can’t do the work that I need to do correctly and I can’t reply correctly.

in my handler, I assume that the first call to io_read must be done with offset to
0, maybe I’m wrong!

So if I:

fd = open(“your file”, O_RDONLY);
lseek(fd, 0, SEEK_END);
lseek(fd, -42, SEEK_CUR);
read(fd, buf, buflen);

Your manager is not going to work, right ?

If you really don’t want this happen, you probably want to have your
own “lseek()” handler in resmanager, to fail (or pretend) users request.

-xtang


this is my io_read handler:

int io_read_database(resmgr_context_t *ctp, io_read_t *msg, datas_server_ocb_t
*tocb)
{
int nbytes, nleft, nparts;
iofunc_attr_t *iofunc_attr_p = (iofunc_attr_t *)(&tocb->ocb.attr->attr);
char *reply_msg = NULL;

if (optv) {
printf("%s: in io_read_database for %s\n", progname,
basename(database_path[0]));
}

if ((status = iofunc_read_verify(ctp, msg, &tocb->ocb, NULL)) != EOK) {
return(status);
}

if (S_ISDIR(iofunc_attr_p->mode)) {
return(io_read_records_list(ctp, msg, tocb));
} else if (S_ISREG(iofunc_attr_p->mode)) {
// no special xtypes
if (msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE) {
return(ENOSYS);
}

if ((iofunc_attr_p->nbytes - tocb->ocb.offset) == 42) {
printf(" THE bug is comming back nbytes = %d, offset = %d\n",
(int)iofunc_attr_p->nbytes, (int)tocb->ocb.offset);
}

//figure out how many bytes are left
nleft = iofunc_attr_p->nbytes - tocb->ocb.offset;

// and how many bytes we can return to the client
nbytes = min(nleft, msg->i.nbytes);

if (nbytes) {
data_hash_t *data_hash;
if (tocb->record_buffer.name == NULL) {
// This is the case if we execute this function for the first time
for this access; look if we know the device
data_hash = (data_hash_t *)Tcl_GetHashValue((Tcl_HashEntry
*)((int)iofunc_attr_p->inode));
if (data_hash) {
if ((reply_msg = (char *) calloc(1, iofunc_attr_p->nbytes)) ==
NULL) {
return(errno);
}
pthread_rwlock_wrlock(&tocb->record_buffer_rwlock);
if (read_record(&tocb->record_buffer, data_hash) != 0) {
pthread_rwlock_unlock(&tocb->record_buffer_rwlock);
free(reply_msg);
reply_msg = NULL;
return(EFAULT);
}
} else {
free(reply_msg);
reply_msg = NULL;
return(EINVAL);
}
//create the output string
concatenate_database_record(&tocb->record_buffer, reply_msg);
}
SETIOV(ctp->iov, reply_msg +tocb->ocb.offset, nbytes);

_IO_SET_READ_NBYTES(ctp, nbytes);
// return it back to the client
//MsgReply(ctp->rcvid, nbytes, reply_msg + tocb->ocb.offset, nbytes);

//update flags and offset
iofunc_attr_p->flags |= IOFUNC_ATTR_ATIME | IOFUNC_ATTR_DIRTY_TIME;
tocb->ocb.offset += nbytes;

nparts = 1;
} else {
free(reply_msg);
reply_msg = NULL;
free_record_buffer(&tocb->record_buffer);

pthread_rwlock_trywrlock(&tocb->record_buffer_rwlock);
pthread_rwlock_unlock(&tocb->record_buffer_rwlock);

_IO_SET_READ_NBYTES(ctp, 0);

nparts = 0;
}

return(_RESMGR_NPARTS(nparts));
} else {
return(EBADF);
}
}

Thanks,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

In that case, during the first execution
of my io_read handler, offset is not set to 0 so, I can’t do the work
that I need to do correctly and I can’t reply correctly.



in my handler, I assume that the first call to io_read must be done
with offset to 0, maybe I’m wrong!

This is an incorrect assumption. You can see this from
ped’s behaviour, but any program is actually allowed to do a
lseek(offset);read();. If you don’t want to allow this, you should
override the lseek() and fail it at that point. Or, possibly override
lseek() and do your init work at that point.

this is my io_read handler:

int io_read_database(resmgr_context_t *ctp, io_read_t *msg, datas_server_ocb_t
*tocb)

Side note:

This may be do to debugging, but currently looking at the code, reply_msg
can get allocated but end up not being freed.


-David


QNX Training Services
dagibbs@qnx.com

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:

In that case, during the first execution
of my io_read handler, offset is not set to 0 so, I can’t do the work
that I need to do correctly and I can’t reply correctly.

in my handler, I assume that the first call to io_read must be done
with offset to 0, maybe I’m wrong!

This is an incorrect assumption. You can see this from
ped’s behaviour, but any program is actually allowed to do a
lseek(offset);read();. If you don’t want to allow this, you should
override the lseek() and fail it at that point. Or, possibly override
lseek() and do your init work at that point.

Ok, my problem came from that reply_msg pointer was not static (stupid mistake) so,
multiple read msg couldn’t work of course!

this is my io_read handler:

int io_read_database(resmgr_context_t *ctp, io_read_t *msg, datas_server_ocb_t
*tocb)

Side note:

This may be do to debugging, but currently looking at the code, reply_msg
can get allocated but end up not being freed.

Not found !?!
The only possibilities to not free the buffer is, for a same open and after a first
read:
io_func_read verify() failed - seems impossible.
S_IREG() condition not verified - I don’t think so.
never go in the (nbytes = 0) block of code. I suppose that a read request intiated
by a client will always ends to the (nbytes = 0) block of code, even if the C
library perform several IO_REAd message to get the entire file, no ? Maybe if the
client crashes during a read but what can I do ?

Thanks
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

David Gibbs a ecrit :

Ok, my problem came from that reply_msg pointer was not static
(stupid mistake) so, multiple read msg couldn’t work of course!


this is my io_read handler:

int io_read_database(resmgr_context_t *ctp, io_read_t *msg,
datas_server_ocb_t
*tocb)

Side note:

This may be do to debugging, but currently looking at the code, reply_msg
can get allocated but end up not being freed.


Not found !?!
The only possibilities to not free the buffer is, for a same
open and after a first read: io_func_read verify() failed -
seems impossible.
S_IREG() condition not verified - I don’t think so.

never go in the (nbytes = 0) block of code. I suppose that a read
request intiated by a client will always ends to the (nbytes = 0)
block of code, even if the C library perform several IO_REAd message
to get the entire file, no ? Maybe if the client crashes during a
read but what can I do ?

The never go into the (nbytes=0) block of code is quite possible.

For instance, if a program does a :
open()
fstat() to find out how big the file is
allocate big enough buffer to hold the file
read() of exactly the number of bytes in the file
close()
In that case, you will never get reply_msg being freed.

Or, a process could read just part of the file, find out what it wants,
and close.

Or… lots of other cases…

Also, what happens if two different proceses have the file open at the
same time and are reading from it? Should they be getting the exact
same data? Are you handling multiple different files that use the same
io_read_database() function? If so, you might allocate a new buffer…

It strikes me that the databuffer you are using there would better belong
in either the OCB (per client information) or in the attribute structure,
depending on exactly what is being implement. Using a static in the
read function is not usually a good choice.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:
David Gibbs a ecrit :

Ok, my problem came from that reply_msg pointer was not static
(stupid mistake) so, multiple read msg couldn’t work of course!


this is my io_read handler:

int io_read_database(resmgr_context_t *ctp, io_read_t *msg,
datas_server_ocb_t
*tocb)

Side note:

This may be do to debugging, but currently looking at the code, reply_msg
can get allocated but end up not being freed.


Not found !?!
The only possibilities to not free the buffer is, for a same
open and after a first read: io_func_read verify() failed -
seems impossible.
S_IREG() condition not verified - I don’t think so.

never go in the (nbytes = 0) block of code. I suppose that a read
request intiated by a client will always ends to the (nbytes = 0)
block of code, even if the C library perform several IO_REAd message
to get the entire file, no ? Maybe if the client crashes during a
read but what can I do ?

The never go into the (nbytes=0) block of code is quite possible.

For instance, if a program does a :
open()
fstat() to find out how big the file is
allocate big enough buffer to hold the file
read() of exactly the number of bytes in the file
close()
In that case, you will never get reply_msg being freed.

Or, a process could read just part of the file, find out what it wants,
and close.

As far as I understood, when a file wants to read some bytes whatever he wants
to read the entire file or just a part of the file, we first receive the info
that he wants to read msg->i.nbytes, and the library perform as many io_read msg
as necessary to get this number of bytes, until the resmgr reply with 0 bytes.
So, in any of the two cases, I’ll free my buffer. No ?

Or… lots of other cases…

Also, what happens if two different proceses have the file open at the
same time and are reading from it? Should they be getting the exact
same data? Are you handling multiple different files that use the same
io_read_database() function? If so, you might allocate a new buffer…

You are right, my static pointer is not a good choice here!

It strikes me that the databuffer you are using there would better belong
in either the OCB (per client information) or in the attribute structure,
depending on exactly what is being implement. Using a static in the
read function is not usually a good choice.

Absolutely!

Thanks, David
Alain.

-David

QNX Training Services
dagibbs@qnx.com

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

As far as I understood, when a file wants to read some bytes
whatever he wants to read the entire file or just a part of the
file, we first receive the info that he wants to read msg->i.nbytes,
and the library perform as many io_read msg as necessary to get
this number of bytes, until the resmgr reply with 0 bytes.
So, in any of the two cases, I’ll free my buffer. No ?

No, that is not the case.

Simplified, the code to read() essentially looks like:

int read( int fd, void buf, size_t size )
{
msg.hdr.type = _IO_READ;
msg.hdr.nbytes = size;

return ( MsgSend( fd, &msg, sizeof(msg), buf, size ));

}

It actually does more than that, but the above is the functional
core. If you assume the above, you will get close enough to the
expected behaviour.

Thanks, David

You’re welcome.

-David

QNX Training Services
dagibbs@qnx.com

David,

I don’t think you would have overwhelmed anyone by posting the full
source (you only removed 3 lines :slight_smile:

Did you do this for some sort of legalistic reason (i.e. posting actual
source to newsgroup weakens copyright or something) ? Just curious.

Alain,

The libc source is available at cvs.qnx.com (doesn’t build, but useful
for things like this).

-----Original Message-----
From: David Gibbs [mailto:dagibbs@qnx.com]
Posted At: Tuesday, August 14, 2001 9:57 AM
Posted To: applications
Conversation: How ped read a file ??
Subject: Re: How ped read a file ??


Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

As far as I understood, when a file wants to read some bytes
whatever he wants to read the entire file or just a part of the
file, we first receive the info that he wants to read msg->i.nbytes,
and the library perform as many io_read msg as necessary to get
this number of bytes, until the resmgr reply with 0 bytes.
So, in any of the two cases, I’ll free my buffer. No ?

No, that is not the case.

Simplified, the code to read() essentially looks like:

int read( int fd, void buf, size_t size )
{
msg.hdr.type = _IO_READ;
msg.hdr.nbytes = size;

return ( MsgSend( fd, &msg, sizeof(msg), buf, size ));

}

It actually does more than that, but the above is the functional
core. If you assume the above, you will get close enough to the
expected behaviour.

Thanks, David

You’re welcome.

-David

QNX Training Services
dagibbs@qnx.com

Rennie Allen <RAllen@csical.com> wrote:

David,

I don’t think you would have overwhelmed anyone by posting the full
source (you only removed 3 lines > :slight_smile:

Did you do this for some sort of legalistic reason (i.e. posting actual
source to newsgroup weakens copyright or something) ? Just curious.

No, I just didn’t bother to look at the source, but instead wrote
read() from memory of what it should look like.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs a écrit :

Alain Bonnefoy <> alain.bonnefoy@icbt.com> > wrote:

As far as I understood, when a file wants to read some bytes
whatever he wants to read the entire file or just a part of the
file, we first receive the info that he wants to read msg->i.nbytes,
and the library perform as many io_read msg as necessary to get
this number of bytes, until the resmgr reply with 0 bytes.
So, in any of the two cases, I’ll free my buffer. No ?

No, that is not the case.

Simplified, the code to read() essentially looks like:

int read( int fd, void buf, size_t size )
{
msg.hdr.type = _IO_READ;
msg.hdr.nbytes = size;

return ( MsgSend( fd, &msg, sizeof(msg), buf, size ));

}

It actually does more than that, but the above is the functional
core. If you assume the above, you will get close enough to the
expected behaviour.

Thanks, David

You’re welcome.

-David

QNX Training Services
dagibbs@qnx.com

The work may be done elsewhere because I remember having seen my io_read
handler executed several times until it replied with 0 byte, no ?!


Thanks,
Alain.

Alain Bonnefoy <alain.bonnefoy@icbt.com> wrote:

The work may be done elsewhere because I remember having seen my io_read
handler executed several times until it replied with 0 byte, no ?!

That is a common behaviour – reading 0 bytes from a file shows end of
file, and many programs will read until they get nothing, and then figure
they’re at the end of the file. But you can’t depend on all client
programs to behave in this way.

For instance, the cat utility is, basically, a program that does:

fd = open()
while ( (nbytes = read(fd, buf, bufsize)) != 0)
write(stdout, buf, nbytes );
close( fd )

But, as I said, programs need not read until end of file, and you should
not depend on that behaviour.

-David

QNX Training Services
dagibbs@qnx.com