This is the mail archive of the
cygwin-patches@cygwin.com
mailing list for the Cygwin project.
Re: gethostbyname() problem?
- From: Yitzchak Scott-Thoennes <sthoenna at efn dot org>
- To: cygwin-patches at cygwin dot com
- Date: Sun, 6 Feb 2005 21:53:48 -0800
- Subject: Re: gethostbyname() problem?
- Organization: bs"d
- References: <200502051240.j15CevQ32345@webmail.web-mania.com> <4205D6D1.70D38D40@dessent.net> <20050206110530.GR19096@cygbert.vinschen.de> <20050206230129.GA3512@efn.org> <20050206234458.GA2425@trixie.casa.cgf.cx>
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 ();