]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/bss_fd.c
Create BIO_read_ex() which handles size_t arguments
[thirdparty/openssl.git] / crypto / bio / bss_fd.c
CommitLineData
b1322259
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
b1322259
RS
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
d02b48c6
RE
8 */
9
664d83bb
DSH
10#include <stdio.h>
11#include <errno.h>
a5cc75d6
RL
12
13#include "bio_lcl.h"
1715e488
AP
14
15#if defined(OPENSSL_NO_POSIX_IO)
16/*
a006fef7 17 * Dummy placeholder for BIO_s_fd...
1715e488 18 */
0f113f3e
MC
19BIO *BIO_new_fd(int fd, int close_flag)
20{
21 return NULL;
22}
23
a006fef7 24int BIO_fd_non_fatal_error(int err)
0f113f3e
MC
25{
26 return 0;
27}
28
a006fef7 29int BIO_fd_should_retry(int i)
0f113f3e
MC
30{
31 return 0;
32}
a006fef7 33
04f6b0fd 34const BIO_METHOD *BIO_s_fd(void)
0f113f3e
MC
35{
36 return NULL;
37}
1715e488 38#else
ea1b02db
AP
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 */
664d83bb
DSH
51static int fd_write(BIO *h, const char *buf, int num);
52static int fd_read(BIO *h, char *buf, int size);
53static int fd_puts(BIO *h, const char *str);
c7235be6 54static int fd_gets(BIO *h, char *buf, int size);
664d83bb
DSH
55static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
56static int fd_new(BIO *h);
57static int fd_free(BIO *data);
58int BIO_fd_should_retry(int s);
59
04f6b0fd 60static const BIO_METHOD methods_fdp = {
0f113f3e
MC
61 BIO_TYPE_FD, "file descriptor",
62 fd_write,
d07aee2c
MC
63 /* TODO: Convert to new style read function */
64 bread_conv,
0f113f3e
MC
65 fd_read,
66 fd_puts,
67 fd_gets,
68 fd_ctrl,
69 fd_new,
70 fd_free,
71 NULL,
72};
664d83bb 73
04f6b0fd 74const BIO_METHOD *BIO_s_fd(void)
0f113f3e
MC
75{
76 return (&methods_fdp);
77}
78
79BIO *BIO_new_fd(int fd, int close_flag)
80{
81 BIO *ret;
82 ret = BIO_new(BIO_s_fd());
83 if (ret == NULL)
84 return (NULL);
85 BIO_set_fd(ret, fd, close_flag);
86 return (ret);
87}
664d83bb
DSH
88
89static int fd_new(BIO *bi)
0f113f3e
MC
90{
91 bi->init = 0;
92 bi->num = -1;
93 bi->ptr = NULL;
94 bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
95 return (1);
96}
664d83bb
DSH
97
98static int fd_free(BIO *a)
0f113f3e
MC
99{
100 if (a == NULL)
101 return (0);
102 if (a->shutdown) {
103 if (a->init) {
104 UP_close(a->num);
105 }
106 a->init = 0;
107 a->flags = BIO_FLAGS_UPLINK;
108 }
109 return (1);
110}
111
112static int fd_read(BIO *b, char *out, int outl)
113{
114 int ret = 0;
115
116 if (out != NULL) {
117 clear_sys_error();
118 ret = UP_read(b->num, out, outl);
119 BIO_clear_retry_flags(b);
120 if (ret <= 0) {
121 if (BIO_fd_should_retry(ret))
122 BIO_set_retry_read(b);
123 }
124 }
125 return (ret);
126}
664d83bb
DSH
127
128static int fd_write(BIO *b, const char *in, int inl)
0f113f3e
MC
129{
130 int ret;
131 clear_sys_error();
132 ret = UP_write(b->num, in, inl);
133 BIO_clear_retry_flags(b);
134 if (ret <= 0) {
135 if (BIO_fd_should_retry(ret))
136 BIO_set_retry_write(b);
137 }
138 return (ret);
139}
664d83bb
DSH
140
141static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
0f113f3e
MC
142{
143 long ret = 1;
144 int *ip;
145
146 switch (cmd) {
147 case BIO_CTRL_RESET:
148 num = 0;
149 case BIO_C_FILE_SEEK:
150 ret = (long)UP_lseek(b->num, num, 0);
151 break;
152 case BIO_C_FILE_TELL:
153 case BIO_CTRL_INFO:
154 ret = (long)UP_lseek(b->num, 0, 1);
155 break;
156 case BIO_C_SET_FD:
157 fd_free(b);
158 b->num = *((int *)ptr);
159 b->shutdown = (int)num;
160 b->init = 1;
161 break;
162 case BIO_C_GET_FD:
163 if (b->init) {
164 ip = (int *)ptr;
165 if (ip != NULL)
166 *ip = b->num;
167 ret = b->num;
168 } else
169 ret = -1;
170 break;
171 case BIO_CTRL_GET_CLOSE:
172 ret = b->shutdown;
173 break;
174 case BIO_CTRL_SET_CLOSE:
175 b->shutdown = (int)num;
176 break;
177 case BIO_CTRL_PENDING:
178 case BIO_CTRL_WPENDING:
179 ret = 0;
180 break;
181 case BIO_CTRL_DUP:
182 case BIO_CTRL_FLUSH:
183 ret = 1;
184 break;
185 default:
186 ret = 0;
187 break;
188 }
189 return (ret);
190}
664d83bb
DSH
191
192static int fd_puts(BIO *bp, const char *str)
0f113f3e
MC
193{
194 int n, ret;
664d83bb 195
0f113f3e
MC
196 n = strlen(str);
197 ret = fd_write(bp, str, n);
198 return (ret);
199}
664d83bb 200
c7235be6 201static int fd_gets(BIO *bp, char *buf, int size)
0f113f3e
MC
202{
203 int ret = 0;
204 char *ptr = buf;
205 char *end = buf + size - 1;
c7235be6 206
0f113f3e
MC
207 while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
208 ptr++;
c7235be6 209
0f113f3e 210 ptr[0] = '\0';
c7235be6 211
0f113f3e
MC
212 if (buf[0] != '\0')
213 ret = strlen(buf);
214 return (ret);
215}
c7235be6 216
664d83bb 217int BIO_fd_should_retry(int i)
0f113f3e
MC
218{
219 int err;
664d83bb 220
0f113f3e
MC
221 if ((i == 0) || (i == -1)) {
222 err = get_last_sys_error();
664d83bb 223
0f113f3e
MC
224 return (BIO_fd_non_fatal_error(err));
225 }
226 return (0);
227}
664d83bb
DSH
228
229int BIO_fd_non_fatal_error(int err)
0f113f3e
MC
230{
231 switch (err) {
232
233# ifdef EWOULDBLOCK
234# ifdef WSAEWOULDBLOCK
235# if WSAEWOULDBLOCK != EWOULDBLOCK
236 case EWOULDBLOCK:
237# endif
238# else
239 case EWOULDBLOCK:
664d83bb 240# endif
664d83bb 241# endif
664d83bb 242
0f113f3e
MC
243# if defined(ENOTCONN)
244 case ENOTCONN:
245# endif
664d83bb 246
0f113f3e
MC
247# ifdef EINTR
248 case EINTR:
249# endif
664d83bb 250
0f113f3e
MC
251# ifdef EAGAIN
252# if EWOULDBLOCK != EAGAIN
253 case EAGAIN:
254# endif
664d83bb 255# endif
664d83bb 256
0f113f3e
MC
257# ifdef EPROTO
258 case EPROTO:
259# endif
664d83bb 260
0f113f3e
MC
261# ifdef EINPROGRESS
262 case EINPROGRESS:
263# endif
664d83bb 264
0f113f3e
MC
265# ifdef EALREADY
266 case EALREADY:
267# endif
268 return (1);
269 /* break; */
270 default:
271 break;
272 }
273 return (0);
274}
eff7cb41 275#endif