General
cancel
Showing results for 
Search instead for 
Did you mean: 

Error with read() function in C program

SOLVED
Go to solution
Curtis Deese
Frequent Advisor

Error with read() function in C program

We are using the following version of cc on HP-UX 11.31 Itanium: cc: HP C/aC++ B3910B A.06.25 [Nov 30 2009]

We are trying to connect from a PowerBuilder client (compiled 32-bit) on Windows to our C program (compilied 64-bit.) Can this be done? The socket_read() function below is returning the following error. Why are we getting this error and how can we resolve it?

3584-09:03:52.916-log Unable to read from client (0/8) errno(22)

3584-09:03:52.929-log sd : '3'
3584-09:03:52.929-log buffer: '99960000'


int socket_read(int sd, char *buffer, int sz)
{
int nbyte ;

/*
* Set the ALARM signal for TimeOut purpose
*/

/*-- [##ARCS] Testing --*/
/*alarm(server_timeout_secs) ;*/
if ((nbyte = read(sd,buffer,sz)) != sz)
{
LogPrintf("Unable to read from client (%d/%d) errno(%d) \n", nby
te, sz, errno) ;
LogPrintf("sd : '%d'", sd);
LogPrintf("buffer: '%s'", buffer);

shutdown_server() ;
}
/*-- [##ARCS] Testing --*/
/*alarm(0) ;*/
return(nbyte) ;
}
19 REPLIES
Dennis Handly
Acclaimed Contributor

Re: Error with read() function in C program

>connect from a PowerBuilder client (compiled 32-bit) on Windows to our C program (compiled 64-bit.) Can this be done?

Separate processes can be of different bitness. With some issues if using shared memory.

>Unable to read from client (0/8) errno(22)

What is errno 22? What does read(2) say about the conditions that produce that error?

rick jones
Honored Contributor

Re: Error with read() function in C program

If you grep for "22" in /usr/include/sys/errno.h you will likely find the mnemonic for that error number, which will then help give you some clues. That, or perror() or strerror() can be used in your application to get the actual error message for a given errno value. You would then need to go to the read(2) manpage and find that mnenomic listed. Might not be a bad idea to also look at the recv(2) manpage.

As Dennis has said - via "networking" 32 vs 64 bits at either end is a "don't care." However, bit ordering is a "care" - Windows is always "little endian" and HP-UX is always "big endian" and if you expect to exchange binary data between them you will have to take that into account.

Drifting further... I assume this is a TCP connection. That being the case, you cannot assume that you will always get "sz" bytes from the read() call against a TCP connection (unless sz is 1). TCP provides a byte-stream service, it does not preserve message boundaries. Therefore, if the other side sends say 1024 bytes, that could arrive at the receiver as 1024, single-byte receives. You will have to handle that situation in your code. Especially when the quantity of data being transferred is larger than the MSS (maximum segment size) for the TCP connection.

If you do not already have it, something like the latest edition of "Unix Network Programming" by Stevens, Fenner and Rudoff would be a good thing to have on your book shelf. Or perhaps one of Stallings' works.
there is no rest for the wicked yet the virtuous have no pillows
Dennis Handly
Acclaimed Contributor

Re: Error with read() function in C program

>What is errno 22? What does read(2) say about the conditions that produce that error?

I really don't see how you get EINVAL from that read. Though you seem to get 0 bytes back and that doesn't set errno.
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

errno of 22 is EINVAL. I still am not certain why we are getting this. I think the data the PowerBuilder client is sending is not the right size for the server because the PowerBuilder client is compiled 32-bit and the server is compiled 64-bit. I think the memory is getting mixed up between th two. I am waiting for our Oracle DBA to install the 32-bit libraries for Oracle on our UNIX server so that I can compile the server application 32-bit.
rick jones
Honored Contributor

Re: Error with read() function in C program

Again, since TCP is a byte-stream, the read() call won't care about how many bytes are present or not on the socket. If you ask for 8 and there are 800 it will simply return 8. If you ask for 8 and there are only 4 it will give you the four.

Dennis' observation about the return value of 0 and an errno is a very interesting and good one one. One thing to keep in mind is that absent some non-blocking corner case, a read return of 0 from a socket associated with a TCP connection means the remote has closed his end of the connection. The return of zer o is how that is communicated. That is yet another thing your code will have to be fixed to deal with, along with the byte-stream nature of TCP.

As you are not (I hope) trying to pass pointers, the only data type in 64 bit that would be larger than 32 bit would be "long" and those derived from it.

