Revamp client's Windows POSIX compatibility code
Unlike POSIX sockets, Windows sockets are not file descriptors, but "OS handles", with a completely separate set of functions. However, Windows can create a file descriptor for a socket, and return a file descriptor's underlying handle. Use that instead of our gross hacks to keep up the illusion that sockets are file descriptors. Slightly dirty: we put file descriptors into fd_set. Works because both boil down to int. Change w32_select(), w32_socket(), w32_connect(), w32_recv(), w32_writev_socket(), w32_send() to take and return only file descriptors, and map to sockets internally. Replace w32_close_socket() by w32_close(), and drop the close() macro hackery that made tcp_connect(), host_connect() use w32_close_socket(). New fd_is_socket(). Windows provides select()-like functions only for handles. Because of that, the client used a handle for reading script files, and stored it in file descriptor input_fd. Drop this dirty hack, use a file descriptor instead. Works because we can get its underlying handle. Remove the dirty macro hackery that made play(), ring_from_file() and doexecute() unwittingly work with a handle. Remove w32_openhandle() and w32_close_handle(). Replace w32_readv_handle() by w32_readv_fd(). Update w32_select(). Remove w32_openfd(), it's not really needed. The old code stuffed WSA error codes into errno, which doesn't work. Use new w32_set_winsock_errno() to convert & stuff. Fix signed vs. unsigned warnings in Windows client. Move the struct sigaction replacement next to the sigaction() replacement. Rename sysdep_init() to w32_sysdep_init() for consistency.
This commit is contained in:
parent
f4209f7ea9
commit
798af5b45b
8 changed files with 155 additions and 176 deletions
|
@ -88,7 +88,7 @@ play.$O: linebuf.h misc.h sysdep_w32.h proto.h ringbuf.h secure.h
|
||||||
ringbuf.$O: misc.h sysdep_w32.h ringbuf.h
|
ringbuf.$O: misc.h sysdep_w32.h ringbuf.h
|
||||||
secure.$O: ringbuf.h secure.h
|
secure.$O: ringbuf.h secure.h
|
||||||
servcmd.$O: misc.h sysdep_w32.h proto.h secure.h
|
servcmd.$O: misc.h sysdep_w32.h proto.h secure.h
|
||||||
sysdep_w32.$O: misc.h sysdep_w32.h linebuf.h ringbuf.h secure.h
|
sysdep_w32.$O: misc.h sysdep_w32.h
|
||||||
termlib.$O: misc.h
|
termlib.$O: misc.h
|
||||||
version.$O: version.h
|
version.$O: version.h
|
||||||
$(obj): config.h
|
$(obj): config.h
|
||||||
|
|
|
@ -47,8 +47,6 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
|
||||||
#define close(fd) w32_close_socket((fd))
|
|
||||||
#endif
|
#endif
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
* Dave Pare, 1986
|
* Dave Pare, 1986
|
||||||
* Steve McClure, 1998
|
* Steve McClure, 1998
|
||||||
* Ron Koenderink, 2004-2005
|
* Ron Koenderink, 2004-2005
|
||||||
* Markus Armbruster, 2005-2008
|
* Markus Armbruster, 2005-2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -47,6 +47,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define getuid() 0
|
#define getuid() 0
|
||||||
#define getpwuid(uid) ((void)(uid), w32_getpw())
|
#define getpwuid(uid) ((void)(uid), w32_getpw())
|
||||||
|
#define sysdep_init() w32_sysdep_init()
|
||||||
#else
|
#else
|
||||||
#define sysdep_init() ((void)0)
|
#define sysdep_init() ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* play.c: Playing the game
|
* play.c: Playing the game
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Markus Armbruster, 2007
|
* Markus Armbruster, 2007-2009
|
||||||
* Ron Koenderink, 2007-2009
|
* Ron Koenderink, 2007-2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -71,6 +71,11 @@ static HANDLE bounce_full;
|
||||||
static HANDLE ctrl_c_event;
|
static HANDLE ctrl_c_event;
|
||||||
static int bounce_status, bounce_error;
|
static int bounce_status, bounce_error;
|
||||||
|
|
||||||
|
struct sigaction {
|
||||||
|
int sa_flags;
|
||||||
|
void (*sa_handler)(int sig);
|
||||||
|
};
|
||||||
|
|
||||||
#define SIGPIPE -1
|
#define SIGPIPE -1
|
||||||
static void (*ctrl_handler)(int sig) = { SIG_DFL };
|
static void (*ctrl_handler)(int sig) = { SIG_DFL };
|
||||||
|
|
||||||
|
@ -170,45 +175,45 @@ sysdep_stdin_init(void)
|
||||||
/*
|
/*
|
||||||
* This function uses to WaitForMultipleObjects to wait for both
|
* This function uses to WaitForMultipleObjects to wait for both
|
||||||
* stdin and socket reading or writing.
|
* stdin and socket reading or writing.
|
||||||
* Stdin is treated special in WIN32. Waiting for stdin is done
|
* Stdin is treated special in WIN32. Waiting for stdin is done
|
||||||
* via a bounce_full event which is set in the stdin thread.
|
* via a bounce_full event which is set in the stdin thread.
|
||||||
* Execute command file reading is done via handle. Execute
|
* Execute command file reading is done via handle.
|
||||||
* command is read via CreateFile/ReadFile instead open/read
|
* WaitForMultipleObjects will only respond with one object,
|
||||||
* because a file descriptor is not waitable.
|
|
||||||
* WaitForMultipleObjects will only respond with one object
|
|
||||||
* so an additonal select is also done to determine
|
* so an additonal select is also done to determine
|
||||||
* which individual events are active for the sock.
|
* which individual events are active.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval* time)
|
w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval* time)
|
||||||
{
|
{
|
||||||
HANDLE handles[3];
|
HANDLE handles[3];
|
||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
int inp, result, s_result, num_handles;
|
int inp, sockfd, result, s_result, num_handles;
|
||||||
struct timeval tv_time = {0, 0};
|
struct timeval tv_time = {0, 0};
|
||||||
fd_set rdfd2;
|
fd_set rdsock, wrsock;
|
||||||
|
|
||||||
switch (rdfd->fd_count) {
|
switch (rdfd->fd_count) {
|
||||||
case 1:
|
case 1:
|
||||||
inp = -1;
|
inp = -1;
|
||||||
sock = rdfd->fd_array[0];
|
sockfd = rdfd->fd_array[0];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
inp = rdfd->fd_array[0];
|
inp = rdfd->fd_array[0];
|
||||||
sock = rdfd->fd_array[1];
|
sockfd = rdfd->fd_array[1];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
sock = W32_FD_TO_SOCKET(sockfd);
|
||||||
|
|
||||||
assert(wrfd->fd_count == 0
|
assert(wrfd->fd_count == 0
|
||||||
|| (wrfd->fd_count == 1 && wrfd->fd_array[0] == sock));
|
|| (wrfd->fd_count == 1 && wrfd->fd_array[0] == (SOCKET)sockfd));
|
||||||
assert(inp < 0 || inp == input_fd);
|
assert(inp < 0 || inp == input_fd);
|
||||||
|
|
||||||
num_handles = 0;
|
num_handles = 0;
|
||||||
handles[num_handles++] = ctrl_c_event;
|
handles[num_handles++] = ctrl_c_event;
|
||||||
if (inp >= 0)
|
if (inp >= 0)
|
||||||
handles[num_handles++] = inp ? (HANDLE)inp : bounce_full;
|
handles[num_handles++]
|
||||||
|
= inp ? (HANDLE)_get_osfhandle(inp) : bounce_full;
|
||||||
/* always wait on the socket */
|
/* always wait on the socket */
|
||||||
handles[num_handles++] = WSACreateEvent();
|
handles[num_handles++] = WSACreateEvent();
|
||||||
|
|
||||||
|
@ -232,20 +237,27 @@ w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval*
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_ZERO(&rdfd2);
|
FD_ZERO(&rdsock);
|
||||||
FD_SET(sock, &rdfd2);
|
FD_ZERO(&wrsock);
|
||||||
s_result = select(sock + 1, &rdfd2, wrfd, NULL, &tv_time);
|
FD_SET(sock, &rdsock);
|
||||||
|
if (wrfd->fd_count)
|
||||||
|
FD_SET(sock, &wrsock);
|
||||||
|
s_result = select(sock + 1, &rdsock, &wrsock, NULL, &tv_time);
|
||||||
|
|
||||||
if (s_result < 0) {
|
if (s_result < 0) {
|
||||||
errno = WSAGetLastError();
|
w32_set_winsock_errno();
|
||||||
return s_result;
|
return s_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
*rdfd = rdfd2;
|
if (!FD_ISSET(sock, &rdsock))
|
||||||
if (inp >= 0 && result == WAIT_OBJECT_0 + 1) {
|
FD_CLR((SOCKET)sockfd, rdfd);
|
||||||
FD_SET((SOCKET)inp, rdfd);
|
if (!FD_ISSET(sock, &wrsock))
|
||||||
|
FD_CLR((SOCKET)sockfd, wrfd);
|
||||||
|
if (inp >= 0 && result == WAIT_OBJECT_0 + 1)
|
||||||
s_result++;
|
s_result++;
|
||||||
}
|
else
|
||||||
|
FD_CLR((SOCKET)inp, rdfd);
|
||||||
|
|
||||||
return s_result;
|
return s_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +294,6 @@ w32_ring_from_file_or_bounce_buf(struct ring *r, int fd)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#define ring_from_file w32_ring_from_file_or_bounce_buf
|
#define ring_from_file w32_ring_from_file_or_bounce_buf
|
||||||
#define close(fd) w32_close_handle((fd))
|
|
||||||
#define read(sock, buffer, buf_size) \
|
#define read(sock, buffer, buf_size) \
|
||||||
w32_recv((sock), (buffer), (buf_size), 0)
|
w32_recv((sock), (buffer), (buf_size), 0)
|
||||||
#define select(nfds, rd, wr, error, time) \
|
#define select(nfds, rd, wr, error, time) \
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* ringbuf.c: Simple ring buffer
|
* ringbuf.c: Simple ring buffer
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Markus Armbruster, 2007
|
* Markus Armbruster, 2007-2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#else
|
||||||
#define readv(fd, iov, iovcnt) \
|
#define readv(fd, iov, iovcnt) \
|
||||||
w32_readv_handle((fd), (iov), (iovcnt))
|
w32_readv_fd((fd), (iov), (iovcnt))
|
||||||
#define writev(fd, iov, iovcnt) \
|
#define writev(fd, iov, iovcnt) \
|
||||||
w32_writev_socket((fd), (iov), (iovcnt))
|
w32_writev_socket((fd), (iov), (iovcnt))
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
* Dave Pare, 1989
|
* Dave Pare, 1989
|
||||||
* Steve McClure, 1998
|
* Steve McClure, 1998
|
||||||
* Ron Koenderink, 2005
|
* Ron Koenderink, 2005
|
||||||
* Markus Armbruster, 2005-2007
|
* Markus Armbruster, 2005-2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -46,13 +46,6 @@
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "secure.h"
|
#include "secure.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define open(filename, flags, ...) \
|
|
||||||
((flags & O_CREAT) \
|
|
||||||
? w32_openfd((filename), (flags), ## __VA_ARGS__) \
|
|
||||||
: w32_openhandle((filename), (flags)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int eight_bit_clean;
|
int eight_bit_clean;
|
||||||
FILE *auxfp;
|
FILE *auxfp;
|
||||||
|
|
||||||
|
|
|
@ -29,18 +29,58 @@
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Ron Koenderink, 2007
|
* Ron Koenderink, 2007
|
||||||
|
* Markus Armbruster, 2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <assert.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <io.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "linebuf.h"
|
|
||||||
#include "ringbuf.h"
|
static int
|
||||||
#include "secure.h"
|
fd_is_socket(int fd, SOCKET *sockp)
|
||||||
|
{
|
||||||
|
SOCKET sock;
|
||||||
|
WSANETWORKEVENTS ev;
|
||||||
|
|
||||||
|
sock = W32_FD_TO_SOCKET(fd);
|
||||||
|
if (sockp)
|
||||||
|
*sockp = sock;
|
||||||
|
return WSAEnumNetworkEvents(sock, NULL, &ev) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
w32_set_winsock_errno(void)
|
||||||
|
{
|
||||||
|
int err = WSAGetLastError();
|
||||||
|
WSASetLastError(0);
|
||||||
|
|
||||||
|
/* Map some WSAE* errors to the runtime library's error codes. */
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case WSA_INVALID_HANDLE:
|
||||||
|
errno = EBADF;
|
||||||
|
break;
|
||||||
|
case WSA_NOT_ENOUGH_MEMORY:
|
||||||
|
errno = ENOMEM;
|
||||||
|
break;
|
||||||
|
case WSA_INVALID_PARAMETER:
|
||||||
|
errno = EINVAL;
|
||||||
|
break;
|
||||||
|
case WSAEWOULDBLOCK:
|
||||||
|
errno = EAGAIN;
|
||||||
|
break;
|
||||||
|
case WSAENAMETOOLONG:
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
break;
|
||||||
|
case WSAENOTEMPTY:
|
||||||
|
errno = ENOTEMPTY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = (err > 10000 && err < 10025) ? err - 10000 : err;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get user name in the WIN32 environment
|
* Get user name in the WIN32 environment
|
||||||
|
@ -50,12 +90,12 @@ w32_getpw(void)
|
||||||
{
|
{
|
||||||
static char unamebuf[128];
|
static char unamebuf[128];
|
||||||
static struct passwd pwd;
|
static struct passwd pwd;
|
||||||
long unamesize;
|
DWORD unamesize;
|
||||||
|
|
||||||
unamesize = sizeof(unamebuf);
|
unamesize = sizeof(unamebuf);
|
||||||
if (GetUserName(unamebuf, &unamesize)) {
|
if (GetUserName(unamebuf, &unamesize)) {
|
||||||
pwd.pw_name = unamebuf;
|
pwd.pw_name = unamebuf;
|
||||||
if ((unamesize <= 0 ) || (strlen(unamebuf) <= 0))
|
if (unamesize == 0 || strlen(unamebuf) == 0)
|
||||||
pwd.pw_name = "nobody";
|
pwd.pw_name = "nobody";
|
||||||
} else
|
} else
|
||||||
pwd.pw_name = "nobody";
|
pwd.pw_name = "nobody";
|
||||||
|
@ -67,7 +107,7 @@ w32_getpw(void)
|
||||||
* set up stdout to work around bugs
|
* set up stdout to work around bugs
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
sysdep_init(void)
|
w32_sysdep_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
WSADATA WsaData;
|
WSADATA WsaData;
|
||||||
|
@ -92,16 +132,20 @@ sysdep_init(void)
|
||||||
*/
|
*/
|
||||||
#undef socket
|
#undef socket
|
||||||
int
|
int
|
||||||
w32_socket(int family, int sock_type, int protocol)
|
w32_socket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
SOCKET result;
|
SOCKET sock;
|
||||||
|
|
||||||
result = socket(family, sock_type, protocol);
|
/*
|
||||||
if (result == INVALID_SOCKET) {
|
* We have to use WSASocket() to create non-overlapped IO sockets.
|
||||||
errno = WSAGetLastError();
|
* Overlapped IO sockets cannot be used with read/write.
|
||||||
|
*/
|
||||||
|
sock = WSASocket(domain, type, protocol, NULL, 0, 0);
|
||||||
|
if (sock == INVALID_SOCKET) {
|
||||||
|
w32_set_winsock_errno();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return (int)result;
|
return W32_SOCKET_TO_FD(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -109,13 +153,15 @@ w32_socket(int family, int sock_type, int protocol)
|
||||||
*/
|
*/
|
||||||
#undef connect
|
#undef connect
|
||||||
int
|
int
|
||||||
w32_connect(int sock, struct sockaddr *addr, int addrlen)
|
w32_connect(int sockfd, const struct sockaddr *addr, int addrlen)
|
||||||
{
|
{
|
||||||
|
SOCKET sock = W32_FD_TO_SOCKET(sockfd);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = connect(sock, addr, addrlen);
|
result = connect(sock, addr, addrlen);
|
||||||
if (result == SOCKET_ERROR) {
|
if (result == SOCKET_ERROR) {
|
||||||
errno = WSAGetLastError();
|
/* FIXME map WSAEWOULDBLOCK to EINPROGRESS */
|
||||||
|
w32_set_winsock_errno();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -126,13 +172,14 @@ w32_connect(int sock, struct sockaddr *addr, int addrlen)
|
||||||
*/
|
*/
|
||||||
#undef recv
|
#undef recv
|
||||||
int
|
int
|
||||||
w32_recv(int socket, char *buffer, size_t buf_size, int flags)
|
w32_recv(int sockfd, void *buffer, size_t buf_size, int flags)
|
||||||
{
|
{
|
||||||
|
SOCKET socket = W32_FD_TO_SOCKET(sockfd);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = recv(socket, buffer, buf_size, flags);
|
result = recv(socket, buffer, buf_size, flags);
|
||||||
if (result == SOCKET_ERROR) {
|
if (result == SOCKET_ERROR) {
|
||||||
errno = WSAGetLastError();
|
w32_set_winsock_errno();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -143,10 +190,11 @@ w32_recv(int socket, char *buffer, size_t buf_size, int flags)
|
||||||
* Modelled after the GNU's libc/sysdeps/posix/writev.c
|
* Modelled after the GNU's libc/sysdeps/posix/writev.c
|
||||||
*/
|
*/
|
||||||
ssize_t
|
ssize_t
|
||||||
w32_writev_socket(int fd, const struct iovec *iov, int iovcnt)
|
w32_writev_socket(int sockfd, const struct iovec *iov, int iovcnt)
|
||||||
{
|
{
|
||||||
|
SOCKET sock = W32_FD_TO_SOCKET(sockfd);
|
||||||
int i;
|
int i;
|
||||||
unsigned char *buffer, *buffer_location;
|
char *buffer, *buffer_location;
|
||||||
size_t total_bytes = 0;
|
size_t total_bytes = 0;
|
||||||
int bytes_written;
|
int bytes_written;
|
||||||
|
|
||||||
|
@ -165,12 +213,10 @@ w32_writev_socket(int fd, const struct iovec *iov, int iovcnt)
|
||||||
buffer_location += iov[i].iov_len;
|
buffer_location += iov[i].iov_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_written = send(fd, buffer, total_bytes, 0);
|
bytes_written = send(sock, buffer, total_bytes, 0);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
if (bytes_written == SOCKET_ERROR) {
|
if (bytes_written == SOCKET_ERROR) {
|
||||||
errno = WSAGetLastError();
|
w32_set_winsock_errno();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
|
@ -180,87 +226,38 @@ w32_writev_socket(int fd, const struct iovec *iov, int iovcnt)
|
||||||
* POSIX compatible send() replacement
|
* POSIX compatible send() replacement
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
w32_send(int socket, char *buffer, size_t buf_size, int flags)
|
w32_send(int sockfd, const void *buffer, size_t buf_size, int flags)
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = send(socket, buffer, buf_size, flags);
|
|
||||||
if (result == SOCKET_ERROR)
|
|
||||||
errno = WSAGetLastError();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* POSIX compatible close() replacement specialized to sockets.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
w32_close_socket(int fd)
|
|
||||||
{
|
{
|
||||||
|
SOCKET socket = W32_FD_TO_SOCKET(sockfd);
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = closesocket(fd);
|
result = send(socket, buffer, buf_size, flags);
|
||||||
if (result == SOCKET_ERROR)
|
if (result == SOCKET_ERROR)
|
||||||
errno = WSAGetLastError();
|
w32_set_winsock_errno();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* POSIX compatible open() replacement
|
* POSIX compatible close() replacement
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
w32_openfd(const char *fname, int oflag, ...)
|
w32_close(int fd)
|
||||||
{
|
{
|
||||||
va_list ap;
|
SOCKET sock;
|
||||||
int pmode = 0;
|
|
||||||
int fd;
|
|
||||||
int create_permission = 0;
|
|
||||||
|
|
||||||
if (oflag & O_CREAT) {
|
if (fd_is_socket(fd, &sock)) {
|
||||||
va_start(ap, oflag);
|
if (closesocket(sock)) {
|
||||||
pmode = va_arg(ap, int);
|
w32_set_winsock_errno();
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (pmode & 0400)
|
|
||||||
create_permission |= _S_IREAD;
|
|
||||||
if (pmode & 0200)
|
|
||||||
create_permission |= _S_IWRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = _open(fname, oflag, create_permission);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Open a file for reading, return its handle.
|
|
||||||
* This can be used in place of open() when a handle is desired for
|
|
||||||
* waiting on it with WaitForMultipleObjects() or similar.
|
|
||||||
* Ensure the handle is not zero in order to prevent a problem
|
|
||||||
* input_fd.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
w32_openhandle(const char *fname, int oflag)
|
|
||||||
{
|
|
||||||
HANDLE handle;
|
|
||||||
|
|
||||||
handle = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
|
||||||
errno = GetLastError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (handle == 0) {
|
|
||||||
HANDLE dup_handle;
|
|
||||||
if (!DuplicateHandle(GetCurrentProcess(), handle,
|
|
||||||
GetCurrentProcess(), &dup_handle,
|
|
||||||
0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
|
||||||
errno = GetLastError();
|
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
CloseHandle(handle);
|
|
||||||
handle = dup_handle;
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* This always fails because the underlying handle is already
|
||||||
|
* gone, but it closes the fd just fine.
|
||||||
|
*/
|
||||||
|
_close(fd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return (int)handle;
|
return _close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -268,12 +265,12 @@ w32_openhandle(const char *fname, int oflag)
|
||||||
* Modelled after the GNU's libc/sysdeps/posix/readv.c
|
* Modelled after the GNU's libc/sysdeps/posix/readv.c
|
||||||
*/
|
*/
|
||||||
ssize_t
|
ssize_t
|
||||||
w32_readv_handle(int fd, const struct iovec *iov, int iovcnt)
|
w32_readv_fd(int fd, const struct iovec *iov, int iovcnt)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned char *buffer, *buffer_location;
|
char *buffer, *buffer_location;
|
||||||
size_t total_bytes = 0;
|
size_t total_bytes = 0;
|
||||||
DWORD bytes_read;
|
int bytes_read;
|
||||||
size_t bytes_left;
|
size_t bytes_left;
|
||||||
|
|
||||||
for (i = 0; i < iovcnt; i++) {
|
for (i = 0; i < iovcnt; i++) {
|
||||||
|
@ -286,11 +283,9 @@ w32_readv_handle(int fd, const struct iovec *iov, int iovcnt)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ReadFile((HANDLE)fd, buffer, total_bytes, &bytes_read, NULL)) {
|
bytes_read = read(fd, buffer, total_bytes);
|
||||||
free(buffer);
|
if (bytes_read < 0)
|
||||||
errno = GetLastError();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
bytes_left = bytes_read;
|
bytes_left = bytes_read;
|
||||||
buffer_location = buffer;
|
buffer_location = buffer;
|
||||||
|
@ -306,23 +301,7 @@ w32_readv_handle(int fd, const struct iovec *iov, int iovcnt)
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* POSIX compatible close() replacement specialized to files.
|
|
||||||
* Hack: expects a handle, cannot be used with a file descriptor.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
w32_close_handle(int fd)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = CloseHandle((HANDLE)fd);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
errno = GetLastError();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
|
@ -29,13 +29,13 @@
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
* Ron Koenderink, 2007
|
* Ron Koenderink, 2007
|
||||||
|
* Markus Armbruster, 2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYSDEF_W32_H
|
#ifndef _SYSDEF_W32_H
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
extern int getopt(int, char * const[], const char *);
|
extern int getopt(int, char * const[], const char *);
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
|
@ -54,35 +54,32 @@ struct iovec {
|
||||||
size_t iov_len;
|
size_t iov_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sigaction {
|
#define W32_FD_TO_SOCKET(fd) ((SOCKET)_get_osfhandle((fd)))
|
||||||
int sa_flags;
|
#define W32_SOCKET_TO_FD(fh) (_open_osfhandle((long)(fh), O_RDWR | O_BINARY))
|
||||||
void (*sa_handler)(int sig);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int w32_recv(int socket, char *buffer,
|
extern void w32_set_winsock_errno(void);
|
||||||
size_t buf_size, int flags);
|
|
||||||
extern int w32_send(int socket, char *buffer,
|
extern int w32_recv(int sockfd, void *, size_t, int flags);
|
||||||
size_t buf_size, int flags);
|
extern int w32_send(int sockfd, const void *, size_t, int flags);
|
||||||
extern int w32_close_socket(int fd);
|
extern int w32_close(int fd);
|
||||||
extern int w32_socket(int family, int sock_type, int protocol);
|
extern int w32_socket(int domain, int type, int protocol);
|
||||||
extern int w32_connect(int sock, struct sockaddr *addr, int addrlen);
|
extern int w32_connect(int sockfd, const struct sockaddr *, int addrlen);
|
||||||
extern int w32_close_handle(int fd);
|
extern ssize_t w32_readv_fd(int fd, const struct iovec *iov,
|
||||||
extern ssize_t w32_readv_handle(int fd, const struct iovec *iov,
|
int iovcnt);
|
||||||
int iovcnt);
|
extern ssize_t w32_writev_socket(int sockfd, const struct iovec *iov,
|
||||||
extern ssize_t w32_writev_socket(int fd, const struct iovec *iov,
|
|
||||||
int iovcnt);
|
int iovcnt);
|
||||||
extern int w32_openfd(const char *fname, int oflag, ...);
|
|
||||||
extern int w32_openhandle(const char *fname, int oflag);
|
|
||||||
|
|
||||||
extern struct passwd *w32_getpw(void);
|
extern struct passwd *w32_getpw(void);
|
||||||
extern void sysdep_init(void);
|
extern void w32_sysdep_init(void);
|
||||||
|
|
||||||
#define recv(sock, buffer, buf_size, flags) \
|
#define recv(sockfd, buffer, buf_size, flags) \
|
||||||
w32_recv((sock), (buffer), (buf_size), (flags))
|
w32_recv((sockfd), (buffer), (buf_size), (flags))
|
||||||
#define socket(family, sock_type, protocol) \
|
#define close(fd) \
|
||||||
w32_socket((family), (sock_type), (protocol))
|
w32_close((fd))
|
||||||
#define connect(sock, addr, addrlen) \
|
#define socket(domain, type, protocol) \
|
||||||
w32_connect((sock), (addr), (addrlen))
|
w32_socket((domain), (type), (protocol))
|
||||||
|
#define connect(sockfd, addr, addrlen) \
|
||||||
|
w32_connect((sockfd), (addr), (addrlen))
|
||||||
|
|
||||||
#define pclose _pclose
|
#define pclose _pclose
|
||||||
#define popen _popen
|
#define popen _popen
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue