summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2012-08-18 16:48:18 +0000
committerEric Faurot <eric@cvs.openbsd.org>2012-08-18 16:48:18 +0000
commit2d6170fe443f939945152c4cd272112d4f396646 (patch)
treed3c68ef23fe798f210956132cbcde53b53c04964 /lib
parente4218038d13ffd6856abc67fe6b5fd2b44d0a970 (diff)
ensure that async_run() and async_run_sync() always preserve errno.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/asr/asr.c18
-rw-r--r--lib/libc/asr/asr_resolver.c10
-rw-r--r--lib/libc/asr/async_resolver.312
3 files changed, 27 insertions, 13 deletions
diff --git a/lib/libc/asr/asr.c b/lib/libc/asr/asr.c
index 48460d31ac0..d4db4ed2606 100644
--- a/lib/libc/asr/asr.c
+++ b/lib/libc/asr/asr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr.c,v 1.3 2012/04/15 22:25:14 eric Exp $ */
+/* $OpenBSD: asr.c,v 1.4 2012/08/18 16:48:17 eric Exp $ */
/*
* Copyright (c) 2010-2012 Eric Faurot <eric@openbsd.org>
*
@@ -159,7 +159,7 @@ async_abort(struct async *as)
int
async_run(struct async *as, struct async_res *ar)
{
- int r;
+ int r, saved_errno = errno;
#ifdef DEBUG
asr_printf("asr: async_run(%p, %p) %s ctx=[%p]\n",
@@ -182,6 +182,8 @@ async_run(struct async *as, struct async_res *ar)
if (r == ASYNC_DONE)
async_free(as);
+ errno = saved_errno;
+
return (r);
}
@@ -191,8 +193,8 @@ async_run(struct async *as, struct async_res *ar)
int
async_run_sync(struct async *as, struct async_res *ar)
{
- struct pollfd fds[1];
- int r;
+ struct pollfd fds[1];
+ int r, saved_errno = errno;
while((r = async_run(as, ar)) == ASYNC_COND) {
fds[0].fd = ar->ar_fd;
@@ -201,10 +203,14 @@ async_run_sync(struct async *as, struct async_res *ar)
r = poll(fds, 1, ar->ar_timeout);
if (r == -1 && errno == EINTR)
goto again;
- if (r == -1) /* XXX Is it possible? and what to do if so? */
- err(1, "poll");
+ /*
+ * Otherwise, just ignore the error and let async_run()
+ * catch the failure.
+ */
}
+ errno = saved_errno;
+
return (r);
}
diff --git a/lib/libc/asr/asr_resolver.c b/lib/libc/asr/asr_resolver.c
index ab996fd97b6..acebcbd6753 100644
--- a/lib/libc/asr/asr_resolver.c
+++ b/lib/libc/asr/asr_resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: asr_resolver.c,v 1.7 2012/08/18 13:49:13 eric Exp $ */
+/* $OpenBSD: asr_resolver.c,v 1.8 2012/08/18 16:48:17 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -237,7 +237,6 @@ getrrsetbyname(const char *name, unsigned int class, unsigned int type,
async_run_sync(as, &ar);
- errno = saved_errno;
*res = ar.ar_rrsetinfo;
return (ar.ar_rrset_errno);
@@ -490,7 +489,8 @@ getaddrinfo(const char *hostname, const char *servname,
async_run_sync(as, &ar);
*res = ar.ar_addrinfo;
- errno = (ar.ar_gai_errno == EAI_SYSTEM) ? ar.ar_errno : saved_errno;
+ if (ar.ar_gai_errno == EAI_SYSTEM)
+ errno = ar.ar_errno;
return (ar.ar_gai_errno);
}
@@ -514,8 +514,8 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
}
async_run_sync(as, &ar);
-
- errno = (ar.ar_gai_errno == EAI_SYSTEM) ? ar.ar_errno : saved_errno;
+ if (ar.ar_gai_errno == EAI_SYSTEM)
+ errno = ar.ar_errno;
return (ar.ar_gai_errno);
}
diff --git a/lib/libc/asr/async_resolver.3 b/lib/libc/asr/async_resolver.3
index 2fa4204abe7..81ae9f92e23 100644
--- a/lib/libc/asr/async_resolver.3
+++ b/lib/libc/asr/async_resolver.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: async_resolver.3,v 1.2 2012/04/15 15:08:12 jmc Exp $
+.\" $OpenBSD: async_resolver.3,v 1.3 2012/08/18 16:48:17 eric Exp $
.\"
.\" Copyright (c) 2012, Eric Faurot <eric@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: April 15 2012 $
+.Dd $Mdocdate: August 18 2012 $
.Dt ASYN_RESOLVER 3
.Os
.Sh NAME
@@ -212,6 +212,13 @@ are set accordingly and the resolving process can be resumed by calling
.Fn async_run .
.El
.Pp
+Note that although the query itself may fail (the error being properly reported
+in the
+.Fa ar
+structure), the
+.Fn async_run
+function itself cannot fail and it always preserves errno.
+.Pp
The
.Fn async_run_sync
function is a wrapper around
@@ -220,6 +227,7 @@ that handles the read/write conditions, thus falling back to a blocking
interface.
It only returns partial and complete results through ASYNC_YIELD and ASYNC_DONE
respectively.
+It also preserves errno.
.Pp
The
.Fn async_abort