Unix Programming - Strange read problem

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > February 2007 > Strange read problem





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Strange read problem
Jack

2007-02-12, 7:20 am

Hi,

Below is a simple code:

#include <errno.h>
#include <fcntl.h>
#include <iostream.h>
using namespace std;
int main()
{
int handle;
char *BUF = "HELLO, HELLO[20]";
char b[10];
handle = creat("t/a", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int ret = write(handle, BUF, strlen(BUF)); //LINE1
cout << "ret:" << ret << endl;
cout << "BUF:" << BUF << endl;
int err;
int r = read(handle,b, 10); //LINE2
if ( r != 10 )
{
cout<<"r:"<<r<<" Errno:" <<errno<<" b:"<<b<<endl;
}
return 0;

}

The output of the code is:
> ./test


ret:16
BUF:HELLO, HELLO[20]
r:-1 Errno:9 b:T-??T-??T-??T-??T-??T-??T-??T-??

Why the read( ) at LINE2 failed, but the write( ) at LINE1 succeeded.
The errno 9 is:
#define EBADF 9 /* Bad file descriptor */

The file handle works for write( ), but does not work for read( ).
Why?
The system is IBM AIX. The compiler is xlC.

Thanks.

Jack

matevzb

2007-02-12, 7:20 am

On Feb 12, 9:25 am, "Jack" <junw2...@gmail.com> wrote:
> Hi,
>
> Below is a simple code:
>
> #include <errno.h>
> #include <fcntl.h>
> #include <iostream.h>
> using namespace std;
> int main()
> {
> int handle;
> char *BUF = "HELLO, HELLO[20]";
> char b[10];
> handle = creat("t/a", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
> int ret = write(handle, BUF, strlen(BUF)); //LINE1
> cout << "ret:" << ret << endl;
> cout << "BUF:" << BUF << endl;
> int err;
> int r = read(handle,b, 10); //LINE2
> if ( r != 10 )
> {
> cout<<"r:"<<r<<" Errno:" <<errno<<" b:"<<b<<endl;
> }
> return 0;
>
> }
>
> The output of the code is:
>
>
> ret:16
> BUF:HELLO, HELLO[20]
> r:-1 Errno:9 b:T-??T-??T-??T-??T-??T-??T-??T-??
>
> Why the read( ) at LINE2 failed, but the write( ) at LINE1 succeeded.
> The errno 9 is:
> #define EBADF 9 /* Bad file descriptor */
>
> The file handle works for write( ), but does not work for read( ).
> Why?
> The system is IBM AIX. The compiler is xlC.

Because (if you had read the write() the man page), the file offset is
incremented after write(): "Before successful return from write(), the
file offset shall be incremented by the number of bytes actually
written. On a regular file, if this incremented file offset is greater
than the length of the file, the length of the file shall be set to
this file offset."
You have to seek back (in this case to the beginning of a file) in
order to be able to read() - check the lseek() man page. Also, if
read() fails, there's probably no reason to output the buffer
contents. Since it wasn't initialized, it contains trash anyway.
--
WYCIWYG

matevzb

2007-02-12, 7:20 am

On Feb 12, 9:33 am, "matevzb" <mate...@gmail.com> wrote:
> On Feb 12, 9:25 am, "Jack" <junw2...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
>
> Because (if you had read the write() the man page), the file offset is
> incremented after write(): "Before successful return from write(), the
> file offset shall be incremented by the number of bytes actually
> written. On a regular file, if this incremented file offset is greater
> than the length of the file, the length of the file shall be set to
> this file offset."
> You have to seek back (in this case to the beginning of a file) in
> order to be able to read() - check the lseek() man page. Also, if
> read() fails, there's probably no reason to output the buffer
> contents. Since it wasn't initialized, it contains trash anyway.

One more thing, consider open() instead of creat(), since creat()
opens the file as write-only and is considered reduntant by SUSv3.
--
WYCIWYG - what you C is what you get


Beej

2007-02-12, 1:18 pm

On Feb 12, 12:33 am, "matevzb" <mate...@gmail.com> wrote:
> Because (if you had read the write() the man page), the file offset is
> incremented after write(): "Before successful return from write(), the
> file offset shall be incremented by the number of bytes actually
> written. On a regular file, if this incremented file offset is greater
> than the length of the file, the length of the file shall be set to
> this file offset."


This would actually cause read() to return 0 (EOF), not -1, in this
case.

In any case, you're totally right that it's a logic error, and with
the creat() bit, below.

Another note to the OP: you can use perror() or strerror() to get a
nice human-readable string out of errno.

-Beej

David Schwartz

2007-02-13, 1:30 am

On Feb 12, 12:25 am, "Jack" <junw2...@gmail.com> wrote:

Aside from everything else pointed out, this code is broken:

> char b[10];


> int r = read(handle,b, 10); > > if ( r != 10 )
> {
> cout<<"r:"<<r<<" Errno:" <<errno<<" b:"<<b<<endl;
> }
> return 0;


The '<<' operator for streams accepts a 'char *' only if it points to
a C-style string. In this case it does not. This code is broken for
the same reason 'strlen(b)' would be broken here.

DS

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com