As for the non-blocking corner case - see the O_NDELAY discussion in the recv(2) manpage.
there is no rest for the wicked yet the virtuous have no pillows
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

We are using non-blocking I/O. The code was working on our old server (HP-UX 11.11 PA/RISC). We have had the same code for years. The code was compiled 32-bit on our old server. I had to make some small modifications in the code because we moved from Sybase on our old servers to Oracle on our new servers.
rick jones
Honored Contributor

Re: Error with read() function in C program

Which of the *three* forms of non-blocking I/O does your code use? Only the O_NDELAY form has that troublesome cornercase for recv/read. The other two will always have a return of zero mean the remote has closed its end of the connection.

BTW, little details like the socket being non-blocking are actually quite helpful to include in the initial problem descriptions.
there is no rest for the wicked yet the virtuous have no pillows
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

NDELAY is not found anywhere in our code, so I do not believe we are using it.
rick jones
Honored Contributor

Re: Error with read() function in C program

Then I am quite confident that if indeed your read() call is returning zero that the remote end of the TCP connection has called either close() or shutdown(SHUT_WR), or something akin to them if it is using "native" WSA calls on Windows.
there is no rest for the wicked yet the virtuous have no pillows
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

Here's something I found while researching 'read(2) can return EINVAL for unaligned access to block devices':

The read system call will return EINVAL if the current file offset is not a multiple of the block size.
rick jones
Honored Contributor

Re: Error with read() function in C program

There is no such thing as a block size or alignment for a TCP socket. TCP is a byte-stream.
there is no rest for the wicked yet the virtuous have no pillows
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

I compiled the C program 32-bit. Now I am getting the following error in the log:

-----
7635-15:50:24.529-log -- Commiting After Cache. --
7635-15:53:17.624-log Unable to read from client (0/8) errno(25)

7635-15:53:17.629-log sd : '3'
7635-15:53:17.629-log buffer: '99960000'
------
Notice that the errno changed from 22 to 25. 25 is ENOTTY (Not a typewriter.) Why am I getting the errno=25 and how do I resolve it?

James R. Ferguson
Acclaimed Contributor
Solution

Re: Error with read() function in C program

Hi Curtis:

> Why am I getting the errno=25 and how do I resolve it?

This occurs when STDOUT isn't associated with a terminal, as for example with a daemon-ized program or one run as a crontask.

Regards!

...JRF...
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

Then, if I do not force termination of the program on errno=25, it should work, right?
rick jones
Honored Contributor

Re: Error with read() function in C program

Um, I thought that errno was only valid when read() returned -1. That it has gone from 22 to 25 could simply be a function of reading uninitialized data from different places between 32 and 64 bit.

Again, a read return of zero means the remote end of the TCP connection has called close or shutdown. Or at least it is supposed to.
there is no rest for the wicked yet the virtuous have no pillows
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

How do I handle the errno=25, since it is not reading from the client? stdout is a log file, not the terminal.
rick jones
Honored Contributor

Re: Error with read() function in C program

My comment about uninitialized data was meant to convey that you should not consider errno to hold a valid value *unless* read() returns -1. As read() is returning zero, there is no reason to believe that errno is actually being set to an errno value.

One way to confirm this (hopefully Dennis can confirm) I suppose is to explicitly set errno to 0 before the call to read() and then see what it says after.

I think you are chasing after red herrings. Read return of zero against a file descriptor associated with a TCP connection means the remote has closed his end of the connection. The remote has indicated it will be sending no more data to be read. Further, read return of zero is given only after all previously sent data has been "consumed" (read) it means you have already seen all the data you are going to see.

If this is then happening at an unexpected time, it suggests not a problem with the read() call (well apart from the broken assumption about always getting sz bytes) but with the "application protocol" between your client and server. Somehow they have gotten out of sync with one another.
there is no rest for the wicked yet the virtuous have no pillows
Dennis Handly
Acclaimed Contributor

Re: Error with read() function in C program

>rick: One way to confirm this (hopefully Dennis can confirm) I suppose is to explicitly set errno to 0 before the call to read() and then see what it says after.

(You're too quick for me.)
Right, you have no business looking at errno, unless you get that -1 return:
When an end-of-file is reached, a value of 0 is returned. Otherwise, a -1 is returned and errno is set to indicate the error.
Curtis Deese
Frequent Advisor

Re: Error with read() function in C program

The problem is with the calling program shutting down with an error. Thanks everyone for your help.

Curtis