2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2007, 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 * WIN32 equivalent for getpass
211 getpass(char *prompt)
213 static char tmp[128];
217 HANDLE input_handle = GetStdHandle(STD_INPUT_HANDLE);
219 if (GetConsoleMode(input_handle, &mode))
220 SetConsoleMode(input_handle, mode & ~ENABLE_ECHO_INPUT);
222 printf("Note: This is echoed to the screen\n");
223 printf("%s", prompt);
225 cpass = fgets(tmp, sizeof(tmp), stdin);
226 if (GetConsoleMode(input_handle, &mode))
227 SetConsoleMode(input_handle, mode | ENABLE_ECHO_INPUT);
231 if (tmp[len - 1] == '\n')
237 * POSIX compatible open() replacement
240 w32_openfd(const char *fname, int oflag, ...)
245 int create_permission = 0;
247 if (oflag & O_CREAT) {
249 pmode = va_arg(ap, int);
253 create_permission |= _S_IREAD;
255 create_permission |= _S_IWRITE;
258 fd = _open(fname, oflag, create_permission);
262 * Open a file for reading, return its handle.
263 * This can be used in place of open() when a handle is desired for
264 * waiting on it with WaitForMultipleObjects() or similar.
265 * Ensure the handle is not zero in order to prevent a problem
269 w32_openhandle(const char *fname, int oflag)
273 handle = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
274 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
276 if (handle == INVALID_HANDLE_VALUE) {
277 errno = GetLastError();
282 if (!DuplicateHandle(GetCurrentProcess(), handle,
283 GetCurrentProcess(), &dup_handle,
284 0, FALSE, DUPLICATE_SAME_ACCESS)) {
285 errno = GetLastError();
296 * POSIX compatible readv() replacement specialized to files.
297 * Modelled after the GNU's libc/sysdeps/posix/readv.c
300 w32_readv_handle(int fd, const struct iovec *iov, int iovcnt)
303 unsigned char *buffer, *buffer_location;
304 size_t total_bytes = 0;
308 for (i = 0; i < iovcnt; i++) {
309 total_bytes += iov[i].iov_len;
312 buffer = malloc(total_bytes);
313 if (buffer == NULL && total_bytes != 0) {
318 if (!ReadFile((HANDLE)fd, buffer, total_bytes, &bytes_read, NULL)) {
320 errno = GetLastError();
324 bytes_left = bytes_read;
325 buffer_location = buffer;
326 for (i = 0; i < iovcnt; i++) {
327 size_t copy = MIN(iov[i].iov_len, bytes_left);
329 memcpy(iov[i].iov_base, buffer_location, copy);
331 buffer_location += copy;
343 * POSIX compatible close() replacement specialized to files.
344 * Hack: expects a handle, cannot be used with a file descriptor.
347 w32_close_handle(int fd)
351 result = CloseHandle((HANDLE)fd);
354 errno = GetLastError();