public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* RE: 1.3.2: Cygwin && UDP && O_NONBLOCK
@ 2001-08-14 12:54 Troy Noble
  2001-08-14 13:17 ` Keith Seitz
  2001-08-15  0:50 ` Corinna Vinschen
  0 siblings, 2 replies; 9+ messages in thread
From: Troy Noble @ 2001-08-14 12:54 UTC (permalink / raw)
  To: 'Keith Seitz', Roderick Groesbeek; +Cc: cygwin

Roderick,

Unless I misunderstood entirely, I think you've found a bug.

I got the same blocking behavior you described when testing
(after fixing many of the same things that Keith
described in his mail).  And it does appear to be inconsistent
with behavior on Linux for the same program as you noted.

Looks like there was a fix for some code related to setting up the
non-blocking behavior in fhandler_socket.cc:fctl on Aug 13, 2001
so the flags are set properly now, but the recvfrom appears not
to be checking for the non-blocking flag.  I updated my src tree
from CVS today and tested, and it still exhibits the blocking
behavior you describe.

The problem appears to be the wait for an event at net.cc:93
which looks like:

  switch (WSAWaitForMultipleEvents(2, ev, FALSE, WSA_INFINITE, FALSE))

There seem to be at least two ways to fix it, otherwise I'd just
submit a patch.  But I don't know that I understand the philosopy
entirely, so it'd be best to defer to Corinna's better judgement.

It seems to me in net.cc:recvfrom one of the following
needs to happen:

1. if ((h->get_flags() & O_NONBLOCK_MASK)
       || !(ovr = wsock_evt.prepare ()))
    {
       ...

   which would cause behavior to revert to Winsock 1.1's
   recvfrom which appears to do the right thing, at least in
   my minimal testing.

2. add another check for !(h->get_flags() & O_NONBLOCK_MASK)
   before calling wait(...) in the overlapped section of
   code before net.cc:537.

3. I guess a test of the same sort as #2 above might be
   appropriate inside wait() around line 93 instead.
   It's not entirely as straightforward detecting when
   no data is there when using non-blocking sockets with
   the overlapped calls.

Ok, that's technically 3 ways.

Troy

-----Original Message-----
From: Keith Seitz [ mailto:keiths@cygnus.com ]
Sent: Tuesday, August 14, 2001 10:34 AM
To: Roderick Groesbeek
Cc: cygwin@cygwin.com
Subject: Re: 1.3.2: Cygwin && UDP && O_NONBLOCK


On Tue, 14 Aug 2001, Roderick Groesbeek wrote:

> #ifdef __linux__
>    #include <linux/in.h>
> #endif
> #ifdef __CYGWIN__
>    #include <cygwin/in.h>
> #endif

Why not just #include <netinet/in.h>?

>
> #include <unistd.h>
> #include <fcntl.h>
>
>
>
> #define BUFSIZE 1024
>
> int main(int argc, char* argv[], char* env[])
> {
>   int sock;
>   int ret;
>   char buf[BUFSIZE];
>   struct sockaddr_in me, from;
>   unsigned int from_len;
>
>   int flags;
>
>
>   sock = socket(PF_INET, SOCK_DGRAM, 0);
>
>   if (sock < 0) {
>         perror("socket");
>         exit(1);
>   }
>
>   flags = fcntl(sock, F_GETFL, 0);
>   ret = fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);
>   printf("ret=%d|\n", ret);

This fcntl stuff shouldn't really be necessary, but it should do no harm.

>   bzero((char*) &from, sizeof(from));

Ugh. You mean "bzero (&me, sizeof (me));"?

>   me.sin_family = AF_INET;
>   me.sin_addr.s_addr = htonl(INADDR_ANY);
>   me.sin_port = htons(1025);
>   ret = bind(sock, (struct sockaddr *) & me, sizeof(me));
>   if (ret < 0) {
>         perror("bind");
>         exit(1);
>   }
>   while(1) {
>         int len;
>
>         len = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *) &from,
> &from_len);

This is not correct. from_len is not initialized (typo?). You MUST set it
to "sizeof (from)". This is a "value/result argument".

>         perror("recvfrom");
>         printf("len=%d|\n", len);
>   }
>
>   return 0;
> }

FWIW, I tried the following program on my system and had no problems
whatsoever, with or without SET_BLOCKING set.

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#ifdef SET_BLOCKING
#include <fcntl.h>
#endif

#ifdef __CYGWIN__
typedef unsigned int socklen_t;
#endif

int
main (int argc, char *argv[])
{
  int ret;
  char buf[1024];
  socklen_t len;
  struct sockaddr_in my_addr, client_addr;
  int sock;
#ifdef SET_BLOCKING
  int flags;
#endif

  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      perror ("couldn't create socket");
      exit (1);
    }

#ifdef SET_BLOCKING
  flags = fcntl (sock, F_GETFL, 0);
  flags &= ~O_NONBLOCK;
  ret = fcntl (sock, F_SETFL, flags);
  if (ret < 0)
   {
     perror ("couldn't force blocking");
     exit (1);
   }
