From 18cdf03962910233188c8a93fa79a99b36a52cb6 Mon Sep 17 00:00:00 2001
From: beck <>
Date: Thu, 10 Sep 2015 14:57:29 +0000
Subject: document changed tls_read and tls_write semantics. document functions
 that clear errno. change examples to provide demonstration of both the
 blocking and  non-blocking cases. ok jsing@, bluhm@

---
 src/lib/libtls/tls_init.3 | 73 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 58 insertions(+), 15 deletions(-)

(limited to 'src')

diff --git a/src/lib/libtls/tls_init.3 b/src/lib/libtls/tls_init.3
index d2ba9d0978..62f52e4331 100644
--- a/src/lib/libtls/tls_init.3
+++ b/src/lib/libtls/tls_init.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tls_init.3,v 1.32 2015/09/10 14:17:22 jmc Exp $
+.\" $OpenBSD: tls_init.3,v 1.33 2015/09/10 14:57:29 beck Exp $
 .\"
 .\" Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
 .\"
@@ -131,10 +131,10 @@
 .Fn tls_accept_socket "struct tls *tls" "struct tls **cctx" "int socket"
 .Ft "int"
 .Fn tls_handshake "struct tls *ctx"
-.Ft "int"
-.Fn tls_read "struct tls *ctx" "void *buf" "size_t buflen" "size_t *outlen"
-.Ft "int"
-.Fn tls_write "struct tls *ctx" "const void *buf" "size_t buflen" "size_t *outlen"
+.Ft "ssize_t"
+.Fn tls_read "struct tls *ctx" "void *buf" "size_t buflen"
+.Ft "ssize_t"
+.Fn tls_write "struct tls *ctx" "const void *buf" "size_t buflen"
 .Ft "int"
 .Fn tls_close "struct tls *ctx"
 .Sh DESCRIPTION
@@ -431,6 +431,8 @@ or
 .Sh RETURN VALUES
 Functions that return
 .Vt int
+or 
+.Vt ssize_t 
 will return 0 on success and -1 on error.
 Functions that return a pointer will return NULL on error, which indicates an
 out of memory condition.
@@ -454,20 +456,61 @@ In the case of blocking file descriptors, the same function call should be
 repeated immediately.
 In the case of non-blocking file descriptors, the same function call should be
 repeated when the required condition has been met.
+.Pp
+Callers of these functions can not rely on the value of the global
+.Ar errno .
+To prevent mishandling of error conditions,
+.Fn tls_handshake ,
+.Fn tls_read ,
+.Fn tls_write ,
+and
+.Fn tls_close
+all explicitly clear
+.Ar errno .
 .Sh EXAMPLES
-Example showing how to handle TLS writes.
+The following example demonstrates how to handle TLS writes on a blocking
+file descriptor:
+.Bd -literal -offset indent
+\&...
+while (len > 0) {
+	ret = tls_write(ctx, buf, len);
+	if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
+		continue;
+        if (ret < 0)
+		err(1, "tls_write: %s", tls_error(ctx));
+	buf += ret;
+	len -= ret;
+}
+\&...
+.Ed
+.Pp
+The following example demonstrates how to handle TLS writes on a
+non-blocking file descriptor using
+.Xr poll 2
 .Bd -literal -offset indent
 \&...
+pevent = POLLOUT;
 while (len > 0) {
-	ret = tls_write(ctx, buf, len, &num_written);
-	if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
-		/* Retry - use select to wait for non-blocking. */
-	} else if (ret < 0) {
-		return -1;
-	} else {
-		buf += num_written;
-		len -= num_written;
-	}
+	pfd[0].fd = fd;
+	pfd[0].events = pevent;
+	nready = poll(pfd, 1, 0);
+	if (nready == -1)
+		err(1, "poll");
+	if ((pfd[0].revents & (POLLERR|POLLNVAL)))
+		errx(1, "bad fd %d", pfd[0].fd);
+	if ((pfd[0].revents & (pevent|POLLHUP))) {
+		ret = tls_write(ctx, buf, len);
+		if (ret == TLS_WANT_POLLIN)
+			pevent = POLLIN;
+		else if (ret == TLS_WANT_POLLOUT)
+			pevent = POLLOUT;
+		else if (ret < 0)
+			err(1, "tls_write: %s", tls_error(ctx));
+		else {
+			buf += ret;
+			len -= ret;
+		}
+        }
 }
 \&...
 .Ed
-- 
cgit v1.2.3-55-g6feb