Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / backend / port / win32 / socket.c
blob344917e00a4c51ec72ae59f4c62421754d0fe030
1 /*-------------------------------------------------------------------------
3 * socket.c
4 * Microsoft Windows Win32 Socket Functions
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
8 * IDENTIFICATION
9 * $PostgreSQL$
11 *-------------------------------------------------------------------------
14 #include "postgres.h"
16 #undef socket
17 #undef accept
18 #undef connect
19 #undef select
20 #undef recv
21 #undef send
24 * Blocking socket functions implemented so they listen on both
25 * the socket and the signal event, required for signal handling.
29 * Convert the last socket error code into errno
31 static void
32 TranslateSocketError(void)
34 switch (WSAGetLastError())
36 case WSANOTINITIALISED:
37 case WSAENETDOWN:
38 case WSAEINPROGRESS:
39 case WSAEINVAL:
40 case WSAESOCKTNOSUPPORT:
41 case WSAEFAULT:
42 case WSAEINVALIDPROVIDER:
43 case WSAEINVALIDPROCTABLE:
44 case WSAEMSGSIZE:
45 errno = EINVAL;
46 break;
47 case WSAEAFNOSUPPORT:
48 errno = EAFNOSUPPORT;
49 break;
50 case WSAEMFILE:
51 errno = EMFILE;
52 break;
53 case WSAENOBUFS:
54 errno = ENOBUFS;
55 break;
56 case WSAEPROTONOSUPPORT:
57 case WSAEPROTOTYPE:
58 errno = EPROTONOSUPPORT;
59 break;
60 case WSAECONNREFUSED:
61 errno = ECONNREFUSED;
62 break;
63 case WSAEINTR:
64 errno = EINTR;
65 break;
66 case WSAENOTSOCK:
67 errno = EBADFD;
68 break;
69 case WSAEOPNOTSUPP:
70 errno = EOPNOTSUPP;
71 break;
72 case WSAEWOULDBLOCK:
73 errno = EWOULDBLOCK;
74 break;
75 case WSAEACCES:
76 errno = EACCES;
77 break;
78 case WSAENOTCONN:
79 case WSAENETRESET:
80 case WSAECONNRESET:
81 case WSAESHUTDOWN:
82 case WSAECONNABORTED:
83 case WSAEDISCON:
84 errno = ECONNREFUSED; /* ENOTCONN? */
85 break;
86 default:
87 ereport(NOTICE,
88 (errmsg_internal("Unknown win32 socket error code: %i", WSAGetLastError())));
89 errno = EINVAL;
93 static int
94 pgwin32_poll_signals(void)
96 if (UNBLOCKED_SIGNAL_QUEUE())
98 pgwin32_dispatch_queued_signals();
99 errno = EINTR;
100 return 1;
102 return 0;
105 static int
106 isDataGram(SOCKET s)
108 int type;
109 int typelen = sizeof(type);
111 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &typelen))
112 return 1;
114 return (type == SOCK_DGRAM) ? 1 : 0;
118 pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
120 static HANDLE waitevent = INVALID_HANDLE_VALUE;
121 static SOCKET current_socket = -1;
122 static int isUDP = 0;
123 HANDLE events[2];
124 int r;
126 if (waitevent == INVALID_HANDLE_VALUE)
128 waitevent = CreateEvent(NULL, TRUE, FALSE, NULL);
130 if (waitevent == INVALID_HANDLE_VALUE)
131 ereport(ERROR,
132 (errmsg_internal("Failed to create socket waiting event: %i", (int) GetLastError())));
134 else if (!ResetEvent(waitevent))
135 ereport(ERROR,
136 (errmsg_internal("Failed to reset socket waiting event: %i", (int) GetLastError())));
139 * make sure we don't multiplex this kernel event object with a different
140 * socket from a previous call
143 if (current_socket != s)
145 if (current_socket != -1)
146 WSAEventSelect(current_socket, waitevent, 0);
147 isUDP = isDataGram(s);
150 current_socket = s;
152 if (WSAEventSelect(s, waitevent, what) == SOCKET_ERROR)
154 TranslateSocketError();
155 return 0;
158 events[0] = pgwin32_signal_event;
159 events[1] = waitevent;
162 * Just a workaround of unknown locking problem with writing in UDP socket
163 * under high load: Client's pgsql backend sleeps infinitely in
164 * WaitForMultipleObjectsEx, pgstat process sleeps in pgwin32_select().
165 * So, we will wait with small timeout(0.1 sec) and if sockect is still
166 * blocked, try WSASend (see comments in pgwin32_select) and wait again.
168 if ((what & FD_WRITE) && isUDP)
170 for (;;)
172 r = WaitForMultipleObjectsEx(2, events, FALSE, 100, TRUE);
174 if (r == WAIT_TIMEOUT)
176 char c;
177 WSABUF buf;
178 DWORD sent;
180 buf.buf = &c;
181 buf.len = 0;
183 r = WSASend(s, &buf, 1, &sent, 0, NULL, NULL);
184 if (r == 0) /* Completed - means things are fine! */
185 return 1;
186 else if (WSAGetLastError() != WSAEWOULDBLOCK)
188 TranslateSocketError();
189 return 0;
192 else
193 break;
196 else
197 r = WaitForMultipleObjectsEx(2, events, FALSE, timeout, TRUE);
199 if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
201 pgwin32_dispatch_queued_signals();
202 errno = EINTR;
203 return 0;
205 if (r == WAIT_OBJECT_0 + 1)
206 return 1;
207 if (r == WAIT_TIMEOUT)
208 return 0;
209 ereport(ERROR,
210 (errmsg_internal("Bad return from WaitForMultipleObjects: %i (%i)", r, (int) GetLastError())));
211 return 0;
215 * Create a socket, setting it to overlapped and non-blocking
217 SOCKET
218 pgwin32_socket(int af, int type, int protocol)
220 SOCKET s;
221 unsigned long on = 1;
223 s = WSASocket(af, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
224 if (s == INVALID_SOCKET)
226 TranslateSocketError();
227 return INVALID_SOCKET;
230 if (ioctlsocket(s, FIONBIO, &on))
232 TranslateSocketError();
233 return INVALID_SOCKET;
235 errno = 0;
237 return s;
241 SOCKET
242 pgwin32_accept(SOCKET s, struct sockaddr * addr, int *addrlen)
244 SOCKET rs;
247 * Poll for signals, but don't return with EINTR, since we don't handle
248 * that in pqcomm.c
250 pgwin32_poll_signals();
252 rs = WSAAccept(s, addr, addrlen, NULL, 0);
253 if (rs == INVALID_SOCKET)
255 TranslateSocketError();
256 return INVALID_SOCKET;
258 return rs;
262 /* No signal delivery during connect. */
264 pgwin32_connect(SOCKET s, const struct sockaddr * addr, int addrlen)
266 int r;
268 r = WSAConnect(s, addr, addrlen, NULL, NULL, NULL, NULL);
269 if (r == 0)
270 return 0;
272 if (WSAGetLastError() != WSAEWOULDBLOCK)
274 TranslateSocketError();
275 return -1;
278 while (pgwin32_waitforsinglesocket(s, FD_CONNECT, INFINITE) == 0)
280 /* Loop endlessly as long as we are just delivering signals */
283 return 0;
287 pgwin32_recv(SOCKET s, char *buf, int len, int f)
289 WSABUF wbuf;
290 int r;
291 DWORD b;
292 DWORD flags = f;
293 int n;
295 if (pgwin32_poll_signals())
296 return -1;
298 wbuf.len = len;
299 wbuf.buf = buf;
301 r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
302 if (r != SOCKET_ERROR && b > 0)
303 /* Read succeeded right away */
304 return b;
306 if (r == SOCKET_ERROR &&
307 WSAGetLastError() != WSAEWOULDBLOCK)
309 TranslateSocketError();
310 return -1;
313 /* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
315 for (n = 0; n < 5; n++)
317 if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
318 INFINITE) == 0)
319 return -1; /* errno already set */
321 r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
322 if (r == SOCKET_ERROR)
324 if (WSAGetLastError() == WSAEWOULDBLOCK)
327 * There seem to be cases on win2k (at least) where WSARecv
328 * can return WSAEWOULDBLOCK even when
329 * pgwin32_waitforsinglesocket claims the socket is readable.
330 * In this case, just sleep for a moment and try again. We try
331 * up to 5 times - if it fails more than that it's not likely
332 * to ever come back.
334 pg_usleep(10000);
335 continue;
337 TranslateSocketError();
338 return -1;
340 return b;
342 ereport(NOTICE,
343 (errmsg_internal("Failed to read from ready socket (after retries)")));
344 errno = EWOULDBLOCK;
345 return -1;
349 pgwin32_send(SOCKET s, char *buf, int len, int flags)
351 WSABUF wbuf;
352 int r;
353 DWORD b;
355 if (pgwin32_poll_signals())
356 return -1;
358 wbuf.len = len;
359 wbuf.buf = buf;
362 * Readiness of socket to send data to UDP socket may be not true: socket
363 * can become busy again! So loop until send or error occurs.
365 for (;;)
367 r = WSASend(s, &wbuf, 1, &b, flags, NULL, NULL);
368 if (r != SOCKET_ERROR && b > 0)
369 /* Write succeeded right away */
370 return b;
372 if (r == SOCKET_ERROR &&
373 WSAGetLastError() != WSAEWOULDBLOCK)
375 TranslateSocketError();
376 return -1;
379 /* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
381 if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE, INFINITE) == 0)
382 return -1;
385 return -1;
390 * Wait for activity on one or more sockets.
391 * While waiting, allow signals to run
393 * NOTE! Currently does not implement exceptfds check,
394 * since it is not used in postgresql!
397 pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval * timeout)
399 WSAEVENT events[FD_SETSIZE * 2]; /* worst case is readfds totally
400 * different from writefds, so
401 * 2*FD_SETSIZE sockets */
402 SOCKET sockets[FD_SETSIZE * 2];
403 int numevents = 0;
404 int i;
405 int r;
406 DWORD timeoutval = WSA_INFINITE;
407 FD_SET outreadfds;
408 FD_SET outwritefds;
409 int nummatches = 0;
411 Assert(exceptfds == NULL);
413 if (pgwin32_poll_signals())
414 return -1;
416 FD_ZERO(&outreadfds);
417 FD_ZERO(&outwritefds);
420 * Write FDs are different in the way that it is only flagged by
421 * WSASelectEvent() if we have tried to write to them first. So try an
422 * empty write
424 if (writefds)
426 for (i = 0; i < writefds->fd_count; i++)
428 char c;
429 WSABUF buf;
430 DWORD sent;
432 buf.buf = &c;
433 buf.len = 0;
435 r = WSASend(writefds->fd_array[i], &buf, 1, &sent, 0, NULL, NULL);
436 if (r == 0) /* Completed - means things are fine! */
437 FD_SET (writefds->fd_array[i], &outwritefds);
439 else
440 { /* Not completed */
441 if (WSAGetLastError() != WSAEWOULDBLOCK)
444 * Not completed, and not just "would block", so an error
445 * occured
447 FD_SET (writefds->fd_array[i], &outwritefds);
450 if (outwritefds.fd_count > 0)
452 memcpy(writefds, &outwritefds, sizeof(fd_set));
453 if (readfds)
454 FD_ZERO(readfds);
455 return outwritefds.fd_count;
460 /* Now set up for an actual select */
462 if (timeout != NULL)
464 /* timeoutval is in milliseconds */
465 timeoutval = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
468 if (readfds != NULL)
470 for (i = 0; i < readfds->fd_count; i++)
472 events[numevents] = WSACreateEvent();
473 sockets[numevents] = readfds->fd_array[i];
474 numevents++;
477 if (writefds != NULL)
479 for (i = 0; i < writefds->fd_count; i++)
481 if (!readfds ||
482 !FD_ISSET(writefds->fd_array[i], readfds))
484 /* If the socket is not in the read list */
485 events[numevents] = WSACreateEvent();
486 sockets[numevents] = writefds->fd_array[i];
487 numevents++;
492 for (i = 0; i < numevents; i++)
494 int flags = 0;
496 if (readfds && FD_ISSET(sockets[i], readfds))
497 flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
499 if (writefds && FD_ISSET(sockets[i], writefds))
500 flags |= FD_WRITE | FD_CLOSE;
502 if (WSAEventSelect(sockets[i], events[i], flags) == SOCKET_ERROR)
504 TranslateSocketError();
505 for (i = 0; i < numevents; i++)
506 WSACloseEvent(events[i]);
507 return -1;
511 events[numevents] = pgwin32_signal_event;
512 r = WaitForMultipleObjectsEx(numevents + 1, events, FALSE, timeoutval, TRUE);
513 if (r != WAIT_TIMEOUT && r != WAIT_IO_COMPLETION && r != (WAIT_OBJECT_0 + numevents))
516 * We scan all events, even those not signalled, in case more than one
517 * event has been tagged but Wait.. can only return one.
519 WSANETWORKEVENTS resEvents;
521 for (i = 0; i < numevents; i++)
523 ZeroMemory(&resEvents, sizeof(resEvents));
524 if (WSAEnumNetworkEvents(sockets[i], events[i], &resEvents) == SOCKET_ERROR)
525 ereport(FATAL,
526 (errmsg_internal("failed to enumerate network events: %i", (int) GetLastError())));
527 /* Read activity? */
528 if (readfds && FD_ISSET(sockets[i], readfds))
530 if ((resEvents.lNetworkEvents & FD_READ) ||
531 (resEvents.lNetworkEvents & FD_ACCEPT) ||
532 (resEvents.lNetworkEvents & FD_CLOSE))
534 FD_SET (sockets[i], &outreadfds);
536 nummatches++;
539 /* Write activity? */
540 if (writefds && FD_ISSET(sockets[i], writefds))
542 if ((resEvents.lNetworkEvents & FD_WRITE) ||
543 (resEvents.lNetworkEvents & FD_CLOSE))
545 FD_SET (sockets[i], &outwritefds);
547 nummatches++;
553 /* Clean up all handles */
554 for (i = 0; i < numevents; i++)
556 WSAEventSelect(sockets[i], events[i], 0);
557 WSACloseEvent(events[i]);
560 if (r == WSA_WAIT_TIMEOUT)
562 if (readfds)
563 FD_ZERO(readfds);
564 if (writefds)
565 FD_ZERO(writefds);
566 return 0;
569 if (r == WAIT_OBJECT_0 + numevents)
571 pgwin32_dispatch_queued_signals();
572 errno = EINTR;
573 if (readfds)
574 FD_ZERO(readfds);
575 if (writefds)
576 FD_ZERO(writefds);
577 return -1;
580 /* Overwrite socket sets with our resulting values */
581 if (readfds)
582 memcpy(readfds, &outreadfds, sizeof(fd_set));
583 if (writefds)
584 memcpy(writefds, &outwritefds, sizeof(fd_set));
585 return nummatches;
590 * Return win32 error string, since strerror can't
591 * handle winsock codes
593 static char wserrbuf[256];
594 const char *
595 pgwin32_socket_strerror(int err)
597 static HANDLE handleDLL = INVALID_HANDLE_VALUE;
599 if (handleDLL == INVALID_HANDLE_VALUE)
601 handleDLL = LoadLibraryEx("netmsg.dll", NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
602 if (handleDLL == NULL)
603 ereport(FATAL,
604 (errmsg_internal("Failed to load netmsg.dll: %i", (int) GetLastError())));
607 ZeroMemory(&wserrbuf, sizeof(wserrbuf));
608 if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
609 handleDLL,
610 err,
611 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
612 wserrbuf,
613 sizeof(wserrbuf) - 1,
614 NULL) == 0)
616 /* Failed to get id */
617 sprintf(wserrbuf, "Unknown winsock error %i", err);
619 return wserrbuf;