#endif


  bzero (&my_addr, sizeof (my_addr));
  my_addr.sin_family = AF_INET;
  my_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  my_addr.sin_port = htons (10025);
  if (bind (sock, (struct sockaddr *) &my_addr, sizeof (my_addr)) < 0)
    {
      perror ("couldn't bind to address");
      exit (1);
    }

  while (1)
    {
      len = sizeof (client_addr);
      ret = recvfrom (sock, buf, 1024, 0, (struct sockaddr *) &client_addr,
&len);
      printf ("recvfrom returned %d\n", ret);
      if (ret < 0)
	{
	  perror ("error getting data from socket");
	  continue;
	}

      /* Do something with the data. Echo it. */
      ret = sendto (sock, buf, ret, 0, (struct sockaddr *) &client_addr,
len);
      if (ret < 0)
	{
	  perror ("error sending data");
	  continue;
	}

      printf ("Sent %d bytes to client at %x\n", ret,
client_addr.sin_addr.s_addr);
    }

  return 0;
}




--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 9+ messages in thread
* 1.3.2: Cygwin && UDP && O_NONBLOCK
@ 2001-08-14  8:12 Roderick Groesbeek
  2001-08-14  9:34 ` Keith Seitz
  0 siblings, 1 reply; 9+ messages in thread
From: Roderick Groesbeek @ 2001-08-14  8:12 UTC (permalink / raw)
  To: cygwin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3582 bytes --]

                                                    Howdy People,


According to the website this is the right mailinglist.

Info:
-------
I'm porting an Unix library to Cygwin.
First I builded a test environment to analyze/study
the behaviour of using DLL's with Cygwin.

All my tests with the DLL's succeed, so after that
I patched my Unix Library Makefile to build a DLL with dlltool.

The library, both .dll as .a import, are ok.
Crafted with DLLTOOL I can perfectly port my
library to Cygwin, and link against it.



Problem:
------------
- My Unix library uses nonblocking UDP sockets,
  which works under Linux, but still blocks under Cygwin.

Analyze:
------------
After some debugging of the library, I found that indeed the
recvfrom() is blocking, and couldn't quite come to a fix.

I finally came to the point to build some UDP server + client test program,
to see if UDP && Cygwin is operating correctly.



But my first UDP test program is already acting 'weird'.

Under Linux:
~~
[root@xml /tmp]# gcc -Wall -o server server.c
[root@xml /tmp]# ./server
(ctrl + c)
[root@xml /tmp]#
~~
(Nice blocking..)

Under Cygwin:
~~
Administrator@PIGGY ~/cvsroot/blocktest
$ gcc -Wall -o server server.c

Administrator@PIGGY ~/cvsroot/blocktest
$ ./server.exe
ret=0|
recvfrom: Invalid argument
len=-1|
recvfrom: Invalid argument
len=-1|

(ctrl + c)
Administrator@PIGGY ~/cvsroot/blocktest
$
~~
(Not blocking? Acting weird?)


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#ifdef __linux__
   #include <linux/in.h>
#endif
#ifdef __CYGWIN__
   #include <cygwin/in.h>
#endif

#include <unistd.h>
#include <fcntl.h>



#define BUFSIZE 1024

int main(int argc, char* argv[], char* env[])
{
  int sock;
  int ret;
  char buf[BUFSIZE];
  struct sockaddr_in me, from;
  unsigned int from_len;

  int flags;


  sock = socket(PF_INET, SOCK_DGRAM, 0);

  if (sock < 0) {
        perror("socket");
        exit(1);
  }

  flags = fcntl(sock, F_GETFL, 0);
  ret = fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);
  printf("ret=%d|\n", ret);

  bzero((char*) &from, sizeof(from));
  me.sin_family = AF_INET;
  me.sin_addr.s_addr = htonl(INADDR_ANY);
  me.sin_port = htons(1025);
  ret = bind(sock, (struct sockaddr *) & me, sizeof(me));
  if (ret < 0) {
        perror("bind");
        exit(1);
  }
  while(1) {
        int len;

        len = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *) &from,
&from_len);
        perror("recvfrom");
        printf("len=%d|\n", len);
  }

  return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Questions:
---------------
- Are UDP sockets problematic under Cygwin?
  (Couldn't find any references in the mailinglist archive)
- Are NONBLOCKING sockets operating correctly under Cygwin?
   fcntl(sock, F_SETFL, flags & ~O_NONBLOCK);



I hereby thank you for your time.



Vriendelijke Groet,

Note: For efficiënt work-behaviour, I'm currently only reading my E-mail
twice a day!

Roderick
--
Pettemerstraat 12A                                  T r I p l e
1823 CW Alkmaar                                         T
Tel. +31 (0)72-5129516
fax. +31 (0)72-5129520                              Automatisering
www.triple-it.nl                                 "Laat uw Net Werken!"



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2001-08-16  5:59 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-14 12:54 1.3.2: Cygwin && UDP && O_NONBLOCK Troy Noble
2001-08-14 13:17 ` Keith Seitz
2001-08-15  0:50 ` Corinna Vinschen
2001-08-16  5:18   ` Roderick Groesbeek
2001-08-16  5:59     ` Corinna Vinschen
  -- strict thread matches above, loose matches on Subject: below --
2001-08-14  8:12 Roderick Groesbeek
2001-08-14  9:34 ` Keith Seitz
2001-08-14 13:09   ` Roderick Groesbeek
2001-08-14 13:23     ` Keith Seitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).