2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * sysdep_w32.c: system dependent functions for WIN32 environments
30 * Known contributors to this file:
31 * Ron Koenderink, 2007
46 * Get user name in the WIN32 environment
51 static char unamebuf[128];
52 static struct passwd pwd;
55 unamesize = sizeof(unamebuf);
56 if (GetUserName(unamebuf, &unamesize)) {
57 pwd.pw_name = unamebuf;
58 if ((unamesize <= 0 ) || (strlen(unamebuf) <= 0))
59 pwd.pw_name = "nobody";
61 pwd.pw_name = "nobody";
66 * Initialize the WIN32 socket library and
67 * set up stdout to work around bugs
75 * stdout is unbuffered under Windows if connected to a character
76 * device, and putchar() screws up when printing multibyte strings
77 * bytewise to an unbuffered stream. Switch stdout to line-
78 * buffered mode. Unfortunately, ISO C allows implementations to
79 * screw that up, and of course Windows does. Manual flushing
80 * after each prompt is required.
82 setvbuf(stdout, NULL, _IOLBF, 4096);
83 err = WSAStartup(MAKEWORD(2, 0), &WsaData);
85 printf("WSAStartup Failed, error code %d\n", err);
91 * POSIX compatible socket() replacement
95 w32_socket(int family, int sock_type, int protocol)
99 result = socket(family, sock_type, protocol);
100 if (result == INVALID_SOCKET) {
101 errno = WSAGetLastError();
108 * POSIX compatible connect() replacement
112 w32_connect(int sock, struct sockaddr *addr, int addrlen)
116 result = connect(sock, addr, addrlen);
117 if (result == SOCKET_ERROR) {
118 errno = WSAGetLastError();
125 * POSIX compatible recv() replacement
129 w32_recv(int socket, char *buffer, size_t buf_size, int flags)
133 result = recv(socket, buffer, buf_size, flags);
134 if (result == SOCKET_ERROR) {
135 errno = WSAGetLastError();
142 * POSIX compatible writev() replacement specialized to sockets
143 * Modelled after the GNU's libc/sysdeps/posix/writev.c
146 w32_writev_socket(int fd, const struct iovec *iov, int iovcnt)
149 unsigned char *buffer, *buffer_location;
150 size_t total_bytes = 0;
153 for (i = 0; i < iovcnt; i++)
154 total_bytes += iov[i].iov_len;
156 buffer = malloc(total_bytes);
157 if (buffer == NULL && total_bytes != 0) {
162 buffer_location = buffer;
163 for (i = 0; i < iovcnt; i++) {
164 memcpy(buffer_location, iov[i].iov_base, iov[i].iov_len);
165 buffer_location += iov[i].iov_len;
168 bytes_written = send(fd, buffer, total_bytes, 0);
172 if (bytes_written == SOCKET_ERROR) {
173 errno = WSAGetLastError();
176 return bytes_written;
180 * POSIX compatible send() replacement
183 w32_send(int socket, char *buffer, size_t buf_size, int flags)
187 result = send(socket, buffer, buf_size, flags);
188 if (result == SOCKET_ERROR)
189 errno = WSAGetLastError();
194 * POSIX compatible close() replacement specialized to sockets.
197 w32_close_socket(int fd)
201 result = closesocket(fd);
202 if (result == SOCKET_ERROR)
203 errno = WSAGetLastError();
208 * POSIX compatible open() replacement
211 w32_openfd(const char *fname, int oflag, ...)
216 int create_permission = 0;
218 if (oflag & O_CREAT) {
220 pmode = va_arg(ap, int);
224 create_permission |= _S_IREAD;
226 create_permission |= _S_IWRITE;
229 fd = _open(fname, oflag, create_permission);
233 * Open a file for reading, return its handle.
234 * This can be used in place of open() when a handle is desired for
235 * waiting on it with WaitForMultipleObjects() or similar.
236 * Ensure the handle is not zero in order to prevent a problem
240 w32_openhandle(const char *fname, int oflag)
244 handle = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
245 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
247 if (handle == INVALID_HANDLE_VALUE) {
248 errno = GetLastError();
253 if (!DuplicateHandle(GetCurrentProcess(), handle,
254 GetCurrentProcess(), &dup_handle,
255 0, FALSE, DUPLICATE_SAME_ACCESS)) {
256 errno = GetLastError();
267 * POSIX compatible readv() replacement specialized to files.
268 * Modelled after the GNU's libc/sysdeps/posix/readv.c
271 w32_readv_handle(int fd, const struct iovec *iov, int iovcnt)
274 unsigned char *buffer, *buffer_location;
275 size_t total_bytes = 0;
279 for (i = 0; i < iovcnt; i++) {
280 total_bytes += iov[i].iov_len;
283 buffer = malloc(total_bytes);
284 if (buffer == NULL && total_bytes != 0) {
289 if (!ReadFile((HANDLE)fd, buffer, total_bytes, &bytes_read, NULL)) {
291 errno = GetLastError();
295 bytes_left = bytes_read;
296 buffer_location = buffer;
297 for (i = 0; i < iovcnt; i++) {
298 size_t copy = MIN(iov[i].iov_len, bytes_left);
300 memcpy(iov[i].iov_base, buffer_location, copy);
302 buffer_location += copy;
314 * POSIX compatible close() replacement specialized to files.
315 * Hack: expects a handle, cannot be used with a file descriptor.
318 w32_close_handle(int fd)
322 result = CloseHandle((HANDLE)fd);
325 errno = GetLastError();