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 * Ignore alarm for WIN32 client
55 * Get user name in the WIN32 environment
60 static char unamebuf[128];
61 static struct passwd pwd;
64 unamesize = sizeof(unamebuf);
65 if (GetUserName(unamebuf, &unamesize)) {
66 pwd.pw_name = unamebuf;
67 if ((unamesize <= 0 ) || (strlen(unamebuf) <= 0))
68 pwd.pw_name = "nobody";
70 pwd.pw_name = "nobody";
75 * Initialize the WIN32 socket library and
76 * set up stdout to work around bugs
84 * stdout is unbuffered under Windows if connected to a character
85 * device, and putchar() screws up when printing multibyte strings
86 * bytewise to an unbuffered stream. Switch stdout to line-
87 * buffered mode. Unfortunately, ISO C allows implementations to
88 * screw that up, and of course Windows does. Manual flushing
89 * after each prompt is required.
91 setvbuf(stdout, NULL, _IOLBF, 4096);
92 err = WSAStartup(MAKEWORD(2, 0), &WsaData);
94 printf("WSAStartup Failed, error code %d\n", err);
100 * POSIX compatible socket() replacement
104 w32_socket(int family, int sock_type, int protocol)
108 result = socket(family, sock_type, protocol);
109 if (result == INVALID_SOCKET) {
110 errno = WSAGetLastError();
117 * POSIX compatible connect() replacement
121 w32_connect(int sock, struct sockaddr *addr, int addrlen)
125 result = connect(sock, addr, addrlen);
126 if (result == SOCKET_ERROR) {
127 errno = WSAGetLastError();
134 * POSIX compatible recv() replacement
138 w32_recv(int socket, char *buffer, size_t buf_size, int flags)
142 result = recv(socket, buffer, buf_size, flags);
143 if (result == SOCKET_ERROR) {
144 errno = WSAGetLastError();
151 * POSIX compatible writev() replacement specialized to sockets
152 * Modelled after the GNU's libc/sysdeps/posix/writev.c
155 w32_writev_socket(int fd, const struct iovec *iov, int iovcnt)
158 unsigned char *buffer, *buffer_location;
159 size_t total_bytes = 0;
162 for (i = 0; i < iovcnt; i++)
163 total_bytes += iov[i].iov_len;
165 buffer = malloc(total_bytes);
166 if (buffer == NULL && total_bytes != 0) {
171 buffer_location = buffer;
172 for (i = 0; i < iovcnt; i++) {
173 memcpy(buffer_location, iov[i].iov_base, iov[i].iov_len);
174 buffer_location += iov[i].iov_len;
177 bytes_written = send(fd, buffer, total_bytes, 0);
181 if (bytes_written == SOCKET_ERROR) {
182 errno = WSAGetLastError();
185 return bytes_written;
189 * POSIX compatible send() replacement
192 w32_send(int socket, char *buffer, size_t buf_size, int flags)
196 result = send(socket, buffer, buf_size, flags);
197 if (result == SOCKET_ERROR)
198 errno = WSAGetLastError();
203 * POSIX compatible close() replacement specialized to sockets.
206 w32_close_socket(int fd)
210 result = closesocket(fd);
211 if (result == SOCKET_ERROR)
212 errno = WSAGetLastError();
217 * WIN32 equivalent for getpass
220 getpass(char *prompt)
222 static char tmp[128];
226 HANDLE input_handle = GetStdHandle(STD_INPUT_HANDLE);
228 if (GetConsoleMode(input_handle, &mode))
229 SetConsoleMode(input_handle, mode & ~ENABLE_ECHO_INPUT);
231 printf("Note: This is echoed to the screen\n");
232 printf("%s", prompt);
234 cpass = fgets(tmp, sizeof(tmp), stdin);
235 if (GetConsoleMode(input_handle, &mode))
236 SetConsoleMode(input_handle, mode | ENABLE_ECHO_INPUT);
240 if (tmp[len - 1] == '\n')
246 * POSIX compatible open() replacement
249 w32_openfd(const char *fname, int oflag, ...)
254 int create_permission = 0;
256 if (oflag & O_CREAT) {
258 pmode = va_arg(ap, int);
262 create_permission |= _S_IREAD;
264 create_permission |= _S_IWRITE;
267 fd = _open(fname, oflag, create_permission);
271 * Open a file for reading, return its handle.
272 * This can be used in place of open() when a handle is desired for
273 * waiting on it with WaitForMultipleObjects() or similar.
274 * Ensure the handle is not zero in order to prevent a problem
278 w32_openhandle(const char *fname, int oflag)
282 handle = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL,
283 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
285 if (handle == INVALID_HANDLE_VALUE) {
286 errno = GetLastError();
291 if (!DuplicateHandle(GetCurrentProcess(), handle,
292 GetCurrentProcess(), &dup_handle,
293 0, FALSE, DUPLICATE_SAME_ACCESS)) {
294 errno = GetLastError();
305 * POSIX compatible readv() replacement specialized to files.
306 * Modelled after the GNU's libc/sysdeps/posix/readv.c
309 w32_readv_handle(int fd, const struct iovec *iov, int iovcnt)
312 unsigned char *buffer, *buffer_location;
313 size_t total_bytes = 0;
317 for (i = 0; i < iovcnt; i++) {
318 total_bytes += iov[i].iov_len;
321 buffer = malloc(total_bytes);
322 if (buffer == NULL && total_bytes != 0) {
327 if (!ReadFile((HANDLE)fd, buffer, total_bytes, &bytes_read, NULL)) {
329 errno = GetLastError();
333 bytes_left = bytes_read;
334 buffer_location = buffer;
335 for (i = 0; i < iovcnt; i++) {
336 size_t copy = MIN(iov[i].iov_len, bytes_left);
338 memcpy(iov[i].iov_base, buffer_location, copy);
340 buffer_location += copy;
352 * POSIX compatible close() replacement specialized to files.
353 * Hack: expects a handle, cannot be used with a file descriptor.
356 w32_close_handle(int fd)
360 result = CloseHandle((HANDLE)fd);
363 errno = GetLastError();