gethostbyname() problem?

Yitzchak Scott-Thoennes sthoenna@efn.org
Mon Feb 7 05:53:00 GMT 2005


On Sun, Feb 06, 2005 at 06:44:58PM -0500, Christopher Faylor wrote:
> On Sun, Feb 06, 2005 at 03:01:29PM -0800, Yitzchak Scott-Thoennes wrote:
> >On Sun, Feb 06, 2005 at 12:05:30PM +0100, Corinna Vinschen wrote:
> >> On Feb  6 00:35, Brian Dessent wrote:
> >> > -  static int a, b, c, d;
> >> > +  static int a, b, c, d, n;
> >> >  
> >> >    sig_dispatch_pending ();
> >> >    if (check_null_str_errno (name))
> >> >      return NULL;
> >> >  
> >> > -  if (sscanf (name, "%d.%d.%d.%d", &a, &b, &c, &d) == 4)
> >> > +  if (sscanf (name, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4 && (unsigned)n == strlen (name))
> >>
> >> Thanks for the patch, Brian.  Do you also have a nice ChangeLog entry
> >> for me?
> >
> >I've always done this like below; then the n==strlen(name) check isn't
> >needed (since the ==4 verifies that %c wasn't used).  Even using the
> >%n, there's no reason to make n static, is there?
> 
> There has been no reason to make a, b, c, d static either AFAICT.
> This whole function is frightfully non-reentrant, but I knew that.

Better?  Reentrancy isn't actually required, but no reason not to do it.
I have compiled net.cc but not done any other testing.  Did I mention
that dup_ent is really neat?

2005-02-06  Yitzchak Scott-Thoennes <sthoenna@efn.org>

	* net.cc (cygwin_gethostbyname): Be more picky about what's
	a numeric address string, and use tls in that case too.

--- winsup/cygwin/net.cc.orig	2004-04-11 10:41:17.000000000 -0700
+++ winsup/cygwin/net.cc	2005-02-06 21:41:46.811609600 -0800
@@ -992,17 +992,19 @@ cygwin_gethostname (char *name, size_t l
 extern "C" struct hostent *
 cygwin_gethostbyname (const char *name)
 {
-  static unsigned char tmp_addr[4];
-  static struct hostent tmp;
-  static char *tmp_aliases[1];
-  static char *tmp_addr_list[2];
-  static int a, b, c, d;
+  unsigned char tmp_addr[4];
+  struct hostent tmp, *h;
+  char *tmp_aliases[1] = {0};
+  char *tmp_addr_list[2] = {0,0};
+  unsigned int a, b, c, d;
+  char dummy;
 
   sig_dispatch_pending ();
   if (check_null_str_errno (name))
     return NULL;
 
-  if (sscanf (name, "%d.%d.%d.%d", &a, &b, &c, &d) == 4)
+  if (sscanf (name, "%u.%u.%u.%u%c", &a, &b, &c, &d, &dummy) == 4
+      && a < 256 && b < 256 && c < 256 && d < 256)
     {
       /* In case you don't have DNS, at least x.x.x.x still works */
       memset (&tmp, 0, sizeof (tmp));
@@ -1016,11 +1018,13 @@ cygwin_gethostbyname (const char *name)
       tmp.h_addrtype = 2;
       tmp.h_length = 4;
       tmp.h_addr_list = tmp_addr_list;
-      return &tmp;
+      h = &tmp;
     }
+  else
+    h = gethostbyname (name);
+
+  _my_tls.locals.hostent_buf = (hostent *) dup_ent (_my_tls.locals.hostent_buf, h, is_hostent);
 
-  _my_tls.locals.hostent_buf = (hostent *) dup_ent (_my_tls.locals.hostent_buf, gethostbyname (name),
-				     is_hostent);
   if (!_my_tls.locals.hostent_buf)
     {
       set_winsock_errno ();



More information about the Cygwin-patches mailing list