2 * based on Windows Sockets 1.1 specs
3 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
5 * (C) 1993,1994 John Brezak, Erik Bos.
11 #include <sys/types.h>
13 #include <sys/ioctl.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
27 static WORD wsa_errno
;
28 static int wsa_initted
;
29 static key_t wine_key
= 0;
30 static FARPROC BlockFunction
;
31 static fd_set fd_in_use
;
45 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
46 #define MTYPE 0xb0b0eb05
48 /* These structures are Win16 only */
51 SEGPTR h_name WINE_PACKED
; /* official name of host */
52 SEGPTR h_aliases WINE_PACKED
; /* alias list */
53 INT h_addrtype WINE_PACKED
; /* host address type */
54 INT h_length WINE_PACKED
; /* length of address */
55 char **h_addr_list WINE_PACKED
; /* list of addresses from name server */
61 SEGPTR p_name WINE_PACKED
; /* official protocol name */
62 SEGPTR p_aliases WINE_PACKED
; /* alias list */
63 INT p_proto WINE_PACKED
; /* protocol # */
67 SEGPTR s_name WINE_PACKED
; /* official service name */
68 SEGPTR s_aliases WINE_PACKED
; /* alias list */
69 INT s_port WINE_PACKED
; /* port # */
70 SEGPTR s_proto WINE_PACKED
; /* protocol to use */
76 struct WIN_hostent hostent_addr
;
77 struct WIN_hostent hostent_name
;
78 struct WIN_protoent protoent_name
;
79 struct WIN_protoent protoent_number
;
80 struct WIN_servent servent_name
;
81 struct WIN_servent servent_port
;
83 struct WIN_hostent WSAhostent_addr
;
84 struct WIN_hostent WSAhostent_name
;
85 struct WIN_protoent WSAprotoent_name
;
86 struct WIN_protoent WSAprotoent_number
;
87 struct WIN_servent WSAservent_name
;
88 struct WIN_servent WSAservent_port
;
89 /* 8K scratch buffer for aliases and friends are hopefully enough */
92 static struct WinSockHeap
*Heap
;
93 static int HeapHandle
;
94 static int ScratchPtr
;
97 #define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
98 GlobalHandleToSel(HeapHandle))
100 #define GET_SEG_PTR(x) (x)
107 #define dump_sockaddr(a) \
108 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
109 ((struct sockaddr_in *)a)->sin_family, \
110 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
111 ntohs(((struct sockaddr_in *)a)->sin_port))
113 static void ResetScratch()
118 static void *scratch_alloc(int size
)
121 if(ScratchPtr
+size
> sizeof(Heap
->scratch
))
123 ret
= Heap
->scratch
+ ScratchPtr
;
128 static SEGPTR
scratch_strdup(char * s
)
130 char *ret
=scratch_alloc(strlen(s
)+1);
132 return GET_SEG_PTR(ret
);
135 static WORD
wsaerrno(void)
139 #if defined(__FreeBSD__)
140 fprintf(stderr
, "winsock: errno %d, (%s).\n",
141 errno
, sys_errlist
[errno
]);
143 fprintf(stderr
, "winsock: errno %d, (%s).\n",
144 errno
, strerror(errno
));
147 fprintf(stderr
, "winsock: errno %d\n", errno
);
153 case EINTR
: return WSAEINTR
;
154 case EACCES
: return WSAEACCES
;
155 case EFAULT
: return WSAEFAULT
;
156 case EINVAL
: return WSAEINVAL
;
157 case EMFILE
: return WSAEMFILE
;
158 case EWOULDBLOCK
: return WSAEWOULDBLOCK
;
159 case EINPROGRESS
: return WSAEINPROGRESS
;
160 case EALREADY
: return WSAEALREADY
;
162 case ENOTSOCK
: return WSAENOTSOCK
;
163 case EDESTADDRREQ
: return WSAEDESTADDRREQ
;
164 case EMSGSIZE
: return WSAEMSGSIZE
;
165 case EPROTOTYPE
: return WSAEPROTOTYPE
;
166 case ENOPROTOOPT
: return WSAENOPROTOOPT
;
167 case EPROTONOSUPPORT
: return WSAEPROTONOSUPPORT
;
168 case ESOCKTNOSUPPORT
: return WSAESOCKTNOSUPPORT
;
169 case EOPNOTSUPP
: return WSAEOPNOTSUPP
;
170 case EPFNOSUPPORT
: return WSAEPFNOSUPPORT
;
171 case EAFNOSUPPORT
: return WSAEAFNOSUPPORT
;
172 case EADDRINUSE
: return WSAEADDRINUSE
;
173 case EADDRNOTAVAIL
: return WSAEADDRNOTAVAIL
;
174 case ENETDOWN
: return WSAENETDOWN
;
175 case ENETUNREACH
: return WSAENETUNREACH
;
176 case ENETRESET
: return WSAENETRESET
;
177 case ECONNABORTED
: return WSAECONNABORTED
;
178 case ECONNRESET
: return WSAECONNRESET
;
179 case ENOBUFS
: return WSAENOBUFS
;
180 case EISCONN
: return WSAEISCONN
;
181 case ENOTCONN
: return WSAENOTCONN
;
182 case ESHUTDOWN
: return WSAESHUTDOWN
;
183 case ETOOMANYREFS
: return WSAETOOMANYREFS
;
184 case ETIMEDOUT
: return WSAETIMEDOUT
;
185 case ECONNREFUSED
: return WSAECONNREFUSED
;
186 case ELOOP
: return WSAELOOP
;
187 case ENAMETOOLONG
: return WSAENAMETOOLONG
;
188 case EHOSTDOWN
: return WSAEHOSTDOWN
;
189 case EHOSTUNREACH
: return WSAEHOSTUNREACH
;
190 case ENOTEMPTY
: return WSAENOTEMPTY
;
192 case EPROCLIM
: return WSAEPROCLIM
;
194 case EUSERS
: return WSAEUSERS
;
195 case EDQUOT
: return WSAEDQUOT
;
196 case ESTALE
: return WSAESTALE
;
197 case EREMOTE
: return WSAEREMOTE
;
200 fprintf(stderr
, "winsock: unknown errorno %d!\n", errno
);
201 return WSAEOPNOTSUPP
;
205 static void errno_to_wsaerrno(void)
207 wsa_errno
= wsaerrno();
210 static void convert_sockopt(INT
*level
, INT
*optname
)
212 /* $%#%!@! why couldn't they use the same values for both winsock and unix ? */
218 case 0x01: *optname
= SO_DEBUG
;
220 case 0x04: *optname
= SO_REUSEADDR
;
222 case 0x08: *optname
= SO_KEEPALIVE
;
224 case 0x10: *optname
= SO_DONTROUTE
;
226 case 0x20: *optname
= SO_BROADCAST
;
228 case 0x80: *optname
= SO_LINGER
;
230 case 0x100: *optname
= SO_OOBINLINE
;
232 case 0x1001: *optname
= SO_SNDBUF
;
234 case 0x1002: *optname
= SO_RCVBUF
;
236 case 0x1007: *optname
= SO_ERROR
;
238 case 0x1008: *optname
= SO_TYPE
;
241 fprintf(stderr
, "convert_sockopt() unknown optname %d\n", *optname
);
245 case 6: *optname
= IPPROTO_TCP
;
250 static SEGPTR
copy_stringlist(char **list
)
256 s_list
= scratch_alloc(sizeof(SEGPTR
)*(i
+1));
259 void *copy
= scratch_alloc(strlen(list
[i
])+1);
260 strcpy(copy
,list
[i
]);
261 s_list
[i
]=GET_SEG_PTR(copy
);
264 return GET_SEG_PTR(s_list
);
268 static void CONVERT_HOSTENT(struct WIN_hostent
*heapent
, struct hostent
*host
)
273 strcpy(heapent
->hostname
,host
->h_name
);
274 heapent
->h_name
= GET_SEG_PTR(heapent
->hostname
);
275 /* Convert aliases. Have to create array with FAR pointers */
277 heapent
->h_aliases
= 0;
279 heapent
->h_aliases
= copy_stringlist(host
->h_aliases
);
281 heapent
->h_addrtype
= host
->h_addrtype
;
282 heapent
->h_length
= host
->h_length
;
283 for(i
=0;host
->h_addr_list
[i
];i
++)
285 addr_list
=scratch_alloc(sizeof(SEGPTR
)*(i
+1));
286 heapent
->h_addr_list
= GET_SEG_PTR(addr_list
);
287 for(i
=0;host
->h_addr_list
[i
];i
++)
289 void *addr
=scratch_alloc(host
->h_length
);
290 memcpy(addr
,host
->h_addr_list
[i
],host
->h_length
);
291 addr_list
[i
]=GET_SEG_PTR(addr
);
296 static void CONVERT_PROTOENT(struct WIN_protoent
*heapent
,
297 struct protoent
*proto
)
300 heapent
->p_name
= scratch_strdup(proto
->p_name
);
301 heapent
->p_aliases
=proto
->p_aliases
?
302 copy_stringlist(proto
->p_aliases
) : 0;
303 heapent
->p_proto
= proto
->p_proto
;
306 static void CONVERT_SERVENT(struct WIN_servent
*heapent
, struct servent
*serv
)
309 heapent
->s_name
= scratch_strdup(serv
->s_name
);
310 heapent
->s_aliases
= serv
->s_aliases
?
311 copy_stringlist(serv
->s_aliases
) : 0;
312 heapent
->s_port
= serv
->s_port
;
313 heapent
->s_proto
= scratch_strdup(serv
->s_proto
);
316 #define CONVERT_HOSTENT(a,b) memcpy(a, &b, sizeof(a))
317 #define CONVERT_PROTOENT(a,b) memcpy(a, &b, sizeof(a))
318 #define CONVERT_SERVENT(a,b) memcpy(a, &b, sizeof(a))
321 SOCKET
WINSOCK_accept(SOCKET s
, struct sockaddr
*addr
, INT
*addrlen
)
325 dprintf_winsock(stddeb
, "WSA_accept: socket %d, ptr %8x, length %d\n", s
, (int) addr
, *addrlen
);
327 if ((sock
= accept(s
, addr
, (int *) addrlen
)) < 0) {
329 return INVALID_SOCKET
;
334 INT
WINSOCK_bind(SOCKET s
, struct sockaddr
*name
, INT namelen
)
336 dprintf_winsock(stddeb
, "WSA_bind: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
339 if (bind(s
, name
, namelen
) < 0) {
346 INT
WINSOCK_closesocket(SOCKET s
)
348 dprintf_winsock(stddeb
, "WSA_closesocket: socket %d\n", s
);
350 FD_CLR(s
, &fd_in_use
);
359 INT
WINSOCK_connect(SOCKET s
, struct sockaddr
*name
, INT namelen
)
361 dprintf_winsock(stddeb
, "WSA_connect: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
364 if (connect(s
, name
, namelen
) < 0) {
371 INT
WINSOCK_getpeername(SOCKET s
, struct sockaddr
*name
, INT
*namelen
)
373 dprintf_winsock(stddeb
, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, *namelen
);
376 if (getpeername(s
, name
, (int *) namelen
) < 0) {
383 INT
WINSOCK_getsockname(SOCKET s
, struct sockaddr
*name
, INT
*namelen
)
385 dprintf_winsock(stddeb
, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, (int) *namelen
);
386 if (getsockname(s
, name
, (int *) namelen
) < 0) {
394 WINSOCK_getsockopt(SOCKET s
, INT level
, INT optname
, char *optval
, INT
*optlen
)
396 dprintf_winsock(stddeb
, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s
, level
, (int) optval
, (int) *optlen
);
397 convert_sockopt(&level
, &optname
);
399 if (getsockopt(s
, (int) level
, optname
, optval
, (int *) optlen
) < 0) {
406 u_long
WINSOCK_htonl(u_long hostlong
)
408 return( htonl(hostlong
) );
411 u_short
WINSOCK_htons(u_short hostshort
)
413 return( htons(hostshort
) );
416 u_long
WINSOCK_inet_addr(char *cp
)
418 return( inet_addr(cp
) );
421 char *WINSOCK_inet_ntoa(struct in_addr in
)
425 /* dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/
427 if ((s
= inet_ntoa(in
)) == NULL
) {
432 strncpy(Heap
->ntoa_buffer
, s
, sizeof(Heap
->ntoa_buffer
) );
434 return (char *) GET_SEG_PTR(&Heap
->ntoa_buffer
);
437 INT
WINSOCK_ioctlsocket(SOCKET s
, u_long cmd
, u_long
*argp
)
442 dprintf_winsock(stddeb
, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s
, cmd
, (int) argp
);
444 /* Why can't they all use the same ioctl numbers */
448 if(cmd
== _IOR('f',127,u_long
))
453 if(cmd
== _IOW('f',126,u_long
) || cmd
== _IOR('f',126,u_long
))
458 if(cmd
== _IOW('f',125,u_long
))
465 fprintf(stderr
,"Unknown winsock ioctl. Trying anyway\n");
467 dprintf_winsock(stddeb
,"Recognized as %s\n", ctlname
);
470 if (ioctl(s
, newcmd
, newargp
) < 0) {
477 INT
WINSOCK_listen(SOCKET s
, INT backlog
)
479 dprintf_winsock(stddeb
, "WSA_listen: socket %d, backlog %d\n", s
, backlog
);
481 if (listen(s
, backlog
) < 0) {
488 u_long
WINSOCK_ntohl(u_long netlong
)
490 return( ntohl(netlong
) );
493 u_short
WINSOCK_ntohs(u_short netshort
)
495 return( ntohs(netshort
) );
498 INT
WINSOCK_recv(SOCKET s
, char *buf
, INT len
, INT flags
)
502 dprintf_winsock(stddeb
, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s
, (int) buf
, len
, flags
);
504 if ((length
= recv(s
, buf
, len
, flags
)) < 0) {
511 INT
WINSOCK_recvfrom(SOCKET s
, char *buf
, INT len
, INT flags
,
512 struct sockaddr
*from
, int *fromlen
)
516 dprintf_winsock(stddeb
, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long)buf
, len
, flags
);
518 if ((length
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
)) < 0) {
525 INT
WINSOCK_select(INT nfds
, fd_set
*readfds
, fd_set
*writefds
,
526 fd_set
*exceptfds
, struct timeval
*timeout
)
528 dprintf_winsock(stddeb
, "WSA_select: fd # %d, ptr %8lx, ptr %8lx, ptr %8lX\n", nfds
, (unsigned long) readfds
, (unsigned long) writefds
, (unsigned long) exceptfds
);
530 return(select(nfds
, readfds
, writefds
, exceptfds
, timeout
));
533 INT
WINSOCK_send(SOCKET s
, char *buf
, INT len
, INT flags
)
537 dprintf_winsock(stddeb
, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
539 if ((length
= send(s
, buf
, len
, flags
)) < 0) {
546 INT
WINSOCK_sendto(SOCKET s
, char *buf
, INT len
, INT flags
,
547 struct sockaddr
*to
, INT tolen
)
551 dprintf_winsock(stddeb
, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
553 if ((length
= sendto(s
, buf
, len
, flags
, to
, tolen
)) < 0) {
560 INT
WINSOCK_setsockopt(SOCKET s
, INT level
, INT optname
, const char *optval
,
563 dprintf_winsock(stddeb
, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s
, level
, optname
, (int) optval
, optlen
);
564 convert_sockopt(&level
, &optname
);
566 if (setsockopt(s
, level
, optname
, optval
, optlen
) < 0) {
573 INT
WINSOCK_shutdown(SOCKET s
, INT how
)
575 dprintf_winsock(stddeb
, "WSA_shutdown: socket s %d, how %d\n", s
, how
);
577 if (shutdown(s
, how
) < 0) {
584 SOCKET
WINSOCK_socket(INT af
, INT type
, INT protocol
)
588 dprintf_winsock(stddeb
, "WSA_socket: af=%d type=%d protocol=%d\n", af
, type
, protocol
);
590 if ((sock
= socket(af
, type
, protocol
)) < 0) {
592 dprintf_winsock(stddeb
, "WSA_socket: failed !\n");
593 return INVALID_SOCKET
;
597 wsa_errno
= WSAEMFILE
;
598 return INVALID_SOCKET
;
601 FD_SET(sock
, &fd_in_use
);
603 dprintf_winsock(stddeb
, "WSA_socket: fd %d\n", sock
);
610 SEGPTR
WINSOCK_gethostbyaddr(const char *addr
, INT len
, INT type
)
612 struct hostent
*host
;
614 dprintf_winsock(stddeb
, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr
, len
, type
);
616 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
620 CONVERT_HOSTENT(&Heap
->hostent_addr
, host
);
622 return GET_SEG_PTR(&Heap
->hostent_addr
);
628 SEGPTR
WINSOCK_gethostbyname(const char *name
)
630 struct hostent
*host
;
632 dprintf_winsock(stddeb
, "WSA_gethostbyname: %s\n", name
);
634 if ((host
= gethostbyname(name
)) == NULL
) {
638 CONVERT_HOSTENT(&Heap
->hostent_name
, host
);
640 return GET_SEG_PTR(&Heap
->hostent_name
);
643 INT
WINSOCK_gethostname(char *name
, INT namelen
)
645 dprintf_winsock(stddeb
, "WSA_gethostname: name %s, len %d\n", name
, namelen
);
647 if (gethostname(name
, namelen
) < 0) {
655 struct WIN_protoent *
657 SEGPTR
WINSOCK_getprotobyname(char *name
)
659 struct protoent
*proto
;
661 dprintf_winsock(stddeb
, "WSA_getprotobyname: name %s\n", name
);
663 if ((proto
= getprotobyname(name
)) == NULL
) {
667 CONVERT_PROTOENT(&Heap
->protoent_name
, proto
);
669 return GET_SEG_PTR(&Heap
->protoent_name
);
673 struct WIN_protoent *
675 SEGPTR
WINSOCK_getprotobynumber(INT number
)
677 struct protoent
*proto
;
679 dprintf_winsock(stddeb
, "WSA_getprotobynumber: num %d\n", number
);
681 if ((proto
= getprotobynumber(number
)) == NULL
) {
685 CONVERT_PROTOENT(&Heap
->protoent_number
, proto
);
687 return GET_SEG_PTR(&Heap
->protoent_number
);
693 SEGPTR
WINSOCK_getservbyname(const char *name
, const char *proto
)
695 struct servent
*service
;
700 dprintf_winsock(stddeb
, "WSA_getservbyname: name %s, proto %s\n", name
, proto
);
702 if ((service
= getservbyname(name
, proto
)) == NULL
) {
706 CONVERT_SERVENT(&Heap
->servent_name
, service
);
708 return GET_SEG_PTR(&Heap
->servent_name
);
714 SEGPTR
WINSOCK_getservbyport(INT port
, const char *proto
)
716 struct servent
*service
;
718 dprintf_winsock(stddeb
, "WSA_getservbyport: port %d, name %s\n", port
, proto
);
720 if ((service
= getservbyport(port
, proto
)) == NULL
) {
724 CONVERT_SERVENT(&Heap
->servent_port
, service
);
726 return GET_SEG_PTR(&Heap
->servent_port
);
729 /******************** winsock specific functions ************************
732 static HANDLE new_handle
= 0;
734 static HANDLE
AllocWSAHandle(void)
739 static void recv_message(int sig
)
741 struct ipc_packet message
;
743 if (msgrcv(wine_key
, &message
, IPC_PACKET_SIZE
, MTYPE
, IPC_NOWAIT
) == -1)
744 perror("wine: msgrcv");
747 "WSA: PostMessage (hwnd %d, wMsg %d, wParam %d, lParam %ld)\n",
753 PostMessage(message
.hWnd
, message
.wMsg
, message
.handle
, message
.lParam
);
755 signal(SIGUSR1
, recv_message
);
759 static void send_message(HANDLE handle
, HWND hWnd
, u_int wMsg
, long lParam
)
761 struct ipc_packet message
;
763 message
.mtype
= MTYPE
;
764 message
.handle
= handle
;
767 message
.lParam
= lParam
;
770 "WSA: send (hwnd %d, wMsg %d, handle %d, lParam %ld)\n",
771 hWnd
, wMsg
, handle
, lParam
);
773 if (msgsnd(wine_key
, &message
, IPC_PACKET_SIZE
, IPC_NOWAIT
) == -1)
774 perror("wine: msgsnd");
776 kill(getppid(), SIGUSR1
);
780 HANDLE
WSAAsyncGetHostByAddr(HWND hWnd
, u_int wMsg
, const char *addr
,
781 INT len
, INT type
, char *buf
, INT buflen
)
784 struct hostent
*host
;
786 handle
= AllocWSAHandle();
791 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
792 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
795 memcpy(buf
, host
, buflen
);
796 send_message(hWnd
, wMsg
, handle
, 0);
802 HANDLE
WSAAsyncGetHostByName(HWND hWnd
, u_int wMsg
, const char *name
,
803 char *buf
, INT buflen
)
806 struct hostent
*host
;
808 handle
= AllocWSAHandle();
813 if ((host
= gethostbyname(name
)) == NULL
) {
814 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
817 memcpy(buf
, host
, buflen
);
818 send_message(hWnd
, wMsg
, handle
, 0);
824 HANDLE
WSAAsyncGetProtoByName(HWND hWnd
, u_int wMsg
, const char *name
,
825 char *buf
, INT buflen
)
828 struct protoent
*proto
;
830 handle
= AllocWSAHandle();
835 if ((proto
= getprotobyname(name
)) == NULL
) {
836 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
839 memcpy(buf
, proto
, buflen
);
840 send_message(hWnd
, wMsg
, handle
, 0);
846 HANDLE
WSAAsyncGetProtoByNumber(HWND hWnd
, u_int wMsg
, INT number
,
847 char *buf
, INT buflen
)
850 struct protoent
*proto
;
852 handle
= AllocWSAHandle();
857 if ((proto
= getprotobynumber(number
)) == NULL
) {
858 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
861 memcpy(buf
, proto
, buflen
);
862 send_message(hWnd
, wMsg
, handle
, 0);
868 HANDLE
WSAAsyncGetServByName(HWND hWnd
, u_int wMsg
, const char *name
,
869 const char *proto
, char *buf
, INT buflen
)
872 struct servent
*service
;
874 handle
= AllocWSAHandle();
879 if ((service
= getservbyname(name
, proto
)) == NULL
) {
880 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
883 memcpy(buf
, service
, buflen
);
884 send_message(hWnd
, wMsg
, handle
, 0);
890 HANDLE
WSAAsyncGetServByPort(HWND hWnd
, u_int wMsg
, INT port
, const char
891 *proto
, char *buf
, INT buflen
)
894 struct servent
*service
;
896 handle
= AllocWSAHandle();
901 if ((service
= getservbyport(port
, proto
)) == NULL
) {
902 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
905 memcpy(buf
, service
, buflen
);
906 send_message(hWnd
, wMsg
, handle
, 0);
911 INT
WSAAsyncSelect(SOCKET s
, HWND hWnd
, u_int wMsg
, long lEvent
)
914 fd_set read_fds
, write_fds
, except_fds
;
916 dprintf_winsock(stddeb
, "WSA_AsyncSelect: socket %d, HWND %d, wMsg %d, event %ld\n", s
, hWnd
, wMsg
, lEvent
);
918 /* remove outstanding asyncselect() processes */
921 if (wMsg
== 0 && lEvent
== 0)
930 FD_ZERO(&except_fds
);
932 if (lEvent
& FD_READ
)
933 FD_SET(s
, &read_fds
);
934 if (lEvent
& FD_WRITE
)
935 FD_SET(s
, &write_fds
);
937 fcntl(s
, F_SETFL
, O_NONBLOCK
);
938 select(s
+ 1, &read_fds
, &write_fds
, &except_fds
, NULL
);
941 if (FD_ISSET(s
, &read_fds
))
943 if (FD_ISSET(s
, &write_fds
))
946 send_message(hWnd
, wMsg
, s
, (wsaerrno() << 16) | event
);
951 INT
WSAFDIsSet(INT fd
, fd_set
*set
)
953 return( FD_ISSET(fd
, set
) );
956 INT
WSACancelAsyncRequest(HANDLE hAsyncTaskHandle
)
958 dprintf_winsock(stddeb
, "WSA_AsyncRequest: handle %d\n", hAsyncTaskHandle
);
963 INT
WSACancelBlockingCall(void)
965 dprintf_winsock(stddeb
, "WSA_CancelBlockCall\n");
969 INT
WSAGetLastError(void)
971 dprintf_winsock(stddeb
, "WSA_GetLastError = %x\n", wsa_errno
);
976 void WSASetLastError(INT iError
)
978 dprintf_winsock(stddeb
, "WSA_SetLastErorr %d\n", iError
);
983 BOOL
WSAIsBlocking(void)
985 dprintf_winsock(stddeb
, "WSA_IsBlocking\n");
990 FARPROC
WSASetBlockingHook(FARPROC lpBlockFunc
)
992 dprintf_winsock(stddeb
, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc
);
993 BlockFunction
= lpBlockFunc
;
995 return (FARPROC
) lpBlockFunc
;
998 INT
WSAUnhookBlockingHook(void)
1000 dprintf_winsock(stddeb
, "WSA_UnhookBlockingHook\n");
1001 BlockFunction
= NULL
;
1006 WSADATA WINSOCK_data
= {
1024 INT
WSAStartup(WORD wVersionRequested
, LPWSADATA lpWSAData
)
1027 dprintf_winsock(stddeb
, "WSAStartup: verReq=%x\n", wVersionRequested
);
1029 if (LOBYTE(wVersionRequested
) < 1 ||
1030 (LOBYTE(wVersionRequested
) == 1 &&
1031 HIBYTE(wVersionRequested
) < 1))
1032 return WSAVERNOTSUPPORTED
;
1037 /* alloc winsock heap */
1039 if ((HeapHandle
= GlobalAlloc(GMEM_FIXED
,sizeof(struct WinSockHeap
))) == 0)
1040 return WSASYSNOTREADY
;
1042 Heap
= (struct WinSockHeap
*) GlobalLock(HeapHandle
);
1043 bcopy(&WINSOCK_data
, lpWSAData
, sizeof(WINSOCK_data
));
1047 if ((wine_key
= msgget(IPC_PRIVATE
, 0600)) == -1)
1048 perror("wine: msgget");
1050 signal(SIGUSR1
, recv_message
);
1054 FD_ZERO(&fd_in_use
);
1060 INT
WSACleanup(void)
1065 if (msgctl(wine_key
, IPC_RMID
, NULL
) == -1)
1066 perror("wine: shmctl");
1068 for (fd
= 0; fd
!= FD_SETSIZE
; fd
++)
1069 if (FD_ISSET(fd
, &fd_in_use
))