Release 971012
[wine/multimedia.git] / misc / winsock.c
blob5aa8477a429272fe7e7abce2b6ba72016ab6a280
1 /*
2 * based on Windows Sockets 1.1 specs
3 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
4 *
5 * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
7 * TODO: 32-bit asynchronous services.
8 */
10 #include <stdio.h>
11 #include <string.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 #include <sys/ipc.h>
15 #include <sys/ioctl.h>
16 #if defined(__svr4__)
17 #include <sys/filio.h>
18 #include <sys/ioccom.h>
19 #include <sys/sockio.h>
20 #endif
21 #if defined(__EMX__)
22 #include <sys/so_ioctl.h>
23 #include <sys/param.h>
24 #endif
25 #include <sys/msg.h>
26 #include <sys/wait.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include <netdb.h>
33 #include <unistd.h>
35 #include "windows.h"
36 #include "winnt.h"
37 #include "heap.h"
38 #include "ldt.h"
39 #include "task.h"
40 #include "message.h"
41 #include "winsock.h"
42 #include "miscemu.h"
43 #include "stddebug.h"
44 #include "debug.h"
46 #define DEBUG_SOCKADDR 0
47 #define dump_sockaddr(a) \
48 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
49 ((struct sockaddr_in *)a)->sin_family, \
50 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
51 ntohs(((struct sockaddr_in *)a)->sin_port))
53 #pragma pack(4)
55 /* ----------------------------------- internal data */
57 extern int h_errno;
59 static HANDLE32 _WSHeap = 0;
60 static unsigned char* _ws_stub = NULL;
61 static LPWSINFO _wsi_list = NULL;
63 #define WS_ALLOC(size) \
64 HeapAlloc(_WSHeap, HEAP_ZERO_MEMORY, (size) )
65 #define WS_FREE(ptr) \
66 HeapFree(_WSHeap, 0, (ptr) )
68 #define WS_PTR2HANDLE(ptr) \
69 ((short)((int)(ptr) - (int)_ws_stub))
70 #define WS_HANDLE2PTR(handle) \
71 ((unsigned)((int)_ws_stub + (int)(handle)))
73 #define WSI_CHECK_RANGE(pwsi, pws) \
74 ( ((unsigned)(pws) > (unsigned)(pwsi)) && \
75 ((unsigned)(pws) < ((unsigned)(pwsi) + sizeof(WSINFO))) )
77 static INT32 _ws_sock_ops[] =
78 { WS_SO_DEBUG, WS_SO_REUSEADDR, WS_SO_KEEPALIVE, WS_SO_DONTROUTE,
79 WS_SO_BROADCAST, WS_SO_LINGER, WS_SO_OOBINLINE, WS_SO_SNDBUF,
80 WS_SO_RCVBUF, WS_SO_ERROR, WS_SO_TYPE, WS_SO_DONTLINGER, 0 };
81 static int _px_sock_ops[] =
82 { SO_DEBUG, SO_REUSEADDR, SO_KEEPALIVE, SO_DONTROUTE, SO_BROADCAST,
83 SO_LINGER, SO_OOBINLINE, SO_SNDBUF, SO_RCVBUF, SO_ERROR, SO_TYPE,
84 SO_LINGER };
86 static int _check_ws(LPWSINFO pwsi, ws_socket* pws);
87 static int _check_buffer(LPWSINFO pwsi, int size);
89 extern void EVENT_AddIO( int fd, unsigned flag );
90 extern void EVENT_DeleteIO( int fd, unsigned flag );
92 /***********************************************************************
93 * convert_sockopt()
95 * Converts socket flags from Windows format.
97 static void convert_sockopt(INT32 *level, INT32 *optname)
99 int i;
100 switch (*level)
102 case WS_SOL_SOCKET:
103 *level = SOL_SOCKET;
104 for(i=0; _ws_sock_ops[i]; i++)
105 if( _ws_sock_ops[i] == *optname ) break;
106 if( _ws_sock_ops[i] ) *optname = _px_sock_ops[i];
107 else fprintf(stderr, "convert_sockopt() unknown optname %d\n", *optname);
108 break;
109 case WS_IPPROTO_TCP:
110 *optname = IPPROTO_TCP;
114 /* ----------------------------------- Per-thread info (or per-process?) */
116 static LPWSINFO wsi_find(HTASK16 hTask)
118 TDB* pTask = (TDB*)GlobalLock16(hTask);
119 if( pTask )
121 if( pTask->pwsi ) return pTask->pwsi;
122 else
124 LPWSINFO pwsi = _wsi_list;
125 while( pwsi && pwsi->tid != hTask ) pwsi = pwsi->next;
126 if( pwsi )
127 fprintf(stderr,"loose wsi struct! pwsi=0x%08x, task=0x%04x\n",
128 (unsigned)pwsi, hTask );
129 return pwsi;
132 return NULL;
135 static ws_socket* wsi_alloc_socket(LPWSINFO pwsi, int fd)
137 /* Initialize a new entry in the socket table */
139 if( pwsi->last_free >= 0 )
141 int i = pwsi->last_free;
143 pwsi->last_free = pwsi->sock[i].flags; /* free list */
144 pwsi->sock[i].fd = fd;
145 pwsi->sock[i].flags = 0;
146 return &pwsi->sock[i];
148 return NULL;
151 static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, ws_fd_set* ws, int* highfd )
153 /* translate Winsock fd set into local fd set */
155 if( ws )
157 int i;
158 ws_socket* pws;
160 FD_ZERO(fds);
161 for( i = 0; i < (ws->fd_count) ; i++ )
163 pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
164 if( _check_ws(pwsi, pws) )
166 if( pws->fd > *highfd ) *highfd = pws->fd;
167 FD_SET(pws->fd, fds);
170 return fds;
172 return NULL;
175 __inline__ static int sock_error_p(int s)
177 unsigned int optval, optlen;
179 optlen = sizeof(optval);
180 getsockopt(s, SOL_SOCKET, SO_ERROR, &optval, &optlen);
181 if (optval) dprintf_winsock(stddeb, "\t[%i] error: %d\n", s, optval);
182 return optval != 0;
185 static int fd_set_export( LPWSINFO pwsi, fd_set* fds, fd_set* exceptfds, ws_fd_set* ws )
187 int num_err = 0;
189 /* translate local fd set into Winsock fd set, adding
190 * errors to exceptfds (only if app requested it) */
192 if( ws )
194 int i, j, count = ws->fd_count;
196 for( i = 0, j = 0; i < count; i++ )
198 ws_socket *pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
199 int fd = pws->fd;
201 if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
203 if ( exceptfds && sock_error_p(fd) )
205 FD_SET(fd, exceptfds);
206 num_err++;
208 else
209 ws->fd_array[j++] = ws->fd_array[i];
212 ws->fd_count = j;
213 dprintf_winsock(stddeb, "\n");
215 return num_err;
218 HANDLE16 __ws_gethandle( void* ptr )
220 return (HANDLE16)WS_PTR2HANDLE(ptr);
223 void* __ws_memalloc( int size )
225 return WS_ALLOC(size);
228 void __ws_memfree(void* ptr)
230 WS_FREE(ptr);
233 /* ----------------------------------- API -----
235 * Init / cleanup / error checking.
238 /***********************************************************************
239 * WSAStartup16() (WINSOCK.115)
241 * Create socket control struct, attach it to the global list and
242 * update a pointer in the task struct.
244 INT16 WINAPI WSAStartup16(UINT16 wVersionRequested, LPWSADATA lpWSAData)
246 WSADATA WINSOCK_data = { 0x0101, 0x0101,
247 "WINE Sockets 1.1",
248 #ifdef linux
249 "Linux/i386",
250 #elif defined(__NetBSD__)
251 "NetBSD/i386",
252 #elif defined(sunos)
253 "SunOS",
254 #elif defined(__FreeBSD__)
255 "FreeBSD",
256 #elif defined(__OpenBSD__)
257 "OpenBSD/i386",
258 #else
259 "Unknown",
260 #endif
261 WS_MAX_SOCKETS_PER_THREAD,
262 WS_MAX_UDP_DATAGRAM, (SEGPTR)NULL };
263 HTASK16 tid = GetCurrentTask();
264 LPWSINFO pwsi;
266 dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);
268 if (LOBYTE(wVersionRequested) < 1 || (LOBYTE(wVersionRequested) == 1 &&
269 HIBYTE(wVersionRequested) < 1)) return WSAVERNOTSUPPORTED;
271 if (!lpWSAData) return WSAEINVAL;
273 /* initialize socket heap */
275 if( !_ws_stub )
277 _WSHeap = HeapCreate(HEAP_ZERO_MEMORY, 8120, 32768);
278 if( !(_ws_stub = WS_ALLOC(0x10)) )
280 fprintf(stderr,"Fatal: failed to create WinSock heap\n");
281 return 0;
284 if( _WSHeap == 0 ) return WSASYSNOTREADY;
286 /* create socket array for this task */
288 pwsi = wsi_find(GetCurrentTask());
289 if( pwsi == NULL )
291 TDB* pTask = (TDB*)GlobalLock16( tid );
293 if( (pwsi = (LPWSINFO)WS_ALLOC( sizeof(WSINFO))) )
295 int i = 0;
296 pwsi->tid = tid;
297 for( i = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++ )
299 pwsi->sock[i].fd = -1;
300 pwsi->sock[i].flags = i + 1;
302 pwsi->sock[WS_MAX_SOCKETS_PER_THREAD - 1].flags = -1;
304 else return WSASYSNOTREADY;
306 /* add this control struct to the global list */
308 pwsi->prev = NULL;
309 if( _wsi_list )
310 _wsi_list->prev = pwsi;
311 pwsi->next = _wsi_list;
312 _wsi_list = pwsi;
313 pTask->pwsi = pwsi;
315 else pwsi->num_startup++;
317 /* return winsock information */
319 memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data));
321 dprintf_winsock(stddeb, "WSAStartup: succeeded\n");
322 return 0;
325 /***********************************************************************
326 * WSAStartup32() (WSOCK32.115)
328 INT32 WINAPI WSAStartup32(UINT32 wVersionRequested, LPWSADATA lpWSAData)
330 return WSAStartup16( wVersionRequested, lpWSAData );
333 /***********************************************************************
334 * WSACleanup() (WINSOCK.116)
336 * Cleanup functions of varying impact.
338 void WINSOCK_Shutdown()
340 /* Called on exit(), has to remove all outstanding async DNS processes. */
342 WINSOCK_cancel_task_aops( 0, __ws_memfree );
345 INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, LPWSINFO pwsi )
347 /* WSACleanup() backend, called on task termination as well.
348 * Real DLL would have registered its own signal handler with
349 * TaskSetSignalHandler() and waited until USIG_TERMINATION/USIG_GPF
350 * but this scheme is much more straightforward.
353 int i, j, n;
355 if( --pwsi->num_startup > 0 ) return 0;
357 SIGNAL_MaskAsyncEvents( TRUE );
358 if( pTask )
359 pTask->pwsi = NULL;
360 WINSOCK_cancel_task_aops( pTask->hSelf, __ws_memfree );
361 SIGNAL_MaskAsyncEvents( FALSE );
363 /* unlink socket control struct */
365 if( pwsi == _wsi_list )
366 _wsi_list = pwsi->next;
367 else
368 pwsi->prev->next = pwsi->next;
369 if( pwsi->next ) pwsi->next->prev = pwsi->prev;
371 if( _wsi_list == NULL )
372 WINSOCK_Shutdown(); /* just in case */
374 if( pwsi->flags & WSI_BLOCKINGCALL )
375 dprintf_winsock(stddeb,"\tinside blocking call!\n");
377 /* FIXME: aop_control() doesn't decrement pwsi->num_async_rq
379 * if( pwsi->num_async_rq )
380 * dprintf_winsock(stddeb,"\thave %i outstanding async ops!\n", pwsi->num_async_rq );
383 for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++)
384 if( pwsi->sock[i].fd != -1 )
386 if( pwsi->sock[i].psop )
388 n++;
389 WSAAsyncSelect( (SOCKET16)WS_PTR2HANDLE(pwsi->sock + i), 0, 0, 0 );
391 close(pwsi->sock[i].fd); j++;
393 if( j )
394 dprintf_winsock(stddeb,"\tclosed %i sockets, killed %i async selects!\n", j, n);
396 /* delete scratch buffers */
398 if( pwsi->buffer ) SEGPTR_FREE(pwsi->buffer);
399 if( pwsi->dbuffer ) SEGPTR_FREE(pwsi->dbuffer);
401 memset( pwsi, 0, sizeof(WSINFO) );
402 WS_FREE(pwsi);
403 return 0;
406 INT32 WINAPI WSACleanup(void)
408 HTASK16 hTask = GetCurrentTask();
410 dprintf_winsock(stddeb, "WSACleanup(%04x)\n", hTask );
411 if( hTask )
413 LPWSINFO pwsi = wsi_find(hTask);
414 if( pwsi )
415 return WINSOCK_DeleteTaskWSI( (TDB*)GlobalLock16(hTask), pwsi );
416 return SOCKET_ERROR;
418 else
419 WINSOCK_Shutdown(); /* remove all outstanding DNS requests */
420 return 0;
424 /***********************************************************************
425 * WSAGetLastError() (WSOCK32.111)(WINSOCK.111)
427 INT32 WINAPI WSAGetLastError(void)
429 LPWSINFO pwsi = wsi_find(GetCurrentTask());
430 INT16 ret;
432 dprintf_winsock(stddeb, "WSAGetLastError(%08x)", (unsigned)pwsi);
434 ret = (pwsi) ? pwsi->err : WSANOTINITIALISED;
436 dprintf_winsock(stddeb, " = %i\n", (int)ret);
437 return ret;
440 /***********************************************************************
441 * WSASetLastError32() (WSOCK32.112)
443 void WINAPI WSASetLastError32(INT32 iError)
445 LPWSINFO pwsi = wsi_find(GetCurrentTask());
447 dprintf_winsock(stddeb, "WSASetLastError(%08x): %d\n", (unsigned)pwsi, (int)iError);
448 if( pwsi ) pwsi->err = iError;
451 /***********************************************************************
452 * WSASetLastError16() (WINSOCK.112)
454 void WINAPI WSASetLastError16(INT16 iError)
456 WSASetLastError32(iError);
459 int _check_ws(LPWSINFO pwsi, ws_socket* pws)
461 if( pwsi )
462 if( pwsi->flags & WSI_BLOCKINGCALL ) pwsi->err = WSAEINPROGRESS;
463 else if( WSI_CHECK_RANGE(pwsi, pws) ) return 1;
464 else pwsi->err = WSAENOTSOCK;
465 return 0;
468 int _check_buffer(LPWSINFO pwsi, int size)
470 if( pwsi->buffer && pwsi->buflen >= size ) return 1;
471 else SEGPTR_FREE(pwsi->buffer);
473 pwsi->buffer = (char*)SEGPTR_ALLOC((pwsi->buflen = size));
474 return (pwsi->buffer != NULL);
477 /* ----------------------------------- i/o APIs */
479 /***********************************************************************
480 * accept() (WSOCK32.1)
482 SOCKET32 WINAPI WINSOCK_accept32(SOCKET32 s, struct sockaddr *addr,
483 INT32 *addrlen32)
485 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR((SOCKET16)s);
486 LPWSINFO pwsi = wsi_find(GetCurrentTask());
488 dprintf_winsock(stddeb, "WS_ACCEPT(%08x): socket %04x\n",
489 (unsigned)pwsi, (UINT16)s );
490 if( _check_ws(pwsi, pws) )
492 int sock, fd_flags;
494 fd_flags = fcntl(pws->fd, F_GETFL, 0);
496 if( (sock = accept(pws->fd, addr, addrlen32)) >= 0 )
498 ws_socket* pnew = wsi_alloc_socket(pwsi, sock);
499 if( pnew )
501 s = (SOCKET32)WS_PTR2HANDLE(pnew);
502 if( pws->psop && pws->flags & WS_FD_ACCEPT )
504 EVENT_AddIO( pws->fd, EVENT_IO_READ ); /* reenabler */
506 /* async select the accept()'ed socket */
507 WSAAsyncSelect( s, pws->psop->hWnd, pws->psop->uMsg,
508 pws->flags & ~WS_FD_ACCEPT );
510 return s;
512 else pwsi->err = WSAENOBUFS;
514 else pwsi->err = wsaErrno();
516 return INVALID_SOCKET32;
519 /***********************************************************************
520 * accept() (WINSOCK.1)
522 SOCKET16 WINAPI WINSOCK_accept16(SOCKET16 s, struct sockaddr* addr,
523 INT16* addrlen16 )
525 INT32 addrlen32 = addrlen16 ? *addrlen16 : 0;
526 SOCKET32 retSocket = WINSOCK_accept32( s, addr, &addrlen32 );
527 if( addrlen16 ) *addrlen16 = (INT16)addrlen32;
528 return (SOCKET16)retSocket;
531 /***********************************************************************
532 * bind() (WSOCK32.2)
534 INT32 WINAPI WINSOCK_bind32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
536 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
537 LPWSINFO pwsi = wsi_find(GetCurrentTask());
539 dprintf_winsock(stddeb, "WS_BIND(%08x): socket %04x, ptr %8x, length %d\n",
540 (unsigned)pwsi, s, (int) name, namelen);
541 #if DEBUG_SOCKADDR
542 dump_sockaddr(name);
543 #endif
545 if ( _check_ws(pwsi, pws) )
546 if ( namelen >= sizeof(*name) )
547 if ( ((struct sockaddr_in *)name)->sin_family == AF_INET )
548 if ( bind(pws->fd, name, namelen) < 0 )
550 int loc_errno = errno;
551 dprintf_winsock(stddeb,"\tfailure - errno = %i\n", errno);
552 errno = loc_errno;
553 switch(errno)
555 case EBADF: pwsi->err = WSAENOTSOCK; break;
556 case EADDRNOTAVAIL: pwsi->err = WSAEINVAL; break;
557 default: pwsi->err = wsaErrno();
560 else return 0; /* success */
561 else pwsi->err = WSAEAFNOSUPPORT;
562 else pwsi->err = WSAEFAULT;
563 return SOCKET_ERROR;
566 /***********************************************************************
567 * bind() (WINSOCK.2)
569 INT16 WINAPI WINSOCK_bind16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
571 return (INT16)WINSOCK_bind32( s, name, namelen );
574 /***********************************************************************
575 * closesocket() (WSOCK32.3)
577 INT32 WINAPI WINSOCK_closesocket32(SOCKET32 s)
579 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
580 LPWSINFO pwsi = wsi_find(GetCurrentTask());
582 dprintf_winsock(stddeb, "WS_CLOSE(%08x): socket %08x\n", (unsigned)pwsi, s);
584 if( _check_ws(pwsi, pws) )
586 int fd = pws->fd;
588 if( pws->psop ) WSAAsyncSelect( s, 0, 0, 0 );
590 pws->fd = -1;
591 pws->flags = (unsigned)pwsi->last_free;
592 pwsi->last_free = pws - &pwsi->sock[0]; /* add to free list */
594 if( close(fd) == 0 )
595 return 0;
596 pwsi->err = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
598 return SOCKET_ERROR;
601 /***********************************************************************
602 * closesocket() (WINSOCK.3)
604 INT16 WINAPI WINSOCK_closesocket16(SOCKET16 s)
606 return (INT16)WINSOCK_closesocket32(s);
609 /***********************************************************************
610 * connect() (WSOCK32.4)
612 INT32 WINAPI WINSOCK_connect32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
614 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
615 LPWSINFO pwsi = wsi_find(GetCurrentTask());
617 dprintf_winsock(stddeb, "WS_CONNECT(%08x): socket %04x, ptr %8x, length %d\n",
618 (unsigned)pwsi, s, (int) name, namelen);
619 #if DEBUG_SOCKADDR
620 dump_sockaddr(name);
621 #endif
623 if( _check_ws(pwsi, pws) )
625 if (connect(pws->fd, name, namelen) == 0)
627 if( pws->psop && (pws->flags & WS_FD_CONNECT) )
629 /* application did AsyncSelect() but then went
630 * ahead and called connect() without waiting for
631 * notification.
633 * FIXME: Do we have to post a notification message
634 * in this case?
637 if( !(pws->flags & WS_FD_CONNECTED) )
639 if( pws->flags & (WS_FD_READ | WS_FD_CLOSE) )
640 EVENT_AddIO( pws->fd, EVENT_IO_READ );
641 else
642 EVENT_DeleteIO( pws->fd, EVENT_IO_READ );
643 if( pws->flags & WS_FD_WRITE )
644 EVENT_AddIO( pws->fd, EVENT_IO_WRITE );
645 else
646 EVENT_DeleteIO( pws->fd, EVENT_IO_WRITE );
649 pws->flags |= WS_FD_CONNECTED;
650 pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT | WS_FD_LISTENING);
651 return 0;
653 pwsi->err = (errno == EINPROGRESS) ? WSAEWOULDBLOCK : wsaErrno();
655 return SOCKET_ERROR;
658 /***********************************************************************
659 * connect() (WINSOCK.4)
661 INT16 WINAPI WINSOCK_connect16(SOCKET16 s, struct sockaddr *name, INT16 namelen)
663 return (INT16)WINSOCK_connect32( s, name, namelen );
666 /***********************************************************************
667 * getpeername() (WSOCK32.5)
669 INT32 WINAPI WINSOCK_getpeername32(SOCKET32 s, struct sockaddr *name,
670 INT32 *namelen)
672 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
673 LPWSINFO pwsi = wsi_find(GetCurrentTask());
675 dprintf_winsock(stddeb, "WS_GETPEERNAME(%08x): socket: %04x, ptr %8x, ptr %8x\n",
676 (unsigned)pwsi, s, (int) name, *namelen);
677 if( _check_ws(pwsi, pws) )
679 if (getpeername(pws->fd, name, namelen) == 0)
680 return 0;
681 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
683 return SOCKET_ERROR;
686 /***********************************************************************
687 * getpeername() (WINSOCK.5)
689 INT16 WINAPI WINSOCK_getpeername16(SOCKET16 s, struct sockaddr *name,
690 INT16 *namelen16)
692 INT32 namelen32 = *namelen16;
693 INT32 retVal = WINSOCK_getpeername32( s, name, &namelen32 );
695 #if DEBUG_SOCKADDR
696 dump_sockaddr(name);
697 #endif
699 *namelen16 = namelen32;
700 return (INT16)retVal;
703 /***********************************************************************
704 * getsockname() (WSOCK32.6)
706 INT32 WINAPI WINSOCK_getsockname32(SOCKET32 s, struct sockaddr *name,
707 INT32 *namelen)
709 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
710 LPWSINFO pwsi = wsi_find(GetCurrentTask());
712 dprintf_winsock(stddeb, "WS_GETSOCKNAME(%08x): socket: %04x, ptr %8x, ptr %8x\n",
713 (unsigned)pwsi, s, (int) name, (int) *namelen);
714 if( _check_ws(pwsi, pws) )
716 if (getsockname(pws->fd, name, namelen) == 0)
717 return 0;
718 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
720 return SOCKET_ERROR;
723 /***********************************************************************
724 * getsockname() (WINSOCK.6)
726 INT16 WINAPI WINSOCK_getsockname16(SOCKET16 s, struct sockaddr *name,
727 INT16 *namelen16)
729 INT32 retVal;
731 if( namelen16 )
733 INT32 namelen32 = *namelen16;
734 retVal = WINSOCK_getsockname32( s, name, &namelen32 );
735 *namelen16 = namelen32;
737 #if DEBUG_SOCKADDR
738 dump_sockaddr(name);
739 #endif
742 else retVal = SOCKET_ERROR;
743 return (INT16)retVal;
747 /***********************************************************************
748 * getsockopt() (WSOCK32.7)
750 INT32 WINAPI WINSOCK_getsockopt32(SOCKET32 s, INT32 level,
751 INT32 optname, char *optval, INT32 *optlen)
753 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
754 LPWSINFO pwsi = wsi_find(GetCurrentTask());
756 dprintf_winsock(stddeb, "WS_GETSOCKOPT(%08x): socket: %04x, opt %d, ptr %8x, ptr %8x\n",
757 (unsigned)pwsi, s, level, (int) optval, (int) *optlen);
758 if( _check_ws(pwsi, pws) )
760 convert_sockopt(&level, &optname);
761 if (getsockopt(pws->fd, (int) level, optname, optval, optlen) == 0 )
762 return 0;
763 pwsi->err = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
765 return SOCKET_ERROR;
768 /***********************************************************************
769 * getsockopt() (WINSOCK.7)
771 INT16 WINAPI WINSOCK_getsockopt16(SOCKET16 s, INT16 level,
772 INT16 optname, char *optval, INT16 *optlen)
774 INT32 optlen32;
775 INT32 *p = &optlen32;
776 INT32 retVal;
777 if( optlen ) optlen32 = *optlen; else p = NULL;
778 retVal = WINSOCK_getsockopt32( s, level, optname, optval, p );
779 if( optlen ) *optlen = optlen32;
780 return (INT16)retVal;
783 /***********************************************************************
784 * htonl() (WINSOCK.8)(WSOCK32.8)
786 u_long WINAPI WINSOCK_htonl(u_long hostlong) { return( htonl(hostlong) ); }
787 /***********************************************************************
788 * htons() (WINSOCK.9)(WSOCK32.9)
790 u_short WINAPI WINSOCK_htons(u_short hostshort) { return( htons(hostshort) ); }
791 /***********************************************************************
792 * inet_addr() (WINSOCK.10)
794 u_long WINAPI WINSOCK_inet_addr(char *cp) { return( inet_addr(cp) ); }
795 /***********************************************************************
796 * htohl() (WINSOCK.14)(WSOCK32.14)
798 u_long WINAPI WINSOCK_ntohl(u_long netlong) { return( ntohl(netlong) ); }
799 /***********************************************************************
800 * ntohs() (WINSOCK.15)(WSOCK32.15)
802 u_short WINAPI WINSOCK_ntohs(u_short netshort) { return( ntohs(netshort) ); }
804 /***********************************************************************
805 * inet_ntoa() (WINSOCK.11)
807 SEGPTR WINAPI WINSOCK_inet_ntoa(struct in_addr in)
809 /* use "buffer for dummies" here because some applications have
810 * propensity to decode addresses in ws_hostent structure without
811 * saving them first...
814 LPWSINFO pwsi = wsi_find(GetCurrentTask());
816 if( pwsi )
818 char* s = inet_ntoa(in);
819 if( s )
821 if( pwsi->dbuffer == NULL )
822 if((pwsi->dbuffer = (char*) SEGPTR_ALLOC(32)) == NULL )
824 pwsi->err = WSAENOBUFS;
825 return (SEGPTR)NULL;
827 strncpy(pwsi->dbuffer, s, 32 );
828 return SEGPTR_GET(pwsi->dbuffer);
830 pwsi->err = wsaErrno();
832 return (SEGPTR)NULL;
835 /***********************************************************************
836 * ioctlsocket() (WSOCK32.12)
838 INT32 WINAPI WINSOCK_ioctlsocket32(SOCKET32 s, UINT32 cmd, UINT32 *argp)
840 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
841 LPWSINFO pwsi = wsi_find(GetCurrentTask());
843 dprintf_winsock(stddeb, "WS_IOCTL(%08x): socket %04x, cmd %08x, ptr %8x\n",
844 (unsigned)pwsi, s, cmd, (unsigned) argp);
845 if( _check_ws(pwsi, pws) )
847 long newcmd = cmd;
849 switch( cmd )
851 case WS_FIONREAD:
852 newcmd=FIONREAD;
853 break;
855 case WS_FIONBIO:
856 newcmd=FIONBIO;
857 if( pws->psop && *argp == 0 )
859 /* AsyncSelect()'ed sockets are always nonblocking */
860 pwsi->err = WSAEINVAL;
861 return SOCKET_ERROR;
863 break;
865 case WS_SIOCATMARK:
866 newcmd=SIOCATMARK;
867 break;
869 case WS_IOW('f',125,u_long):
870 fprintf(stderr,"Warning: WS1.1 shouldn't be using async I/O\n");
871 pwsi->err = WSAEINVAL;
872 return SOCKET_ERROR;
874 default:
875 /* Netscape tries hard to use bogus ioctl 0x667e */
876 dprintf_winsock(stddeb,"\tunknown WS_IOCTL cmd (%08x)\n", cmd);
878 if( ioctl(pws->fd, newcmd, (char*)argp ) == 0 ) return 0;
879 pwsi->err = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
881 return SOCKET_ERROR;
884 /***********************************************************************
885 * ioctlsocket() (WINSOCK.12)
887 INT16 WINAPI WINSOCK_ioctlsocket16(SOCKET16 s, UINT32 cmd, UINT32 *argp)
889 return (INT16)WINSOCK_ioctlsocket32( s, cmd, argp );
893 /***********************************************************************
894 * listen() (WSOCK32.13)
896 INT32 WINAPI WINSOCK_listen32(SOCKET32 s, INT32 backlog)
898 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
899 LPWSINFO pwsi = wsi_find(GetCurrentTask());
901 dprintf_winsock(stddeb, "WS_LISTEN(%08x): socket %04x, backlog %d\n",
902 (unsigned)pwsi, s, backlog);
903 if( _check_ws(pwsi, pws) )
905 if (listen(pws->fd, backlog) == 0)
907 if( !pws->psop )
909 int fd_flags = fcntl(pws->fd, F_GETFL, 0);
910 if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
912 pws->flags |= WS_FD_LISTENING;
913 pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECTED); /* just in case */
914 return 0;
916 pwsi->err = wsaErrno();
918 else if( pwsi ) pwsi->err = WSAENOTSOCK;
919 return SOCKET_ERROR;
922 /***********************************************************************
923 * listen() (WINSOCK.13)
925 INT16 WINAPI WINSOCK_listen16(SOCKET16 s, INT16 backlog)
927 return (INT16)WINSOCK_listen32( s, backlog );
931 /***********************************************************************
932 * recv() (WSOCK32.16)
934 INT32 WINAPI WINSOCK_recv32(SOCKET32 s, char *buf, INT32 len, INT32 flags)
936 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
937 LPWSINFO pwsi = wsi_find(GetCurrentTask());
939 dprintf_winsock(stddeb, "WS_RECV(%08x): socket %04x, buf %8x, len %d, flags %d",
940 (unsigned)pwsi, s, (unsigned)buf, len, flags);
941 if( _check_ws(pwsi, pws) )
943 INT32 length;
944 if ((length = recv(pws->fd, buf, len, flags)) >= 0)
946 dprintf_winsock(stddeb, " -> %i bytes\n", length);
948 if( pws->psop && (pws->flags & (WS_FD_READ | WS_FD_CLOSE)) )
949 EVENT_AddIO( pws->fd, EVENT_IO_READ ); /* reenabler */
951 return length;
953 pwsi->err = wsaErrno();
955 else if( pwsi ) pwsi->err = WSAENOTSOCK;
956 dprintf_winsock(stddeb, " -> ERROR\n");
957 return SOCKET_ERROR;
960 /***********************************************************************
961 * recv() (WINSOCK.16)
963 INT16 WINAPI WINSOCK_recv16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
965 return (INT16)WINSOCK_recv32( s, buf, len, flags );
969 /***********************************************************************
970 * recvfrom() (WSOCK32.17)
972 INT32 WINAPI WINSOCK_recvfrom32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
973 struct sockaddr *from, INT32 *fromlen32)
975 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
976 LPWSINFO pwsi = wsi_find(GetCurrentTask());
978 dprintf_winsock(stddeb, "WS_RECVFROM(%08x): socket %04x, ptr %08x, len %d, flags %d",
979 (unsigned)pwsi, s, (unsigned)buf, len, flags);
980 #if DEBUG_SOCKADDR
981 if( from ) dump_sockaddr(from);
982 else fprintf(stderr, "\tfrom = NULL\n");
983 #endif
985 if( _check_ws(pwsi, pws) )
987 int length;
989 if ((length = recvfrom(pws->fd, buf, len, flags, from, fromlen32)) >= 0)
991 dprintf_winsock(stddeb, " -> %i bytes\n", length);
993 if( pws->psop && (pws->flags & (WS_FD_READ | WS_FD_CLOSE)) )
994 EVENT_AddIO( pws->fd, EVENT_IO_READ ); /* reenabler */
996 return (INT16)length;
998 pwsi->err = wsaErrno();
1000 else if( pwsi ) pwsi->err = WSAENOTSOCK;
1001 dprintf_winsock(stddeb, " -> ERROR\n");
1002 return SOCKET_ERROR;
1005 /***********************************************************************
1006 * recvfrom() (WINSOCK.17)
1008 INT16 WINAPI WINSOCK_recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
1009 struct sockaddr *from, INT16 *fromlen16)
1011 INT32 fromlen32;
1012 INT32 *p = &fromlen32;
1013 INT32 retVal;
1015 if( fromlen16 ) fromlen32 = *fromlen16; else p = NULL;
1016 retVal = WINSOCK_recvfrom32( s, buf, len, flags, from, p );
1017 if( fromlen16 ) *fromlen16 = fromlen32;
1018 return (INT16)retVal;
1021 /***********************************************************************
1022 * select() (WINSOCK.18)
1024 INT16 WINAPI WINSOCK_select16(INT16 nfds, ws_fd_set *ws_readfds,
1025 ws_fd_set *ws_writefds, ws_fd_set *ws_exceptfds,
1026 struct timeval *timeout)
1028 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1030 dprintf_winsock(stddeb, "WS_SELECT(%08x): nfds %d (ignored), read %8x, write %8x, excp %8x\n",
1031 (unsigned) pwsi, nfds, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
1033 if( pwsi )
1035 int highfd = 0;
1036 fd_set readfds, writefds, exceptfds;
1037 fd_set *p_read, *p_write, *p_except;
1039 p_read = fd_set_import(&readfds, pwsi, ws_readfds, &highfd);
1040 p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd);
1041 p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd);
1043 if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) >= 0 )
1045 if( highfd )
1047 fd_set_export(pwsi, &readfds, p_except, ws_readfds);
1048 fd_set_export(pwsi, &writefds, p_except, ws_writefds);
1050 if (p_except && ws_exceptfds)
1052 int i, j, count = ws_exceptfds->fd_count;
1054 for (i = j = 0; i < count; i++)
1056 ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws_exceptfds->fd_array[i]);
1057 if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
1058 ws_exceptfds->fd_array[j++] = ws_exceptfds->fd_array[i];
1060 ws_exceptfds->fd_count = j;
1063 return highfd;
1065 pwsi->err = wsaErrno();
1067 return SOCKET_ERROR;
1070 /***********************************************************************
1071 * select() (WSOCK32.18)
1073 INT32 WINAPI WINSOCK_select32(INT32 nfds, ws_fd_set *ws_readfds,
1074 ws_fd_set *ws_writefds, ws_fd_set *ws_exceptfds,
1075 struct timeval *timeout)
1077 /* struct timeval is the same for both 32- and 16-bit code */
1078 return WINSOCK_select16( (INT16)nfds, ws_readfds, ws_writefds, ws_exceptfds, timeout );
1082 /***********************************************************************
1083 * send() (WSOCK32.19)
1085 INT32 WINAPI WINSOCK_send32(SOCKET32 s, char *buf, INT32 len, INT32 flags)
1087 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
1088 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1090 dprintf_winsock(stddeb, "WS_SEND(%08x): socket %04x, ptr %08x, length %d, flags %d\n",
1091 (unsigned)pwsi, s, (unsigned) buf, len, flags);
1092 if( _check_ws(pwsi, pws) )
1094 int length;
1096 if ((length = send(pws->fd, buf, len, flags)) < 0 )
1098 pwsi->err = wsaErrno();
1099 if( pwsi->err == WSAEWOULDBLOCK &&
1100 pws->psop && pws->flags & WS_FD_WRITE )
1101 EVENT_AddIO( pws->fd, EVENT_IO_WRITE ); /* reenabler */
1103 else return (INT16)length;
1105 else if( pwsi ) pwsi->err = WSAENOTSOCK;
1106 return SOCKET_ERROR;
1109 /***********************************************************************
1110 * send() (WINSOCK.19)
1112 INT16 WINAPI WINSOCK_send16(SOCKET16 s, char *buf, INT16 len, INT16 flags)
1114 return WINSOCK_send32( s, buf, len, flags );
1117 /***********************************************************************
1118 * sendto() (WSOCK32.20)
1120 INT32 WINAPI WINSOCK_sendto32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
1121 struct sockaddr *to, INT32 tolen)
1123 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
1124 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1126 dprintf_winsock(stddeb, "WS_SENDTO(%08x): socket %04x, ptr %08x, length %d, flags %d\n",
1127 (unsigned)pwsi, s, (unsigned) buf, len, flags);
1128 if( _check_ws(pwsi, pws) )
1130 INT32 length;
1132 if ((length = sendto(pws->fd, buf, len, flags, to, tolen)) < 0 )
1134 pwsi->err = wsaErrno();
1135 if( pwsi->err == WSAEWOULDBLOCK &&
1136 pws->psop && pws->flags & WS_FD_WRITE )
1137 EVENT_AddIO( pws->fd, EVENT_IO_WRITE ); /* reenabler */
1139 else return length;
1141 else if( pwsi ) pwsi->err = WSAENOTSOCK;
1142 return SOCKET_ERROR;
1145 /***********************************************************************
1146 * sendto() (WINSOCK.20)
1148 INT16 WINAPI WINSOCK_sendto16(SOCKET16 s, char *buf, INT16 len, INT16 flags,
1149 struct sockaddr *to, INT16 tolen)
1151 return (INT16)WINSOCK_sendto32( s, buf, len, flags, to, tolen );
1154 /***********************************************************************
1155 * setsockopt() (WSOCK32.21)
1157 INT32 WINAPI WINSOCK_setsockopt32(SOCKET16 s, INT32 level, INT32 optname,
1158 char *optval, INT32 optlen)
1160 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
1161 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1163 dprintf_winsock(stddeb, "WS_SETSOCKOPT(%08x): socket %04x, lev %d, opt %d, ptr %08x, len %d\n",
1164 (unsigned)pwsi, s, level, optname, (int) optval, optlen);
1165 if( _check_ws(pwsi, pws) )
1167 convert_sockopt(&level, &optname);
1168 if (setsockopt(pws->fd, level, optname, optval, optlen) == 0) return 0;
1169 pwsi->err = wsaErrno();
1171 else if( pwsi ) pwsi->err = WSAENOTSOCK;
1172 return SOCKET_ERROR;
1175 /***********************************************************************
1176 * setsockopt() (WINSOCK.21)
1178 INT16 WINAPI WINSOCK_setsockopt16(SOCKET16 s, INT16 level, INT16 optname,
1179 char *optval, INT16 optlen)
1181 INT32 linger32[2];
1182 if( !optval ) return SOCKET_ERROR;
1183 if( optname == SO_LINGER )
1185 INT16* ptr = (INT16*)optval;
1186 linger32[0] = ptr[0];
1187 linger32[1] = ptr[1];
1188 optval = (char*)&linger32;
1189 optlen = sizeof(linger32);
1191 return (INT16)WINSOCK_setsockopt32( s, level, optname, optval, optlen );
1195 /***********************************************************************
1196 * shutdown() (WSOCK32.22)
1198 INT32 WINAPI WINSOCK_shutdown32(SOCKET32 s, INT32 how)
1200 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
1201 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1203 dprintf_winsock(stddeb, "WS_SHUTDOWN(%08x): socket %04x, how %i\n",
1204 (unsigned)pwsi, s, how );
1205 if( _check_ws(pwsi, pws) )
1207 if( pws->psop )
1208 switch( how )
1210 case 0: /* drop receives */
1211 if( pws->flags & (WS_FD_READ | WS_FD_CLOSE) )
1212 EVENT_DeleteIO( pws->fd, EVENT_IO_READ );
1213 pws->flags &= ~(WS_FD_READ | WS_FD_CLOSE);
1214 break;
1216 case 1: /* drop sends */
1217 if( pws->flags & WS_FD_WRITE )
1218 EVENT_DeleteIO( pws->fd, EVENT_IO_WRITE );
1219 pws->flags &= ~WS_FD_WRITE;
1220 break;
1222 case 2: /* drop all */
1223 default:
1224 WSAAsyncSelect( s, 0, 0, 0 );
1225 break;
1228 if (shutdown(pws->fd, how) == 0)
1230 if( how > 1 )
1232 pws->flags &= ~(WS_FD_CONNECTED | WS_FD_LISTENING);
1233 pws->flags |= WS_FD_INACTIVE;
1235 return 0;
1237 pwsi->err = wsaErrno();
1239 else if( pwsi ) pwsi->err = WSAENOTSOCK;
1240 return SOCKET_ERROR;
1243 /***********************************************************************
1244 * shutdown() (WINSOCK.22)
1246 INT16 WINAPI WINSOCK_shutdown16(SOCKET16 s, INT16 how)
1248 return (INT16)WINSOCK_shutdown32( s, how );
1252 /***********************************************************************
1253 * socket() (WSOCK32.23)
1255 SOCKET32 WINAPI WINSOCK_socket32(INT32 af, INT32 type, INT32 protocol)
1257 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1259 dprintf_winsock(stddeb, "WS_SOCKET(%08x): af=%d type=%d protocol=%d\n",
1260 (unsigned)pwsi, af, type, protocol);
1262 if( pwsi )
1264 int sock;
1266 /* check the socket family */
1267 switch(af)
1269 case AF_INET:
1270 case AF_UNSPEC: break;
1271 default: pwsi->err = WSAEAFNOSUPPORT;
1272 return INVALID_SOCKET32;
1275 /* check the socket type */
1276 switch(type)
1278 case SOCK_STREAM:
1279 case SOCK_DGRAM:
1280 case SOCK_RAW: break;
1281 default: pwsi->err = WSAESOCKTNOSUPPORT;
1282 return INVALID_SOCKET32;
1285 /* check the protocol type */
1286 if ( protocol < 0 ) /* don't support negative values */
1287 { pwsi->err = WSAEPROTONOSUPPORT; return INVALID_SOCKET32; }
1289 if ( af == AF_UNSPEC) /* did they not specify the address family? */
1290 switch(protocol)
1292 case IPPROTO_TCP:
1293 if (type == SOCK_STREAM) { af = AF_INET; break; }
1294 case IPPROTO_UDP:
1295 if (type == SOCK_DGRAM) { af = AF_INET; break; }
1296 default: pwsi->err = WSAEPROTOTYPE; return INVALID_SOCKET32;
1299 if ((sock = socket(af, type, protocol)) >= 0)
1301 ws_socket* pnew = wsi_alloc_socket(pwsi, sock);
1303 dprintf_winsock(stddeb,"\tcreated %04x (handle %i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
1305 if( pnew ) return (SOCKET16)WS_PTR2HANDLE(pnew);
1307 close(sock);
1308 pwsi->err = WSAENOBUFS;
1309 return INVALID_SOCKET32;
1312 if (errno == EPERM) /* raw socket denied */
1314 fprintf(stderr, "WS_SOCKET: not enough privileges\n");
1315 pwsi->err = WSAESOCKTNOSUPPORT;
1316 } else pwsi->err = wsaErrno();
1319 dprintf_winsock(stddeb, "\t\tfailed!\n");
1320 return INVALID_SOCKET32;
1323 /***********************************************************************
1324 * socket() (WINSOCK.23)
1326 SOCKET16 WINAPI WINSOCK_socket16(INT16 af, INT16 type, INT16 protocol)
1328 return (SOCKET16)WINSOCK_socket32( af, type, protocol );
1332 /* ----------------------------------- DNS services
1334 * IMPORTANT: 16-bit API structures have SEGPTR pointers inside them.
1335 * Also, we have to use wsock32 stubs to convert error codes from Unix
1336 * to WSA, hence no direct mapping in if1632/wsock32.spec.
1338 * FIXME: Win32 may need "short" h_addrtype and h_length in
1339 * ...ent structures. If so, use WS_dup_...(pwsi, ..., 0) to
1340 * convert.
1343 static char* NULL_STRING = "NULL";
1346 /***********************************************************************
1347 * gethostbyaddr() (WINSOCK.51)
1350 struct WIN_hostent *
1352 SEGPTR WINAPI WINSOCK_gethostbyaddr16(const char *addr, INT16 len, INT16 type)
1354 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1356 dprintf_winsock(stddeb, "WS_GetHostByAddr16(%08x): ptr %8x, len %d, type %d\n",
1357 (unsigned)pwsi, (unsigned) addr, len, type);
1358 if( pwsi )
1360 struct hostent* host = gethostbyaddr(addr, len, type);
1361 if( host )
1362 if( WS_dup_he(pwsi, host, WS_DUP_SEGPTR) )
1363 return SEGPTR_GET(pwsi->buffer);
1364 else
1365 pwsi->err = WSAENOBUFS;
1366 else
1367 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1369 return (SEGPTR)NULL;
1372 /***********************************************************************
1373 * gethostbyaddr() (WSOCK32.51)
1375 struct hostent* WINAPI WINSOCK_gethostbyaddr32(const char *addr, INT32 len,
1376 INT32 type)
1378 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1380 dprintf_winsock(stddeb, "WS_GetHostByAddr32(%08x): ptr %8x, len %d, type %d\n",
1381 (unsigned)pwsi, (unsigned) addr, len, type);
1382 if( pwsi )
1384 struct hostent* host = gethostbyaddr( addr, len, type );
1385 if( host )
1386 return host;
1387 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1389 return NULL;
1392 /***********************************************************************
1393 * gethostbyname() (WINSOCK.52)
1396 struct WIN_hostent *
1398 SEGPTR WINAPI WINSOCK_gethostbyname16(const char *name)
1400 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1402 dprintf_winsock(stddeb, "WS_GetHostByName16(%08x): %s\n",
1403 (unsigned)pwsi, (name)?name:"NULL");
1404 if( pwsi )
1406 struct hostent* host;
1407 if( (host = gethostbyname(name)) != NULL )
1408 if( WS_dup_he(pwsi, host, WS_DUP_SEGPTR) )
1409 return SEGPTR_GET(pwsi->buffer);
1410 else pwsi->err = WSAENOBUFS;
1411 else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1413 return (SEGPTR)NULL;
1416 /***********************************************************************
1417 * gethostbyname() (WSOCK32,52)
1419 struct hostent* WINAPI WINSOCK_gethostbyname32(const char* name)
1421 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1423 dprintf_winsock(stddeb, "WS_GetHostByName32(%08x): %s\n",
1424 (unsigned)pwsi, (name)?name:"NULL");
1425 if( pwsi )
1427 struct hostent* host = gethostbyname( name );
1428 if( host )
1429 return host;
1430 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1432 return NULL;
1435 /***********************************************************************
1436 * gethostname() (WSOCK32.57)
1438 INT32 WINAPI WINSOCK_gethostname32(char *name, INT32 namelen)
1440 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1442 dprintf_winsock(stddeb, "WS_GetHostName(%08x): name %s, len %d\n",
1443 (unsigned)pwsi, (name)?name:NULL_STRING, namelen);
1444 if( pwsi )
1446 if (gethostname(name, namelen) == 0) return 0;
1447 pwsi->err = (errno == EINVAL) ? WSAEFAULT : wsaErrno();
1449 return SOCKET_ERROR;
1452 /***********************************************************************
1453 * gethostname() (WINSOCK.57)
1455 INT16 WINAPI WINSOCK_gethostname16(char *name, INT16 namelen)
1457 return (INT16)WINSOCK_gethostname32(name, namelen);
1460 /***********************************************************************
1461 * getprotobyname() (WINSOCK.53)
1464 struct WIN_protoent *
1466 SEGPTR WINAPI WINSOCK_getprotobyname16(char *name)
1468 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1470 dprintf_winsock(stddeb, "WS_GetProtoByName16(%08x): %s\n",
1471 (unsigned)pwsi, (name)?name:NULL_STRING);
1472 if( pwsi )
1474 struct protoent* proto;
1475 if( (proto = getprotobyname(name)) != NULL )
1476 if( WS_dup_pe(pwsi, proto, WS_DUP_SEGPTR) )
1477 return SEGPTR_GET(pwsi->buffer);
1478 else pwsi->err = WSAENOBUFS;
1479 else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1481 return (SEGPTR)NULL;
1484 /***********************************************************************
1485 * getprotobyname() (WSOCK32.53)
1487 struct protoent* WINAPI WINSOCK_getprotobyname32(char* name)
1489 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1491 dprintf_winsock(stddeb, "WS_GetProtoByName32(%08x): %s\n",
1492 (unsigned)pwsi, (name)?name:NULL_STRING);
1493 if( pwsi )
1495 struct protoent* proto;
1496 if( (proto = getprotobyname(name)) != NULL )
1497 return proto;
1498 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1500 return NULL;
1504 /***********************************************************************
1505 * getprotobynumber() (WINSOCK.54)
1508 struct WIN_protoent *
1510 SEGPTR WINAPI WINSOCK_getprotobynumber16(INT16 number)
1512 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1514 dprintf_winsock(stddeb, "WS_GetProtoByNumber16(%08x): %i\n", (unsigned)pwsi, number);
1516 if( pwsi )
1518 struct protoent* proto;
1519 if( (proto = getprotobynumber(number)) != NULL )
1520 if( WS_dup_pe(pwsi, proto, WS_DUP_SEGPTR) )
1521 return SEGPTR_GET(pwsi->buffer);
1522 else pwsi->err = WSAENOBUFS;
1523 else pwsi->err = WSANO_DATA;
1525 return (SEGPTR)NULL;
1528 /***********************************************************************
1529 * getprotobynumber() (WSOCK32.54)
1531 struct protoent* WINAPI WINSOCK_getprotobynumber32(INT32 number)
1533 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1535 dprintf_winsock(stddeb, "WS_GetProtoByNumber32(%08x): %i\n", (unsigned)pwsi, number);
1537 if( pwsi )
1539 struct protoent* proto;
1540 if( (proto = getprotobynumber(number)) != NULL )
1541 return proto;
1542 pwsi->err = WSANO_DATA;
1544 return NULL;
1547 /***********************************************************************
1548 * getservbyname() (WINSOCK.55)
1551 struct WIN_servent *
1553 SEGPTR WINAPI WINSOCK_getservbyname16(const char *name, const char *proto)
1555 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1557 dprintf_winsock(stddeb, "WS_GetServByName16(%08x): '%s', '%s'\n",
1558 (unsigned)pwsi, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING);
1559 if( pwsi )
1561 struct servent* serv;
1562 if( (serv = getservbyname(name, proto)) != NULL )
1563 if( WS_dup_se(pwsi, serv, WS_DUP_SEGPTR) )
1564 return SEGPTR_GET(pwsi->buffer);
1565 else pwsi->err = WSAENOBUFS;
1566 else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1568 return (SEGPTR)NULL;
1571 /***********************************************************************
1572 * getservbyname() (WSOCK32.55)
1574 struct servent* WINAPI WINSOCK_getservbyname32(const char *name, const char *proto)
1576 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1578 dprintf_winsock(stddeb, "WS_GetServByName32(%08x): '%s', '%s'\n",
1579 (unsigned)pwsi, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING);
1580 if( pwsi )
1582 struct servent* serv;
1583 if( (serv = getservbyname(name, proto)) != NULL )
1584 return serv;
1585 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1587 return NULL;
1590 /***********************************************************************
1591 * getservbyport() (WINSOCK.56)
1594 struct WIN_servent *
1596 SEGPTR WINAPI WINSOCK_getservbyport16(INT16 port, const char *proto)
1598 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1600 dprintf_winsock(stddeb, "WS_GetServByPort16(%08x): %i, '%s'\n",
1601 (unsigned)pwsi, (int)port, (proto)?proto:NULL_STRING);
1602 if( pwsi )
1604 struct servent* serv;
1605 if( (serv = getservbyport(port, proto)) != NULL )
1606 if( WS_dup_se(pwsi, serv, WS_DUP_SEGPTR) )
1607 return SEGPTR_GET(pwsi->buffer);
1608 else pwsi->err = WSAENOBUFS;
1609 else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1611 return (SEGPTR)NULL;
1614 /***********************************************************************
1615 * getservbyport() (WSOCK32.56)
1617 struct servent* WINAPI WINSOCK_getservbyport32(INT32 port, const char *proto)
1619 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1621 dprintf_winsock(stddeb, "WS_GetServByPort32(%08x): %i, '%s'\n",
1622 (unsigned)pwsi, (int)port, (proto)?proto:NULL_STRING);
1623 if( pwsi )
1625 struct servent* serv;
1626 if( (serv = getservbyport(port, proto)) != NULL )
1627 return serv;
1628 pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
1630 return NULL;
1634 /* ------------------------------------- Windows sockets extensions -- *
1636 * ------------------------------------------------------------------- */
1639 /***********************************************************************
1640 * Asynchronous DNS services
1643 /* winsock_dns.c */
1644 extern HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND16 hWnd, UINT16 uMsg, INT16 type, LPCSTR init,
1645 INT16 len, LPCSTR proto, SEGPTR sbuf, INT16 buflen, UINT32 flag);
1647 /***********************************************************************
1648 * WSAAsyncGetHostByAddr() (WINSOCK.102)
1650 HANDLE16 WINAPI WSAAsyncGetHostByAddr(HWND16 hWnd, UINT16 uMsg, LPCSTR addr,
1651 INT16 len, INT16 type, SEGPTR sbuf, INT16 buflen)
1653 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1655 dprintf_winsock(stddeb, "WS_AsyncGetHostByAddr(%08x): hwnd %04x, msg %04x, addr %08x[%i]\n",
1656 (unsigned)pwsi, hWnd, uMsg, (unsigned)addr , len );
1658 if( pwsi )
1659 return __WSAsyncDBQuery(pwsi, hWnd, uMsg, type, addr, len,
1660 NULL, sbuf, buflen, WSMSG_ASYNC_HOSTBYADDR );
1661 return 0;
1665 /***********************************************************************
1666 * WSAAsyncGetHostByName() (WINSOCK.103)
1668 HANDLE16 WINAPI WSAAsyncGetHostByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
1669 SEGPTR sbuf, INT16 buflen)
1671 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1673 dprintf_winsock(stddeb, "WS_AsyncGetHostByName(%08x): hwnd %04x, msg %04x, host %s, buffer %i\n",
1674 (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (int)buflen );
1676 if( pwsi )
1677 return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
1678 NULL, sbuf, buflen, WSMSG_ASYNC_HOSTBYNAME );
1679 return 0;
1683 /***********************************************************************
1684 * WSAAsyncGetProtoByName() (WINSOCK.105)
1686 HANDLE16 WINAPI WSAAsyncGetProtoByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
1687 SEGPTR sbuf, INT16 buflen)
1689 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1691 dprintf_winsock(stddeb, "WS_AsyncGetProtoByName(%08x): hwnd %04x, msg %04x, protocol %s\n",
1692 (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING );
1694 if( pwsi )
1695 return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
1696 NULL, sbuf, buflen, WSMSG_ASYNC_PROTOBYNAME );
1697 return 0;
1701 /***********************************************************************
1702 * WSAAsyncGetProtoByNumber() (WINSOCK.104)
1704 HANDLE16 WINAPI WSAAsyncGetProtoByNumber(HWND16 hWnd, UINT16 uMsg, INT16 number,
1705 SEGPTR sbuf, INT16 buflen)
1707 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1709 dprintf_winsock(stddeb, "WS_AsyncGetProtoByNumber(%08x): hwnd %04x, msg %04x, num %i\n",
1710 (unsigned)pwsi, hWnd, uMsg, number );
1712 if( pwsi )
1713 return __WSAsyncDBQuery(pwsi, hWnd, uMsg, number, NULL, 0,
1714 NULL, sbuf, buflen, WSMSG_ASYNC_PROTOBYNUM );
1715 return 0;
1719 /***********************************************************************
1720 * WSAAsyncGetServByName() (WINSOCK.107)
1722 HANDLE16 WINAPI WSAAsyncGetServByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
1723 LPCSTR proto, SEGPTR sbuf, INT16 buflen)
1725 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1727 dprintf_winsock(stddeb, "WS_AsyncGetServByName(%08x): hwnd %04x, msg %04x, name %s, proto %s\n",
1728 (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
1730 if( pwsi )
1731 return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
1732 proto, sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
1733 return 0;
1736 /***********************************************************************
1737 * WSAAsyncGetServByPort() (WINSOCK.106)
1739 HANDLE16 WINAPI WSAAsyncGetServByPort(HWND16 hWnd, UINT16 uMsg, INT16 port,
1740 LPCSTR proto, SEGPTR sbuf, INT16 buflen)
1742 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1744 dprintf_winsock(stddeb, "WS_AsyncGetServByPort(%08x): hwnd %04x, msg %04x, port %i, proto %s\n",
1745 (unsigned)pwsi, hWnd, uMsg, port, (proto)?proto:NULL_STRING );
1747 if( pwsi )
1748 return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
1749 NULL, sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
1750 return 0;
1753 /***********************************************************************
1754 * WSACancelAsyncRequest() (WINSOCK.108)
1756 INT16 WINAPI WSACancelAsyncRequest(HANDLE16 hAsyncTaskHandle)
1758 INT16 retVal = SOCKET_ERROR;
1759 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1760 ws_async_op* p_aop = (ws_async_op*)WS_HANDLE2PTR(hAsyncTaskHandle);
1762 dprintf_winsock(stddeb, "WS_CancelAsyncRequest(%08x): handle %04x\n",
1763 (unsigned)pwsi, hAsyncTaskHandle);
1764 if( pwsi )
1766 SIGNAL_MaskAsyncEvents( TRUE ); /* block SIGIO */
1767 if( WINSOCK_cancel_async_op(p_aop) )
1769 WS_FREE(p_aop);
1770 pwsi->num_async_rq--;
1771 retVal = 0;
1773 else pwsi->err = WSAEINVAL;
1774 SIGNAL_MaskAsyncEvents( FALSE );
1776 return retVal;
1779 /***********************************************************************
1780 * WSAAsyncSelect() (WINSOCK.101)
1783 static ws_select_op* __ws_select_list = NULL;
1785 BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] )
1787 /* This function is called by the event dispatcher
1788 * with io_set containing the result of select() */
1790 ws_select_op* psop = __ws_select_list;
1791 BOOL32 bPost = FALSE;
1792 DWORD dwEvent, dwErrBytes;
1793 int num_posted;
1795 dprintf_winsock(stddeb,"WINSOCK_HandleIO: %i pending descriptors\n", num_pending );
1797 for( num_posted = dwEvent = 0 ; psop; psop = psop->next )
1799 unsigned flags = psop->pws->flags;
1800 int fd = psop->pws->fd;
1801 int r, w, e;
1803 w = 0;
1804 if( (r = FD_ISSET( fd, &io_set[EVENT_IO_READ] )) ||
1805 (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] )) ||
1806 (e = FD_ISSET( fd, &io_set[EVENT_IO_EXCEPT] )) )
1808 /* This code removes WS_FD flags on one-shot events (WS_FD_CLOSE,
1809 * WS_FD_CONNECT), otherwise it clears descriptors in the io_set.
1810 * Reenabling calls turn them back on.
1813 dprintf_winsock(stddeb,"\tchecking psop = 0x%08x\n", (unsigned) psop );
1815 num_pending--;
1817 /* Now figure out what kind of event we've got. The worst problem
1818 * we have to contend with is that some out of control applications
1819 * really want to use mutually exclusive AsyncSelect() flags all at
1820 * the same time.
1823 if((flags & WS_FD_ACCEPT) && (flags & WS_FD_LISTENING))
1825 /* WS_FD_ACCEPT is valid only if the socket is in the
1826 * listening state */
1828 FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
1829 if( r )
1831 FD_CLR( fd, &io_set[EVENT_IO_READ] ); /* reenabled by the next accept() */
1832 dwEvent = WSAMAKESELECTREPLY( WS_FD_ACCEPT, 0 );
1833 bPost = TRUE;
1835 else continue;
1837 else if( flags & WS_FD_CONNECT )
1839 /* connecting socket */
1841 if( w || (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] )) )
1843 /* ready to write means that socket is connected */
1845 psop->pws->flags |= WS_FD_CONNECTED;
1846 psop->pws->flags &= ~(WS_FD_CONNECT | WS_FD_INACTIVE);
1847 dwEvent = WSAMAKESELECTREPLY( WS_FD_CONNECT, 0 );
1849 if( flags & (WS_FD_READ | WS_FD_CLOSE))
1850 FD_SET( fd, &io_set[EVENT_IO_READ] );
1851 else
1852 FD_CLR( fd, &io_set[EVENT_IO_READ] );
1853 if( flags & WS_FD_WRITE )
1854 FD_SET( fd, &io_set[EVENT_IO_WRITE] );
1855 else
1856 FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
1857 bPost = TRUE;
1859 else if( r )
1861 /* failure - do read() to get correct errno */
1863 if( read( fd, &dwErrBytes, sizeof(dwErrBytes) ) == -1 )
1865 dwEvent = WSAMAKESELECTREPLY( WS_FD_CONNECT, wsaErrno() );
1866 bPost = TRUE;
1869 /* otherwise bPost stays FALSE */
1871 else
1873 /* connected socket --
1874 * removed WS_FD_OOB code for now.
1877 if( flags & WS_FD_WRITE &&
1878 (w || (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] ))) )
1880 /* this will be reenabled when send() or sendto() fail with
1881 * WSAEWOULDBLOCK */
1883 if( PostMessage16( psop->hWnd, psop->uMsg, (WPARAM16)WS_PTR2HANDLE(psop->pws),
1884 (LPARAM)WSAMAKESELECTREPLY( WS_FD_WRITE, 0 ) ) )
1886 dprintf_winsock(stddeb, "\t hwnd %04x - %04x, %08x\n",
1887 psop->hWnd, psop->uMsg, (unsigned)MAKELONG(WS_FD_WRITE, 0) );
1888 FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
1889 num_posted++;
1893 if( r && (flags & (WS_FD_READ | WS_FD_CLOSE)) )
1895 int val = (flags & WS_FD_RAW);
1897 /* WS_FD_RAW is set by the WSAAsyncSelect() init */
1899 bPost = TRUE;
1900 if( !val && ioctl( fd, FIONREAD, (char*)&dwErrBytes) == -1 )
1902 /* weirdness */
1904 dwEvent = WSAMAKESELECTREPLY( WS_FD_READ, wsaErrno() );
1906 else if( val || dwErrBytes )
1908 /* got pending data, will be reenabled by recv() or recvfrom() */
1910 FD_CLR( fd, &io_set[EVENT_IO_READ] );
1911 dwEvent = WSAMAKESELECTREPLY( WS_FD_READ, 0 );
1913 else
1915 /* 0 bytes to read - connection reset by peer? */
1918 val = read( fd, (char*)&dwErrBytes, sizeof(dwErrBytes));
1919 while( errno == EINTR );
1920 if( errno != EWOULDBLOCK )
1922 switch( val )
1924 case 0: errno = ENETDOWN; /* soft reset, fall through */
1925 case -1: /* hard reset */
1926 dwEvent = WSAMAKESELECTREPLY( WS_FD_CLOSE, wsaErrno() );
1927 break;
1929 default: bPost = FALSE;
1930 continue; /* FIXME: this is real bad */
1933 else { bPost = FALSE; continue; } /* more weirdness */
1935 /* this is it, this socket is closed */
1937 psop->pws->flags &= ~(WS_FD_READ | WS_FD_CLOSE | WS_FD_WRITE);
1938 FD_CLR( fd, &io_set[EVENT_IO_READ] );
1939 FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
1941 if( *max_fd == (fd + 1) ) (*max_fd)--;
1946 if( bPost )
1948 dprintf_winsock(stddeb, "\t hwnd %04x - %04x, %08x\n",
1949 psop->hWnd, psop->uMsg, (unsigned)dwEvent );
1950 PostMessage16( psop->hWnd, psop->uMsg,
1951 (WPARAM16)WS_PTR2HANDLE(psop->pws), (LPARAM)dwEvent );
1952 bPost = FALSE;
1953 num_posted++;
1956 if( num_pending <= 0 ) break;
1959 dprintf_winsock(stddeb, "\tdone, %i posted events\n", num_posted );
1960 return ( num_posted ) ? TRUE : FALSE;
1964 INT16 WINAPI WSAAsyncSelect(SOCKET16 s, HWND16 hWnd, UINT16 uMsg, UINT32 lEvent)
1966 ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
1967 LPWSINFO pwsi = wsi_find(GetCurrentTask());
1969 dprintf_winsock(stddeb, "WS_AsyncSelect(%08x): %04x, hWnd %04x, uMsg %04x, event %08x\n",
1970 (unsigned)pwsi, s, hWnd, uMsg, (unsigned)lEvent );
1971 if( _check_ws(pwsi, pws) )
1973 ws_select_op* psop;
1975 if( (psop = pws->psop) )
1977 /* delete previous control struct */
1979 if( psop == __ws_select_list )
1980 __ws_select_list = psop->next;
1981 else
1982 psop->prev->next = psop->next;
1983 if( psop->next ) psop->next->prev = psop->prev;
1985 if( pws->flags & (WS_FD_ACCEPT | WS_FD_CONNECT | WS_FD_READ | WS_FD_CLOSE) )
1986 EVENT_DeleteIO( pws->fd, EVENT_IO_READ );
1987 if( pws->flags & (WS_FD_CONNECT | WS_FD_WRITE) )
1988 EVENT_DeleteIO( pws->fd, EVENT_IO_WRITE );
1990 dprintf_winsock(stddeb,"\tremoving psop = 0x%08x\n", (unsigned) psop );
1992 WS_FREE( pws->psop );
1993 pws->flags &= ~(WS_FD_RAW | WS_FD_ACCEPT | WS_FD_CONNECT |
1994 WS_FD_READ | WS_FD_WRITE | WS_FD_CLOSE);
1995 pws->psop = NULL;
1998 if( lEvent )
2000 psop = (ws_select_op*)WS_ALLOC(sizeof(ws_select_op));
2001 if( psop )
2003 int sock_type, bytes = sizeof(int);
2005 WINSOCK_unblock_io( pws->fd, TRUE );
2007 psop->prev = NULL;
2008 psop->next = __ws_select_list;
2009 if( __ws_select_list )
2010 __ws_select_list->prev = psop;
2011 __ws_select_list = psop;
2013 psop->pws = pws;
2014 psop->hWnd = hWnd;
2015 psop->uMsg = uMsg;
2017 pws->psop = psop;
2018 pws->flags |= (0x0000FFFF &lEvent);
2019 getsockopt(pws->fd, SOL_SOCKET, SO_TYPE, &sock_type, &bytes);
2020 if( sock_type == SOCK_RAW ) pws->flags |= WS_FD_RAW;
2022 if( lEvent & (WS_FD_ACCEPT | WS_FD_CONNECT | WS_FD_READ | WS_FD_CLOSE) )
2023 EVENT_AddIO( pws->fd, EVENT_IO_READ );
2024 if( lEvent & (WS_FD_CONNECT | WS_FD_WRITE) )
2025 EVENT_AddIO( pws->fd, EVENT_IO_WRITE );
2027 /* TODO: handle WS_FD_ACCEPT right away if the socket is readable */
2029 dprintf_winsock(stddeb,"\tcreating psop = 0x%08x\n", (unsigned)psop );
2031 return 0; /* success */
2033 else pwsi->err = WSAENOBUFS;
2035 else return 0;
2037 else if( pwsi ) pwsi->err = WSAEINVAL;
2038 return SOCKET_ERROR;
2042 /***********************************************************************
2043 * __WSAFDIsSet() (WINSOCK.151)
2045 INT16 WINAPI __WSAFDIsSet16(SOCKET16 s, ws_fd_set *set)
2047 int i = set->fd_count;
2049 dprintf_winsock(stddeb, "__WSAFDIsSet(%d,%8lx)\n", s,(unsigned long)set);
2051 while (i--)
2052 if (set->fd_array[i] == s) return 1;
2053 return 0;
2056 /***********************************************************************
2057 * __WSAFDIsSet() (WSOCK32.151)
2059 INT32 WINAPI __WSAFDIsSet32(SOCKET32 s, ws_fd_set *set)
2061 return __WSAFDIsSet16( (SOCKET16)s, set );
2064 /***********************************************************************
2065 * WSAIsBlocking() (WINSOCK.114)(WSOCK32.114)
2067 BOOL32 WINAPI WSAIsBlocking(void)
2069 /* By default WinSock should set all its sockets to non-blocking mode
2070 * and poll in PeekMessage loop when processing "blocking" ones. This
2071 * function is supposed to tell if program is in this loop. Our
2072 * blocking calls are truly blocking so we always return FALSE.
2074 * Note: It is allowed to call this function without prior WSAStartup().
2077 dprintf_winsock(stddeb, "WS_IsBlocking()\n");
2078 return FALSE;
2081 /***********************************************************************
2082 * WSACancelBlockingCall() (WINSOCK.113)(WSOCK32.113)
2084 INT32 WINAPI WSACancelBlockingCall(void)
2086 LPWSINFO pwsi = wsi_find(GetCurrentTask());
2088 dprintf_winsock(stddeb, "WS_CancelBlockingCall(%08x)\n", (unsigned)pwsi);
2090 if( pwsi ) return 0;
2091 return SOCKET_ERROR;
2095 /***********************************************************************
2096 * WSASetBlockingHook16() (WINSOCK.109)
2098 FARPROC16 WINAPI WSASetBlockingHook16(FARPROC16 lpBlockFunc)
2100 FARPROC16 prev;
2101 LPWSINFO pwsi = wsi_find(GetCurrentTask());
2103 dprintf_winsock(stddeb, "WS_SetBlockingHook16(%08x): hook %08x\n",
2104 (unsigned)pwsi, (unsigned) lpBlockFunc);
2105 if( pwsi )
2107 prev = (FARPROC16)pwsi->blocking_hook;
2108 pwsi->blocking_hook = (DWORD)lpBlockFunc;
2109 pwsi->flags &= ~WSI_BLOCKINGHOOK32;
2110 return prev;
2112 return 0;
2116 /***********************************************************************
2117 * WSASetBlockingHook32()
2119 FARPROC32 WINAPI WSASetBlockingHook32(FARPROC32 lpBlockFunc)
2121 FARPROC32 prev;
2122 LPWSINFO pwsi = wsi_find(GetCurrentTask());
2124 dprintf_winsock(stddeb, "WS_SetBlockingHook32(%08x): hook %08x\n",
2125 (unsigned)pwsi, (unsigned) lpBlockFunc);
2126 if( pwsi ) {
2127 prev = (FARPROC32)pwsi->blocking_hook;
2128 pwsi->blocking_hook = (DWORD)lpBlockFunc;
2129 pwsi->flags |= WSI_BLOCKINGHOOK32;
2130 return prev;
2132 return NULL;
2136 /***********************************************************************
2137 * WSAUnhookBlockingHook16() (WINSOCK.110)
2139 INT16 WINAPI WSAUnhookBlockingHook16(void)
2141 LPWSINFO pwsi = wsi_find(GetCurrentTask());
2143 dprintf_winsock(stddeb, "WS_UnhookBlockingHook16(%08x)\n", (unsigned)pwsi);
2144 if( pwsi ) return (INT16)(pwsi->blocking_hook = 0);
2145 return SOCKET_ERROR;
2149 /***********************************************************************
2150 * WSAUnhookBlockingHook32()
2152 INT32 WINAPI WSAUnhookBlockingHook32(void)
2154 LPWSINFO pwsi = wsi_find(GetCurrentTask());
2156 dprintf_winsock(stddeb, "WS_UnhookBlockingHook32(%08x)\n", (unsigned)pwsi);
2157 if( pwsi )
2159 pwsi->blocking_hook = 0;
2160 pwsi->flags &= ~WSI_BLOCKINGHOOK32;
2161 return 0;
2163 return SOCKET_ERROR;
2166 /***********************************************************************
2167 * WsControl()
2169 VOID WINAPI WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,
2170 LPDWORD x5,LPDWORD x6)
2172 fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p)\n",
2173 x1,x2,x3,x4,x5,x6
2175 fprintf(stdnimp,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",
2176 x3?*x3:0,x4?*x4:0,x5?*x5:0,x6?*x6:0
2178 return;
2180 /* ----------------------------------- end of API stuff */
2184 /* ----------------------------------- helper functions */
2186 static int list_size(char** l, int item_size)
2188 int i,j = 0;
2189 if(l)
2190 { for(i=0;l[i];i++)
2191 j += (item_size) ? item_size : strlen(l[i]) + 1;
2192 j += (i + 1) * sizeof(char*); }
2193 return j;
2196 static int list_dup(char** l_src, char* ref, char* base, int item_size)
2198 /* base is either either equal to ref or 0 or SEGPTR */
2200 char* p = ref;
2201 char** l_to = (char**)ref;
2202 int i,j,k;
2204 for(j=0;l_src[j];j++) ;
2205 p += (j + 1) * sizeof(char*);
2206 for(i=0;i<j;i++)
2207 { l_to[i] = base + (p - ref);
2208 k = ( item_size ) ? item_size : strlen(l_src[i]) + 1;
2209 memcpy(p, l_src[i], k); p += k; }
2210 l_to[i] = NULL;
2211 return (p - ref);
2214 /* ----- hostent */
2216 static int hostent_size(struct hostent* p_he)
2218 int size = 0;
2219 if( p_he )
2220 { size = sizeof(struct hostent);
2221 size += strlen(p_he->h_name) + 1;
2222 size += list_size(p_he->h_aliases, 0);
2223 size += list_size(p_he->h_addr_list, p_he->h_length ); }
2224 return size;
2227 int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag)
2229 /* Duplicate hostent structure and flatten data (with its pointers)
2230 * into pwsi->buffer. Internal pointers can be linear, SEGPTR, or
2231 * relative to pwsi->buffer depending on "flag" value. Returns size
2232 * of the data copied (also in the pwsi->buflen).
2235 int size = hostent_size(p_he);
2236 if( size )
2238 char* p_name,*p_aliases,*p_addr,*p_base,*p;
2240 _check_buffer(pwsi, size);
2241 p = pwsi->buffer;
2242 p_base = (flag & WS_DUP_OFFSET) ? NULL
2243 : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
2244 p += (flag & WS_DUP_NATIVE) ? sizeof(struct hostent) : sizeof(struct ws_hostent);
2245 p_name = p;
2246 strcpy(p, p_he->h_name); p += strlen(p) + 1;
2247 p_aliases = p;
2248 p += list_dup(p_he->h_aliases, p, p_base + (p - pwsi->buffer), 0);
2249 p_addr = p;
2250 list_dup(p_he->h_addr_list, p, p_base + (p - pwsi->buffer), p_he->h_length);
2251 if( flag & WS_DUP_NATIVE )
2252 { struct hostent* p_to = (struct hostent*)pwsi->buffer;
2253 p_to->h_addrtype = p_he->h_addrtype; p_to->h_length = p_he->h_length;
2254 p_to->h_name = p_base + (p_name - pwsi->buffer);
2255 p_to->h_aliases = (char**)(p_base + (p_aliases - pwsi->buffer));
2256 p_to->h_addr_list = (char**)(p_base + (p_addr - pwsi->buffer)); }
2257 else
2258 { struct ws_hostent* p_to = (struct ws_hostent*)pwsi->buffer;
2259 p_to->h_addrtype = (INT16)p_he->h_addrtype;
2260 p_to->h_length = (INT16)p_he->h_length;
2261 p_to->h_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
2262 p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
2263 p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - pwsi->buffer));
2265 return (size + sizeof(struct ws_hostent) - sizeof(struct hostent)); }
2267 return size;
2270 /* ----- protoent */
2272 static int protoent_size(struct protoent* p_pe)
2274 int size = 0;
2275 if( p_pe )
2276 { size = sizeof(struct protoent);
2277 size += strlen(p_pe->p_name) + 1;
2278 size += list_size(p_pe->p_aliases, 0); }
2279 return size;
2282 int WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag)
2284 int size = protoent_size(p_pe);
2285 if( size )
2287 char* p_name,*p_aliases,*p_base,*p;
2289 _check_buffer(pwsi, size);
2290 p = pwsi->buffer;
2291 p_base = (flag & WS_DUP_OFFSET) ? NULL
2292 : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
2293 p += (flag & WS_DUP_NATIVE)? sizeof(struct protoent) : sizeof(struct ws_protoent);
2294 p_name = p;
2295 strcpy(p, p_pe->p_name); p += strlen(p) + 1;
2296 p_aliases = p;
2297 list_dup(p_pe->p_aliases, p, p_base + (p - pwsi->buffer), 0);
2298 if( flag & WS_DUP_NATIVE )
2299 { struct protoent* p_to = (struct protoent*)pwsi->buffer;
2300 p_to->p_proto = p_pe->p_proto;
2301 p_to->p_name = p_base + (p_name - pwsi->buffer);
2302 p_to->p_aliases = (char**)(p_base + (p_aliases - pwsi->buffer)); }
2303 else
2304 { struct ws_protoent* p_to = (struct ws_protoent*)pwsi->buffer;
2305 p_to->p_proto = (INT16)p_pe->p_proto;
2306 p_to->p_name = (SEGPTR)(p_base) + (p_name - pwsi->buffer);
2307 p_to->p_aliases = (SEGPTR)((p_base) + (p_aliases - pwsi->buffer));
2308 return (size + sizeof(struct ws_protoent) - sizeof(struct protoent)); }
2310 return size;
2313 /* ----- servent */
2315 static int servent_size(struct servent* p_se)
2317 int size = 0;
2318 if( p_se )
2319 { size += sizeof(struct servent);
2320 size += strlen(p_se->s_proto) + strlen(p_se->s_name) + 2;
2321 size += list_size(p_se->s_aliases, 0); }
2322 return size;
2325 int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag)
2327 int size = servent_size(p_se);
2328 if( size )
2330 char* p_name,*p_aliases,*p_proto,*p_base,*p;
2332 _check_buffer(pwsi, size);
2333 p = pwsi->buffer;
2334 p_base = (flag & WS_DUP_OFFSET) ? NULL
2335 : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
2336 p += (flag & WS_DUP_NATIVE)? sizeof(struct servent) : sizeof(struct ws_servent);
2337 p_name = p;
2338 strcpy(p, p_se->s_name); p += strlen(p) + 1;
2339 p_proto = p;
2340 strcpy(p, p_se->s_proto); p += strlen(p) + 1;
2341 p_aliases = p;
2342 list_dup(p_se->s_aliases, p, p_base + (p - pwsi->buffer), 0);
2344 if( flag & WS_DUP_NATIVE )
2345 { struct servent* p_to = (struct servent*)pwsi->buffer;
2346 p_to->s_port = p_se->s_port;
2347 p_to->s_name = p_base + (p_name - pwsi->buffer);
2348 p_to->s_proto = p_base + (p_proto - pwsi->buffer);
2349 p_to->s_aliases = (char**)(p_base + (p_aliases - pwsi->buffer)); }
2350 else
2351 { struct ws_servent* p_to = (struct ws_servent*)pwsi->buffer;
2352 p_to->s_port = (INT16)p_se->s_port;
2353 p_to->s_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
2354 p_to->s_proto = (SEGPTR)(p_base + (p_proto - pwsi->buffer));
2355 p_to->s_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
2356 return (size + sizeof(struct ws_servent) - sizeof(struct servent)); }
2358 return size;
2361 /* ----------------------------------- error handling */
2363 UINT16 wsaErrno(void)
2365 int loc_errno = errno;
2366 #if defined(__FreeBSD__)
2367 dprintf_winsock(stderr, "winsock: errno %d, (%s).\n",
2368 errno, sys_errlist[errno]);
2369 #else
2370 dprintf_winsock(stderr, "winsock: errno %d\n", errno);
2371 #endif
2373 switch(loc_errno)
2375 case EINTR: return WSAEINTR;
2376 case EBADF: return WSAEBADF;
2377 case EACCES: return WSAEACCES;
2378 case EFAULT: return WSAEFAULT;
2379 case EINVAL: return WSAEINVAL;
2380 case EMFILE: return WSAEMFILE;
2381 case EWOULDBLOCK: return WSAEWOULDBLOCK;
2382 case EINPROGRESS: return WSAEINPROGRESS;
2383 case EALREADY: return WSAEALREADY;
2384 case ENOTSOCK: return WSAENOTSOCK;
2385 case EDESTADDRREQ: return WSAEDESTADDRREQ;
2386 case EMSGSIZE: return WSAEMSGSIZE;
2387 case EPROTOTYPE: return WSAEPROTOTYPE;
2388 case ENOPROTOOPT: return WSAENOPROTOOPT;
2389 case EPROTONOSUPPORT: return WSAEPROTONOSUPPORT;
2390 case ESOCKTNOSUPPORT: return WSAESOCKTNOSUPPORT;
2391 case EOPNOTSUPP: return WSAEOPNOTSUPP;
2392 case EPFNOSUPPORT: return WSAEPFNOSUPPORT;
2393 case EAFNOSUPPORT: return WSAEAFNOSUPPORT;
2394 case EADDRINUSE: return WSAEADDRINUSE;
2395 case EADDRNOTAVAIL: return WSAEADDRNOTAVAIL;
2396 case ENETDOWN: return WSAENETDOWN;
2397 case ENETUNREACH: return WSAENETUNREACH;
2398 case ENETRESET: return WSAENETRESET;
2399 case ECONNABORTED: return WSAECONNABORTED;
2400 case ECONNRESET: return WSAECONNRESET;
2401 case ENOBUFS: return WSAENOBUFS;
2402 case EISCONN: return WSAEISCONN;
2403 case ENOTCONN: return WSAENOTCONN;
2404 case ESHUTDOWN: return WSAESHUTDOWN;
2405 case ETOOMANYREFS: return WSAETOOMANYREFS;
2406 case ETIMEDOUT: return WSAETIMEDOUT;
2407 case ECONNREFUSED: return WSAECONNREFUSED;
2408 case ELOOP: return WSAELOOP;
2409 case ENAMETOOLONG: return WSAENAMETOOLONG;
2410 case EHOSTDOWN: return WSAEHOSTDOWN;
2411 case EHOSTUNREACH: return WSAEHOSTUNREACH;
2412 case ENOTEMPTY: return WSAENOTEMPTY;
2413 #ifdef EPROCLIM
2414 case EPROCLIM: return WSAEPROCLIM;
2415 #endif
2416 #ifdef EUSERS
2417 case EUSERS: return WSAEUSERS;
2418 #endif
2419 #ifdef EDQUOT
2420 case EDQUOT: return WSAEDQUOT;
2421 #endif
2422 #ifdef ESTALE
2423 case ESTALE: return WSAESTALE;
2424 #endif
2425 #ifdef EREMOTE
2426 case EREMOTE: return WSAEREMOTE;
2427 #endif
2429 /* just in case we ever get here and there are no problems */
2430 case 0: return 0;
2431 default:
2432 fprintf(stderr, "winsock: unknown errno %d!\n", errno);
2433 return WSAEOPNOTSUPP;
2437 UINT16 wsaHerrno(void)
2439 int loc_errno = h_errno;
2441 #if defined(__FreeBSD__)
2442 dprintf_winsock(stderr, "winsock: h_errno %d, (%s).\n",
2443 h_errno, sys_errlist[h_errno]);
2444 #else
2445 dprintf_winsock(stderr, "winsock: h_errno %d.\n", h_errno);
2446 #ifndef sun
2447 if( debugging_winsock ) herror("wine: winsock: wsaherrno");
2448 #endif
2449 #endif
2451 switch(loc_errno)
2453 case HOST_NOT_FOUND: return WSAHOST_NOT_FOUND;
2454 case TRY_AGAIN: return WSATRY_AGAIN;
2455 case NO_RECOVERY: return WSANO_RECOVERY;
2456 case NO_DATA: return WSANO_DATA;
2458 case 0: return 0;
2459 default:
2460 fprintf(stderr, "winsock: unknown h_errno %d!\n", h_errno);
2461 return WSAEOPNOTSUPP;