]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/bio/bss_fd.c
Fix gcc-7 warnings.
[thirdparty/openssl.git] / crypto / bio / bss_fd.c
1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <stdio.h>
11 #include <errno.h>
12
13 #include "bio_lcl.h"
14
15 #if defined(OPENSSL_NO_POSIX_IO)
16 /*
17 * Dummy placeholder for BIO_s_fd...
18 */
19 BIO *BIO_new_fd(int fd, int close_flag)
20 {
21 return NULL;
22 }
23
24 int BIO_fd_non_fatal_error(int err)
25 {
26 return 0;
27 }
28
29 int BIO_fd_should_retry(int i)
30 {
31 return 0;
32 }
33
34 const BIO_METHOD *BIO_s_fd(void)
35 {
36 return NULL;
37 }
38 #else
39 /*
40 * As for unconditional usage of "UPLINK" interface in this module.
41 * Trouble is that unlike Unix file descriptors [which are indexes
42 * in kernel-side per-process table], corresponding descriptors on
43 * platforms which require "UPLINK" interface seem to be indexes
44 * in a user-land, non-global table. Well, in fact they are indexes
45 * in stdio _iob[], and recall that _iob[] was the very reason why
46 * "UPLINK" interface was introduced in first place. But one way on
47 * another. Neither libcrypto or libssl use this BIO meaning that
48 * file descriptors can only be provided by application. Therefore
49 * "UPLINK" calls are due...
50 */
51 static int fd_write(BIO *h, const char *buf, int num);
52 static int fd_read(BIO *h, char *buf, int size);
53 static int fd_puts(BIO *h, const char *str);
54 static int fd_gets(BIO *h, char *buf, int size);
55 static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
56 static int fd_new(BIO *h);
57 static int fd_free(BIO *data);
58 int BIO_fd_should_retry(int s);
59
60 static const BIO_METHOD methods_fdp = {
61 BIO_TYPE_FD, "file descriptor",
62 /* TODO: Convert to new style write function */
63 bwrite_conv,
64 fd_write,
65 /* TODO: Convert to new style read function */
66 bread_conv,
67 fd_read,
68 fd_puts,
69 fd_gets,
70 fd_ctrl,
71 fd_new,
72 fd_free,
73 NULL,
74 };
75
76 const BIO_METHOD *BIO_s_fd(void)
77 {
78 return (&methods_fdp);
79 }
80
81 BIO *BIO_new_fd(int fd, int close_flag)
82 {
83 BIO *ret;
84 ret = BIO_new(BIO_s_fd());
85 if (ret == NULL)
86 return (NULL);
87 BIO_set_fd(ret, fd, close_flag);
88 return (ret);
89 }
90
91 static int fd_new(BIO *bi)
92 {
93 bi->init = 0;
94 bi->num = -1;
95 bi->ptr = NULL;
96 bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
97 return (1);
98 }
99
100 static int fd_free(BIO *a)
101 {
102 if (a == NULL)
103 return (0);
104 if (a->shutdown) {
105 if (a->init) {
106 UP_close(a->num);
107 }
108 a->init = 0;
109 a->flags = BIO_FLAGS_UPLINK;
110 }
111 return (1);
112 }
113
114 static int fd_read(BIO *b, char *out, int outl)
115 {
116 int ret = 0;
117
118 if (out != NULL) {
119 clear_sys_error();
120 ret = UP_read(b->num, out, outl);
121 BIO_clear_retry_flags(b);
122 if (ret <= 0) {
123 if (BIO_fd_should_retry(ret))
124 BIO_set_retry_read(b);
125 }
126 }
127 return (ret);
128 }
129
130 static int fd_write(BIO *b, const char *in, int inl)
131 {
132 int ret;
133 clear_sys_error();
134 ret = UP_write(b->num, in, inl);
135 BIO_clear_retry_flags(b);
136 if (ret <= 0) {
137 if (BIO_fd_should_retry(ret))
138 BIO_set_retry_write(b);
139 }
140 return (ret);
141 }
142
143 static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
144 {
145 long ret = 1;
146 int *ip;
147
148 switch (cmd) {
149 case BIO_CTRL_RESET:
150 num = 0;
151 /* fall thru */
152 case BIO_C_FILE_SEEK:
153 ret = (long)UP_lseek(b->num, num, 0);
154 break;
155 case BIO_C_FILE_TELL:
156 case BIO_CTRL_INFO:
157 ret = (long)UP_lseek(b->num, 0, 1);
158 break;
159 case BIO_C_SET_FD:
160 fd_free(b);
161 b->num = *((int *)ptr);
162 b->shutdown = (int)num;
163 b->init = 1;
164 break;
165 case BIO_C_GET_FD:
166 if (b->init) {
167 ip = (int *)ptr;
168 if (ip != NULL)
169 *ip = b->num;
170 ret = b->num;
171 } else
172 ret = -1;
173 break;
174 case BIO_CTRL_GET_CLOSE:
175 ret = b->shutdown;
176 break;
177 case BIO_CTRL_SET_CLOSE:
178 b->shutdown = (int)num;
179 break;
180 case BIO_CTRL_PENDING:
181 case BIO_CTRL_WPENDING:
182 ret = 0;
183 break;
184 case BIO_CTRL_DUP:
185 case BIO_CTRL_FLUSH:
186 ret = 1;
187 break;
188 default:
189 ret = 0;
190 break;
191 }
192 return (ret);
193 }
194
195 static int fd_puts(BIO *bp, const char *str)
196 {
197 int n, ret;
198
199 n = strlen(str);
200 ret = fd_write(bp, str, n);
201 return (ret);
202 }
203
204 static int fd_gets(BIO *bp, char *buf, int size)
205 {
206 int ret = 0;
207 char *ptr = buf;
208 char *end = buf + size - 1;
209
210 while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
211 ptr++;
212
213 ptr[0] = '\0';
214
215 if (buf[0] != '\0')
216 ret = strlen(buf);
217 return (ret);
218 }
219
220 int BIO_fd_should_retry(int i)
221 {
222 int err;
223
224 if ((i == 0) || (i == -1)) {
225 err = get_last_sys_error();
226
227 return (BIO_fd_non_fatal_error(err));
228 }
229 return (0);
230 }
231
232 int BIO_fd_non_fatal_error(int err)
233 {
234 switch (err) {
235
236 # ifdef EWOULDBLOCK
237 # ifdef WSAEWOULDBLOCK
238 # if WSAEWOULDBLOCK != EWOULDBLOCK
239 case EWOULDBLOCK:
240 # endif
241 # else
242 case EWOULDBLOCK:
243 # endif
244 # endif
245
246 # if defined(ENOTCONN)
247 case ENOTCONN:
248 # endif
249
250 # ifdef EINTR
251 case EINTR:
252 # endif
253
254 # ifdef EAGAIN
255 # if EWOULDBLOCK != EAGAIN
256 case EAGAIN:
257 # endif
258 # endif
259
260 # ifdef EPROTO
261 case EPROTO:
262 # endif
263
264 # ifdef EINPROGRESS
265 case EINPROGRESS:
266 # endif
267
268 # ifdef EALREADY
269 case EALREADY:
270 # endif
271 return (1);
272 default:
273 break;
274 }
275 return (0);
276 }
277 #endif