Re: compile error via SIOCGLIFCONF from ip.c on hpux-11

From: Merlin Moncure <mmoncure(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, Andrew Chernow <achernow(at)esilo(dot)com>
Subject: Re: compile error via SIOCGLIFCONF from ip.c on hpux-11
Date: 2010-11-29 19:18:59
Message-ID: AANLkTikvz6KEkCspg0PextMyNeZP7iJcEZ0DxCn__81V@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Nov 29, 2010 at 1:38 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Merlin Moncure <mmoncure(at)gmail(dot)com> writes:
>> PostgreSQL 9 is breaking for me on line 654 of ip.c.  ip.c is checking
>> on presence SIOCGLIFCONF to determine if it's ok to use linux method
>> of polling if addrs etc over ioctl, which is not enough. hpux provides
>> this method in similar fashion, but the structs are named different,
>> and have different members.
>
> This was complained of last month, and the situation has not changed:
> http://archives.postgresql.org/pgsql-general/2010-10/msg00408.php

well, what should the fix be? checking on presence of SIOCGLIFCONF is
obviously weak sauce...it looks like some type of configure check is
needed I converted the function to a version that compiles clean on
hpux (note, I couldn't figure out how to set family, maybe that's not
required?). How do you test this feature?

merlin

int
pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
{
struct if_laddrconf lifc;
struct if_laddrreq *lifr,
lmask;
struct sockaddr *addr,
*mask;
char *ptr,
*buffer = NULL;
size_t n_buffer = 1024;
pgsocket sock,
fd;

#ifdef HAVE_IPV6
pgsocket sock6;
#endif
int i,
total;

sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1)
return -1;

while (n_buffer < 1024 * 100)
{
n_buffer += 1024;
ptr = realloc(buffer, n_buffer);
if (!ptr)
{
free(buffer);
close(sock);
errno = ENOMEM;
return -1;
}

memset(&lifc, 0, sizeof(lifc));
/* XXX how to set family? lifc.iflc_family = AF_UNSPEC; */
lifc.iflc_buf = buffer = ptr;
lifc.iflc_len = n_buffer;

if (ioctl(sock, SIOCGLIFCONF, &lifc) < 0)
{
if (errno == EINVAL)
continue;
free(buffer);
close(sock);
return -1;
}

/*
* Some Unixes try to return as much data as possible, with no
* indication of whether enough space allocated. Don't
believe we have
* it all unless there's lots of slop.
*/
if (lifc.iflc_len < n_buffer - 1024)
break;
}

#ifdef HAVE_IPV6
/* We'll need an IPv6 socket too for the SIOCGLIFNETMASK ioctls */
sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock6 == -1)
{
free(buffer);
close(sock);
return -1;
}
#endif

total = lifc.iflc_len / sizeof(struct lifreq);
lifr = lifc.iflc_req;
for (i = 0; i < total; ++i)
{
addr = (struct sockaddr *) & lifr[i].iflr_addr;
memcpy(&lmask, &lifr[i], sizeof(struct lifreq));
#ifdef HAVE_IPV6
fd = (addr->sa_family == AF_INET6) ? sock6 : sock;
#else
fd = sock;
#endif
if (ioctl(fd, SIOCGLIFNETMASK, &lmask) < 0)
mask = NULL;
else
mask = (struct sockaddr *) & lmask.iflr_addr;
run_ifaddr_callback(callback, cb_data, addr, mask);
}

free(buffer);
close(sock);
#ifdef HAVE_IPV6
close(sock6);
#endif
return 0;
}

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2010-11-29 19:26:12 Re: compile error via SIOCGLIFCONF from ip.c on hpux-11
Previous Message Andrew Dunstan 2010-11-29 19:15:43 Re: PROPOSAL of xmlvalidate