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

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

bugfixes

File size: 32.5 KB
RevLine 
[3210]1/* $Id: wsock32.cpp,v 1.18 2000-03-23 23:07:23 sandervl Exp $ */
[3198]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 }
[3205]96 if(iData == NULL) {
[3198]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//******************************************************************************
[3205]147void WIN32API WSASetLastError(int iError)
[3198]148{
149 // according to the docs, WSASetLastError() is just a call-through
150 // to SetLastError()
[3205]151 if(iError) {
152 dprintf(("WSASetLastError %x", iError));
153 }
[3198]154 SetLastError(iError);
155}
156//******************************************************************************
157//******************************************************************************
[3205]158int WIN32API WSAGetLastError()
[3198]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 //Close WSAAsyncSelect thread if one was created for this socket
[3210]235 FindAndSetAsyncEvent(s, 0, 0, 0);
236
[3198]237 if(ret == SOCKET_ERROR) {
238 WSASetLastError(wsaErrno());
239 }
240 else WSASetLastError(NO_ERROR);
241 return ret;
242}
243//******************************************************************************
244//******************************************************************************
245ODINFUNCTION3(int,OS2connect,
246 SOCKET, s,
247 const struct sockaddr *,name,
248 int, namelen)
249{
250 int ret;
251
252 if(!fWSAInitialized) {
253 WSASetLastError(WSANOTINITIALISED);
254 return SOCKET_ERROR;
255 }
256 else
257 if(WSAIsBlocking()) {
258 WSASetLastError(WSAEINPROGRESS);
259 return SOCKET_ERROR;
260 }
261 ret = connect(s, (sockaddr *)name, namelen);
262 // map BSD error codes
263 if(ret == SOCKET_ERROR) {
264 if(sock_errno() == SOCEINPROGRESS) {
265 WSASetLastError(WSAEWOULDBLOCK);
266 }
267 else
268 if (sock_errno() == SOCEOPNOTSUPP) {
269 WSASetLastError(WSAEINVAL);
270 }
271 else WSASetLastError(wsaErrno());
272 }
273 else WSASetLastError(NO_ERROR);
274 return ret;
275}
276//******************************************************************************
277//******************************************************************************
278ODINFUNCTION3(int,OS2ioctlsocket,
279 SOCKET,s,
280 long, cmd,
281 u_long *,argp)
282{
283 int ret;
284
285 if(!fWSAInitialized) {
286 WSASetLastError(WSANOTINITIALISED);
287 return SOCKET_ERROR;
288 }
289 else
290 if(WSAIsBlocking()) {
291 WSASetLastError(WSAEINPROGRESS);
292 return SOCKET_ERROR;
293 }
[3205]294 // clear high word (not used in OS/2's tcpip stack)
295 cmd = LOUSHORT(cmd);
296
[3198]297 if(cmd != FIONBIO && cmd != FIONREAD && cmd != SIOCATMARK) {
298 WSASetLastError(WSAEINVAL);
299 return SOCKET_ERROR;
300 }
301
302 WSASetLastError(NO_ERROR);
303
304 //check if app want to set a socket, which has an outstanding async select,
305 //to blocking mode
306 if (cmd == FIONBIO) {
307 HWND hwnd;
308 int msg;
309 ULONG lEvent;
310
311 if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
312 if(*argp != 0) {
313 //nothing to do; already non-blocking
314 return NO_ERROR;
315 }
316 else {
317 dprintf(("Trying to set socket to blocking mode while async select active -> return error!"));
318 WSASetLastError(WSAEINVAL);
319 return SOCKET_ERROR;
320 }
321 }
322 }
[3205]323 ret = ioctl(s, cmd, (char *)argp, sizeof(int));
[3198]324
325 // Map EOPNOTSUPP to EINVAL
326 if(ret == SOCKET_ERROR && sock_errno() == SOCEOPNOTSUPP)
327 WSASetLastError(WSAEINVAL);
328 else
329 if(ret == SOCKET_ERROR) {
330 WSASetLastError(wsaErrno());
331 }
332 else WSASetLastError(NO_ERROR);
333 return ret;
334}
335//******************************************************************************
336//******************************************************************************
337ODINFUNCTION3(int,OS2getpeername,
338 SOCKET, s,
339 struct sockaddr *,name,
340 int *, namelen)
341{
342 int ret;
343
344 if(!fWSAInitialized) {
345 WSASetLastError(WSANOTINITIALISED);
346 return SOCKET_ERROR;
347 }
348 else
349 if(WSAIsBlocking()) {
350 WSASetLastError(WSAEINPROGRESS);
351 return SOCKET_ERROR;
352 }
353 else
354 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
355 WSASetLastError(WSAEFAULT);
356 return SOCKET_ERROR;
357 }
358 ret = getsockname(s, name, namelen);
359 if(ret == SOCKET_ERROR) {
360 WSASetLastError(wsaErrno());
361 }
362 else WSASetLastError(NO_ERROR);
363 return ret;
364}
365//******************************************************************************
366//******************************************************************************
367ODINFUNCTION3(int,OS2getsockname,
368 SOCKET,s,
369 struct sockaddr *,name,
370 int *, namelen)
371{
372 int ret;
373
374 if(!fWSAInitialized) {
375 WSASetLastError(WSANOTINITIALISED);
376 return SOCKET_ERROR;
377 }
378 else
379 if(WSAIsBlocking()) {
380 WSASetLastError(WSAEINPROGRESS);
381 return SOCKET_ERROR;
382 }
383 else
384 if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
385 WSASetLastError(WSAEFAULT);
386 return SOCKET_ERROR;
387 }
388 ret = getsockname(s, name, namelen);
389 if(ret == SOCKET_ERROR) {
390 WSASetLastError(wsaErrno());
391 }
392 else WSASetLastError(NO_ERROR);
393 return ret;
394}
395//******************************************************************************
396//******************************************************************************
397ODINFUNCTION1(u_long,OS2htonl,
398 u_long,hostlong)
399{
400 return(htonl(hostlong));
401}
402//******************************************************************************
403//******************************************************************************
404ODINFUNCTION1(u_short,OS2htons,
405 u_short,hostshort)
406{
407 return(htons(hostshort));
408}
409//******************************************************************************
410//******************************************************************************
411ODINFUNCTION1(u_long,OS2ntohl,
412 u_long,netlong)
413{
414 return(ntohl(netlong));
415}
416//******************************************************************************
417//******************************************************************************
418ODINFUNCTION1(u_short,OS2ntohs,
419 u_short,netshort)
420{
421 return(ntohs(netshort));
422}
423//******************************************************************************
424//******************************************************************************
425ODINFUNCTION1(unsigned long,OS2inet_addr,
426 const char *, cp)
427{
428 dprintf(("WSOCK32: OS2inet_addr(%s)\n",
429 cp));
430
431 return (inet_addr((char *)cp));
432}
433//******************************************************************************
434//******************************************************************************
435ODINFUNCTION1(char *,OS2inet_ntoa,
436 struct in_addr, in)
437{
438 return(inet_ntoa(in));
439}
440//******************************************************************************
441//******************************************************************************
442ODINFUNCTION3(SOCKET,OS2accept, SOCKET, s,
443 struct sockaddr *,addr,
444 int *, addrlen)
445{
446 int ret, msg;
447 HWND hwnd;
448 ULONG lEvent;
449
450 if(!fWSAInitialized) {
451 WSASetLastError(WSANOTINITIALISED);
452 return SOCKET_ERROR;
453 }
454 else
455 if(WSAIsBlocking()) {
456 WSASetLastError(WSAEINPROGRESS);
457 return SOCKET_ERROR;
458 }
459 else
460 if ((addr != NULL) && (addrlen != NULL)) {
461 if (*addrlen < (int)sizeof(struct sockaddr_in)) {
462 WSASetLastError(WSAEFAULT);
463 return SOCKET_ERROR;
464 }
465 }
466 ret = accept(s, addr, addrlen);
467
468 if(ret != SOCKET_ERROR) {
469 //Enable FD_ACCEPT event flag if WSAAsyncSelect was called for this socket
470 EnableAsyncEvent(s, FD_ACCEPT);
471
472 //if this socket has an active async. select pending, then call WSAAsyncSelect
473 //with the same parameters for the new socket (see docs)
474 if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
475 if(WSAAsyncSelect(ret, hwnd, msg, lEvent) == SOCKET_ERROR) {
476 ret = SOCKET_ERROR;
477 }
478 }
479 }
480 if(ret == SOCKET_ERROR) {
481 WSASetLastError(wsaErrno());
482 }
483 else WSASetLastError(NO_ERROR);
484 return ret;
485}
486//******************************************************************************
487//******************************************************************************
488ODINFUNCTION3(int,OS2bind,
489 SOCKET ,s,
490 const struct sockaddr *,addr,
491 int, namelen)
492{
493 int ret;
494
495 if(!fWSAInitialized) {
496 WSASetLastError(WSANOTINITIALISED);
497 return SOCKET_ERROR;
498 }
499 else
500 if(WSAIsBlocking()) {
501 WSASetLastError(WSAEINPROGRESS);
502 return SOCKET_ERROR;
503 }
504 else
505 if(namelen < (int)sizeof(struct sockaddr_in)) {
506 WSASetLastError(WSAEFAULT);
507 return SOCKET_ERROR;
508 }
509 ret = bind(s, (struct sockaddr *)addr, namelen);
510
511 if(ret == SOCKET_ERROR) {
512 WSASetLastError(wsaErrno());
513 }
514 else WSASetLastError(NO_ERROR);
515 return ret;
516}
517//******************************************************************************
518//******************************************************************************
519ODINFUNCTION2(int,OS2listen,
520 SOCKET, s,
521 int, backlog)
522{
523 int ret, tmp, namelen;
524 struct sockaddr_in name;
525
526 if(!fWSAInitialized) {
527 WSASetLastError(WSANOTINITIALISED);
528 return SOCKET_ERROR;
529 }
530 else
531 if(WSAIsBlocking()) {
532 WSASetLastError(WSAEINPROGRESS);
533 return SOCKET_ERROR;
534 }
535 namelen = sizeof(name);
536 ret = getsockname(s, (struct sockaddr *)&name, &namelen);
537 if (ret == 0) {
538 if (name.sin_port == 0 && name.sin_addr.s_addr == 0) {
539 // Socket is not bound
540 WSASetLastError(WSAEINVAL);
541 return SOCKET_ERROR;
542 }
543 ret = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp)) &
544 (SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING);
545 if(ret) {
546 // Socket is already connected
547 WSASetLastError(WSAEISCONN);
548 return SOCKET_ERROR;
549 }
550 ret = listen(s, backlog);
551 //todo: reset FD_ACCEPT bit? (wine seems to do this, but it's not documented)
552 }
553 if(ret == SOCKET_ERROR) {
554 WSASetLastError(wsaErrno());
555 }
556 else WSASetLastError(NO_ERROR);
557 return ret;
558}
559//******************************************************************************
560//******************************************************************************
561ODINFUNCTION4(int,OS2recv,
562 SOCKET,s,
563 char *,buf,
564 int,len,
565 int,flags)
566{
567 int ret;
568
569 if(!fWSAInitialized) {
570 WSASetLastError(WSANOTINITIALISED);
571 return SOCKET_ERROR;
572 }
573 else
574 if(WSAIsBlocking()) {
575 WSASetLastError(WSAEINPROGRESS);
576 return SOCKET_ERROR;
577 }
578 ret = recv(s, buf, len, flags);
579
580 if(ret == SOCKET_ERROR) {
581 WSASetLastError(wsaErrno());
582 }
583 else WSASetLastError(NO_ERROR);
584
585 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
586 EnableAsyncEvent(s, FD_READ);
587 return ret;
588}
589//******************************************************************************
590//******************************************************************************
591ODINFUNCTION6(int,OS2recvfrom,
592 SOCKET,s,
593 char *,buf,
594 int,len,
595 int,flags,
596 struct sockaddr *,from,
597 int *,fromlen)
598{
599 int ret;
600
601 if(!fWSAInitialized) {
602 WSASetLastError(WSANOTINITIALISED);
603 return SOCKET_ERROR;
604 }
605 else
606 if(WSAIsBlocking()) {
607 WSASetLastError(WSAEINPROGRESS);
608 return SOCKET_ERROR;
609 }
610 else
611 if(fromlen == NULL || *fromlen < (int)sizeof(struct sockaddr_in)) {
612 WSASetLastError(WSAEFAULT);
613 return SOCKET_ERROR;
614 }
615 ret = recvfrom(s, buf, len, flags, from, fromlen);
616
617 if(ret == SOCKET_ERROR) {
618 WSASetLastError(wsaErrno());
619 }
620 else WSASetLastError(NO_ERROR);
621
622 //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
623 EnableAsyncEvent(s, FD_READ);
624 return ret;
625}
626//******************************************************************************
627//******************************************************************************
628ODINFUNCTION4(int,OS2send,
629 SOCKET,s,
630 const char *,buf,
631 int,len,
632 int,flags)
633{
634 int ret;
635
636 if(!fWSAInitialized) {
637 WSASetLastError(WSANOTINITIALISED);
638 return SOCKET_ERROR;
639 }
640 else
641 if(WSAIsBlocking()) {
642 WSASetLastError(WSAEINPROGRESS);
643 return SOCKET_ERROR;
644 }
645 ret = send(s, (char *)buf, len, flags);
646
647 if(ret == SOCKET_ERROR) {
648 WSASetLastError(wsaErrno());
649 }
650 else WSASetLastError(NO_ERROR);
651
652 //Reset FD_WRITE event flagfor WSAAsyncSelect thread if one was created for this socket
653 EnableAsyncEvent(s, FD_WRITE);
654 return ret;
655}
656//******************************************************************************
657//******************************************************************************
658ODINFUNCTION6(int,OS2sendto,
659 SOCKET,s,
660 const char *,buf,
661 int,len,
662 int,flags,
663 const struct sockaddr *,to,
664 int,tolen)
665{
666 int ret;
667
668 if(!fWSAInitialized) {
669 WSASetLastError(WSANOTINITIALISED);
670 return SOCKET_ERROR;
671 }
672 else
673 if(WSAIsBlocking()) {
674 WSASetLastError(WSAEINPROGRESS);
675 return SOCKET_ERROR;
676 }
677 else
678 if(tolen < (int)sizeof(struct sockaddr_in)) {
679 WSASetLastError(WSAEFAULT);
680 return SOCKET_ERROR;
681 }
682 ret = sendto(s, (char *)buf, len, flags, (struct sockaddr *)to, tolen);
683
684 if(ret == SOCKET_ERROR) {
685 WSASetLastError(wsaErrno());
686 }
687 else WSASetLastError(NO_ERROR);
688
689 //Reset FD_WRITE event flagfor WSAAsyncSelect thread if one was created for this socket
690 EnableAsyncEvent(s, FD_WRITE);
691 return ret;
692}
693//******************************************************************************
694//******************************************************************************
695ODINFUNCTION5(int,OS2select,
696 int,nfds,
697 ws_fd_set *,readfds,
698 ws_fd_set *,writefds,
699 ws_fd_set *,exceptfds,
700 const struct timeval *,timeout)
701{
702 int ret, i, j;
703 int *sockets, *socktmp;
704 int nrread, nrwrite, nrexcept;
705 ULONG ttimeout;
706
707 WSASetLastError(NO_ERROR);
708
709 if(!fWSAInitialized) {
710 WSASetLastError(WSANOTINITIALISED);
711 return SOCKET_ERROR;
712 }
713 else
714 if(WSAIsBlocking()) {
715 WSASetLastError(WSAEINPROGRESS);
716 return SOCKET_ERROR;
717 }
718 else {
719 nrread = nrwrite = nrexcept = 0;
720 if(readfds) {
721 nrread += readfds->fd_count;
722 }
723 if(writefds) {
724 nrwrite += writefds->fd_count;
725 }
726 if(exceptfds) {
727 nrexcept += exceptfds->fd_count;
728 }
729 if(nrread + nrwrite + nrexcept == 0) {
730 WSASetLastError(WSAEINVAL);
731 return SOCKET_ERROR;
732 }
733 if(timeout != NULL && (timeout->tv_sec < 0 || timeout->tv_usec < 0)) {
734 WSASetLastError(WSAEINVAL);
735 return SOCKET_ERROR;
736 }
737 if(timeout == NULL) {
738 ttimeout = -1L; // no timeout
739 }
740 else ttimeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
741
742 sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept));
743 if(readfds) {
744 memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET));
745 }
746 if(writefds) {
747 memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET));
748 }
749 if(exceptfds) {
750 memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET));
751 }
752
753 ret = select(sockets, nrread, nrwrite, nrexcept, ttimeout);
754
755 if(ret == SOCKET_ERROR)
756 {
757 if(readfds != NULL)
758 readfds->fd_count = 0;
759
760 if(writefds != NULL)
761 writefds->fd_count = 0;
762
763 if(exceptfds != NULL)
764 exceptfds->fd_count = 0;
765
766 WSASetLastError(wsaErrno());
767 free(sockets);
768 return SOCKET_ERROR;
769 }
770
771 if(ret != 0) {
772 socktmp = sockets;
773 if(readfds != NULL) {
774 for(i=0;i<nrread;i++) {
775 if(socktmp[i] != -1) {
776 readfds->fd_array[j] = socktmp[i];
777 }
778 }
779 readfds->fd_count = i;
780 socktmp += nrread;
781 }
782
783 if(writefds != NULL) {
784 for(i=0;i<nrwrite;i++) {
785 if(socktmp[i] != -1) {
786 writefds->fd_array[j] = socktmp[i];
787 }
788 }
789 writefds->fd_count = i;
790 socktmp += nrwrite;
791 }
792 if(exceptfds != NULL) {
793 for(i=0;i<nrexcept;i++) {
794 if(socktmp[i] != -1) {
795 exceptfds->fd_array[j] = socktmp[i];
796 }
797 }
798 exceptfds->fd_count = i;
799 }
800 }
801 else {
802 if(readfds != NULL)
803 readfds->fd_count = 0;
804
805 if(writefds != NULL)
806 writefds->fd_count = 0;
807
808 if(exceptfds != NULL)
809 exceptfds->fd_count = 0;
810 }
811 free(sockets);
812 }
813 return ret;
814}
815//******************************************************************************
816//******************************************************************************
817ODINFUNCTION5(int,OS2setsockopt,
818 SOCKET,s,
819 int,level,
820 int,optname,
821 const char *,optval,
822 int,optlen)
823{
824 struct ws_linger *yy;
825 struct linger xx;
826 int ret;
827 ULONG size;
828
829 if(!fWSAInitialized) {
830 WSASetLastError(WSANOTINITIALISED);
831 return SOCKET_ERROR;
832 }
833 else
834 if(WSAIsBlocking()) {
835 WSASetLastError(WSAEINPROGRESS);
836 return SOCKET_ERROR;
837 }
838 if (level == SOL_SOCKET) {
839 switch(optname) {
840 case SO_DONTLINGER:
841 case SO_LINGER:
842 if(optlen < (int)sizeof(ws_linger)) {
843 WSASetLastError(WSAEFAULT);
844 return SOCKET_ERROR;
845 }
846 yy = (struct ws_linger *)optval;
847 xx.l_onoff = (optname == SO_DONTLINGER) ? !yy->l_onoff : yy->l_onoff;
848 xx.l_linger = yy->l_linger;
849
850 ret = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
851 break;
852 case SO_SNDBUF:
853 case SO_RCVBUF:
854 if(optlen < (int)sizeof(int)) {
855 WSASetLastError(WSAEFAULT);
856 return SOCKET_ERROR;
857 }
858
859 size = *(ULONG *)optval;
860tryagain:
861 ret = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
862 if(ret == SOCKET_ERROR && size > 65535) {
[3210]863 dprintf(("setsockopt: change size from %d to 65000", size));
[3198]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:
[3205]884 dprintf(("setsockopt: unknown option %x", optname));
[3198]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 {
[3205]899 dprintf(("setsockopt: unknown option %x", optname));
[3198]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:
[3205]982 dprintf(("getsockopt: unknown option %x", optname));
[3198]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 {
[3205]997 dprintf(("getsockopt: unknown option %x", optname));
[3198]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.