2 * Copyright (C) 2003-2005 The Free Software Foundation, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
17 * - utility functions for cvs under win32
29 #include <sys/socket.h> /* This does: #include <windows.h> */
37 /* #define SYSTEM_CLEANUP woe32_cleanup */
44 if (server_active || error_use_protocol)
45 /* FIXME: how are we supposed to report errors? As of now
46 (Sep 98), error() can in turn call us (if it is out of
47 memory) and in general is built on top of lots of
52 fprintf (stderr, "cvs: cannot WSACleanup: %s\n",
53 sock_strerror (WSAGetLastError ()));
59 /*============================================================================*/
61 How Microsoft does fd_set in Windows 2000 and Visual C++ 6.0:
63 * Select uses arrays of SOCKETs. These macros manipulate such
64 * arrays. FD_SETSIZE may be defined by the user before including
65 * this file, but the default here should be >= 64.
67 * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE
68 * INCLUDED IN WINSOCK2.H EXACTLY AS SHOWN HERE.
74 typedef struct fd_set {
76 SOCKET fd_array[FD_SETSIZE];
79 Microsoft packs all handles between fd_array[0] and fd_array[fd_count-1]
96 u_int ready_count, used_count;
97 woe32_handle_set handle[ FD_SETSIZE ];
100 static int woe32_select_set_fini (woe32_select_set * w32_set, fd_set * crt_set)
104 if (w32_set->ready_count)
107 woe32_handle_set * handle;
110 handle = w32_set->handle;
111 while (index < w32_set->used_count)
113 if (handle->is_ready)
115 FD_SET (handle->crt, crt_set);
123 return w32_set->ready_count;
126 static int woe32_select_set_init (woe32_select_set * w32_set, fd_set * crt_set)
130 woe32_handle_set * handle;
132 w32_set->ready_count = w32_set->used_count = index = 0;
133 handle = w32_set->handle;
135 if (crt_set) while (index < crt_set->fd_count)
137 handle->crt = crt_set->fd_array[index];
139 handle->osf = _get_osfhandle (handle->crt);
140 if (handle->w32 == INVALID_HANDLE_VALUE)
146 handle->type = GetFileType (handle->w32);
147 switch (handle->type)
150 w32_set->ready_count += handle->is_ready = 1;
154 if ( PeekNamedPipe (handle->w32, NULL, 0, NULL, &dwBytesAvail, NULL) )
156 w32_set->ready_count += handle->is_ready = dwBytesAvail > 0;
166 case FILE_TYPE_REMOTE:
167 case FILE_TYPE_UNKNOWN:
176 w32_set->used_count = index;
178 while (index < FD_SETSIZE)
182 handle->w32 = INVALID_HANDLE_VALUE;
184 handle->type = FILE_TYPE_UNKNOWN;
186 handle->is_ready = 0;
192 return w32_set->ready_count;
195 static int woe32_select_set_wait (woe32_select_set * w32_set)
200 /* set contains only non-ready pipes */
201 if (w32_set->used_count != 1)
207 if (! ReadFile (w32_set->handle[0].w32, buffer, 0, &dwBytesRead, NULL))
213 return w32_set->handle[0].is_ready = 1;
216 /* #define fd_select woe32_fd_select */
218 int woe32_fd_select ( int nfds,
219 struct fd_set * readfds,
220 struct fd_set * writefds,
221 struct fd_set * errorfds,
222 struct timeval * timeout)
225 woe32_select_set woe32_rset;
227 /* we don't support these for now */
228 assert(writefds != NULL);
229 assert(errorfds != NULL);
230 assert(timeout != NULL);
232 /* Windows doesn't care but POSIX says it does */
233 if (nfds < 0 || nfds > FD_SETSIZE)
239 ready_fds = woe32_select_set_init (&woe32_rset, readfds);
242 ready_fds = woe32_select_set_wait (&woe32_rset);
247 woe32_select_set_fini (&woe32_rset, readfds);
252 /*============================================================================*/
257 woe32_getlogin (void)
259 static char name[256];
260 DWORD dw = sizeof (name);
261 GetUserName (name, &dw);
270 /* #define SYSTEM_INITIALIZE(pargc,pargv) woe32_init_winsock() */
272 woe32_init_winsock (void)
276 if (WSAStartup (MAKEWORD (1, 1), &data))
278 fprintf (stderr, "cvs: unable to initialize winsock\n");
286 woe32_home_dir (void)
288 static char *home_dir = NULL;
289 char *home_drive, *home_path;
294 if ((home_drive = getenv ("HOMEDRIVE")) && (home_path = getenv ("HOMEPATH")))
296 const char NUL = '\0';
297 size_t home_drive_len, home_path_len;
299 home_drive_len = strlen (home_drive);
300 home_path_len = strlen (home_path);
302 home_dir = xmalloc (home_drive_len + home_path_len + sizeof NUL);
304 memcpy (home_dir, home_drive, home_drive_len );
305 memcpy (home_dir + home_drive_len, home_path, home_path_len );
306 home_dir[ home_drive_len + home_path_len ] = NUL;
316 /* #define nanosleep woe32_nanosleep */
318 woe32_nanosleep (const struct timespec *requested_delay,
319 struct timespec *remaining_delay)
321 const useconds_t one_second = 1000000;
322 const useconds_t nano_per_micro = 1000;
323 useconds_t micro_delay;
325 micro_delay = requested_delay->tv_sec * one_second
326 + ( requested_delay->tv_nsec + nano_per_micro - 1 ) / nano_per_micro
329 return usleep (micro_delay);
339 shell = getenv ("ComSpec");
343 /* Windows always sets ComSpec, the user is messing with us */
346 if ((os = getenv ("OS")) && strcmp (os, "Windows_NT"))
347 /* Windows NT, Windows 2000, Windows XP, Windows 2003 */
350 /* Windows 95, Windows 98, Windows Me */
351 shell = "command.com";