ringbuf.$O: misc.h sysdep_w32.h ringbuf.h
secure.$O: ringbuf.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
version.$O: version.h
$(obj): config.h
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
-#else
-#define close(fd) w32_close_socket((fd))
#endif
#include "misc.h"
* Dave Pare, 1986
* Steve McClure, 1998
* Ron Koenderink, 2004-2005
- * Markus Armbruster, 2005-2008
+ * Markus Armbruster, 2005-2009
*/
#include <config.h>
#ifdef _WIN32
#define getuid() 0
#define getpwuid(uid) ((void)(uid), w32_getpw())
+#define sysdep_init() w32_sysdep_init()
#else
#define sysdep_init() ((void)0)
#endif
* play.c: Playing the game
*
* Known contributors to this file:
- * Markus Armbruster, 2007
+ * Markus Armbruster, 2007-2009
* Ron Koenderink, 2007-2009
*/
static HANDLE ctrl_c_event;
static int bounce_status, bounce_error;
+struct sigaction {
+ int sa_flags;
+ void (*sa_handler)(int sig);
+};
+
#define SIGPIPE -1
static void (*ctrl_handler)(int sig) = { SIG_DFL };
/*
* This function uses to WaitForMultipleObjects to wait for both
* 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.
- * Execute command file reading is done via handle. Execute
- * command is read via CreateFile/ReadFile instead open/read
- * because a file descriptor is not waitable.
- * WaitForMultipleObjects will only respond with one object
+ * Execute command file reading is done via handle.
+ * WaitForMultipleObjects will only respond with one object,
* so an additonal select is also done to determine
- * which individual events are active for the sock.
+ * which individual events are active.
*/
static int
w32_select(int nfds, fd_set *rdfd, fd_set *wrfd, fd_set *errfd, struct timeval* time)
{
HANDLE handles[3];
SOCKET sock;
- int inp, result, s_result, num_handles;
+ int inp, sockfd, result, s_result, num_handles;
struct timeval tv_time = {0, 0};
- fd_set rdfd2;
+ fd_set rdsock, wrsock;
switch (rdfd->fd_count) {
case 1:
inp = -1;
- sock = rdfd->fd_array[0];
+ sockfd = rdfd->fd_array[0];
break;
case 2:
inp = rdfd->fd_array[0];
- sock = rdfd->fd_array[1];
+ sockfd = rdfd->fd_array[1];
break;
default:
assert(0);
}
+ sock = W32_FD_TO_SOCKET(sockfd);
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);
num_handles = 0;
handles[num_handles++] = ctrl_c_event;
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 */
handles[num_handles++] = WSACreateEvent();
return -1;
}
- FD_ZERO(&rdfd2);
- FD_SET(sock, &rdfd2);
- s_result = select(sock + 1, &rdfd2, wrfd, NULL, &tv_time);
+ FD_ZERO(&rdsock);
+ FD_ZERO(&wrsock);
+ 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) {
- errno = WSAGetLastError();
+ w32_set_winsock_errno();
return s_result;
}
- *rdfd = rdfd2;
- if (inp >= 0 && result == WAIT_OBJECT_0 + 1) {
- FD_SET((SOCKET)inp, rdfd);
+ if (!FD_ISSET(sock, &rdsock))
+ FD_CLR((SOCKET)sockfd, rdfd);
+ if (!FD_ISSET(sock, &wrsock))
+ FD_CLR((SOCKET)sockfd, wrfd);
+ if (inp >= 0 && result == WAIT_OBJECT_0 + 1)
s_result++;
- }
+ else
+ FD_CLR((SOCKET)inp, rdfd);
+
return s_result;
}
return res;
}
#define ring_from_file w32_ring_from_file_or_bounce_buf
-#define close(fd) w32_close_handle((fd))
#define read(sock, buffer, buf_size) \
w32_recv((sock), (buffer), (buf_size), 0)
#define select(nfds, rd, wr, error, time) \
* ringbuf.c: Simple ring buffer
*
* Known contributors to this file:
- * Markus Armbruster, 2007
+ * Markus Armbruster, 2007-2009
*/
#include <config.h>
#include <unistd.h>
#else
#define readv(fd, iov, iovcnt) \
- w32_readv_handle((fd), (iov), (iovcnt))
+ w32_readv_fd((fd), (iov), (iovcnt))
#define writev(fd, iov, iovcnt) \
w32_writev_socket((fd), (iov), (iovcnt))
#endif
* Dave Pare, 1989
* Steve McClure, 1998
* Ron Koenderink, 2005
- * Markus Armbruster, 2005-2007
+ * Markus Armbruster, 2005-2009
*/
#include <config.h>
#include "proto.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;
FILE *auxfp;
*
* Known contributors to this file:
* Ron Koenderink, 2007
+ * Markus Armbruster, 2009
*/
#ifdef _WIN32
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
-#include <io.h>
-#include <sys/stat.h>
#include "misc.h"
-#include "linebuf.h"
-#include "ringbuf.h"
-#include "secure.h"
+
+static int
+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
{
static char unamebuf[128];
static struct passwd pwd;
- long unamesize;
+ DWORD unamesize;
unamesize = sizeof(unamebuf);
if (GetUserName(unamebuf, &unamesize)) {
pwd.pw_name = unamebuf;
- if ((unamesize <= 0 ) || (strlen(unamebuf) <= 0))
+ if (unamesize == 0 || strlen(unamebuf) == 0)
pwd.pw_name = "nobody";
} else
pwd.pw_name = "nobody";
* set up stdout to work around bugs
*/
void
-sysdep_init(void)
+w32_sysdep_init(void)
{
int err;
WSADATA WsaData;
*/
#undef socket
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) {
- errno = WSAGetLastError();
+ /*
+ * We have to use WSASocket() to create non-overlapped IO sockets.
+ * 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 (int)result;
+ return W32_SOCKET_TO_FD(sock);
}
/*
*/
#undef connect
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;
- result = connect(sock, addr, addrlen);
+ result = connect(sock, addr, addrlen);
if (result == SOCKET_ERROR) {
- errno = WSAGetLastError();
+ /* FIXME map WSAEWOULDBLOCK to EINPROGRESS */
+ w32_set_winsock_errno();
return -1;
}
return result;
*/
#undef recv
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;
result = recv(socket, buffer, buf_size, flags);
if (result == SOCKET_ERROR) {
- errno = WSAGetLastError();
+ w32_set_winsock_errno();
return -1;
}
return result;
* Modelled after the GNU's libc/sysdeps/posix/writev.c
*/
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;
- unsigned char *buffer, *buffer_location;
+ char *buffer, *buffer_location;
size_t total_bytes = 0;
int bytes_written;
buffer_location += iov[i].iov_len;
}
- bytes_written = send(fd, buffer, total_bytes, 0);
-
+ bytes_written = send(sock, buffer, total_bytes, 0);
free(buffer);
-
if (bytes_written == SOCKET_ERROR) {
- errno = WSAGetLastError();
+ w32_set_winsock_errno();
return -1;
}
return bytes_written;
* POSIX compatible send() replacement
*/
int
-w32_send(int socket, char *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)
+w32_send(int sockfd, const void *buffer, size_t buf_size, int flags)
{
+ SOCKET socket = W32_FD_TO_SOCKET(sockfd);
int result;
- result = closesocket(fd);
+ result = send(socket, buffer, buf_size, flags);
if (result == SOCKET_ERROR)
- errno = WSAGetLastError();
+ w32_set_winsock_errno();
return result;
}
/*
- * POSIX compatible open() replacement
+ * POSIX compatible close() replacement
*/
int
-w32_openfd(const char *fname, int oflag, ...)
+w32_close(int fd)
{
- va_list ap;
- int pmode = 0;
- int fd;
- int create_permission = 0;
-
- if (oflag & O_CREAT) {
- va_start(ap, oflag);
- pmode = va_arg(ap, int);
- va_end(ap);
-
- if (pmode & 0400)
- create_permission |= _S_IREAD;
- if (pmode & 0200)
- create_permission |= _S_IWRITE;
- }
+ SOCKET sock;
- 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();
+ if (fd_is_socket(fd, &sock)) {
+ if (closesocket(sock)) {
+ w32_set_winsock_errno();
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);
}
/*
* Modelled after the GNU's libc/sysdeps/posix/readv.c
*/
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;
- unsigned char *buffer, *buffer_location;
+ char *buffer, *buffer_location;
size_t total_bytes = 0;
- DWORD bytes_read;
+ int bytes_read;
size_t bytes_left;
for (i = 0; i < iovcnt; i++) {
return -1;
}
- if (!ReadFile((HANDLE)fd, buffer, total_bytes, &bytes_read, NULL)) {
- free(buffer);
- errno = GetLastError();
+ bytes_read = read(fd, buffer, total_bytes);
+ if (bytes_read < 0)
return -1;
- }
bytes_left = bytes_read;
buffer_location = buffer;
}
free(buffer);
-
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 */
*
* Known contributors to this file:
* Ron Koenderink, 2007
+ * Markus Armbruster, 2009
*/
#ifndef _SYSDEF_W32_H
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
-#include <signal.h>
extern int getopt(int, char * const[], const char *);
extern char *optarg;
size_t iov_len;
};
-struct sigaction {
- int sa_flags;
- void (*sa_handler)(int sig);
-};
+#define W32_FD_TO_SOCKET(fd) ((SOCKET)_get_osfhandle((fd)))
+#define W32_SOCKET_TO_FD(fh) (_open_osfhandle((long)(fh), O_RDWR | O_BINARY))
+
+extern void w32_set_winsock_errno(void);
-extern int w32_recv(int socket, char *buffer,
- size_t buf_size, int flags);
-extern int w32_send(int socket, char *buffer,
- size_t buf_size, int flags);
-extern int w32_close_socket(int fd);
-extern int w32_socket(int family, int sock_type, int protocol);
-extern int w32_connect(int sock, struct sockaddr *addr, int addrlen);
-extern int w32_close_handle(int fd);
-extern ssize_t w32_readv_handle(int fd, const struct iovec *iov,
- int iovcnt);
-extern ssize_t w32_writev_socket(int fd, const struct iovec *iov,
+extern int w32_recv(int sockfd, void *, size_t, int flags);
+extern int w32_send(int sockfd, const void *, size_t, int flags);
+extern int w32_close(int fd);
+extern int w32_socket(int domain, int type, int protocol);
+extern int w32_connect(int sockfd, const struct sockaddr *, int addrlen);
+extern ssize_t w32_readv_fd(int fd, const struct iovec *iov,
+ int iovcnt);
+extern ssize_t w32_writev_socket(int sockfd, const struct iovec *iov,
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 void sysdep_init(void);
+extern void w32_sysdep_init(void);
-#define recv(sock, buffer, buf_size, flags) \
- w32_recv((sock), (buffer), (buf_size), (flags))
-#define socket(family, sock_type, protocol) \
- w32_socket((family), (sock_type), (protocol))
-#define connect(sock, addr, addrlen) \
- w32_connect((sock), (addr), (addrlen))
+#define recv(sockfd, buffer, buf_size, flags) \
+ w32_recv((sockfd), (buffer), (buf_size), (flags))
+#define close(fd) \
+ w32_close((fd))
+#define socket(domain, type, protocol) \
+ w32_socket((domain), (type), (protocol))
+#define connect(sockfd, addr, addrlen) \
+ w32_connect((sockfd), (addr), (addrlen))
#define pclose _pclose
#define popen _popen