+
+
+/* Exported convenience functions */
+int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
+ BIO **bio2_p, size_t writebuf2)
+ {
+ BIO *bio1 = NULL, *bio2 = NULL;
+ long r;
+ int ret = 0;
+
+ bio1 = BIO_new(BIO_s_bio());
+ if (bio1 == NULL)
+ goto err;
+ bio2 = BIO_new(BIO_s_bio());
+ if (bio2 == NULL)
+ goto err;
+
+ if (writebuf1)
+ {
+ r = BIO_set_write_buf_size(bio1, writebuf1);
+ if (!r)
+ goto err;
+ }
+ if (writebuf2)
+ {
+ r = BIO_set_write_buf_size(bio2, writebuf2);
+ if (!r)
+ goto err;
+ }
+
+ r = BIO_make_bio_pair(bio1, bio2);
+ if (!r)
+ goto err;
+ ret = 1;
+
+ err:
+ if (ret == 0)
+ {
+ if (bio1)
+ {
+ BIO_free(bio1);
+ bio1 = NULL;
+ }
+ if (bio2)
+ {
+ BIO_free(bio2);
+ bio2 = NULL;
+ }
+ }
+
+ *bio1_p = bio1;
+ *bio2_p = bio2;
+ return ret;
+ }
+
+size_t BIO_ctrl_get_write_guarantee(BIO *bio)
+ {
+ return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
+ }
+
+size_t BIO_ctrl_get_read_request(BIO *bio)
+ {
+ return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
+ }
+
+int BIO_ctrl_reset_read_request(BIO *bio)
+ {
+ return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+ }
+
+
+/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
+ * (conceivably some other BIOs could allow non-copying reads and writes too.)
+ */
+int BIO_nread0(BIO *bio, char **buf)
+ {
+ long ret;
+
+ if (!bio->init)
+ {
+ BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
+ if (ret > INT_MAX)
+ return INT_MAX;
+ else
+ return (int) ret;
+ }
+
+int BIO_nread(BIO *bio, char **buf, int num)
+ {
+ int ret;
+
+ if (!bio->init)
+ {
+ BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
+ if (ret > 0)
+ bio->num_read += ret;
+ return ret;
+ }
+
+int BIO_nwrite0(BIO *bio, char **buf)
+ {
+ long ret;
+
+ if (!bio->init)
+ {
+ BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
+ if (ret > INT_MAX)
+ return INT_MAX;
+ else
+ return (int) ret;
+ }
+
+int BIO_nwrite(BIO *bio, char **buf, int num)
+ {
+ int ret;
+
+ if (!bio->init)
+ {
+ BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+ return -2;
+ }
+
+ ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
+ if (ret > 0)
+ bio->num_read += ret;
+ return ret;
+ }