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/filio.h>
16 #include <sys/ioccom.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
37 static WORD wsa_errno
;
38 static int wsa_initted
;
39 static key_t wine_key
= 0;
40 static FARPROC BlockFunction
;
41 static fd_set fd_in_use
;
57 #define WINSOCK_MAX_SOCKETS 256
58 #define WINSOCK_MAX_UDPDG 1024
60 /* we are out by two with the following, is it due to byte alignment?
61 * #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
63 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long) - 2)
64 /*#define MTYPE 0xb0b0eb05*/
65 #define MTYPE 0x30b0eb05
67 /* These structures are Win16 only */
70 SEGPTR h_name WINE_PACKED
; /* official name of host */
71 SEGPTR h_aliases WINE_PACKED
; /* alias list */
72 INT h_addrtype WINE_PACKED
; /* host address type */
73 INT h_length WINE_PACKED
; /* length of address */
74 char **h_addr_list WINE_PACKED
; /* list of addresses from name server */
80 SEGPTR p_name WINE_PACKED
; /* official protocol name */
81 SEGPTR p_aliases WINE_PACKED
; /* alias list */
82 INT p_proto WINE_PACKED
; /* protocol # */
86 SEGPTR s_name WINE_PACKED
; /* official service name */
87 SEGPTR s_aliases WINE_PACKED
; /* alias list */
88 INT s_port WINE_PACKED
; /* port # */
89 SEGPTR s_proto WINE_PACKED
; /* protocol to use */
95 struct WIN_hostent hostent_addr
;
96 struct WIN_hostent hostent_name
;
97 struct WIN_protoent protoent_name
;
98 struct WIN_protoent protoent_number
;
99 struct WIN_servent servent_name
;
100 struct WIN_servent servent_port
;
102 struct WIN_hostent WSAhostent_addr
;
103 struct WIN_hostent WSAhostent_name
;
104 struct WIN_protoent WSAprotoent_name
;
105 struct WIN_protoent WSAprotoent_number
;
106 struct WIN_servent WSAservent_name
;
107 struct WIN_servent WSAservent_port
;
108 /* 8K scratch buffer for aliases and friends are hopefully enough */
111 static struct WinSockHeap
*Heap
;
112 static HANDLE HeapHandle
;
114 static int ScratchPtr
;
118 #define GET_SEG_PTR(x) MAKELONG((int)((char*)(x)-(char*)Heap), \
119 GlobalHandleToSel(HeapHandle))
121 #define GET_SEG_PTR(x) ((SEGPTR)x)
128 #define dump_sockaddr(a) \
129 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
130 ((struct sockaddr_in *)a)->sin_family, \
131 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
132 ntohs(((struct sockaddr_in *)a)->sin_port))
135 static void ResetScratch()
140 static void *scratch_alloc(int size
)
143 if(ScratchPtr
+size
> sizeof(Heap
->scratch
))
145 ret
= Heap
->scratch
+ ScratchPtr
;
150 static SEGPTR
scratch_strdup(char * s
)
152 char *ret
=scratch_alloc(strlen(s
)+1);
154 return GET_SEG_PTR(ret
);
158 static WORD
wsaerrno(void)
162 #if defined(__FreeBSD__)
163 fprintf(stderr
, "winsock: errno %d, (%s).\n",
164 errno
, sys_errlist
[errno
]);
166 fprintf(stderr
, "winsock: errno %d\n", errno
);
169 fprintf(stderr
, "winsock: errno %d\n", errno
);
175 case EINTR
: return WSAEINTR
;
176 case EBADF
: return WSAEBADF
;
177 case EACCES
: return WSAEACCES
;
178 case EFAULT
: return WSAEFAULT
;
179 case EINVAL
: return WSAEINVAL
;
180 case EMFILE
: return WSAEMFILE
;
181 case EWOULDBLOCK
: return WSAEWOULDBLOCK
;
182 case EINPROGRESS
: return WSAEINPROGRESS
;
183 case EALREADY
: return WSAEALREADY
;
184 case ENOTSOCK
: return WSAENOTSOCK
;
185 case EDESTADDRREQ
: return WSAEDESTADDRREQ
;
186 case EMSGSIZE
: return WSAEMSGSIZE
;
187 case EPROTOTYPE
: return WSAEPROTOTYPE
;
188 case ENOPROTOOPT
: return WSAENOPROTOOPT
;
189 case EPROTONOSUPPORT
: return WSAEPROTONOSUPPORT
;
190 case ESOCKTNOSUPPORT
: return WSAESOCKTNOSUPPORT
;
191 case EOPNOTSUPP
: return WSAEOPNOTSUPP
;
192 case EPFNOSUPPORT
: return WSAEPFNOSUPPORT
;
193 case EAFNOSUPPORT
: return WSAEAFNOSUPPORT
;
194 case EADDRINUSE
: return WSAEADDRINUSE
;
195 case EADDRNOTAVAIL
: return WSAEADDRNOTAVAIL
;
196 case ENETDOWN
: return WSAENETDOWN
;
197 case ENETUNREACH
: return WSAENETUNREACH
;
198 case ENETRESET
: return WSAENETRESET
;
199 case ECONNABORTED
: return WSAECONNABORTED
;
200 case ECONNRESET
: return WSAECONNRESET
;
201 case ENOBUFS
: return WSAENOBUFS
;
202 case EISCONN
: return WSAEISCONN
;
203 case ENOTCONN
: return WSAENOTCONN
;
204 case ESHUTDOWN
: return WSAESHUTDOWN
;
205 case ETOOMANYREFS
: return WSAETOOMANYREFS
;
206 case ETIMEDOUT
: return WSAETIMEDOUT
;
207 case ECONNREFUSED
: return WSAECONNREFUSED
;
208 case ELOOP
: return WSAELOOP
;
209 case ENAMETOOLONG
: return WSAENAMETOOLONG
;
210 case EHOSTDOWN
: return WSAEHOSTDOWN
;
211 case EHOSTUNREACH
: return WSAEHOSTUNREACH
;
212 case ENOTEMPTY
: return WSAENOTEMPTY
;
214 case EPROCLIM
: return WSAEPROCLIM
;
217 case EUSERS
: return WSAEUSERS
;
220 case EDQUOT
: return WSAEDQUOT
;
222 case ESTALE
: return WSAESTALE
;
223 case EREMOTE
: return WSAEREMOTE
;
224 /* just in case we ever get here and there are no problems */
228 fprintf(stderr
, "winsock: unknown errorno %d!\n", errno
);
229 return WSAEOPNOTSUPP
;
233 static void errno_to_wsaerrno(void)
235 wsa_errno
= wsaerrno();
239 static WORD
wsaherrno(void)
243 #if defined(__FreeBSD__)
244 fprintf(stderr
, "winsock: h_errno %d, (%s).\n",
245 h_errno
, sys_errlist
[h_errno
]);
247 fprintf(stderr
, "winsock: h_errno %d.\n", h_errno
);
248 herror("wine: winsock: wsaherrno");
251 fprintf(stderr
, "winsock: h_errno %d\n", h_errno
);
257 case HOST_NOT_FOUND
: return WSAHOST_NOT_FOUND
;
258 case TRY_AGAIN
: return WSATRY_AGAIN
;
259 case NO_RECOVERY
: return WSANO_RECOVERY
;
260 case NO_DATA
: return WSANO_DATA
;
261 /* just in case we ever get here and there are no problems */
266 fprintf(stderr
, "winsock: unknown h_errorno %d!\n", h_errno
);
267 return WSAEOPNOTSUPP
;
272 static void herrno_to_wsaerrno(void)
274 wsa_errno
= wsaherrno();
278 static void convert_sockopt(INT
*level
, INT
*optname
)
280 /* $%#%!#! why couldn't they use the same values for both winsock and unix ? */
286 case 0x01: *optname
= SO_DEBUG
;
288 case 0x04: *optname
= SO_REUSEADDR
;
290 case 0x08: *optname
= SO_KEEPALIVE
;
292 case 0x10: *optname
= SO_DONTROUTE
;
294 case 0x20: *optname
= SO_BROADCAST
;
296 case 0x80: *optname
= SO_LINGER
;
298 case 0x100: *optname
= SO_OOBINLINE
;
300 case 0x1001: *optname
= SO_SNDBUF
;
302 case 0x1002: *optname
= SO_RCVBUF
;
304 case 0x1007: *optname
= SO_ERROR
;
306 case 0x1008: *optname
= SO_TYPE
;
309 fprintf(stderr
, "convert_sockopt() unknown optname %d\n", *optname
);
313 case 6: *optname
= IPPROTO_TCP
;
318 static SEGPTR
copy_stringlist(char **list
)
324 s_list
= scratch_alloc(sizeof(SEGPTR
)*(i
+1));
327 void *copy
= scratch_alloc(strlen(list
[i
])+1);
328 strcpy(copy
,list
[i
]);
329 s_list
[i
]=GET_SEG_PTR(copy
);
332 return GET_SEG_PTR(s_list
);
336 static void CONVERT_HOSTENT(struct WIN_hostent
*heapent
, struct hostent
*host
)
341 strcpy(heapent
->hostname
,host
->h_name
);
342 heapent
->h_name
= GET_SEG_PTR(heapent
->hostname
);
343 /* Convert aliases. Have to create array with FAR pointers */
345 heapent
->h_aliases
= 0;
347 heapent
->h_aliases
= copy_stringlist(host
->h_aliases
);
349 heapent
->h_addrtype
= host
->h_addrtype
;
350 heapent
->h_length
= host
->h_length
;
351 for(i
=0;host
->h_addr_list
[i
];i
++)
353 addr_list
=scratch_alloc(sizeof(SEGPTR
)*(i
+1));
354 heapent
->h_addr_list
= (char**)GET_SEG_PTR(addr_list
);
355 for(i
=0;host
->h_addr_list
[i
];i
++)
357 void *addr
=scratch_alloc(host
->h_length
);
358 memcpy(addr
,host
->h_addr_list
[i
],host
->h_length
);
359 addr_list
[i
]=GET_SEG_PTR(addr
);
364 static void CONVERT_PROTOENT(struct WIN_protoent
*heapent
,
365 struct protoent
*proto
)
368 heapent
->p_name
= scratch_strdup(proto
->p_name
);
369 heapent
->p_aliases
=proto
->p_aliases
?
370 copy_stringlist(proto
->p_aliases
) : 0;
371 heapent
->p_proto
= proto
->p_proto
;
374 static void CONVERT_SERVENT(struct WIN_servent
*heapent
, struct servent
*serv
)
377 heapent
->s_name
= scratch_strdup(serv
->s_name
);
378 heapent
->s_aliases
= serv
->s_aliases
?
379 copy_stringlist(serv
->s_aliases
) : 0;
380 heapent
->s_port
= serv
->s_port
;
381 heapent
->s_proto
= scratch_strdup(serv
->s_proto
);
384 #define CONVERT_HOSTENT(a,b) memcpy(a, &b, sizeof(a))
385 #define CONVERT_PROTOENT(a,b) memcpy(a, &b, sizeof(a))
386 #define CONVERT_SERVENT(a,b) memcpy(a, &b, sizeof(a))
389 SOCKET
WINSOCK_accept(SOCKET s
, struct sockaddr
*addr
, INT
*addrlen
)
393 dprintf_winsock(stddeb
, "WSA_accept: socket %d, ptr %8x, length %d\n", s
, (int) addr
, *addrlen
);
396 WSASetLastError(WSANOTINITIALISED
);
397 return INVALID_SOCKET
;
400 if ((sock
= accept(s
, addr
, (int *) addrlen
)) < 0) {
402 return INVALID_SOCKET
;
407 INT
WINSOCK_bind(SOCKET s
, struct sockaddr
*name
, INT namelen
)
410 dprintf_winsock(stddeb
, "WSA_bind: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
414 WSASetLastError(WSANOTINITIALISED
);
418 if (namelen
< sizeof(*name
)) {
419 WSASetLastError(WSAEFAULT
);
423 /* check the socket family */
424 if ( ((struct sockaddr_in
*)name
)->sin_family
!= AF_INET
) {
425 WSASetLastError(WSAEAFNOSUPPORT
);
429 if (bind(s
, name
, namelen
) < 0) {
432 WSASetLastError(WSAENOTSOCK
);
435 WSASetLastError(WSAEINVAL
);
446 INT
WINSOCK_closesocket(SOCKET s
)
448 dprintf_winsock(stddeb
, "WSA_closesocket: socket %d\n", s
);
451 WSASetLastError(WSANOTINITIALISED
);
455 FD_CLR(s
, &fd_in_use
);
459 WSASetLastError(WSAENOTSOCK
);
467 INT
WINSOCK_connect(SOCKET s
, struct sockaddr
*name
, INT namelen
)
469 dprintf_winsock(stddeb
, "WSA_connect: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
473 WSASetLastError(WSANOTINITIALISED
);
477 if (connect(s
, name
, namelen
) < 0) {
484 INT
WINSOCK_getpeername(SOCKET s
, struct sockaddr
*name
, INT
*namelen
)
486 dprintf_winsock(stddeb
, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, *namelen
);
490 WSASetLastError(WSANOTINITIALISED
);
494 if (getpeername(s
, name
, (int *) namelen
) < 0) {
498 herrno_to_wsaerrno();
505 INT
WINSOCK_getsockname(SOCKET s
, struct sockaddr
*name
, INT
*namelen
)
507 dprintf_winsock(stddeb
, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, (int) *namelen
);
510 WSASetLastError(WSANOTINITIALISED
);
514 if (getsockname(s
, name
, (int *) namelen
) < 0) {
518 herrno_to_wsaerrno();
526 WINSOCK_getsockopt(SOCKET s
, INT level
, INT optname
, char *optval
, INT
*optlen
)
528 dprintf_winsock(stddeb
, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s
, level
, (int) optval
, (int) *optlen
);
531 WSASetLastError(WSANOTINITIALISED
);
535 convert_sockopt(&level
, &optname
);
537 if (getsockopt(s
, (int) level
, optname
, optval
, (int *) optlen
) < 0) {
539 WSASetLastError(WSAENOTSOCK
);
547 u_long
WINSOCK_htonl(u_long hostlong
)
549 return( htonl(hostlong
) );
552 u_short
WINSOCK_htons(u_short hostshort
)
554 return( htons(hostshort
) );
557 u_long
WINSOCK_inet_addr(char *cp
)
559 return( inet_addr(cp
) );
562 char *WINSOCK_inet_ntoa(struct in_addr in
)
566 /* dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/
568 if ((s
= inet_ntoa(in
)) == NULL
) {
573 strncpy(Heap
->ntoa_buffer
, s
, sizeof(Heap
->ntoa_buffer
) );
575 return (char *) GET_SEG_PTR(&Heap
->ntoa_buffer
);
578 INT
WINSOCK_ioctlsocket(SOCKET s
, u_long cmd
, u_long
*argp
)
583 dprintf_winsock(stddeb
, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s
, cmd
, (int) argp
);
586 WSASetLastError(WSANOTINITIALISED
);
590 /* Why can't they all use the same ioctl numbers */
594 if(cmd
== _IOR('f',127,u_long
))
599 if(cmd
== _IOW('f',126,u_long
) || cmd
== _IOR('f',126,u_long
))
604 if(cmd
== _IOW('f',125,u_long
))
611 fprintf(stderr
,"Unknown winsock ioctl. Trying anyway\n");
613 dprintf_winsock(stddeb
,"Recognized as %s\n", ctlname
);
616 if (ioctl(s
, newcmd
, newargp
) < 0) {
618 WSASetLastError(WSAENOTSOCK
);
626 INT
WINSOCK_listen(SOCKET s
, INT backlog
)
628 dprintf_winsock(stddeb
, "WSA_listen: socket %d, backlog %d\n", s
, backlog
);
631 WSASetLastError(WSANOTINITIALISED
);
635 if (listen(s
, backlog
) < 0) {
642 u_long
WINSOCK_ntohl(u_long netlong
)
644 return( ntohl(netlong
) );
647 u_short
WINSOCK_ntohs(u_short netshort
)
649 return( ntohs(netshort
) );
652 INT
WINSOCK_recv(SOCKET s
, char *buf
, INT len
, INT flags
)
656 dprintf_winsock(stddeb
, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s
, (int) buf
, len
, flags
);
659 WSASetLastError(WSANOTINITIALISED
);
663 if ((length
= recv(s
, buf
, len
, flags
)) < 0) {
670 INT
WINSOCK_recvfrom(SOCKET s
, char *buf
, INT len
, INT flags
,
671 struct sockaddr
*from
, int *fromlen
)
675 dprintf_winsock(stddeb
, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long)buf
, len
, flags
);
678 WSASetLastError(WSANOTINITIALISED
);
682 if ((length
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
)) < 0) {
689 INT
WINSOCK_select(INT nfds
, fd_set
*readfds
, fd_set
*writefds
,
690 fd_set
*exceptfds
, struct timeval
*timeout
)
692 dprintf_winsock(stddeb
, "WSA_select: fd # %d, ptr %8lx, ptr %8lx, ptr %8lX\n", nfds
, (unsigned long) readfds
, (unsigned long) writefds
, (unsigned long) exceptfds
);
695 WSASetLastError(WSANOTINITIALISED
);
699 return(select(nfds
, readfds
, writefds
, exceptfds
, timeout
));
702 INT
WINSOCK_send(SOCKET s
, char *buf
, INT len
, INT flags
)
706 dprintf_winsock(stddeb
, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
709 WSASetLastError(WSANOTINITIALISED
);
713 if ((length
= send(s
, buf
, len
, flags
)) < 0) {
720 INT
WINSOCK_sendto(SOCKET s
, char *buf
, INT len
, INT flags
,
721 struct sockaddr
*to
, INT tolen
)
725 dprintf_winsock(stddeb
, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s
, (unsigned long) buf
, len
, flags
);
728 WSASetLastError(WSANOTINITIALISED
);
732 if ((length
= sendto(s
, buf
, len
, flags
, to
, tolen
)) < 0) {
739 INT
WINSOCK_setsockopt(SOCKET s
, INT level
, INT optname
, const char *optval
,
742 dprintf_winsock(stddeb
, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s
, level
, optname
, (int) optval
, optlen
);
743 convert_sockopt(&level
, &optname
);
746 WSASetLastError(WSANOTINITIALISED
);
750 if (setsockopt(s
, level
, optname
, optval
, optlen
) < 0) {
757 INT
WINSOCK_shutdown(SOCKET s
, INT how
)
759 dprintf_winsock(stddeb
, "WSA_shutdown: socket s %d, how %d\n", s
, how
);
762 WSASetLastError(WSANOTINITIALISED
);
766 if (shutdown(s
, how
) < 0) {
773 SOCKET
WINSOCK_socket(INT af
, INT type
, INT protocol
)
777 dprintf_winsock(stddeb
, "WSA_socket: af=%d type=%d protocol=%d\n", af
, type
, protocol
);
780 WSASetLastError(WSANOTINITIALISED
);
781 return INVALID_SOCKET
;
784 /* check the socket family */
790 WSASetLastError(WSAEAFNOSUPPORT
);
791 return INVALID_SOCKET
;
795 /* check the socket type */
802 WSASetLastError(WSAESOCKTNOSUPPORT
);
803 return INVALID_SOCKET
;
807 /* check the protocol type */
808 if ( protocol
< 0 ) { /* don't support negative values */
809 WSASetLastError(WSAEPROTONOSUPPORT
);
810 return INVALID_SOCKET
;
813 if ( af
== AF_UNSPEC
) { /* did they not specify the address family? */
816 if (type
== SOCK_STREAM
) {
821 if (type
== SOCK_DGRAM
) {
826 WSASetLastError(WSAEPROTOTYPE
);
827 return INVALID_SOCKET
;
832 if ((sock
= socket(af
, type
, protocol
)) < 0) {
833 if (errno
== EPERM
) {
834 /* non super-user wants a raw socket */
835 fprintf(stderr
, "WSA_socket: not enough privileges\n");
836 WSASetLastError(WSAESOCKTNOSUPPORT
);
839 dprintf_winsock(stddeb
, "WSA_socket: failed !\n");
840 return INVALID_SOCKET
;
843 if (sock
> WINSOCK_MAX_SOCKETS
) {
844 /* we only support socket numbers up to WINSOCK_MAX_SOCKETS.
845 * The return value indicates no more descriptors are available
847 WSASetLastError(WSAEMFILE
);
848 return INVALID_SOCKET
;
851 FD_SET(sock
, &fd_in_use
);
853 dprintf_winsock(stddeb
, "WSA_socket: fd %d\n", sock
);
860 SEGPTR
WINSOCK_gethostbyaddr(const char *addr
, INT len
, INT type
)
862 struct hostent
*host
;
864 dprintf_winsock(stddeb
, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr
, len
, type
);
867 WSASetLastError(WSANOTINITIALISED
);
871 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
875 herrno_to_wsaerrno();
879 CONVERT_HOSTENT(&Heap
->hostent_addr
, host
);
881 return GET_SEG_PTR(&Heap
->hostent_addr
);
887 SEGPTR
WINSOCK_gethostbyname(const char *name
)
889 struct hostent
*host
;
891 dprintf_winsock(stddeb
, "WSA_gethostbyname: %s\n", name
);
894 WSASetLastError(WSANOTINITIALISED
);
898 if ((host
= gethostbyname(name
)) == NULL
) {
902 herrno_to_wsaerrno();
906 CONVERT_HOSTENT(&Heap
->hostent_name
, host
);
908 return GET_SEG_PTR(&Heap
->hostent_name
);
911 INT
WINSOCK_gethostname(char *name
, INT namelen
)
913 dprintf_winsock(stddeb
, "WSA_gethostname: name %s, len %d\n", name
, namelen
);
916 WSASetLastError(WSANOTINITIALISED
);
920 if (gethostname(name
, namelen
) < 0) {
922 WSASetLastError(WSAEFAULT
);
931 struct WIN_protoent *
933 SEGPTR
WINSOCK_getprotobyname(char *name
)
935 struct protoent
*proto
;
937 dprintf_winsock(stddeb
, "WSA_getprotobyname: name %s\n", name
);
940 WSASetLastError(WSANOTINITIALISED
);
944 if ((proto
= getprotobyname(name
)) == NULL
) {
948 herrno_to_wsaerrno();
952 CONVERT_PROTOENT(&Heap
->protoent_name
, proto
);
954 return GET_SEG_PTR(&Heap
->protoent_name
);
958 struct WIN_protoent *
960 SEGPTR
WINSOCK_getprotobynumber(INT number
)
962 struct protoent
*proto
;
964 dprintf_winsock(stddeb
, "WSA_getprotobynumber: num %d\n", number
);
967 WSASetLastError(WSANOTINITIALISED
);
971 if ((proto
= getprotobynumber(number
)) == NULL
) {
976 herrno_to_wsaerrno();
979 WSASetLastError(WSANO_DATA
);
982 CONVERT_PROTOENT(&Heap
->protoent_number
, proto
);
984 return GET_SEG_PTR(&Heap
->protoent_number
);
990 SEGPTR
WINSOCK_getservbyname(const char *name
, const char *proto
)
992 struct servent
*service
;
997 dprintf_winsock(stddeb
, "WSA_getservbyname: name %s, proto %s\n", name
, proto
);
1000 WSASetLastError(WSANOTINITIALISED
);
1004 if ((service
= getservbyname(name
, proto
)) == NULL
) {
1006 errno_to_wsaerrno();
1008 herrno_to_wsaerrno();
1012 CONVERT_SERVENT(&Heap
->servent_name
, service
);
1014 return GET_SEG_PTR(&Heap
->servent_name
);
1018 struct WIN_servent *
1020 SEGPTR
WINSOCK_getservbyport(INT port
, const char *proto
)
1022 struct servent
*service
;
1024 dprintf_winsock(stddeb
, "WSA_getservbyport: port %d, name %s\n", port
, proto
);
1027 WSASetLastError(WSANOTINITIALISED
);
1031 if ((service
= getservbyport(port
, proto
)) == NULL
) {
1033 errno_to_wsaerrno();
1035 herrno_to_wsaerrno();
1039 CONVERT_SERVENT(&Heap
->servent_port
, service
);
1041 return GET_SEG_PTR(&Heap
->servent_port
);
1044 /******************** winsock specific functions ************************
1047 static HANDLE new_handle
= 1;
1049 static HANDLE
AllocWSAHandle(void)
1051 return new_handle
++;
1054 static void recv_message(int sig
)
1056 static struct ipc_packet message
;
1057 int message_is_valid
= 0;
1060 message
.mtype
= MTYPE
;
1062 signal(SIGUSR1
, recv_message
);
1065 if (!message_is_valid
) {
1066 if (msgrcv(wine_key
, (struct msgbuf
*)&(message
),
1067 IPC_PACKET_SIZE
, 0 /*MTYPE*/, IPC_NOWAIT
) == -1) {
1068 perror("wine: winsock: msgrcv");
1073 result
= PostMessage(message
.hWnd
, message
.wMsg
,
1074 (WPARAM
)message
.handle
, message
.lParam
);
1075 if (result
!= FALSE
) {
1076 message_is_valid
= 1;
1080 message_is_valid
= 0;
1084 if ((wine_key
= msgget(IPC_PRIVATE
, 0600)) == -1)
1085 perror("wine: winsock: msgget");
1089 static void send_message( HWND hWnd
, u_int wMsg
, HANDLE handle
, long lParam
)
1091 struct ipc_packet message
;
1093 message
.mtype
= MTYPE
;
1094 message
.handle
= handle
;
1095 message
.hWnd
= hWnd
;
1096 message
.wMsg
= wMsg
;
1097 message
.lParam
= lParam
;
1099 if (msgsnd(wine_key
, (struct msgbuf
*)&(message
),
1100 IPC_PACKET_SIZE
, 0/*IPC_NOWAIT*/) == -1)
1101 perror("wine: winsock: msgsnd");
1103 kill(getppid(), SIGUSR1
);
1107 HANDLE
WSAAsyncGetHostByAddr(HWND hWnd
, u_int wMsg
, LPCSTR addr
,
1108 INT len
, INT type
, LPSTR buf
, INT buflen
)
1111 struct hostent
*host
;
1115 WSASetLastError(WSANOTINITIALISED
);
1119 handle
= AllocWSAHandle();
1123 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1126 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
1128 errno_to_wsaerrno();
1130 herrno_to_wsaerrno();
1132 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1135 memcpy(buf
, host
, buflen
);
1136 send_message(hWnd
, wMsg
, handle
, 0);
1142 HANDLE
WSAAsyncGetHostByName(HWND hWnd
, u_int wMsg
, LPCSTR name
,
1143 LPSTR buf
, INT buflen
)
1146 struct hostent
*host
;
1150 WSASetLastError(WSANOTINITIALISED
);
1154 handle
= AllocWSAHandle();
1158 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1161 if ((host
= gethostbyname(name
)) == NULL
) {
1163 errno_to_wsaerrno();
1165 herrno_to_wsaerrno();
1167 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1170 memcpy(buf
, host
, buflen
);
1171 send_message(hWnd
, wMsg
, handle
, 0);
1177 HANDLE
WSAAsyncGetProtoByName(HWND hWnd
, u_int wMsg
, LPCSTR name
,
1178 LPSTR buf
, INT buflen
)
1181 struct protoent
*proto
;
1185 WSASetLastError(WSANOTINITIALISED
);
1189 handle
= AllocWSAHandle();
1193 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1196 if ((proto
= getprotobyname(name
)) == NULL
) {
1198 errno_to_wsaerrno();
1200 herrno_to_wsaerrno();
1202 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1205 memcpy(buf
, proto
, buflen
);
1206 send_message(hWnd
, wMsg
, handle
, 0);
1212 HANDLE
WSAAsyncGetProtoByNumber(HWND hWnd
, u_int wMsg
, INT number
,
1213 LPSTR buf
, INT buflen
)
1216 struct protoent
*proto
;
1220 WSASetLastError(WSANOTINITIALISED
);
1224 handle
= AllocWSAHandle();
1228 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1231 if ((proto
= getprotobynumber(number
)) == NULL
) {
1233 errno_to_wsaerrno();
1235 herrno_to_wsaerrno();
1237 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1240 memcpy(buf
, proto
, buflen
);
1241 send_message(hWnd
, wMsg
, handle
, 0);
1247 HANDLE
WSAAsyncGetServByName(HWND hWnd
, u_int wMsg
, LPCSTR name
,
1248 LPCSTR proto
, LPSTR buf
, INT buflen
)
1251 struct servent
*service
;
1255 WSASetLastError(WSANOTINITIALISED
);
1259 handle
= AllocWSAHandle();
1263 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1266 if ((service
= getservbyname(name
, proto
)) == NULL
) {
1268 errno_to_wsaerrno();
1270 herrno_to_wsaerrno();
1272 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1275 memcpy(buf
, service
, buflen
);
1276 send_message(hWnd
, wMsg
, handle
, 0);
1282 HANDLE
WSAAsyncGetServByPort(HWND hWnd
, u_int wMsg
, INT port
, LPCSTR proto
,
1283 LPSTR buf
, INT buflen
)
1286 struct servent
*service
;
1290 WSASetLastError(WSANOTINITIALISED
);
1294 handle
= AllocWSAHandle();
1298 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1301 if ((service
= getservbyport(port
, proto
)) == NULL
) {
1303 errno_to_wsaerrno();
1305 herrno_to_wsaerrno();
1307 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
1310 memcpy(buf
, service
, buflen
);
1311 send_message(hWnd
, wMsg
, handle
, 0);
1316 INT
WSAAsyncSelect(SOCKET s
, HWND hWnd
, u_int wMsg
, long lEvent
)
1319 fd_set read_fds
, write_fds
, except_fds
;
1324 WSASetLastError(WSANOTINITIALISED
);
1325 return SOCKET_ERROR
;
1328 dprintf_winsock(stddeb
, "WSA_AsyncSelect: socket %d, HWND %04x, wMsg %d, event %ld\n", s
, hWnd
, wMsg
, lEvent
);
1330 /* remove outstanding asyncselect() processes */
1333 if (wMsg
== 0 && lEvent
== 0)
1338 dprintf_winsock(stddeb
, "forked, child is (%d)\n",newpid
);
1343 FD_ZERO(&write_fds
);
1344 FD_ZERO(&except_fds
);
1346 if (lEvent
& FD_READ
)
1347 FD_SET(s
, &read_fds
);
1348 if (lEvent
& FD_WRITE
)
1349 FD_SET(s
, &write_fds
);
1351 fcntl(s
, F_SETFL
, O_NONBLOCK
);
1352 if (select(s
+ 1, &read_fds
, &write_fds
, &except_fds
, NULL
)<0) {
1353 errors
= wsaerrno();
1357 if (FD_ISSET(s
, &read_fds
))
1359 if (FD_ISSET(s
, &write_fds
))
1361 send_message(hWnd
, wMsg
, s
, WSAMAKESELECTREPLY(event
,errors
));
1366 INT
WSAFDIsSet(INT fd
, fd_set
*set
)
1368 return( FD_ISSET(fd
, set
) );
1371 INT
WSACancelAsyncRequest(HANDLE hAsyncTaskHandle
)
1373 dprintf_winsock(stddeb
, "WSA_AsyncRequest: handle %04x\n", hAsyncTaskHandle
);
1376 WSASetLastError(WSANOTINITIALISED
);
1377 return SOCKET_ERROR
;
1383 INT
WSACancelBlockingCall(void)
1385 dprintf_winsock(stddeb
, "WSA_CancelBlockCall\n");
1388 WSASetLastError(WSANOTINITIALISED
);
1389 return SOCKET_ERROR
;
1395 INT
WSAGetLastError(void)
1397 dprintf_winsock(stddeb
, "WSA_GetLastError = %x\n", wsa_errno
);
1402 void WSASetLastError(INT iError
)
1404 dprintf_winsock(stddeb
, "WSA_SetLastErorr %d\n", iError
);
1406 /* technically, we should make sure that WINESockets
1407 * has been started up correctly. But since this function
1408 * is also used internally, it makes no sense.
1410 *if (!wsa_initted) {
1411 * WSASetLastError(WSANOTINITIALISED);
1412 * return SOCKET_ERROR;
1419 BOOL
WSAIsBlocking(void)
1421 dprintf_winsock(stddeb
, "WSA_IsBlocking\n");
1426 FARPROC
WSASetBlockingHook(FARPROC lpBlockFunc
)
1428 dprintf_winsock(stddeb
, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc
);
1431 WSASetLastError(WSANOTINITIALISED
);
1435 BlockFunction
= lpBlockFunc
;
1437 return (FARPROC
) lpBlockFunc
;
1440 INT
WSAUnhookBlockingHook(void)
1442 dprintf_winsock(stddeb
, "WSA_UnhookBlockingHook\n");
1445 WSASetLastError(WSANOTINITIALISED
);
1449 BlockFunction
= NULL
;
1455 WSADATA WINSOCK_data
= {
1461 #elif defined(__NetBSD__)
1463 #elif defined(sunos)
1465 #elif defined(__FreeBSD__)
1470 WINSOCK_MAX_SOCKETS
,
1476 INT
WSAStartup(WORD wVersionRequested
, LPWSADATA lpWSAData
)
1479 WSADATA WINSOCK_data
= {
1485 #elif defined(__NetBSD__)
1487 #elif defined(sunos)
1489 #elif defined(__FreeBSD__)
1494 WINSOCK_MAX_SOCKETS
,
1499 dprintf_winsock(stddeb
, "WSAStartup: verReq=%x\n", wVersionRequested
);
1501 if (LOBYTE(wVersionRequested
) < 1 ||
1502 (LOBYTE(wVersionRequested
) == 1 &&
1503 HIBYTE(wVersionRequested
) < 1))
1504 return WSAVERNOTSUPPORTED
;
1509 /* alloc winsock heap */
1511 if ((HeapHandle
= GlobalAlloc16(GMEM_FIXED
,sizeof(struct WinSockHeap
))) == 0)
1512 return WSASYSNOTREADY
;
1514 Heap
= (struct WinSockHeap
*) GlobalLock16(HeapHandle
);
1516 /* return winsock information */
1517 memcpy(lpWSAData
, &WINSOCK_data
, sizeof(WINSOCK_data
));
1521 if ((wine_key
= msgget(IPC_PRIVATE
, 0600)) == -1)
1522 perror("wine: winsock: msgget");
1524 signal(SIGUSR1
, recv_message
);
1528 FD_ZERO(&fd_in_use
);
1530 /* increment our usage count */
1532 dprintf_winsock(stddeb
, "WSAStartup: succeeded\n");
1536 INT
WSACleanup(void)
1540 dprintf_winsock(stddeb
, "WSACleanup (%d)\n",getpid());
1543 WSASetLastError(WSANOTINITIALISED
);
1544 return SOCKET_ERROR
;
1547 /* decrement usage count */
1550 if (wsa_initted
== 0) {
1552 if (msgctl(wine_key
, IPC_RMID
, NULL
) == -1)
1553 perror("wine: winsock: msgctl");
1555 for (fd
= 0; fd
!= FD_SETSIZE
; fd
++)
1556 if (FD_ISSET(fd
, &fd_in_use
))