source: trunk/src/wsock32/wsock32.cpp@ 3472

Last change on this file since 3472 was 3472, checked in by bird, 25 years ago

Dirty fix to make this compile - QueryPerformanceCounter int odinwrap.h problem.

File size: 32.8 KB
Line 
1/* $Id: wsock32.cpp,v 1.28 2000-05-02 13:09:44 bird Exp $ */
2
3/*
4 *
5 * Project Odin Software License can be found in LICENSE.TXT
6 *
7 * Win32 SOCK32 for OS/2
8 *
9 * Copyright (C) 1999 Patrick Haller <phaller@gmx.net>
10 * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl)
11 *
12 * Some parts based on Wine code: (dlls\winsock\socket.c)
13 * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
14 *
15 */
16
17/* Remark:
18 * 1999/11/21 experimental rewrite using IBM's PMWSock only
19 * -> some structural differences remain! (hostent)
20 * 1999/12/01 experimental rewrite works (TELNET)
21 * -> open issue: WSASetLastError / WSAGetLastError
22 * call SetLastError / GetLastError according to docs
23 *
24 * 2000/22/03 Complete rewrite -> got rid of pmwsock
25 *
26 * identical structures:
27 * - sockaddr_in
28 * - WSADATA
29 * - sockaddr
30 * - fd_set
31 * - timeval
32 *
33 * incompatible structures:
34 * - hostent
35 * - netent
36 * - servent
37 * - protent
38 * - linger
39 */
40
41
42/*****************************************************************************
43 * Includes *
44 *****************************************************************************/
45
46#define INCL_BASE
47#include <os2wrap.h> //Odin32 OS/2 api wrappers
48
49#include <string.h>
50#include <odinwrap.h>
51#include <os2sel.h>
52#include <stdlib.h>
53#include <win32api.h>
54#include <win32wnd.h>
55#include <wprocess.h>
56#include <misc.h>
57
58#include "wsock32.h"
59#include "wsastruct.h"
60#include "asyncthread.h"
61
62#define DBG_LOCALLOG DBG_wsock32
63#include "dbglocal.h"
64
65//kso: dirty fix to make this compile! not permanent!
66BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER *p);
67#define LowPart u.LowPart
68
69
70ODINDEBUGCHANNEL(WSOCK32-WSOCK32)
71
72
73/*****************************************************************************
74 * Local variables *
75 *****************************************************************************/
76
77static LPWSINFO lpFirstIData = NULL;
78
79//******************************************************************************
80//******************************************************************************
81LPWSINFO WINSOCK_GetIData(HANDLE tid)
82{
83 LPWSINFO iData;
84 BOOL fCurrentThread = FALSE;
85
86 if(tid == CURRENT_THREAD) {
87 tid = GetCurrentThread();
88 fCurrentThread = TRUE;
89 }
90tryagain:
91 for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
92 if (iData->dwThisThread == tid)
93 break;
94 }
95 if(iData == NULL && fCurrentThread) {
96 WINSOCK_CreateIData();
97 fCurrentThread = FALSE; //just to prevent infinite loops
98 goto tryagain;
99 }
100 if(iData == NULL) {
101 dprintf(("WINSOCK_GetIData: couldn't find struct for thread %x", tid));
102 DebugInt3();// should never happen!!!!!!!
103 }
104 return iData;
105}
106//******************************************************************************
107//******************************************************************************
108BOOL WINSOCK_CreateIData(void)
109{
110 LPWSINFO iData;
111
112 iData = (LPWSINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WSINFO));
113 if (!iData)
114 return FALSE;
115 iData->dwThisThread = GetCurrentThread();
116 iData->lpNextIData = lpFirstIData;
117 lpFirstIData = iData;
118 return TRUE;
119}
120//******************************************************************************
121//******************************************************************************
122void WINSOCK_DeleteIData(void)
123{
124 LPWSINFO ppid, iData;
125
126 if (iData) {
127 ppid = lpFirstIData;
128 while(ppid)
129 {
130 iData = ppid;
131 ppid = ppid->lpNextIData;
132
133 if( iData->flags & WSI_BLOCKINGCALL )
134 dprintf(("\tinside blocking call!\n"));
135
136 /* delete scratch buffers */
137
138 if(iData->he) free(iData->he);
139 if(iData->se) free(iData->se);
140 if(iData->pe) free(iData->pe);
141
142 //// if( iData->buffer ) SEGPTR_FREE(iData->buffer);
143 //// if( iData->dbuffer ) SEGPTR_FREE(iData->dbuffer);
144
145 HeapFree(GetProcessHeap(), 0, iData);
146 }
147 }
148}
149//******************************************************************************
150//******************************************************************************
151void WIN32API WSASetLastError(int iError)
152{
153 // according to the docs, WSASetLastError() is just a call-through
154 // to SetLastError()
155 if(iError) {
156 dprintf(("WSASetLastError %x", iError));
157 }
158 SetLastError(iError);
159}
160//******************************************************************************
161//******************************************************************************
162int WIN32API WSAGetLastError()
163{
164 return GetLastError();
165}
166//******************************************************************************
167//******************************************************************************
168ODINFUNCTION2(int,OS2shutdown,
169 SOCKET,s,
170 int,how)
171{
172 int ret;
173
174 if(!fWSAInitialized) {
175 WSASetLastError(WSANOTINITIALISED);
176 return SOCKET_ERROR;
177 }
178 else
179 if(WSAIsBlocking()) {
180 WSASetLastError(WSAEINPROGRESS);
181 return SOCKET_ERROR;
182 }
183 ret = shutdown(s, how);
184
185 if(ret == SOCKET_ERROR) {
186 WSASetLastError(wsaErrno());
187 }
188 else WSASetLastError(NO_ERROR);
189 return ret;
190}
191//******************************************************************************
192//******************************************************************************
193ODINFUNCTION3(SOCKET,OS2socket,
194 int,af,
195 int,type,
196 int,protocol)
197{
198 SOCKET s;
199
200 if(!fWSAInitialized) {
201 WSASetLastError(WSANOTINITIALISED);
202 return SOCKET_ERROR;
203 }
204 else
205 if(WSAIsBlocking()) {
206 WSASetLastError(WSAEINPROGRESS);
207 return SOCKET_ERROR;
208 }
209 s = socket(af, type, protocol);
210
211 if(s == SOCKET_ERROR && sock_errno() == SOCEPFNOSUPPORT) {
212 //map SOCEPFNOSUPPORT to SOCEPFNOSUPPORT
213 WSASetLastError(SOCEPFNOSUPPORT);
214 }
215 else
216 if(s == SOCKET_ERROR) {
217 WSASetLastError(wsaErrno());
218 }
219 else WSASetLastError(NO_ERROR);
220 return s;
221}
222//******************************************************************************
223//******************************************************************************
224ODINFUNCTION1(int,OS2closesocket,SOCKET, s)
225{
226 int ret;
227
228 if(!fWSAInitialized) {
229 WSASetLastError(WSANOTINITIALISED);
230 return SOCKET_ERROR;
231 }
232 else
233 if(WSAIsBlocking()) {
234 WSASetLastError(WSAEINPROGRESS);
235 return SOCKET_ERROR;
236 }
237 ret = soclose(s);
238 //Close WSAAsyncSelect thread if one was created for this socket
239 FindAndSetAsyncEvent(s, 0, 0, 0);
240
241 if(ret == SOCKET_ERROR) {
242 WSASetLastError(wsaErrno());
243 }
244 else WSASetLastError(NO_ERROR);
245 return ret;
246}
247//******************************************************************************
248//******************************************************************************
249ODINFUNCTION3(int,OS2connect,
250 SOCKET, s,
251 const struct sockaddr *,name,
252 int, namelen)
253{
254 int ret;
255
256 if(!fWSAInitialized) {
257 WSASetLastError(WSANOTINITIALISED);
258 return SOCKET_ERROR;
259 }
260 else
261 if(WSAIsBlocking()) {
262 WSASetLastError(WSAEINPROGRESS);
263 return SOCKET_ERROR;
264 }
265 ret = connect(s, (sockaddr *)name, namelen);
266 // map BSD error codes
267 if(ret == SOCKET_ERROR) {
268 int sockerror = sock_errno();
269 if(sockerror && sockerror < SOCBASEERR) {
270 sockerror += SOCBASEERR;
271 }
272 if(sockerror == SOCEINPROGRESS) {
273 WSASetLastError(WSAEWOULDBLOCK);
274 }
275 else
276 if(sockerror == SOCEOPNOTSUPP) {
277 WSASetLastError(WSAEINVAL);
278 }
279 else WSASetLastError(wsaErrno());
280 }
281 else WSASetLastError(NO_ERROR);
282 return ret;
283}
284//******************************************************************************
285//******************************************************************************
286ODINFUNCTION3(int,OS2ioctlsocket,
287 SOCKET,s,
288 long, cmd,
289 u_long *,argp)
290{
291 int ret;
292
293 if(!fWSAInitialized) {
294 WSASetLastError(WSANOTINITIALISED);
295 return SOCKET_ERROR;
296 }
297 else
298 if(WSAIsBlocking()) {
299 WSASetLastError(WSAEINPROGRESS);
300 return SOCKET_ERROR;
301 }
302 // clear high word (not used in OS/2's tcpip stack)
303 cmd = LOUSHORT(cmd);
304
305 if(cmd != FIONBIO && cmd != FIONREAD && cmd != SIOCATMARK) {
306 WSASetLastError(WSAEINVAL);
307 return SOCKET_ERROR;
308 }
309
310 WSASetLastError(NO_ERROR);
311
312 //check if app want to set a socket, which has an outstanding async select,
313 //to blocking mode
314 if (cmd == FIONBIO) {
315 HWND hwnd;
316 int msg;
317 ULONG lEvent;
318
319 if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
320 if(*argp != 0) {
321 //nothing to do; already non-blocking
322 return NO_ERROR;
323 }
324 else {
325 dprintf(("Trying to set socket to blocking mode while async select active -> return error!"));
326 WSASetLastError(WSAEINVAL);
327 return SOCKET_ERROR;
328 }
329 }
330 }
331 ret = ioctl(s, cmd, (char *)argp, sizeof(int));
332
333 // Map EOPNOTSUPP to EINVAL
334 int sockerror = sock_errno();
335 if(sockerror && sockerror < SOCBASEERR) {
336 sockerror += SOCBASEERR;
337 }
338
339 if(ret == SOCKET_ERROR && sockerror == SOCEOPNOTSUPP)
340 WSASetLastError(WSAEINVAL);
341 else
342 if(ret == SOCKET_ERROR) {
343 WSASetLastError(wsaErrno());
344 }
345 else WSASetLastError(NO_ERROR);
346 return ret;
347}
348//******************************************************************************
349//******************************************************************************
350ODINFUNCTION3(int,OS2getpeername,
351 SOCKET, s,
352 struct sockaddr *,name,
353 int *, namelen)
354{
355 int ret;
356
357 if(!fWSAInitialized) {
358 WSASetLastError(WSANOTINITIALISED);
359 return SOCKET_ERROR;
360 }
361 else
362 if(WSAIsBlocking()) {
363 WSASetLastError(WSAEINPROGRESS);
364 return SOCKET_ERROR;
365 }
366 else
367 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
368 WSASetLastError(WSAEFAULT);
369 return SOCKET_ERROR;
370 }
371 ret = getsockname(s, name, namelen);
372 if(ret == SOCKET_ERROR) {
373 WSASetLastError(wsaErrno());
374 }
375 else WSASetLastError(NO_ERROR);
376 return ret;
377}
378//******************************************************************************
379//******************************************************************************
380ODINFUNCTION3(int,OS2getsockname,
381 SOCKET,s,
382 struct sockaddr *,name,
383 int *, namelen)
384{
385 int ret;
386
387 if(!fWSAInitialized) {
388 WSASetLastError(WSANOTINITIALISED);
389 return SOCKET_ERROR;
390 }
391 else
392 if(WSAIsBlocking()) {
393 WSASetLastError(WSAEINPROGRESS);
394 return SOCKET_ERROR;
395 }
396 else
397 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
398 WSASetLastError(WSAEFAULT);
399 return SOCKET_ERROR;
400 }
401 ret = getsockname(s, name, namelen);
402 if(ret == SOCKET_ERROR) {
403 WSASetLastError(wsaErrno());
404 }
405 else WSASetLastError(NO_ERROR);
406 return ret;
407}
408//******************************************************************************
409//******************************************************************************
410ODINFUNCTION1(u_long,OS2htonl,
411 u_long,hostlong)
412{
413 return(htonl(hostlong));
414}
415//******************************************************************************
416//******************************************************************************
417ODINFUNCTION1(u_short,OS2htons,
418 u_short,hostshort)
419{
420 return(htons(hostshort));
421}
422//******************************************************************************
423//******************************************************************************
424ODINFUNCTION1(u_long,OS2ntohl,
425 u_long,netlong)
426{
427 return(ntohl(netlong));
428}
429//******************************************************************************
430//******************************************************************************
431ODINFUNCTION1(u_short,OS2ntohs,
432 u_short,netshort)
433{
434 return(ntohs(netshort));
435}
436//******************************************************************************
437//******************************************************************************
438ODINFUNCTION1(unsigned long,OS2inet_addr,
439 const char *, cp)
440{
441 dprintf(("WSOCK32: OS2inet_addr(%s)\n",
442 cp));
443
444 return (inet_addr((char *)cp));
445}
446//******************************************************************************
447//******************************************************************************
448ODINFUNCTION1(char *,OS2inet_ntoa,
449 struct in_addr, in)
450{
451 return(inet_ntoa(in));
452}
453//******************************************************************************
454//******************************************************************************
455ODINFUNCTION3(SOCKET,OS2accept, SOCKET, s,
456 struct sockaddr *,addr,
457 int *, addrlen)
458{
459 int ret, msg;
460 HWND hwnd;
461 ULONG lEvent;
462
463 if(!fWSAInitialized) {
464 WSASetLastError(WSANOTINITIALISED);
465 return SOCKET_ERROR;
466 }
467 else
468 if(WSAIsBlocking()) {
469 WSASetLastError(WSAEINPROGRESS);
470 return SOCKET_ERROR;
471 }
472 else
473 if ((addr != NULL) && (addrlen != NULL)) {
474 if (*addrlen < (int)sizeof(struct sockaddr_in)) {
475 WSASetLastError(WSAEFAULT);
476 return SOCKET_ERROR;
477 }
478 }
479 ret = accept(s, addr, addrlen);
480
481 if(ret != SOCKET_ERROR) {
482 //Enable FD_ACCEPT event flag if WSAAsyncSelect was called for this socket
483 EnableAsyncEvent(s, FD_ACCEPT);
484
485 //if this socket has an active async. select pending, then call WSAAsyncSelect
486 //with the same parameters for the new socket (see docs)
487 if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
488 if(WSAAsyncSelect(ret, hwnd, msg, lEvent) == SOCKET_ERROR) {
489 ret = SOCKET_ERROR;
490 }
491 }
492 }
493 if(ret == SOCKET_ERROR) {
494 WSASetLastError(wsaErrno());
495 }
496 else WSASetLastError(NO_ERROR);
497 return ret;
498}
499//******************************************************************************
500//******************************************************************************
501ODINFUNCTION3(int,OS2bind,
502 SOCKET ,s,
503 const struct sockaddr *,addr,
504 int, namelen)
505{
506 int ret;
507
508 if(!fWSAInitialized) {
509 WSASetLastError(WSANOTINITIALISED);
510 return SOCKET_ERROR;
511 }
512 else
513 if(WSAIsBlocking()) {
514 WSASetLastError(WSAEINPROGRESS);
515 return SOCKET_ERROR;
516 }
517 else
518 if(namelen < (int)sizeof(struct sockaddr_in)) {
519 WSASetLastError(WSAEFAULT);
520 return SOCKET_ERROR;
521 }
522 ret = bind(s, (struct sockaddr *)addr, namelen);
523
524 if(ret == SOCKET_ERROR) {
525 WSASetLastError(wsaErrno());
526 }
527 else WSASetLastError(NO_ERROR);
528 return ret;
529}
530//******************************************************************************
531//******************************************************************************
532ODINFUNCTION2(int,OS2listen,
533 SOCKET, s,
534 int, backlog)
535{
536 int ret, tmp, namelen;
537 struct sockaddr_in name;
538
539 if(!fWSAInitialized) {
540 WSASetLastError(WSANOTINITIALISED);
541 return SOCKET_ERROR;
542 }
543 else
544 if(WSAIsBlocking()) {
545 WSASetLastError(WSAEINPROGRESS);
546 return SOCKET_ERROR;
547 }
548 namelen = sizeof(name);
549 ret = getsockname(s, (struct sockaddr *)&name, &namelen);
550 if (ret == 0) {
551 if (name.sin_port == 0 && name.sin_addr.s_addr == 0) {
552 // Socket is not bound
553 WSASetLastError(WSAEINVAL);
554 return SOCKET_ERROR;
555 }
556 ret = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp)) &
557 (SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING);
558 if(ret) {
559 // Socket is already connected
560 WSASetLastError(WSAEISCONN);
561 return SOCKET_ERROR;
562 }
563 ret = listen(s, backlog);
564 //todo: reset FD_ACCEPT bit? (wine seems to do this, but it's not documented)
565 }
566 if(ret == SOCKET_ERROR) {
567 WSASetLastError(wsaErrno());
568 }
569 else WSASetLastError(NO_ERROR);
570 return ret;
571}
572//******************************************************************************
573//******************************************************************************
574ODINFUNCTION4(int,OS2recv,
575 SOCKET,s,
576 char *,buf,
577 int,len,
578 int,flags)
579{
580 int ret;
581
582 if(!fWSAInitialized) {
583 WSASetLastError(WSANOTINITIALISED);
584 return SOCKET_ERROR;
585 }
586 else
587 if(WSAIsBlocking()) {
588 WSASetLastError(WSAEINPROGRESS);
589 return SOCKET_ERROR;
590 }
591 ret = recv(s, buf, len, flags);
592
593 if(ret == SOCKET_ERROR) {
594 WSASetLastError(wsaErrno());
595 }
596 else WSASetLastError(NO_ERROR);
597
598 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
599 EnableAsyncEvent(s, FD_READ);
600 return ret;
601}
602//******************************************************************************
603//******************************************************************************
604ODINFUNCTION6(int,OS2recvfrom,
605 SOCKET,s,
606 char *,buf,
607 int,len,
608 int,flags,
609 struct sockaddr *,from,
610 int *,fromlen)
611{
612 int ret;
613
614 if(!fWSAInitialized) {
615 WSASetLastError(WSANOTINITIALISED);
616 return SOCKET_ERROR;
617 }
618 else
619 if(WSAIsBlocking()) {
620 WSASetLastError(WSAEINPROGRESS);
621 return SOCKET_ERROR;
622 }
623 else
624 if(fromlen == NULL || *fromlen < (int)sizeof(struct sockaddr_in)) {
625 WSASetLastError(WSAEFAULT);
626 return SOCKET_ERROR;
627 }
628 ret = recvfrom(s, buf, len, flags, from, fromlen);
629
630 if(ret == SOCKET_ERROR) {
631 WSASetLastError(wsaErrno());
632 }
633 else WSASetLastError(NO_ERROR);
634
635 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
636 EnableAsyncEvent(s, FD_READ);
637 return ret;
638}
639//******************************************************************************
640//******************************************************************************
641ODINFUNCTION4(int,OS2send,
642 SOCKET,s,
643 const char *,buf,
644 int,len,
645 int,flags)
646{
647 int ret;
648
649 if(!fWSAInitialized) {
650 WSASetLastError(WSANOTINITIALISED);
651 return SOCKET_ERROR;
652 }
653 else
654 if(WSAIsBlocking()) {
655 WSASetLastError(WSAEINPROGRESS);
656 return SOCKET_ERROR;
657 }
658 ret = send(s, (char *)buf, len, flags);
659
660 if(ret == SOCKET_ERROR) {
661 WSASetLastError(wsaErrno());
662 }
663 else WSASetLastError(NO_ERROR);
664
665 //Reset FD_WRITE event flagfor WSAAsyncSelect thread if one was created for this socket
666 EnableAsyncEvent(s, FD_WRITE);
667 return ret;
668}
669//******************************************************************************
670//******************************************************************************
671ODINFUNCTION6(int,OS2sendto,
672 SOCKET,s,
673 const char *,buf,
674 int,len,
675 int,flags,
676 const struct sockaddr *,to,
677 int,tolen)
678{
679 int ret;
680
681 if(!fWSAInitialized) {
682 WSASetLastError(WSANOTINITIALISED);
683 return SOCKET_ERROR;
684 }
685 else
686 if(WSAIsBlocking()) {
687 WSASetLastError(WSAEINPROGRESS);
688 return SOCKET_ERROR;
689 }
690 else
691 if(tolen < (int)sizeof(struct sockaddr_in)) {
692 WSASetLastError(WSAEFAULT);
693 return SOCKET_ERROR;
694 }
695 ret = sendto(s, (char *)buf, len, flags, (struct sockaddr *)to, tolen);
696
697 if(ret == SOCKET_ERROR) {
698 WSASetLastError(wsaErrno());
699 }
700 else WSASetLastError(NO_ERROR);
701
702 //Reset FD_WRITE event flagfor WSAAsyncSelect thread if one was created for this socket
703 EnableAsyncEvent(s, FD_WRITE);
704 return ret;
705}
706//******************************************************************************
707//******************************************************************************
708ODINFUNCTION5(int,OS2select,
709 int,nfds,
710 ws_fd_set *,readfds,
711 ws_fd_set *,writefds,
712 ws_fd_set *,exceptfds,
713 const struct timeval *,timeout)
714{
715 int ret, i, j;
716 int *sockets, *socktmp;
717 int nrread, nrwrite, nrexcept;
718 ULONG ttimeout;
719
720 WSASetLastError(NO_ERROR);
721
722 if(!fWSAInitialized) {
723 WSASetLastError(WSANOTINITIALISED);
724 return SOCKET_ERROR;
725 }
726 else
727 if(WSAIsBlocking()) {
728 WSASetLastError(WSAEINPROGRESS);
729 return SOCKET_ERROR;
730 }
731 else {
732 nrread = nrwrite = nrexcept = 0;
733 if(readfds) {
734 nrread += readfds->fd_count;
735 }
736 if(writefds) {
737 nrwrite += writefds->fd_count;
738 }
739 if(exceptfds) {
740 nrexcept += exceptfds->fd_count;
741 }
742 if(nrread + nrwrite + nrexcept == 0) {
743 WSASetLastError(WSAEINVAL);
744 return SOCKET_ERROR;
745 }
746 if(timeout != NULL && (timeout->tv_sec < 0 || timeout->tv_usec < 0)) {
747 WSASetLastError(WSAEINVAL);
748 return SOCKET_ERROR;
749 }
750 if(timeout == NULL) {
751 ttimeout = -1L; // no timeout
752 }
753 else ttimeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
754
755 sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept));
756 if(readfds) {
757 memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET));
758 }
759 if(writefds) {
760 memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET));
761 }
762 if(exceptfds) {
763 memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET));
764 }
765
766 ret = select(sockets, nrread, nrwrite, nrexcept, ttimeout);
767
768 if(ret == SOCKET_ERROR)
769 {
770 if(readfds != NULL)
771 readfds->fd_count = 0;
772
773 if(writefds != NULL)
774 writefds->fd_count = 0;
775
776 if(exceptfds != NULL)
777 exceptfds->fd_count = 0;
778
779 WSASetLastError(wsaErrno());
780 free(sockets);
781 return SOCKET_ERROR;
782 }
783
784 if(ret != 0) {
785 socktmp = sockets;
786 if(readfds != NULL) {
787 j = 0;
788 for(i=0;i<nrread;i++) {
789 if(socktmp[i] != -1) {
790 readfds->fd_array[i] = socktmp[i];
791 j++;
792 }
793 }
794 readfds->fd_count = j;
795 socktmp += nrread;
796 }
797
798 if(writefds != NULL) {
799 j = 0;
800 for(i=0;i<nrwrite;i++) {
801 if(socktmp[i] != -1) {
802 writefds->fd_array[i] = socktmp[i];
803 j++;
804 }
805 }
806 writefds->fd_count = j;
807 socktmp += nrwrite;
808 }
809 if(exceptfds != NULL) {
810 j = 0;
811 for(i=0;i<nrexcept;i++) {
812 if(socktmp[i] != -1) {
813 exceptfds->fd_array[i] = socktmp[i];
814 j++;
815 }
816 }
817 exceptfds->fd_count = j;
818 }
819 }
820 else {
821 if(readfds != NULL)
822 readfds->fd_count = 0;
823
824 if(writefds != NULL)
825 writefds->fd_count = 0;
826
827 if(exceptfds != NULL)
828 exceptfds->fd_count = 0;
829 }
830 free(sockets);
831 }
832 return ret;
833}
834//******************************************************************************
835//******************************************************************************
836ODINFUNCTION5(int,OS2setsockopt,
837 SOCKET,s,
838 int,level,
839 int,optname,
840 const char *,optval,
841 int,optlen)
842{
843 struct ws_linger *yy;
844 struct linger xx;
845 int ret;
846 ULONG size;
847
848 if(!fWSAInitialized) {
849 WSASetLastError(WSANOTINITIALISED);
850 return SOCKET_ERROR;
851 }
852 else
853 if(WSAIsBlocking()) {
854 WSASetLastError(WSAEINPROGRESS);
855 return SOCKET_ERROR;
856 }
857 if (level == SOL_SOCKET) {
858 switch(optname) {
859 case SO_DONTLINGER:
860 case SO_LINGER:
861 if(optlen < (int)sizeof(ws_linger)) {
862 WSASetLastError(WSAEFAULT);
863 return SOCKET_ERROR;
864 }
865 yy = (struct ws_linger *)optval;
866 xx.l_onoff = (optname == SO_DONTLINGER) ? !yy->l_onoff : yy->l_onoff;
867 xx.l_linger = yy->l_linger;
868
869 ret = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
870 break;
871 case SO_SNDBUF:
872 case SO_RCVBUF:
873 if(optlen < (int)sizeof(int)) {
874 WSASetLastError(WSAEFAULT);
875 return SOCKET_ERROR;
876 }
877
878 size = *(ULONG *)optval;
879tryagain:
880 ret = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
881 if(ret == SOCKET_ERROR && size > 65535) {
882 dprintf(("setsockopt: change size from %d to 65000", size));
883 //SvL: Limit send & receive buffer length to 64k
884 // (only happens with 16 bits tcpip stack?)
885 size = 65000;
886 goto tryagain;
887 }
888 break;
889
890 case SO_BROADCAST:
891 case SO_DEBUG:
892 case SO_KEEPALIVE:
893 case SO_DONTROUTE:
894 case SO_OOBINLINE:
895 case SO_REUSEADDR:
896 if(optlen < (int)sizeof(int)) {
897 WSASetLastError(WSAEFAULT);
898 return SOCKET_ERROR;
899 }
900 ret = setsockopt(s, level, optname, (char *)optval, optlen);
901 break;
902 default:
903 dprintf(("setsockopt: unknown option %x", optname));
904 WSASetLastError(WSAENOPROTOOPT);
905 return SOCKET_ERROR;
906 }
907 }
908 else
909 if(level == IPPROTO_TCP) {
910 if(optname == TCP_NODELAY) {
911 if(optlen < (int)sizeof(int)) {
912 WSASetLastError(WSAEFAULT);
913 return SOCKET_ERROR;
914 }
915 ret = setsockopt(s, level, optname, (char *)optval, optlen);
916 }
917 else {
918 dprintf(("setsockopt: unknown option %x", optname));
919 WSASetLastError(WSAENOPROTOOPT);
920 return SOCKET_ERROR;
921 }
922 }
923 else {
924 WSASetLastError(WSAEINVAL);
925 return SOCKET_ERROR;
926 }
927
928 if(ret == SOCKET_ERROR) {
929 WSASetLastError(wsaErrno());
930 }
931 else WSASetLastError(NO_ERROR);
932 return ret;
933}
934//******************************************************************************
935//******************************************************************************
936ODINFUNCTION5(int,OS2getsockopt,
937 SOCKET, s,
938 int, level,
939 int, optname,
940 char *, optval,
941 int *,optlen)
942{
943 struct ws_linger *yy;
944 struct linger xx;
945 int ret;
946 int size, options;
947
948 if(!fWSAInitialized) {
949 WSASetLastError(WSANOTINITIALISED);
950 return SOCKET_ERROR;
951 }
952 else
953 if(WSAIsBlocking()) {
954 WSASetLastError(WSAEINPROGRESS);
955 return SOCKET_ERROR;
956 }
957 if (level == SOL_SOCKET) {
958 switch(optname) {
959 case SO_DONTLINGER:
960 case SO_LINGER:
961 if(optlen == NULL || *optlen < sizeof(ws_linger)) {
962 WSASetLastError(WSAEFAULT);
963 return SOCKET_ERROR;
964 }
965 size = sizeof(xx);
966 ret = getsockopt(s,level,optname,(char *)&xx, &size);
967 yy = (struct ws_linger *)optval;
968 yy->l_onoff = (optname == SO_DONTLINGER) ? !xx.l_onoff : xx.l_onoff;
969 yy->l_linger = xx.l_linger;
970 *optlen = size;
971 break;
972
973 case SO_SNDBUF:
974 case SO_RCVBUF:
975 case SO_BROADCAST:
976 case SO_DEBUG:
977 case SO_KEEPALIVE:
978 case SO_DONTROUTE:
979 case SO_OOBINLINE:
980 case SO_REUSEADDR:
981 case SO_TYPE:
982 if(optlen == NULL || *optlen < sizeof(int)) {
983 WSASetLastError(WSAEFAULT);
984 return SOCKET_ERROR;
985 }
986 ret = getsockopt(s, level, optname, (char *)optval, optlen);
987 break;
988 case SO_ACCEPTCONN:
989 if(optlen == NULL || *optlen < sizeof(int)) {
990 WSASetLastError(WSAEFAULT);
991 return SOCKET_ERROR;
992 }
993 size = sizeof(options);
994 ret = getsockopt(s, SOL_SOCKET, SO_OPTIONS, (char *)&options, &size);
995 if(ret != SOCKET_ERROR) {
996 *(BOOL *)optval = (options & SO_ACCEPTCONN) == SO_ACCEPTCONN;
997 *optlen = sizeof(BOOL);
998 }
999 break;
1000 default:
1001 dprintf(("getsockopt: unknown option %x", optname));
1002 WSASetLastError(WSAENOPROTOOPT);
1003 return SOCKET_ERROR;
1004 }
1005 }
1006 else
1007 if(level == IPPROTO_TCP) {
1008 if(optname == TCP_NODELAY) {
1009 if(optlen == NULL || *optlen < sizeof(int)) {
1010 WSASetLastError(WSAEFAULT);
1011 return SOCKET_ERROR;
1012 }
1013 ret = getsockopt(s, level, optname, (char *)optval, optlen);
1014 }
1015 else {
1016 dprintf(("getsockopt: unknown option %x", optname));
1017 WSASetLastError(WSAENOPROTOOPT);
1018 return SOCKET_ERROR;
1019 }
1020 }
1021 else {
1022 WSASetLastError(WSAEINVAL);
1023 return SOCKET_ERROR;
1024 }
1025
1026 if(ret == SOCKET_ERROR) {
1027 WSASetLastError(wsaErrno());
1028 }
1029 else WSASetLastError(NO_ERROR);
1030 return ret;
1031}
1032//******************************************************************************
1033//******************************************************************************
1034/* Database function prototypes */
1035//******************************************************************************
1036//******************************************************************************
1037ODINFUNCTION2(int,OS2gethostname,
1038 char *,name,
1039 int,namelen)
1040{
1041 int ret;
1042
1043 ret = gethostname(name, namelen);
1044 if(ret == NULL) {
1045 WSASetLastError(NO_ERROR);
1046 return 0;
1047 }
1048 WSASetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
1049 return SOCKET_ERROR;
1050}
1051//******************************************************************************
1052//******************************************************************************
1053ODINFUNCTION3(ws_hostent *,OS2gethostbyaddr,
1054 const char *,addr,
1055 int,len,
1056 int,type)
1057{
1058 LPWSINFO pwsi = WINSOCK_GetIData();
1059
1060 if( pwsi )
1061 {
1062 struct hostent* host;
1063 if( (host = gethostbyaddr((char *)addr, len, type)) != NULL ) {
1064 if( WS_dup_he(pwsi, host) ) {
1065 WSASetLastError(NO_ERROR);
1066 return pwsi->he;
1067 }
1068 else WSASetLastError(WSAENOBUFS);
1069 }
1070 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1071 }
1072 else WSASetLastError(WSANOTINITIALISED);
1073 return NULL;
1074}
1075//******************************************************************************
1076//******************************************************************************
1077ODINFUNCTION1(ws_hostent *,OS2gethostbyname,
1078 const char *,name)
1079{
1080 LPWSINFO pwsi = WINSOCK_GetIData();
1081
1082 if( pwsi )
1083 {
1084 struct hostent* host;
1085 if( (host = gethostbyname((char *)name)) != NULL ) {
1086 if( WS_dup_he(pwsi, host) ) {
1087 WSASetLastError(NO_ERROR);
1088 return pwsi->he;
1089 }
1090 else WSASetLastError(WSAENOBUFS);
1091 }
1092 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1093 }
1094 else WSASetLastError(WSANOTINITIALISED);
1095 return NULL;
1096}
1097//******************************************************************************
1098//******************************************************************************
1099ODINFUNCTION2(struct ws_servent *,OS2getservbyport,
1100 int, port,
1101 const char *, proto)
1102{
1103 LPWSINFO pwsi = WINSOCK_GetIData();
1104
1105 if( pwsi )
1106 {
1107 struct servent* serv;
1108 if( (serv = getservbyport(port, (char *)proto)) != NULL ) {
1109 if( WS_dup_se(pwsi, serv) ) {
1110 WSASetLastError(NO_ERROR);
1111 return pwsi->se;
1112 }
1113 else WSASetLastError(WSAENOBUFS);
1114 }
1115 else WSASetLastError(WSANO_DATA);
1116 }
1117 else WSASetLastError(WSANOTINITIALISED);
1118 return NULL;
1119}
1120//******************************************************************************
1121//******************************************************************************
1122ODINFUNCTION2(struct ws_servent *,OS2getservbyname,
1123 const char *, name,
1124 const char *, proto)
1125{
1126 LPWSINFO pwsi = WINSOCK_GetIData();
1127
1128 if( pwsi )
1129 {
1130 struct servent *serv;
1131 if( (serv = getservbyname((char *)name, (char *)proto)) != NULL ) {
1132 if( WS_dup_se(pwsi, serv) ) {
1133 WSASetLastError(NO_ERROR);
1134 return pwsi->se;
1135 }
1136 else WSASetLastError(WSAENOBUFS);
1137 }
1138 else WSASetLastError(WSANO_DATA);
1139 }
1140 else WSASetLastError(WSANOTINITIALISED);
1141 return NULL;
1142}
1143//******************************************************************************
1144//******************************************************************************
1145ODINFUNCTION1(struct ws_protoent *,OS2getprotobynumber,
1146 int,number)
1147{
1148 LPWSINFO pwsi = WINSOCK_GetIData();
1149
1150 if( pwsi )
1151 {
1152 struct protoent* proto;
1153 if( (proto = getprotobynumber(number)) != NULL ) {
1154 if( WS_dup_pe(pwsi, proto) ) {
1155 WSASetLastError(NO_ERROR);
1156 return pwsi->pe;
1157 }
1158 else WSASetLastError(WSAENOBUFS);
1159 }
1160 else WSASetLastError(WSANO_DATA);
1161 }
1162 else WSASetLastError(WSANOTINITIALISED);
1163 return NULL;
1164}
1165//******************************************************************************
1166//******************************************************************************
1167ODINFUNCTION1(struct ws_protoent *,OS2getprotobyname,
1168 const char *,name)
1169{
1170 LPWSINFO pwsi = WINSOCK_GetIData();
1171
1172 if( pwsi )
1173 {
1174 struct protoent * proto;
1175 if( (proto = getprotobyname((char *)name)) != NULL ) {
1176 if(WS_dup_pe(pwsi, proto)) {
1177 WSASetLastError(NO_ERROR);
1178 return pwsi->pe;
1179 }
1180 else WSASetLastError(WSAENOBUFS);
1181 }
1182 else WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
1183 }
1184 else WSASetLastError(WSANOTINITIALISED);
1185 return NULL;
1186}
1187//******************************************************************************
1188//******************************************************************************
Note: See TracBrowser for help on using the repository browser.