bss_bio.c revision 68651
117721Speter/* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */ 217721Speter 317721Speter/* Special method for a BIO where the other endpoint is also a BIO 417721Speter * of this kind, handled by the same thread (i.e. the "peer" is actually 532785Speter * ourselves, wearing a different hat). 617721Speter * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces 717721Speter * for which no specific BIO method is available. 817721Speter * See ssl/ssltest.c for some hints on how this can be used. */ 917721Speter 1017721Speter#ifndef BIO_PAIR_DEBUG 1117721Speter# undef NDEBUG /* avoid conflicting definitions */ 1217721Speter# define NDEBUG 1317721Speter#endif 1417721Speter 1517721Speter#include <assert.h> 1617721Speter#include <limits.h> 1717721Speter#include <stdlib.h> 1817721Speter#include <string.h> 1917721Speter 2017721Speter#include <openssl/bio.h> 2117721Speter#include <openssl/err.h> 2225839Speter#include <openssl/err.h> 2317721Speter#include <openssl/crypto.h> 2432785Speter 2532785Speter#include "openssl/e_os.h" 2617721Speter#ifndef SSIZE_MAX 2717721Speter# define SSIZE_MAX INT_MAX 2817721Speter#endif 2917721Speter 3017721Speterstatic int bio_new(BIO *bio); 3117721Speterstatic int bio_free(BIO *bio); 3217721Speterstatic int bio_read(BIO *bio, char *buf, int size); 3317721Speterstatic int bio_write(BIO *bio, const char *buf, int num); 3417721Speterstatic long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); 3517721Speterstatic int bio_puts(BIO *bio, const char *str); 3625839Speter 3717721Speterstatic int bio_make_pair(BIO *bio1, BIO *bio2); 3817721Speterstatic void bio_destroy_pair(BIO *bio); 3917721Speter 4017721Speterstatic BIO_METHOD methods_biop = 4117721Speter{ 4217721Speter BIO_TYPE_BIO, 4317721Speter "BIO pair", 4417721Speter bio_write, 4517721Speter bio_read, 4617721Speter bio_puts, 4717721Speter NULL /* no bio_gets */, 4817721Speter bio_ctrl, 4917721Speter bio_new, 5017721Speter bio_free, 5117721Speter NULL /* no bio_callback_ctrl */ 5217721Speter}; 5317721Speter 5417721SpeterBIO_METHOD *BIO_s_bio(void) 5517721Speter { 5617721Speter return &methods_biop; 5717721Speter } 5817721Speter 5917721Speterstruct bio_bio_st 6017721Speter{ 6117721Speter BIO *peer; /* NULL if buf == NULL. 6217721Speter * If peer != NULL, then peer->ptr is also a bio_bio_st, 6317721Speter * and its "peer" member points back to us. 6417721Speter * peer != NULL iff init != 0 in the BIO. */ 6517721Speter 6617721Speter /* This is for what we write (i.e. reading uses peer's struct): */ 6717721Speter int closed; /* valid iff peer != NULL */ 6817721Speter size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ 6917721Speter size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ 7017721Speter size_t size; 7117721Speter char *buf; /* "size" elements (if != NULL) */ 7217721Speter 7317721Speter size_t request; /* valid iff peer != NULL; 0 if len != 0, 7417721Speter * otherwise set by peer to number of bytes 7517721Speter * it (unsuccessfully) tried to read, 7625839Speter * never more than buffer space (size-len) warrants. */ 7717721Speter}; 7817721Speter 7917721Speterstatic int bio_new(BIO *bio) 8017721Speter { 8117721Speter struct bio_bio_st *b; 8217721Speter 8317721Speter b = OPENSSL_malloc(sizeof *b); 8417721Speter if (b == NULL) 8517721Speter return 0; 8617721Speter 8717721Speter b->peer = NULL; 8817721Speter b->size = 17*1024; /* enough for one TLS record (just a default) */ 8917721Speter b->buf = NULL; 9017721Speter 9117721Speter bio->ptr = b; 9217721Speter return 1; 9317721Speter } 9417721Speter 9517721Speter 9617721Speterstatic int bio_free(BIO *bio) 9717721Speter { 9817721Speter struct bio_bio_st *b; 9917721Speter 10017721Speter if (bio == NULL) 10117721Speter return 0; 10217721Speter b = bio->ptr; 10317721Speter 10417721Speter assert(b != NULL); 10517721Speter 10617721Speter if (b->peer) 10717721Speter bio_destroy_pair(bio); 10817721Speter 10917721Speter if (b->buf != NULL) 11017721Speter { 11117721Speter OPENSSL_free(b->buf); 11217721Speter } 11317721Speter 11417721Speter OPENSSL_free(b); 11517721Speter 11617721Speter return 1; 11717721Speter } 11817721Speter 11917721Speter 12017721Speter 12117721Speterstatic int bio_read(BIO *bio, char *buf, int size_) 12217721Speter { 12317721Speter size_t size = size_; 12417721Speter size_t rest; 12517721Speter struct bio_bio_st *b, *peer_b; 12617721Speter 12717721Speter BIO_clear_retry_flags(bio); 12817721Speter 12917721Speter if (!bio->init) 13017721Speter return 0; 13117721Speter 13217721Speter b = bio->ptr; 13317721Speter assert(b != NULL); 13417721Speter assert(b->peer != NULL); 13517721Speter peer_b = b->peer->ptr; 13617721Speter assert(peer_b != NULL); 13717721Speter assert(peer_b->buf != NULL); 13817721Speter 13917721Speter peer_b->request = 0; /* will be set in "retry_read" situation */ 14017721Speter 14117721Speter if (buf == NULL || size == 0) 14217721Speter return 0; 14317721Speter 14417721Speter if (peer_b->len == 0) 14517721Speter { 14617721Speter if (peer_b->closed) 14717721Speter return 0; /* writer has closed, and no data is left */ 14817721Speter else 14917721Speter { 15017721Speter BIO_set_retry_read(bio); /* buffer is empty */ 15117721Speter if (size <= peer_b->size) 15217721Speter peer_b->request = size; 15317721Speter else 15417721Speter /* don't ask for more than the peer can 15517721Speter * deliver in one write */ 15617721Speter peer_b->request = peer_b->size; 15717721Speter return -1; 15817721Speter } 15917721Speter } 16017721Speter 16117721Speter /* we can read */ 16217721Speter if (peer_b->len < size) 16317721Speter size = peer_b->len; 16417721Speter 16517721Speter /* now read "size" bytes */ 16617721Speter 16717721Speter rest = size; 16817721Speter 16917721Speter assert(rest > 0); 17017721Speter do /* one or two iterations */ 17117721Speter { 17217721Speter size_t chunk; 17317721Speter 17417721Speter assert(rest <= peer_b->len); 17517721Speter if (peer_b->offset + rest <= peer_b->size) 17617721Speter chunk = rest; 17717721Speter else 17817721Speter /* wrap around ring buffer */ 17917721Speter chunk = peer_b->size - peer_b->offset; 18017721Speter assert(peer_b->offset + chunk <= peer_b->size); 18117721Speter 18217721Speter memcpy(buf, peer_b->buf + peer_b->offset, chunk); 18317721Speter 18417721Speter peer_b->len -= chunk; 18517721Speter if (peer_b->len) 18617721Speter { 18717721Speter peer_b->offset += chunk; 18817721Speter assert(peer_b->offset <= peer_b->size); 18917721Speter if (peer_b->offset == peer_b->size) 19017721Speter peer_b->offset = 0; 19117721Speter buf += chunk; 19217721Speter } 19317721Speter else 19417721Speter { 19517721Speter /* buffer now empty, no need to advance "buf" */ 19617721Speter assert(chunk == rest); 19717721Speter peer_b->offset = 0; 19817721Speter } 19917721Speter rest -= chunk; 20017721Speter } 20117721Speter while (rest); 20217721Speter 20317721Speter return size; 20425839Speter } 20525839Speter 20617721Speter/* non-copying interface: provide pointer to available data in buffer 20717721Speter * bio_nread0: return number of available bytes 20832785Speter * bio_nread: also advance index 20917721Speter * (example usage: bio_nread0(), read from buffer, bio_nread() 21025839Speter * or just bio_nread(), read from buffer) 21125839Speter */ 21225839Speter/* WARNING: The non-copying interface is largely untested as of yet 21332785Speter * and may contain bugs. */ 21417721Speterstatic ssize_t bio_nread0(BIO *bio, char **buf) 21517721Speter { 21617721Speter struct bio_bio_st *b, *peer_b; 21717721Speter ssize_t num; 21817721Speter 21917721Speter BIO_clear_retry_flags(bio); 22017721Speter 22117721Speter if (!bio->init) 22217721Speter return 0; 22317721Speter 22417721Speter b = bio->ptr; 22517721Speter assert(b != NULL); 22617721Speter assert(b->peer != NULL); 22717721Speter peer_b = b->peer->ptr; 22817721Speter assert(peer_b != NULL); 22917721Speter assert(peer_b->buf != NULL); 23025839Speter 23125839Speter peer_b->request = 0; 23217721Speter 23317721Speter if (peer_b->len == 0) 23417721Speter { 23517721Speter char dummy; 23617721Speter 23717721Speter /* avoid code duplication -- nothing available for reading */ 23817721Speter return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ 23917721Speter } 24017721Speter 24117721Speter num = peer_b->len; 24217721Speter if (peer_b->size < peer_b->offset + num) 24317721Speter /* no ring buffer wrap-around for non-copying interface */ 24417721Speter num = peer_b->size - peer_b->offset; 24517721Speter assert(num > 0); 24617721Speter 24717721Speter if (buf != NULL) 24817721Speter *buf = peer_b->buf + peer_b->offset; 24917721Speter return num; 25017721Speter } 25125839Speter 25225839Speterstatic ssize_t bio_nread(BIO *bio, char **buf, size_t num_) 25325839Speter { 25425839Speter struct bio_bio_st *b, *peer_b; 25525839Speter ssize_t num, available; 25617721Speter 25717721Speter if (num_ > SSIZE_MAX) 25817721Speter num = SSIZE_MAX; 25917721Speter else 26017721Speter num = (ssize_t)num_; 26117721Speter 26217721Speter available = bio_nread0(bio, buf); 26317721Speter if (num > available) 26417721Speter num = available; 26517721Speter if (num <= 0) 26617721Speter return num; 26717721Speter 26817721Speter b = bio->ptr; 26917721Speter peer_b = b->peer->ptr; 27017721Speter 27117721Speter peer_b->len -= num; 27217721Speter if (peer_b->len) 27317721Speter { 27417721Speter peer_b->offset += num; 27517721Speter assert(peer_b->offset <= peer_b->size); 27617721Speter if (peer_b->offset == peer_b->size) 27717721Speter peer_b->offset = 0; 27817721Speter } 27917721Speter else 28017721Speter peer_b->offset = 0; 28117721Speter 28217721Speter return num; 28317721Speter } 28417721Speter 28517721Speter 28617721Speterstatic int bio_write(BIO *bio, const char *buf, int num_) 28717721Speter { 28817721Speter size_t num = num_; 28917721Speter size_t rest; 29017721Speter struct bio_bio_st *b; 29117721Speter 29217721Speter BIO_clear_retry_flags(bio); 29317721Speter 29432785Speter if (!bio->init || buf == NULL || num == 0) 29532785Speter return 0; 29632785Speter 29732785Speter b = bio->ptr; 29817721Speter assert(b != NULL); 29925839Speter assert(b->peer != NULL); 30017721Speter assert(b->buf != NULL); 30117721Speter 30217721Speter b->request = 0; 303 if (b->closed) 304 { 305 /* we already closed */ 306 BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); 307 return -1; 308 } 309 310 assert(b->len <= b->size); 311 312 if (b->len == b->size) 313 { 314 BIO_set_retry_write(bio); /* buffer is full */ 315 return -1; 316 } 317 318 /* we can write */ 319 if (num > b->size - b->len) 320 num = b->size - b->len; 321 322 /* now write "num" bytes */ 323 324 rest = num; 325 326 assert(rest > 0); 327 do /* one or two iterations */ 328 { 329 size_t write_offset; 330 size_t chunk; 331 332 assert(b->len + rest <= b->size); 333 334 write_offset = b->offset + b->len; 335 if (write_offset >= b->size) 336 write_offset -= b->size; 337 /* b->buf[write_offset] is the first byte we can write to. */ 338 339 if (write_offset + rest <= b->size) 340 chunk = rest; 341 else 342 /* wrap around ring buffer */ 343 chunk = b->size - write_offset; 344 345 memcpy(b->buf + write_offset, buf, chunk); 346 347 b->len += chunk; 348 349 assert(b->len <= b->size); 350 351 rest -= chunk; 352 buf += chunk; 353 } 354 while (rest); 355 356 return num; 357 } 358 359/* non-copying interface: provide pointer to region to write to 360 * bio_nwrite0: check how much space is available 361 * bio_nwrite: also increase length 362 * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() 363 * or just bio_nwrite(), write to buffer) 364 */ 365static ssize_t bio_nwrite0(BIO *bio, char **buf) 366 { 367 struct bio_bio_st *b; 368 size_t num; 369 size_t write_offset; 370 371 BIO_clear_retry_flags(bio); 372 373 if (!bio->init) 374 return 0; 375 376 b = bio->ptr; 377 assert(b != NULL); 378 assert(b->peer != NULL); 379 assert(b->buf != NULL); 380 381 b->request = 0; 382 if (b->closed) 383 { 384 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); 385 return -1; 386 } 387 388 assert(b->len <= b->size); 389 390 if (b->len == b->size) 391 { 392 BIO_set_retry_write(bio); 393 return -1; 394 } 395 396 num = b->size - b->len; 397 write_offset = b->offset + b->len; 398 if (write_offset >= b->size) 399 write_offset -= b->size; 400 if (write_offset + num > b->size) 401 /* no ring buffer wrap-around for non-copying interface 402 * (to fulfil the promise by BIO_ctrl_get_write_guarantee, 403 * BIO_nwrite may have to be called twice) */ 404 num = b->size - write_offset; 405 406 if (buf != NULL) 407 *buf = b->buf + write_offset; 408 assert(write_offset + num <= b->size); 409 410 return num; 411 } 412 413static ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) 414 { 415 struct bio_bio_st *b; 416 ssize_t num, space; 417 418 if (num_ > SSIZE_MAX) 419 num = SSIZE_MAX; 420 else 421 num = (ssize_t)num_; 422 423 space = bio_nwrite0(bio, buf); 424 if (num > space) 425 num = space; 426 if (num <= 0) 427 return num; 428 b = bio->ptr; 429 assert(b != NULL); 430 b->len += num; 431 assert(b->len <= b->size); 432 433 return num; 434 } 435 436 437static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) 438 { 439 long ret; 440 struct bio_bio_st *b = bio->ptr; 441 442 assert(b != NULL); 443 444 switch (cmd) 445 { 446 /* specific CTRL codes */ 447 448 case BIO_C_SET_WRITE_BUF_SIZE: 449 if (b->peer) 450 { 451 BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); 452 ret = 0; 453 } 454 else if (num == 0) 455 { 456 BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); 457 ret = 0; 458 } 459 else 460 { 461 size_t new_size = num; 462 463 if (b->size != new_size) 464 { 465 if (b->buf) 466 { 467 OPENSSL_free(b->buf); 468 b->buf = NULL; 469 } 470 b->size = new_size; 471 } 472 ret = 1; 473 } 474 break; 475 476 case BIO_C_GET_WRITE_BUF_SIZE: 477 num = (long) b->size; 478 479 case BIO_C_MAKE_BIO_PAIR: 480 { 481 BIO *other_bio = ptr; 482 483 if (bio_make_pair(bio, other_bio)) 484 ret = 1; 485 else 486 ret = 0; 487 } 488 break; 489 490 case BIO_C_DESTROY_BIO_PAIR: 491 /* Effects both BIOs in the pair -- call just once! 492 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ 493 bio_destroy_pair(bio); 494 ret = 1; 495 break; 496 497 case BIO_C_GET_WRITE_GUARANTEE: 498 /* How many bytes can the caller feed to the next write 499 * without having to keep any? */ 500 if (b->peer == NULL || b->closed) 501 ret = 0; 502 else 503 ret = (long) b->size - b->len; 504 break; 505 506 case BIO_C_GET_READ_REQUEST: 507 /* If the peer unsuccessfully tried to read, how many bytes 508 * were requested? (As with BIO_CTRL_PENDING, that number 509 * can usually be treated as boolean.) */ 510 ret = (long) b->request; 511 break; 512 513 case BIO_C_RESET_READ_REQUEST: 514 /* Reset request. (Can be useful after read attempts 515 * at the other side that are meant to be non-blocking, 516 * e.g. when probing SSL_read to see if any data is 517 * available.) */ 518 b->request = 0; 519 ret = 1; 520 break; 521 522 case BIO_C_SHUTDOWN_WR: 523 /* similar to shutdown(..., SHUT_WR) */ 524 b->closed = 1; 525 ret = 1; 526 break; 527 528 case BIO_C_NREAD0: 529 /* prepare for non-copying read */ 530 ret = (long) bio_nread0(bio, ptr); 531 break; 532 533 case BIO_C_NREAD: 534 /* non-copying read */ 535 ret = (long) bio_nread(bio, ptr, (size_t) num); 536 break; 537 538 case BIO_C_NWRITE0: 539 /* prepare for non-copying write */ 540 ret = (long) bio_nwrite0(bio, ptr); 541 break; 542 543 case BIO_C_NWRITE: 544 /* non-copying write */ 545 ret = (long) bio_nwrite(bio, ptr, (size_t) num); 546 break; 547 548 549 /* standard CTRL codes follow */ 550 551 case BIO_CTRL_RESET: 552 if (b->buf != NULL) 553 { 554 b->len = 0; 555 b->offset = 0; 556 } 557 ret = 0; 558 break; 559 560 case BIO_CTRL_GET_CLOSE: 561 ret = bio->shutdown; 562 break; 563 564 case BIO_CTRL_SET_CLOSE: 565 bio->shutdown = (int) num; 566 ret = 1; 567 break; 568 569 case BIO_CTRL_PENDING: 570 if (b->peer != NULL) 571 { 572 struct bio_bio_st *peer_b = b->peer->ptr; 573 574 ret = (long) peer_b->len; 575 } 576 else 577 ret = 0; 578 break; 579 580 case BIO_CTRL_WPENDING: 581 if (b->buf != NULL) 582 ret = (long) b->len; 583 else 584 ret = 0; 585 break; 586 587 case BIO_CTRL_DUP: 588 /* See BIO_dup_chain for circumstances we have to expect. */ 589 { 590 BIO *other_bio = ptr; 591 struct bio_bio_st *other_b; 592 593 assert(other_bio != NULL); 594 other_b = other_bio->ptr; 595 assert(other_b != NULL); 596 597 assert(other_b->buf == NULL); /* other_bio is always fresh */ 598 599 other_b->size = b->size; 600 } 601 602 ret = 1; 603 break; 604 605 case BIO_CTRL_FLUSH: 606 ret = 1; 607 break; 608 609 case BIO_CTRL_EOF: 610 { 611 BIO *other_bio = ptr; 612 613 if (other_bio) 614 { 615 struct bio_bio_st *other_b = other_bio->ptr; 616 617 assert(other_b != NULL); 618 ret = other_b->len == 0 && other_b->closed; 619 } 620 else 621 ret = 1; 622 } 623 break; 624 625 default: 626 ret = 0; 627 } 628 return ret; 629 } 630 631static int bio_puts(BIO *bio, const char *str) 632 { 633 return bio_write(bio, str, strlen(str)); 634 } 635 636 637static int bio_make_pair(BIO *bio1, BIO *bio2) 638 { 639 struct bio_bio_st *b1, *b2; 640 641 assert(bio1 != NULL); 642 assert(bio2 != NULL); 643 644 b1 = bio1->ptr; 645 b2 = bio2->ptr; 646 647 if (b1->peer != NULL || b2->peer != NULL) 648 { 649 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); 650 return 0; 651 } 652 653 if (b1->buf == NULL) 654 { 655 b1->buf = OPENSSL_malloc(b1->size); 656 if (b1->buf == NULL) 657 { 658 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); 659 return 0; 660 } 661 b1->len = 0; 662 b1->offset = 0; 663 } 664 665 if (b2->buf == NULL) 666 { 667 b2->buf = OPENSSL_malloc(b2->size); 668 if (b2->buf == NULL) 669 { 670 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); 671 return 0; 672 } 673 b2->len = 0; 674 b2->offset = 0; 675 } 676 677 b1->peer = bio2; 678 b1->closed = 0; 679 b1->request = 0; 680 b2->peer = bio1; 681 b2->closed = 0; 682 b2->request = 0; 683 684 bio1->init = 1; 685 bio2->init = 1; 686 687 return 1; 688 } 689 690static void bio_destroy_pair(BIO *bio) 691 { 692 struct bio_bio_st *b = bio->ptr; 693 694 if (b != NULL) 695 { 696 BIO *peer_bio = b->peer; 697 698 if (peer_bio != NULL) 699 { 700 struct bio_bio_st *peer_b = peer_bio->ptr; 701 702 assert(peer_b != NULL); 703 assert(peer_b->peer == bio); 704 705 peer_b->peer = NULL; 706 peer_bio->init = 0; 707 assert(peer_b->buf != NULL); 708 peer_b->len = 0; 709 peer_b->offset = 0; 710 711 b->peer = NULL; 712 bio->init = 0; 713 assert(b->buf != NULL); 714 b->len = 0; 715 b->offset = 0; 716 } 717 } 718 } 719 720 721/* Exported convenience functions */ 722int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, 723 BIO **bio2_p, size_t writebuf2) 724 { 725 BIO *bio1 = NULL, *bio2 = NULL; 726 long r; 727 int ret = 0; 728 729 bio1 = BIO_new(BIO_s_bio()); 730 if (bio1 == NULL) 731 goto err; 732 bio2 = BIO_new(BIO_s_bio()); 733 if (bio2 == NULL) 734 goto err; 735 736 if (writebuf1) 737 { 738 r = BIO_set_write_buf_size(bio1, writebuf1); 739 if (!r) 740 goto err; 741 } 742 if (writebuf2) 743 { 744 r = BIO_set_write_buf_size(bio2, writebuf2); 745 if (!r) 746 goto err; 747 } 748 749 r = BIO_make_bio_pair(bio1, bio2); 750 if (!r) 751 goto err; 752 ret = 1; 753 754 err: 755 if (ret == 0) 756 { 757 if (bio1) 758 { 759 BIO_free(bio1); 760 bio1 = NULL; 761 } 762 if (bio2) 763 { 764 BIO_free(bio2); 765 bio2 = NULL; 766 } 767 } 768 769 *bio1_p = bio1; 770 *bio2_p = bio2; 771 return ret; 772 } 773 774size_t BIO_ctrl_get_write_guarantee(BIO *bio) 775 { 776 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); 777 } 778 779size_t BIO_ctrl_get_read_request(BIO *bio) 780 { 781 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); 782 } 783 784int BIO_ctrl_reset_read_request(BIO *bio) 785 { 786 return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); 787 } 788 789 790/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now 791 * (conceivably some other BIOs could allow non-copying reads and writes too.) 792 */ 793int BIO_nread0(BIO *bio, char **buf) 794 { 795 long ret; 796 797 if (!bio->init) 798 { 799 BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); 800 return -2; 801 } 802 803 ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); 804 if (ret > INT_MAX) 805 return INT_MAX; 806 else 807 return (int) ret; 808 } 809 810int BIO_nread(BIO *bio, char **buf, int num) 811 { 812 int ret; 813 814 if (!bio->init) 815 { 816 BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); 817 return -2; 818 } 819 820 ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf); 821 if (ret > 0) 822 bio->num_read += ret; 823 return ret; 824 } 825 826int BIO_nwrite0(BIO *bio, char **buf) 827 { 828 long ret; 829 830 if (!bio->init) 831 { 832 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); 833 return -2; 834 } 835 836 ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); 837 if (ret > INT_MAX) 838 return INT_MAX; 839 else 840 return (int) ret; 841 } 842 843int BIO_nwrite(BIO *bio, char **buf, int num) 844 { 845 int ret; 846 847 if (!bio->init) 848 { 849 BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); 850 return -2; 851 } 852 853 ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); 854 if (ret > 0) 855 bio->num_read += ret; 856 return ret; 857 } 858