GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/bio/bss_fd.c Lines: 0 76 0.0 %
Date: 2017-11-07 Branches: 0 51 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: bss_fd.c,v 1.18 2015/02/12 03:54:07 jsing Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <errno.h>
60
#include <stdio.h>
61
#include <string.h>
62
#include <unistd.h>
63
64
#include <openssl/opensslconf.h>
65
66
#include <openssl/bio.h>
67
68
static int fd_write(BIO *h, const char *buf, int num);
69
static int fd_read(BIO *h, char *buf, int size);
70
static int fd_puts(BIO *h, const char *str);
71
static int fd_gets(BIO *h, char *buf, int size);
72
static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
73
static int fd_new(BIO *h);
74
static int fd_free(BIO *data);
75
int BIO_fd_should_retry(int s);
76
77
static BIO_METHOD methods_fdp = {
78
	.type = BIO_TYPE_FD,
79
	.name = "file descriptor",
80
	.bwrite = fd_write,
81
	.bread = fd_read,
82
	.bputs = fd_puts,
83
	.bgets = fd_gets,
84
	.ctrl = fd_ctrl,
85
	.create = fd_new,
86
	.destroy = fd_free
87
};
88
89
BIO_METHOD *
90
BIO_s_fd(void)
91
{
92
	return (&methods_fdp);
93
}
94
95
BIO *
96
BIO_new_fd(int fd, int close_flag)
97
{
98
	BIO *ret;
99
	ret = BIO_new(BIO_s_fd());
100
	if (ret == NULL)
101
		return (NULL);
102
	BIO_set_fd(ret, fd, close_flag);
103
	return (ret);
104
}
105
106
static int
107
fd_new(BIO *bi)
108
{
109
	bi->init = 0;
110
	bi->num = -1;
111
	bi->ptr = NULL;
112
	bi->flags=0;
113
	return (1);
114
}
115
116
static int
117
fd_free(BIO *a)
118
{
119
	if (a == NULL)
120
		return (0);
121
	if (a->shutdown) {
122
		if (a->init) {
123
			close(a->num);
124
		}
125
		a->init = 0;
126
		a->flags = 0;
127
	}
128
	return (1);
129
}
130
131
static int
132
fd_read(BIO *b, char *out, int outl)
133
{
134
	int ret = 0;
135
136
	if (out != NULL) {
137
		errno = 0;
138
		ret = read(b->num, out, outl);
139
		BIO_clear_retry_flags(b);
140
		if (ret <= 0) {
141
			if (BIO_fd_should_retry(ret))
142
				BIO_set_retry_read(b);
143
		}
144
	}
145
	return (ret);
146
}
147
148
static int
149
fd_write(BIO *b, const char *in, int inl)
150
{
151
	int ret;
152
	errno = 0;
153
	ret = write(b->num, in, inl);
154
	BIO_clear_retry_flags(b);
155
	if (ret <= 0) {
156
		if (BIO_fd_should_retry(ret))
157
			BIO_set_retry_write(b);
158
	}
159
	return (ret);
160
}
161
162
static long
163
fd_ctrl(BIO *b, int cmd, long num, void *ptr)
164
{
165
	long ret = 1;
166
	int *ip;
167
168
	switch (cmd) {
169
	case BIO_CTRL_RESET:
170
		num = 0;
171
	case BIO_C_FILE_SEEK:
172
		ret = (long)lseek(b->num, num, 0);
173
		break;
174
	case BIO_C_FILE_TELL:
175
	case BIO_CTRL_INFO:
176
		ret = (long)lseek(b->num, 0, 1);
177
		break;
178
	case BIO_C_SET_FD:
179
		fd_free(b);
180
		b->num= *((int *)ptr);
181
		b->shutdown = (int)num;
182
		b->init = 1;
183
		break;
184
	case BIO_C_GET_FD:
185
		if (b->init) {
186
			ip = (int *)ptr;
187
			if (ip != NULL)
188
				*ip = b->num;
189
			ret = b->num;
190
		} else
191
			ret = -1;
192
		break;
193
	case BIO_CTRL_GET_CLOSE:
194
		ret = b->shutdown;
195
		break;
196
	case BIO_CTRL_SET_CLOSE:
197
		b->shutdown = (int)num;
198
		break;
199
	case BIO_CTRL_PENDING:
200
	case BIO_CTRL_WPENDING:
201
		ret = 0;
202
		break;
203
	case BIO_CTRL_DUP:
204
	case BIO_CTRL_FLUSH:
205
		ret = 1;
206
		break;
207
	default:
208
		ret = 0;
209
		break;
210
	}
211
	return (ret);
212
}
213
214
static int
215
fd_puts(BIO *bp, const char *str)
216
{
217
	int n, ret;
218
219
	n = strlen(str);
220
	ret = fd_write(bp, str, n);
221
	return (ret);
222
}
223
224
static int
225
fd_gets(BIO *bp, char *buf, int size)
226
{
227
	int ret = 0;
228
	char *ptr = buf;
229
	char *end = buf + size - 1;
230
231
	while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
232
		ptr++;
233
234
	ptr[0] = '\0';
235
236
	if (buf[0] != '\0')
237
		ret = strlen(buf);
238
	return (ret);
239
}
240
241
int
242
BIO_fd_should_retry(int i)
243
{
244
	int err;
245
246
	if ((i == 0) || (i == -1)) {
247
		err = errno;
248
		return (BIO_fd_non_fatal_error(err));
249
	}
250
	return (0);
251
}
252
253
int
254
BIO_fd_non_fatal_error(int err)
255
{
256
	switch (err) {
257
	case ENOTCONN:
258
	case EINTR:
259
	case EAGAIN:
260
	case EINPROGRESS:
261
	case EALREADY:
262
		return (1);
263
	default:
264
		break;
265
	}
266
	return (0);
267
}