All Forums |
Register |
Login |
Search |
Subscriptions |
My Profile |
Inbox |
Tool Warehouse |
FAQs |
Resources |
Help |
Member List |
Address Book |
Logout |
|
|
recvfrom fail on 1st read from DGRAM socket
|
Logged in as: Guest |
Users viewing this topic: none |
|
Login |
|
|
recvfrom fail on 1st read from DGRAM socket - Aug. 12, '06, 8:48:05 PM
|
|
|
afripp
Posts: 3
Joined: Jul. 18, '06,
Status: offline
|
Hi,
I have a client-server app that I'm porting to Interix (SFU 3.5 on XP Pro SP2). It has previously been ported to HP-UX, Linux, AIX, SunOS, and IRIX platforms and works well on all of them.
I have an issue with Interix failing on the first read from a SOCK_DGRAM socket - I'm getting return of -1 and errno EINVAL.
My server app waits to get a return from select() indicating the DGRAM socket is ready to read before attempting a read() and it works fine.
The client does not use select() and was implemented so that the first operation on an open DGRAM socket was a read/recvfrom. The read/recvfrom returned -1 with EINVAL every time until I introduced a work-around so that it wrote to the socket before reading.
To my mind this is not an appropriate error according to the recvfrom specification http://www.opengroup.org/onlinepubs/000095399/functions/recvfrom.html. However, it may be that I do not understand the implementation of sockets on SFU/WindowsNT.
Any suggestions or discussion very welcome.
Thanks
Andy - newbee to SFU
|
|
|
RE: recvfrom fail on 1st read from DGRAM socket - Aug. 13, '06, 5:09:57 AM
|
|
|
Rodney
Posts: 3714
Joined: Jul. 9, '02,
From: /Tools lab
Status: offline
|
A wee bit more detail please.
What type of socket are you doing this with? AF_UNIX or AF_INET?
Have you set the socket to be blocking or non-blocking?
Also what's the o/p from "uname -X" and "fileinfo"?
|
|
|
RE: recvfrom fail on 1st read from DGRAM socket - Aug. 13, '06, 12:50:00 PM
|
|
|
afripp
Posts: 3
Joined: Jul. 18, '06,
Status: offline
|
More information.
A minimal program replicates the situation.
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int fd;
int flags,status;
struct sockaddr_in caddr;
int caddr_len = sizeof(caddr);
unsigned char buffer[8192];
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd>=0) {
flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
status = recvfrom(fd,buffer,sizeof(buffer),0,
(struct sockaddr *)&caddr,&caddr_len);
if (status==-1)
printf("recvfrom : %s\n",strerror(errno));
close(fd);
}
return 0;
}
This program produces an output of "recvfrom : Invalid argument".
On OpenBSD this same program produces "recvfrom : Resource temporarily unavailable".
I guess I've kind of answered my own question - I'm trying to read on an unbound socket - the server socket is of course bound before the first read. However, I find it peculiar that I have not encountered the problem on any of the 6 other UNIX platforms on which the application runs.
Any comment?
fileinfo:
/dev/fs/C/WINDOWS/system32/PSXSS.EXE 8.0.1969.2
/dev/fs/C/WINDOWS/system32/PSXDLL.DLL 8.0.1969.1
/dev/fs/C/WINDOWS/system32/POSIX.EXE 8.0.1969.1
/dev/fs/C/WINDOWS/system32/PSXRUN.EXE 8.0.1969.1
/dev/fs/C/WINDOWS/system32/drivers/PSXDRV.SYS 8.0.1969.1
uname -X:
System = Interix
Node = fg1
Release = 3.5
Version = SP-8.0.1969.1
Machine = x86
Processor = Intel_x86_Family15_Model2_Stepping7
HostSystem = Windows
HostRelease = SP2
HostVersion = 5.1
Thanks
|
|
|
RE: recvfrom fail on 1st read from DGRAM socket - Aug. 13, '06, 4:06:39 PM
|
|
|
Rodney
Posts: 3714
Joined: Jul. 9, '02,
From: /Tools lab
Status: offline
|
> Any comment?
Don't do that then.
Actually the result of EAGAIN is what I would have expected with
an unbound file handle set non-blocking.
The model for Interix was to emulate the behavior of 4.3BSD sockets (4.4BSD
sockets are near identical but without the sa_len thing), but it can be tough
at times because it's actually WinSock2 underneath. OpenBSD is, of course,
based on the 4.4BSD sockets. BSD sockets should be the reference for all
socket implementations: CSRG did it first, the overly biased X/Open instead
chose as a standard a different model that virtually no one was using, and
all early followers used the BSD model (if not the code). So coding to BSD
sockets is the de facto standard. If you reference one of the Stevens' books
you'll like get the same answer (that EAGAIN is expected).
I haven't see the Interix socket internals for a number of years at this point,
but I do recall that EAGAIN for errno on non-blocking handles was there. What's
happened between now and then I can't say. I'll try your code and see what I get.
|
|
|
RE: recvfrom fail on 1st read from DGRAM socket - Aug. 13, '06, 4:51:45 PM
|
|
|
afripp
Posts: 3
Joined: Jul. 18, '06,
Status: offline
|
Thanks for your feedback Rodney.
The application discretely handles an EAGAIN but fails on other errors so it's a fair guess that the other platforms are all returning EAGAIN - as OpenBSD did with the test program.
I now have a fix but EAGAIN seems to be the standard return for this situation and is a considerably more appropriate return than EINVAL - which broke my application and sent me on a long and misguided hunt for the source of the problem.
However, looking at the WinSock2 documentation for recvfrom I read:
Under error codes:
WSAEINVAL - "The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative."
Further down:
"The local address of the socket must be known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client applications. For client applications using this function, the socket can become bound implicitly to a local address through sendto, WSASendTo, or WSAJoinLeaf."
So as you indicate, there is a difference here between WinSock2 and BSD sockets. I can see that translating error codes from WinSock2 to BSD cannot be easy, but if it is not possible then it might help significantly for EINVAL to be listed as a possible error code in the man page for recvfrom and recv in Interix, with the WinSock2 explanation for why it is generated.
|
|
|
RE: recvfrom fail on 1st read from DGRAM socket - Aug. 13, '06, 10:36:22 PM
|
|
|
Rodney
Posts: 3714
Joined: Jul. 9, '02,
From: /Tools lab
Status: offline
|
> ...the other platforms are all returning EAGAIN - as OpenBSD did with the test program.
This is good :-)
> ... it might help significantly for EINVAL to be listed as a possible error code in the man page for recvfrom and recv in Interix
Outside of my control really. The manual pages for 3.5 are unlikely to get updated at this point.
I can ask someone at MS for this note in the 6.0 documentation, but I don't know if it'll happen.
The twist is that the whole of WinSock is rewritten for IPv6 on Vista (which is 6.0).
It might end up that this posting will be the Google-answer for people for 3.5 and 5.2.
|
|
|
New Messages |
No New Messages |
Hot Topic w/ New Messages |
Hot Topic w/o New Messages |
|
Locked w/ New Messages |
Locked w/o New Messages |
|
Post New Thread
Reply to Message
Post New Poll
Submit Vote
Delete My Own Post
Delete My Own Thread
Rate Posts |
|
|
|