Hi,
I built exim 4.62 with libspf2-1.2.5. That version of libspf2 uses pthreads,
how or why i'm not sure. But the result of linking it with exim is that
_res() which exim uses and which is a macro for __res_state on NetBSD 3.0
ends up using the __res_state function in libpthreads which calls abort()
cos it's not thread safe.
It also prints an error message to stderr, which is helpful cos fd 2 is
/dev/null when exim is running as a daemon :(
The attached patch uses __res_get_state and __res_put_state instead, which
works for me.
I appreciate this the whole resolver api is a portability nightmare,
but at least this will sitin the list archives if someone else goes looking
--
[http://pointless.net/] [0x2ECA0975]
--- /tmp/exim-4.62/src/dns.c 2006-04-28 11:32:22.000000000 +0100
+++ src/dns.c 2006-07-30 00:38:12.000000000 +0100
@@ -168,18 +168,25 @@
void
dns_init(BOOL qualify_single, BOOL search_parents)
{
-if ((_res.options & RES_INIT) == 0)
+ struct __res_state *rs;
+
+ rs = __res_get_state();
+
+if ((rs->options & RES_INIT) == 0)
{
- DEBUG(D_resolver) _res.options |= RES_DEBUG; /* For Cygwin */
+ DEBUG(D_resolver) rs->options |= RES_DEBUG; /* For Cygwin */
+ __res_put_state(rs);
res_init();
- DEBUG(D_resolver) _res.options |= RES_DEBUG;
+ DEBUG(D_resolver) rs->options |= RES_DEBUG;
+ __res_put_state(rs);
}
-_res.options &= ~(RES_DNSRCH | RES_DEFNAMES);
-_res.options |= (qualify_single? RES_DEFNAMES : 0) |
+rs->options &= ~(RES_DNSRCH | RES_DEFNAMES);
+rs->options |= (qualify_single? RES_DEFNAMES : 0) |
(search_parents? RES_DNSRCH : 0);
-if (dns_retrans > 0) _res.retrans = dns_retrans;
-if (dns_retry > 0) _res.retry = dns_retry;
+if (dns_retrans > 0) rs->retrans = dns_retrans;
+if (dns_retry > 0) rs->retry = dns_retry;
+__res_put_state(rs);
}
@@ -424,9 +431,11 @@
static int
dns_return(uschar *name, int type, int rc)
{
+struct __res_state *rs;
tree_node *node = store_get_perm(sizeof(tree_node) + 290);
+rs = __res_get_state();
sprintf(CS node->name, "%.255s-%s-%lx", name, dns_text_type(type),
- _res.options);
+ rs->options);
node->data.val = rc;
(void)tree_insertnode(&tree_dns_fails, node);
return rc;
@@ -465,6 +474,9 @@
#ifndef STAND_ALONE
uschar *save;
#endif
+struct __res_state *rs;
+
+rs = __res_get_state();
tree_node *previous;
uschar node_name[290];
@@ -475,7 +487,7 @@
caching for successful lookups. */
sprintf(CS node_name, "%.255s-%s-%lx", name, dns_text_type(type),
- _res.options);
+ rs->options);
previous = tree_search(tree_dns_fails, node_name);
if (previous != NULL)
{