Free Downloads, Community Forum,
FAQs and Developer Resources


Make /Tools Your Home | Link to us

Today's posts | Posts since last visit | Most Active Topics

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
  Printable Version
All Forums >> [SFU / Interix / SUA Technology] >> Interix Advanced Forum >> recvfrom fail on 1st read from DGRAM socket Page: [1]
Login
Message << Older Topic   Newer Topic >>
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
Post #: 1
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"?

(in reply to afripp)
Post #: 2
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

(in reply to Rodney)
Post #: 3
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.

(in reply to afripp)
Post #: 4
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.

(in reply to Rodney)
Post #: 5
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.

(in reply to afripp)
Post #: 6
Page:   [1]
All Forums >> [SFU / Interix / SUA Technology] >> Interix Advanced Forum >> recvfrom fail on 1st read from DGRAM socket Page: [1]
Jump to:





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


Search All Forums -

Advanced search


SPONSORS



Forum Software © ASPPlayground.NET Advanced Edition 2.5 ANSI

0.063