⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bss_bio.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (write_offset >= b->size)		write_offset -= b->size;	if (write_offset + num > b->size)		/* no ring buffer wrap-around for non-copying interface		 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,		 * BIO_nwrite may have to be called twice) */		num = b->size - write_offset;	if (buf != NULL)		*buf = b->buf + write_offset;	assert(write_offset + num <= b->size);	return num;	}static ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)	{	struct bio_bio_st *b;	ssize_t num, space;	if (num_ > SSIZE_MAX)		num = SSIZE_MAX;	else		num = (ssize_t)num_;	space = bio_nwrite0(bio, buf);	if (num > space)		num = space;	if (num <= 0)		return num;	b = bio->ptr;	assert(b != NULL);	b->len += num;	assert(b->len <= b->size);	return num;	}static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)	{	long ret;	struct bio_bio_st *b = bio->ptr;		assert(b != NULL);	switch (cmd)		{	/* specific CTRL codes */	case BIO_C_SET_WRITE_BUF_SIZE:		if (b->peer)			{			BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);			ret = 0;			}		else if (num == 0)			{			BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);			ret = 0;			}		else			{			size_t new_size = num;			if (b->size != new_size)				{				if (b->buf) 					{					OPENSSL_free(b->buf);					b->buf = NULL;					}				b->size = new_size;				}			ret = 1;			}		break;	case BIO_C_GET_WRITE_BUF_SIZE:		ret = (long) b->size;		break;	case BIO_C_MAKE_BIO_PAIR:		{		BIO *other_bio = ptr;				if (bio_make_pair(bio, other_bio))			ret = 1;		else			ret = 0;		}		break;			case BIO_C_DESTROY_BIO_PAIR:		/* Affects both BIOs in the pair -- call just once!		 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */		bio_destroy_pair(bio);		ret = 1;		break;	case BIO_C_GET_WRITE_GUARANTEE:		/* How many bytes can the caller feed to the next write		 * without having to keep any? */		if (b->peer == NULL || b->closed)			ret = 0;		else			ret = (long) b->size - b->len;		break;	case BIO_C_GET_READ_REQUEST:		/* If the peer unsuccessfully tried to read, how many bytes		 * were requested?  (As with BIO_CTRL_PENDING, that number		 * can usually be treated as boolean.) */		ret = (long) b->request;		break;	case BIO_C_RESET_READ_REQUEST:		/* Reset request.  (Can be useful after read attempts		 * at the other side that are meant to be non-blocking,		 * e.g. when probing SSL_read to see if any data is		 * available.) */		b->request = 0;		ret = 1;		break;	case BIO_C_SHUTDOWN_WR:		/* similar to shutdown(..., SHUT_WR) */		b->closed = 1;		ret = 1;		break;	case BIO_C_NREAD0:		/* prepare for non-copying read */		ret = (long) bio_nread0(bio, ptr);		break;			case BIO_C_NREAD:		/* non-copying read */		ret = (long) bio_nread(bio, ptr, (size_t) num);		break;			case BIO_C_NWRITE0:		/* prepare for non-copying write */		ret = (long) bio_nwrite0(bio, ptr);		break;	case BIO_C_NWRITE:		/* non-copying write */		ret = (long) bio_nwrite(bio, ptr, (size_t) num);		break;			/* standard CTRL codes follow */	case BIO_CTRL_RESET:		if (b->buf != NULL)			{			b->len = 0;			b->offset = 0;			}		ret = 0;		break;			case BIO_CTRL_GET_CLOSE:		ret = bio->shutdown;		break;	case BIO_CTRL_SET_CLOSE:		bio->shutdown = (int) num;		ret = 1;		break;	case BIO_CTRL_PENDING:		if (b->peer != NULL)			{			struct bio_bio_st *peer_b = b->peer->ptr;						ret = (long) peer_b->len;			}		else			ret = 0;		break;	case BIO_CTRL_WPENDING:		if (b->buf != NULL)			ret = (long) b->len;		else			ret = 0;		break;	case BIO_CTRL_DUP:		/* See BIO_dup_chain for circumstances we have to expect. */		{		BIO *other_bio = ptr;		struct bio_bio_st *other_b;				assert(other_bio != NULL);		other_b = other_bio->ptr;		assert(other_b != NULL);				assert(other_b->buf == NULL); /* other_bio is always fresh */		other_b->size = b->size;		}		ret = 1;		break;	case BIO_CTRL_FLUSH:		ret = 1;		break;	case BIO_CTRL_EOF:		{		BIO *other_bio = ptr;				if (other_bio)			{			struct bio_bio_st *other_b = other_bio->ptr;						assert(other_b != NULL);			ret = other_b->len == 0 && other_b->closed;			}		else			ret = 1;		}		break;	default:		ret = 0;		}	return ret;	}static int bio_puts(BIO *bio, const char *str)	{	return bio_write(bio, str, strlen(str));	}static int bio_make_pair(BIO *bio1, BIO *bio2)	{	struct bio_bio_st *b1, *b2;	assert(bio1 != NULL);	assert(bio2 != NULL);	b1 = bio1->ptr;	b2 = bio2->ptr;		if (b1->peer != NULL || b2->peer != NULL)		{		BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);		return 0;		}		if (b1->buf == NULL)		{		b1->buf = OPENSSL_malloc(b1->size);		if (b1->buf == NULL)			{			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);			return 0;			}		b1->len = 0;		b1->offset = 0;		}		if (b2->buf == NULL)		{		b2->buf = OPENSSL_malloc(b2->size);		if (b2->buf == NULL)			{			BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);			return 0;			}		b2->len = 0;		b2->offset = 0;		}		b1->peer = bio2;	b1->closed = 0;	b1->request = 0;	b2->peer = bio1;	b2->closed = 0;	b2->request = 0;	bio1->init = 1;	bio2->init = 1;	return 1;	}static void bio_destroy_pair(BIO *bio)	{	struct bio_bio_st *b = bio->ptr;	if (b != NULL)		{		BIO *peer_bio = b->peer;		if (peer_bio != NULL)			{			struct bio_bio_st *peer_b = peer_bio->ptr;			assert(peer_b != NULL);			assert(peer_b->peer == bio);			peer_b->peer = NULL;			peer_bio->init = 0;			assert(peer_b->buf != NULL);			peer_b->len = 0;			peer_b->offset = 0;						b->peer = NULL;			bio->init = 0;			assert(b->buf != NULL);			b->len = 0;			b->offset = 0;			}		}	} /* 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_write += ret;	return ret;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -