1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Special method for a BIO where the other endpoint is also a BIO
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * of this kind, handled by the same thread (i.e. the "peer" is actually
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ourselves, wearing a different hat).
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for which no specific BIO method is available.
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * See ssl/ssltest.c for some hints on how this can be used. */
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BIO_DEBUG implies BIO_PAIR_DEBUG */
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef BIO_DEBUG
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# ifndef BIO_PAIR_DEBUG
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#  define BIO_PAIR_DEBUG
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* disable assert() unless BIO_PAIR_DEBUG has been defined */
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef BIO_PAIR_DEBUG
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# ifndef NDEBUG
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#  define NDEBUG
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h>
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <limits.h>
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h>
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bio.h>
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/crypto.h>
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "e_os.h"
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(OPENSSL_SYS_VXWORKS)
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# undef SSIZE_MAX
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef SSIZE_MAX
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# define SSIZE_MAX INT_MAX
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_new(BIO *bio);
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_free(BIO *bio);
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_read(BIO *bio, char *buf, int size);
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_write(BIO *bio, const char *buf, int num);
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_puts(BIO *bio, const char *str);
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_make_pair(BIO *bio1, BIO *bio2);
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void bio_destroy_pair(BIO *bio);
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic BIO_METHOD methods_biop =
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_TYPE_BIO,
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"BIO pair",
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_write,
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_read,
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_puts,
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL /* no bio_gets */,
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_ctrl,
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_new,
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio_free,
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL /* no bio_callback_ctrl */
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectBIO_METHOD *BIO_s_bio(void)
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return &methods_biop;
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct bio_bio_st
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO *peer;     /* NULL if buf == NULL.
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	                * If peer != NULL, then peer->ptr is also a bio_bio_st,
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	                * and its "peer" member points back to us.
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	                * peer != NULL iff init != 0 in the BIO. */
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* This is for what we write (i.e. reading uses peer's struct): */
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int closed;     /* valid iff peer != NULL */
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t size;
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *buf;      /* "size" elements (if != NULL) */
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t request; /* valid iff peer != NULL; 0 if len != 0,
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	                 * otherwise set by peer to number of bytes
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	                 * it (unsuccessfully) tried to read,
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	                 * never more than buffer space (size-len) warrants. */
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_new(BIO *bio)
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = OPENSSL_malloc(sizeof *b);
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b == NULL)
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->peer = NULL;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->size = 17*1024; /* enough for one TLS record (just a default) */
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->buf = NULL;
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio->ptr = b;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_free(BIO *bio)
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bio == NULL)
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->peer)
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bio_destroy_pair(bio);
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->buf != NULL)
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(b->buf);
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_free(b);
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_read(BIO *bio, char *buf, int size_)
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t size = size_;
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t rest;
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b, *peer_b;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(bio);
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->peer != NULL);
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	peer_b = b->peer->ptr;
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(peer_b != NULL);
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(peer_b->buf != NULL);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	peer_b->request = 0; /* will be set in "retry_read" situation */
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buf == NULL || size == 0)
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (peer_b->len == 0)
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (peer_b->closed)
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0; /* writer has closed, and no data is left */
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_set_retry_read(bio); /* buffer is empty */
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (size <= peer_b->size)
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				peer_b->request = size;
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* don't ask for more than the peer can
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				 * deliver in one write */
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				peer_b->request = peer_b->size;
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* we can read */
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (peer_b->len < size)
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		size = peer_b->len;
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* now read "size" bytes */
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rest = size;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(rest > 0);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	do /* one or two iterations */
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		size_t chunk;
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(rest <= peer_b->len);
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (peer_b->offset + rest <= peer_b->size)
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			chunk = rest;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* wrap around ring buffer */
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			chunk = peer_b->size - peer_b->offset;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(peer_b->offset + chunk <= peer_b->size);
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(buf, peer_b->buf + peer_b->offset, chunk);
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		peer_b->len -= chunk;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (peer_b->len)
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_b->offset += chunk;
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(peer_b->offset <= peer_b->size);
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (peer_b->offset == peer_b->size)
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				peer_b->offset = 0;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			buf += chunk;
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* buffer now empty, no need to advance "buf" */
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(chunk == rest);
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_b->offset = 0;
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rest -= chunk;
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (rest);
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return size;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* non-copying interface: provide pointer to available data in buffer
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    bio_nread0:  return number of available bytes
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    bio_nread:   also advance index
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (example usage:  bio_nread0(), read from buffer, bio_nread()
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  or just         bio_nread(), read from buffer)
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* WARNING: The non-copying interface is largely untested as of yet
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and may contain bugs. */
280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nread0(BIO *bio, char **buf)
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b, *peer_b;
283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ossl_ssize_t num;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(bio);
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->peer != NULL);
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	peer_b = b->peer->ptr;
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(peer_b != NULL);
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(peer_b->buf != NULL);
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	peer_b->request = 0;
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (peer_b->len == 0)
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		char dummy;
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* avoid code duplication -- nothing available for reading */
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	num = peer_b->len;
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (peer_b->size < peer_b->offset + num)
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* no ring buffer wrap-around for non-copying interface */
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = peer_b->size - peer_b->offset;
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(num > 0);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buf != NULL)
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*buf = peer_b->buf + peer_b->offset;
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return num;
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
318392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b, *peer_b;
321392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ossl_ssize_t num, available;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num_ > SSIZE_MAX)
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = SSIZE_MAX;
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
326392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		num = (ossl_ssize_t)num_;
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	available = bio_nread0(bio, buf);
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num > available)
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = available;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num <= 0)
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return num;
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	peer_b = b->peer->ptr;
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	peer_b->len -= num;
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (peer_b->len)
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		peer_b->offset += num;
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(peer_b->offset <= peer_b->size);
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (peer_b->offset == peer_b->size)
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_b->offset = 0;
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		peer_b->offset = 0;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return num;
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_write(BIO *bio, const char *buf, int num_)
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t num = num_;
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t rest;
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b;
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(bio);
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init || buf == NULL || num == 0)
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->peer != NULL);
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->buf != NULL);
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->request = 0;
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->closed)
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* we already closed */
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->len <= b->size);
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->len == b->size)
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_set_retry_write(bio); /* buffer is full */
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* we can write */
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num > b->size - b->len)
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = b->size - b->len;
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* now write "num" bytes */
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rest = num;
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(rest > 0);
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	do /* one or two iterations */
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		size_t write_offset;
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		size_t chunk;
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(b->len + rest <= b->size);
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		write_offset = b->offset + b->len;
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (write_offset >= b->size)
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			write_offset -= b->size;
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* b->buf[write_offset] is the first byte we can write to. */
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (write_offset + rest <= b->size)
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			chunk = rest;
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* wrap around ring buffer */
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			chunk = b->size - write_offset;
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(b->buf + write_offset, buf, chunk);
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->len += chunk;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(b->len <= b->size);
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rest -= chunk;
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		buf += chunk;
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while (rest);
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return num;
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* non-copying interface: provide pointer to region to write to
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *   bio_nwrite0:  check how much space is available
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *   bio_nwrite:   also increase length
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *  or just         bio_nwrite(), write to buffer)
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
431392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b;
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t num;
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	size_t write_offset;
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_clear_retry_flags(bio);
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->peer != NULL);
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->buf != NULL);
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->request = 0;
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->closed)
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->len <= b->size);
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b->len == b->size)
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_set_retry_write(bio);
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	num = b->size - b->len;
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	write_offset = b->offset + b->len;
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (write_offset >= b->size)
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		write_offset -= b->size;
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (write_offset + num > b->size)
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* no ring buffer wrap-around for non-copying interface
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * BIO_nwrite may have to be called twice) */
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = b->size - write_offset;
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (buf != NULL)
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*buf = b->buf + write_offset;
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(write_offset + num <= b->size);
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return num;
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
479392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b;
482392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ossl_ssize_t num, space;
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num_ > SSIZE_MAX)
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = SSIZE_MAX;
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
487392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		num = (ossl_ssize_t)num_;
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	space = bio_nwrite0(bio, buf);
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num > space)
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		num = space;
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (num <= 0)
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return num;
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = bio->ptr;
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b->len += num;
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b->len <= b->size);
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return num;
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret;
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b = bio->ptr;
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(b != NULL);
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd)
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* specific CTRL codes */
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_SET_WRITE_BUF_SIZE:
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->peer)
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 0;
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (num == 0)
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 0;
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			size_t new_size = num;
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (b->size != new_size)
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (b->buf)
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					OPENSSL_free(b->buf);
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					b->buf = NULL;
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				b->size = new_size;
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 1;
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_GET_WRITE_BUF_SIZE:
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (long) b->size;
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_MAKE_BIO_PAIR:
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO *other_bio = ptr;
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (bio_make_pair(bio, other_bio))
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 1;
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 0;
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_DESTROY_BIO_PAIR:
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Affects both BIOs in the pair -- call just once!
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bio_destroy_pair(bio);
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_GET_WRITE_GUARANTEE:
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* How many bytes can the caller feed to the next write
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * without having to keep any? */
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->peer == NULL || b->closed)
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 0;
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = (long) b->size - b->len;
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_GET_READ_REQUEST:
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If the peer unsuccessfully tried to read, how many bytes
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * were requested?  (As with BIO_CTRL_PENDING, that number
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * can usually be treated as boolean.) */
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (long) b->request;
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_RESET_READ_REQUEST:
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Reset request.  (Can be useful after read attempts
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * at the other side that are meant to be non-blocking,
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * e.g. when probing SSL_read to see if any data is
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * available.) */
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->request = 0;
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_SHUTDOWN_WR:
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* similar to shutdown(..., SHUT_WR) */
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b->closed = 1;
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_NREAD0:
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* prepare for non-copying read */
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (long) bio_nread0(bio, ptr);
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_NREAD:
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* non-copying read */
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (long) bio_nread(bio, ptr, (size_t) num);
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_NWRITE0:
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* prepare for non-copying write */
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (long) bio_nwrite0(bio, ptr);
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_C_NWRITE:
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* non-copying write */
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (long) bio_nwrite(bio, ptr, (size_t) num);
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* standard CTRL codes follow */
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_RESET:
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->buf != NULL)
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b->len = 0;
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b->offset = 0;
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 0;
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_GET_CLOSE:
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = bio->shutdown;
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_SET_CLOSE:
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bio->shutdown = (int) num;
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_PENDING:
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->peer != NULL)
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			struct bio_bio_st *peer_b = b->peer->ptr;
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = (long) peer_b->len;
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 0;
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_WPENDING:
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b->buf != NULL)
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = (long) b->len;
650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 0;
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_DUP:
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* See BIO_dup_chain for circumstances we have to expect. */
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO *other_bio = ptr;
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		struct bio_bio_st *other_b;
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(other_bio != NULL);
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		other_b = other_bio->ptr;
662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(other_b != NULL);
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		assert(other_b->buf == NULL); /* other_bio is always fresh */
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		other_b->size = b->size;
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_FLUSH:
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case BIO_CTRL_EOF:
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO *other_bio = ptr;
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (other_bio)
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			struct bio_bio_st *other_b = other_bio->ptr;
683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(other_b != NULL);
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = other_b->len == 0 && other_b->closed;
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = 1;
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 0;
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_puts(BIO *bio, const char *str)
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return bio_write(bio, str, strlen(str));
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bio_make_pair(BIO *bio1, BIO *bio2)
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b1, *b2;
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(bio1 != NULL);
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	assert(bio2 != NULL);
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b1 = bio1->ptr;
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b2 = bio2->ptr;
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b1->peer != NULL || b2->peer != NULL)
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b1->buf == NULL)
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b1->buf = OPENSSL_malloc(b1->size);
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b1->buf == NULL)
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b1->len = 0;
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b1->offset = 0;
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b2->buf == NULL)
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b2->buf = OPENSSL_malloc(b2->size);
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (b2->buf == NULL)
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b2->len = 0;
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		b2->offset = 0;
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b1->peer = bio2;
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b1->closed = 0;
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b1->request = 0;
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b2->peer = bio1;
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b2->closed = 0;
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b2->request = 0;
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio1->init = 1;
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bio2->init = 1;
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void bio_destroy_pair(BIO *bio)
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct bio_bio_st *b = bio->ptr;
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b != NULL)
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO *peer_bio = b->peer;
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (peer_bio != NULL)
766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			struct bio_bio_st *peer_b = peer_bio->ptr;
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(peer_b != NULL);
770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(peer_b->peer == bio);
771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_b->peer = NULL;
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_bio->init = 0;
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(peer_b->buf != NULL);
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_b->len = 0;
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			peer_b->offset = 0;
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b->peer = NULL;
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			bio->init = 0;
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			assert(b->buf != NULL);
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b->len = 0;
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b->offset = 0;
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Exported convenience functions */
789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO **bio2_p, size_t writebuf2)
791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 {
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 BIO *bio1 = NULL, *bio2 = NULL;
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 long r;
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 int ret = 0;
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 bio1 = BIO_new(BIO_s_bio());
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 if (bio1 == NULL)
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 goto err;
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 bio2 = BIO_new(BIO_s_bio());
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 if (bio2 == NULL)
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 goto err;
802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 if (writebuf1)
804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 {
805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 r = BIO_set_write_buf_size(bio1, writebuf1);
806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 if (!r)
807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 goto err;
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 }
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 if (writebuf2)
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 {
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 r = BIO_set_write_buf_size(bio2, writebuf2);
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 if (!r)
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 goto err;
814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 }
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 r = BIO_make_bio_pair(bio1, bio2);
817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 if (!r)
818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 goto err;
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 ret = 1;
820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err:
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 if (ret == 0)
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 {
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 if (bio1)
825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 {
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 BIO_free(bio1);
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 bio1 = NULL;
828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 }
829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 if (bio2)
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 {
831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 BIO_free(bio2);
832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 bio2 = NULL;
833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 }
834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 }
835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 *bio1_p = bio1;
837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 *bio2_p = bio2;
838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 return ret;
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 }
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectsize_t BIO_ctrl_get_write_guarantee(BIO *bio)
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectsize_t BIO_ctrl_get_read_request(BIO *bio)
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_ctrl_reset_read_request(BIO *bio)
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (conceivably some other BIOs could allow non-copying reads and writes too.)
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nread0(BIO *bio, char **buf)
861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret;
863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -2;
868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret > INT_MAX)
872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return INT_MAX;
873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (int) ret;
875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
877656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nread(BIO *bio, char **buf, int num)
878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
883656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
884656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -2;
885656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
886656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
887656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
888656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret > 0)
889656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bio->num_read += ret;
890656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
891656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
892656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
893656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nwrite0(BIO *bio, char **buf)
894656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
895656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	long ret;
896656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
897656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
899656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
900656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -2;
901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
904656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret > INT_MAX)
905656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return INT_MAX;
906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
907656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (int) ret;
908656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
909656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
910656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BIO_nwrite(BIO *bio, char **buf, int num)
911656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
913656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!bio->init)
915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -2;
918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ret > 0)
922e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		bio->num_write += ret;
923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
925