source: trunk/src/wsock32/new/wsock32.cpp@ 3205

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

wsock32\new update

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