From b4a6a615134b59435efbecdd8c5b5407b6af8e8f Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Fri, 5 Jun 2015 04:31:56 -0500 Subject: [PATCH] refactor win32 shims into posix_win.c this also adds a rename shim that allows overwrites --- .gitignore | 1 + crypto/Makefile.am | 4 + crypto/compat/posix_win.c | 167 ++++++++++++++++++++++++++++++++++++++ include/stdio.h | 31 ++----- include/win32netcompat.h | 139 +++---------------------------- 5 files changed, 191 insertions(+), 151 deletions(-) create mode 100644 crypto/compat/posix_win.c diff --git a/.gitignore b/.gitignore index b23d139..b12620c 100644 --- a/.gitignore +++ b/.gitignore @@ -116,6 +116,7 @@ include/openssl/*.he !/crypto/Makefile.am.* !/crypto/compat/arc4random.h !/crypto/compat/b_win.c +!/crypto/compat/posix_win.c !/crypto/compat/bsd_asprintf.c !/crypto/compat/ui_openssl_win.c diff --git a/crypto/Makefile.am b/crypto/Makefile.am index ad26168..b996488 100644 --- a/crypto/Makefile.am +++ b/crypto/Makefile.am @@ -65,6 +65,10 @@ if !HAVE_TIMINGSAFE_BCMP libcompat_la_SOURCES += compat/timingsafe_bcmp.c endif +if HOST_WIN +libcompat_la_SOURCES += compat/posix_win.c +endif + include Makefile.am.arc4random libcrypto_la_SOURCES = diff --git a/crypto/compat/posix_win.c b/crypto/compat/posix_win.c new file mode 100644 index 0000000..5793e40 --- /dev/null +++ b/crypto/compat/posix_win.c @@ -0,0 +1,167 @@ +/* + * Public domain + * + * BSD socket emulation code for Winsock2 + * File IO compatibility shims + * Brent Cook + */ + +#define NO_REDEF_POSIX_FUNCTIONS + +#include +#include + +#include +#include +#include +#include + +void +posix_perror(const char *s) +{ + fprintf(stderr, "%s: %s\n", s, strerror(errno)); +} + +FILE * +posix_fopen(const char *path, const char *mode) +{ + if (strchr(mode, 'b') == NULL) { + char *bin_mode = NULL; + if (asprintf(&bin_mode, "%sb", mode) == -1) + return NULL; + FILE *f = fopen(path, bin_mode); + free(bin_mode); + return f; + } + + return fopen(path, mode); +} + +int +posix_rename(const char *oldpath, const char *newpath) +{ + MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING) ? 0 : -1; +} + +static int +wsa_errno(int err) +{ + switch (err) { + case WSAENOBUFS: + errno = ENOMEM; + break; + case WSAEACCES: + errno = EACCES; + break; + case WSANOTINITIALISED: + errno = EPERM; + break; + case WSAEHOSTUNREACH: + case WSAENETDOWN: + errno = EIO; + break; + case WSAEFAULT: + errno = EFAULT; + break; + case WSAEINTR: + errno = EINTR; + break; + case WSAEINVAL: + errno = EINVAL; + break; + case WSAEINPROGRESS: + errno = EINPROGRESS; + break; + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + case WSAEOPNOTSUPP: + errno = ENOTSUP; + break; + case WSAEMSGSIZE: + errno = EFBIG; + break; + case WSAENOTSOCK: + errno = ENOTSOCK; + break; + case WSAENOPROTOOPT: + errno = ENOPROTOOPT; + break; + case WSAECONNREFUSED: + errno = ECONNREFUSED; + break; + case WSAEAFNOSUPPORT: + errno = EAFNOSUPPORT; + break; + case WSAENETRESET: + case WSAENOTCONN: + case WSAECONNABORTED: + case WSAECONNRESET: + case WSAESHUTDOWN: + case WSAETIMEDOUT: + errno = EPIPE; + break; + } + return -1; +} + +int +posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + int rc = connect(sockfd, addr, addrlen); + if (rc == SOCKET_ERROR) + return wsa_errno(WSAGetLastError()); + return rc; +} + +int +posix_close(int fd) +{ + if (closesocket(fd) == SOCKET_ERROR) { + int err = WSAGetLastError(); + return err == WSAENOTSOCK ? + close(fd) : wsa_errno(err); + } + return 0; +} + +ssize_t +posix_read(int fd, void *buf, size_t count) +{ + ssize_t rc = recv(fd, buf, count, 0); + if (rc == SOCKET_ERROR) { + int err = WSAGetLastError(); + return err == WSAENOTSOCK ? + read(fd, buf, count) : wsa_errno(err); + } + return rc; +} + +ssize_t +posix_write(int fd, const void *buf, size_t count) +{ + ssize_t rc = send(fd, buf, count, 0); + if (rc == SOCKET_ERROR) { + int err = WSAGetLastError(); + return err == WSAENOTSOCK ? + write(fd, buf, count) : wsa_errno(err); + } + return rc; +} + +int +posix_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen) +{ + int rc = getsockopt(sockfd, level, optname, (char *)optval, optlen); + return rc == 0 ? 0 : wsa_errno(WSAGetLastError()); + +} + +int +posix_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen) +{ + int rc = setsockopt(sockfd, level, optname, (char *)optval, optlen); + return rc == 0 ? 0 : wsa_errno(WSAGetLastError()); +} diff --git a/include/stdio.h b/include/stdio.h index db369c9..76bd9da 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -15,35 +15,16 @@ int asprintf(char **str, const char *fmt, ...); #endif #ifdef _WIN32 -#include -#include -static inline void -posix_perror(const char *s) -{ - fprintf(stderr, "%s: %s\n", s, strerror(errno)); -} +void posix_perror(const char *s); +FILE * posix_fopen(const char *path, const char *mode); +int posix_rename(const char *oldpath, const char *newpath); +#ifndef NO_REDEF_POSIX_FUNCTIONS #define perror(errnum) posix_perror(errnum) - -static inline FILE * -posix_fopen(const char *path, const char *mode) -{ - char *bin_mode = mode; - if (strchr(mode, 'b') == NULL) { - bin_mode = NULL; - if (asprintf(&bin_mode, "%sb", mode) == -1) - return NULL; - fprintf(stderr, "opening bin file %s\n", bin_mode); - } - - FILE *f = fopen(path, bin_mode); - if (bin_mode != mode) - free(bin_mode); - return f; -} - #define fopen(path, mode) posix_fopen(path, mode) +#define rename(oldpath, newpath) posix_rename(oldpath, newpath) +#endif #endif diff --git a/include/win32netcompat.h b/include/win32netcompat.h index 51384d0..452cfba 100644 --- a/include/win32netcompat.h +++ b/include/win32netcompat.h @@ -19,142 +19,29 @@ #include #include -static int -wsa_errno(int err) -{ - switch (err) { - case WSAENOBUFS: - errno = ENOMEM; - break; - case WSAEACCES: - errno = EACCES; - break; - case WSANOTINITIALISED: - errno = EPERM; - break; - case WSAEHOSTUNREACH: - case WSAENETDOWN: - errno = EIO; - break; - case WSAEFAULT: - errno = EFAULT; - break; - case WSAEINTR: - errno = EINTR; - break; - case WSAEINVAL: - errno = EINVAL; - break; - case WSAEINPROGRESS: - errno = EINPROGRESS; - break; - case WSAEWOULDBLOCK: - errno = EAGAIN; - break; - case WSAEOPNOTSUPP: - errno = ENOTSUP; - break; - case WSAEMSGSIZE: - errno = EFBIG; - break; - case WSAENOTSOCK: - errno = ENOTSOCK; - break; - case WSAENOPROTOOPT: - errno = ENOPROTOOPT; - break; - case WSAECONNREFUSED: - errno = ECONNREFUSED; - break; - case WSAEAFNOSUPPORT: - errno = EAFNOSUPPORT; - break; - case WSAENETRESET: - case WSAENOTCONN: - case WSAECONNABORTED: - case WSAECONNRESET: - case WSAESHUTDOWN: - case WSAETIMEDOUT: - errno = EPIPE; - break; - } - return -1; -} +int posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -static inline int -posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) -{ - int rc = connect(sockfd, addr, addrlen); - if (rc == SOCKET_ERROR) - return wsa_errno(WSAGetLastError()); - return rc; -} +int posix_close(int fd); +ssize_t posix_read(int fd, void *buf, size_t count); +ssize_t posix_write(int fd, const void *buf, size_t count); + +int posix_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen); + +int posix_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen); + +#ifndef NO_REDEF_POSIX_FUNCTIONS #define connect(sockfd, addr, addrlen) posix_connect(sockfd, addr, addrlen) - -static inline int -posix_close(int fd) -{ - if (closesocket(fd) == SOCKET_ERROR) { - int err = WSAGetLastError(); - return err == WSAENOTSOCK ? - close(fd) : wsa_errno(err); - } - return 0; -} - #define close(fd) posix_close(fd) - -static inline ssize_t -posix_read(int fd, void *buf, size_t count) -{ - ssize_t rc = recv(fd, buf, count, 0); - if (rc == SOCKET_ERROR) { - int err = WSAGetLastError(); - return err == WSAENOTSOCK ? - read(fd, buf, count) : wsa_errno(err); - } - return rc; -} - #define read(fd, buf, count) posix_read(fd, buf, count) - -static inline ssize_t -posix_write(int fd, const void *buf, size_t count) -{ - ssize_t rc = send(fd, buf, count, 0); - if (rc == SOCKET_ERROR) { - int err = WSAGetLastError(); - return err == WSAENOTSOCK ? - write(fd, buf, count) : wsa_errno(err); - } - return rc; -} - #define write(fd, buf, count) posix_write(fd, buf, count) - -static inline int -posix_getsockopt(int sockfd, int level, int optname, - void *optval, socklen_t *optlen) -{ - int rc = getsockopt(sockfd, level, optname, (char *)optval, optlen); - return rc == 0 ? 0 : wsa_errno(WSAGetLastError()); - -} - #define getsockopt(sockfd, level, optname, optval, optlen) \ posix_getsockopt(sockfd, level, optname, optval, optlen) - -static inline int -posix_setsockopt(int sockfd, int level, int optname, - const void *optval, socklen_t optlen) -{ - int rc = setsockopt(sockfd, level, optname, (char *)optval, optlen); - return rc == 0 ? 0 : wsa_errno(WSAGetLastError()); -} - #define setsockopt(sockfd, level, optname, optval, optlen) \ posix_setsockopt(sockfd, level, optname, optval, optlen) +#endif #endif