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

Last change on this file since 3195 was 3195, checked in by sandervl, 25 years ago

wsock32 rewrite (no pmwsock dependancy)

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