summaryrefslogtreecommitdiff
path: root/crypto/bio/bss_fd.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2001-02-02 00:31:45 +0000
committerDr. Stephen Henson <steve@openssl.org>2001-02-02 00:31:45 +0000
commit664d83bb23e7e6d30b63f6127b454f7c6dc33da9 (patch)
tree8a2e17bfd35cc2cbeb9a00a499ebf589654eb9db /crypto/bio/bss_fd.c
parent8cff6331c944398cc7889e586116c11e89f89147 (diff)
downloadopenssl-new-664d83bb23e7e6d30b63f6127b454f7c6dc33da9.tar.gz
Tidy up the mess in bss_sock.c and bss_fd.c
by placing them socket/fd code in separate files rather than trying to have them both share the same one.
Diffstat (limited to 'crypto/bio/bss_fd.c')
-rw-r--r--crypto/bio/bss_fd.c226
1 files changed, 223 insertions, 3 deletions
diff --git a/crypto/bio/bss_fd.c b/crypto/bio/bss_fd.c
index 686c4909a2..47f59c467d 100644
--- a/crypto/bio/bss_fd.c
+++ b/crypto/bio/bss_fd.c
@@ -56,7 +56,227 @@
* [including the GNU Public Licence.]
*/
-#define BIO_FD
-#include "bss_sock.c"
-#undef BIO_FD
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "cryptlib.h"
+#include <openssl/bio.h>
+static int fd_write(BIO *h, const char *buf, int num);
+static int fd_read(BIO *h, char *buf, int size);
+static int fd_puts(BIO *h, const char *str);
+static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int fd_new(BIO *h);
+static int fd_free(BIO *data);
+int BIO_fd_should_retry(int s);
+
+static BIO_METHOD methods_fdp=
+ {
+ BIO_TYPE_FD,"file descriptor",
+ fd_write,
+ fd_read,
+ fd_puts,
+ NULL, /* fd_gets, */
+ fd_ctrl,
+ fd_new,
+ fd_free,
+ NULL,
+ };
+
+BIO_METHOD *BIO_s_fd(void)
+ {
+ return(&methods_fdp);
+ }
+
+BIO *BIO_new_fd(int fd,int close_flag)
+ {
+ BIO *ret;
+ ret=BIO_new(BIO_s_fd());
+ if (ret == NULL) return(NULL);
+ BIO_set_fd(ret,fd,close_flag);
+ return(ret);
+ }
+
+static int fd_new(BIO *bi)
+ {
+ bi->init=0;
+ bi->num=0;
+ bi->ptr=NULL;
+ bi->flags=0;
+ return(1);
+ }
+
+static int fd_free(BIO *a)
+ {
+ if (a == NULL) return(0);
+ if (a->shutdown)
+ {
+ if (a->init)
+ {
+ close(a->num);
+ }
+ a->init=0;
+ a->flags=0;
+ }
+ return(1);
+ }
+
+static int fd_read(BIO *b, char *out,int outl)
+ {
+ int ret=0;
+
+ if (out != NULL)
+ {
+ clear_sys_error();
+ ret=read(b->num,out,outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0)
+ {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return(ret);
+ }
+
+static int fd_write(BIO *b, const char *in, int inl)
+ {
+ int ret;
+ clear_sys_error();
+ ret=write(b->num,in,inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0)
+ {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return(ret);
+ }
+
+static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+ long ret=1;
+ int *ip;
+
+ switch (cmd)
+ {
+ case BIO_CTRL_RESET:
+ num=0;
+ case BIO_C_FILE_SEEK:
+ ret=(long)lseek(b->num,num,0);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret=(long)lseek(b->num,0,1);
+ break;
+ case BIO_C_SET_FD:
+ fd_free(b);
+ b->num= *((int *)ptr);
+ b->shutdown=(int)num;
+ b->init=1;
+ break;
+ case BIO_C_GET_FD:
+ if (b->init)
+ {
+ ip=(int *)ptr;
+ if (ip != NULL) *ip=b->num;
+ ret=b->num;
+ }
+ else
+ ret= -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret=b->shutdown;
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ b->shutdown=(int)num;
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret=0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret=1;
+ break;
+ default:
+ ret=0;
+ break;
+ }
+ return(ret);
+ }
+
+static int fd_puts(BIO *bp, const char *str)
+ {
+ int n,ret;
+
+ n=strlen(str);
+ ret=fd_write(bp,str,n);
+ return(ret);
+ }
+
+int BIO_fd_should_retry(int i)
+ {
+ int err;
+
+ if ((i == 0) || (i == -1))
+ {
+ err=get_last_sys_error();
+
+#if defined(WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
+ if ((i == -1) && (err == 0))
+ return(1);
+#endif
+
+ return(BIO_fd_non_fatal_error(err));
+ }
+ return(0);
+ }
+
+int BIO_fd_non_fatal_error(int err)
+ {
+ switch (err)
+ {
+
+#ifdef EWOULDBLOCK
+# ifdef WSAEWOULDBLOCK
+# if WSAEWOULDBLOCK != EWOULDBLOCK
+ case EWOULDBLOCK:
+# endif
+# else
+ case EWOULDBLOCK:
+# endif
+#endif
+
+#if defined(ENOTCONN)
+ case ENOTCONN:
+#endif
+
+#ifdef EINTR
+ case EINTR:
+#endif
+
+#ifdef EAGAIN
+#if EWOULDBLOCK != EAGAIN
+ case EAGAIN:
+# endif
+#endif
+
+#ifdef EPROTO
+ case EPROTO:
+#endif
+
+#ifdef EINPROGRESS
+ case EINPROGRESS:
+#endif
+
+#ifdef EALREADY
+ case EALREADY:
+#endif
+ return(1);
+ /* break; */
+ default:
+ break;
+ }
+ return(0);
+ }