Ignore:
Timestamp:
Mar 22, 2000, 7:46:20 PM (25 years ago)
Author:
sandervl
Message:

wsock32 rewrite (no pmwsock dependancy)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wsock32/wsock32.cpp

    r3171 r3195  
    1 /* $Id: wsock32.cpp,v 1.21 2000-03-20 20:31:30 sandervl Exp $ */
     1/* $Id: wsock32.cpp,v 1.22 2000-03-22 18:46:19 sandervl Exp $ */
    22
    33/*
     
    88 *
    99 * 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.
    1014 *
    1115 */
     
    1721 *            -> open issue: WSASetLastError / WSAGetLastError
    1822 *               call SetLastError / GetLastError according to docs
     23 *
     24 * 2000/22/03 Complete rewrite -> got rid of pmwsock
    1925 *
    2026 * identical structures:
     
    3844 *****************************************************************************/
    3945
    40 #include <pmwsock.h>
    41 #include <odin.h>
     46#define INCL_BASE
     47#include <os2wrap.h>    //Odin32 OS/2 api wrappers
     48
     49#include <string.h>
    4250#include <odinwrap.h>
    4351#include <os2sel.h>
    44 #include <misc.h>
    45 #include <wprocess.h>
    46 #include <heapstring.h>
    47 #include <win32wnd.h>
    4852#include <stdlib.h>
    4953#include <win32api.h>
     54#include <win32wnd.h>
     55#include <wprocess.h>
     56#include <misc.h>
    5057
    5158#include "wsock32.h"
    52 #include "relaywin.h"
     59#include "wsastruct.h"
     60#include "asyncthread.h"
     61
    5362#define DBG_LOCALLOG    DBG_wsock32
    5463#include "dbglocal.h"
     
    6271 *****************************************************************************/
    6372
    64 #define ERROR_SUCCESS 0
    65 
    66 
    67 static WSOCKTHREADDATA wstdFallthru; // for emergency only
    68 
    69 static HWND hwndRelay = NULL; // handle to our relay window
    70 
    71 BOOL fWSAInitialized = FALSE;
    72 
    73 /*****************************************************************************
    74  * Prototypes                                                                *
    75  *****************************************************************************/
    76 
    77 /*****************************************************************************
    78  * Name      :
    79  * Purpose   :
    80  * Parameters:
    81  * Variables :
    82  * Result    :
    83  * Remark    : free memory when thread dies
    84  * Status    : UNTESTED STUB
    85  *
    86  * Author    : Patrick Haller [Tue, 1998/06/16 23:00]
    87  *****************************************************************************/
    88 
    89 PWSOCKTHREADDATA iQueryWsockThreadData(void)
    90 {
    91   struct _THDB*     pThreadDB = (struct _THDB*)GetThreadTHDB();
    92   PWSOCKTHREADDATA pwstd;
    93 
    94   // check for existing pointer
    95   if (pThreadDB != NULL)
    96   {
    97     if (pThreadDB->pWsockData == NULL)
    98     {
    99       // allocate on demand + initialize
    100       pwstd = (PWSOCKTHREADDATA)HEAP_malloc (sizeof(WSOCKTHREADDATA));
    101       pThreadDB->pWsockData = (LPVOID)pwstd;
     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;
    10285    }
    103     else
    104       // use already allocated memory
    105       pwstd = (PWSOCKTHREADDATA)pThreadDB->pWsockData;
    106   }
    107 
    108   if (pwstd == NULL)
    109     pwstd = &wstdFallthru; // no memory and not allocated already
    110 
    111   return pwstd;
    112 }
    113 
    114 
    115 #if 0
    116 /*****************************************************************************
    117  * Name      :
    118  * Purpose   :
    119  * Parameters:
    120  * Variables :
    121  * Result    :
    122  * Remark    :
    123  * Status    : UNTESTED STUB
    124  *
    125  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    126  *****************************************************************************/
    127 
    128 #define CASEERR2(a) case SOC##a: case a: return WSA##a;
    129 #define CASEERR1(a) case SOC##a: return WSA##a;
    130 
    131 int iTranslateSockErrToWSock(int iError)
    132 {
    133   switch(iError)
    134   {
    135     CASEERR2(EINTR)
    136     CASEERR2(EBADF)
    137     CASEERR2(EACCES)
    138     CASEERR2(EINVAL)
    139     CASEERR2(EMFILE)
    140 
    141     CASEERR1(EWOULDBLOCK)
    142     CASEERR1(EINPROGRESS)
    143     CASEERR1(EALREADY)
    144     CASEERR1(ENOTSOCK)
    145 //  CASEERR1(EDESTADRREQ)
    146     CASEERR1(EMSGSIZE)
    147     CASEERR1(EPROTOTYPE)
    148     CASEERR1(ENOPROTOOPT)
    149     CASEERR1(EPROTONOSUPPORT)
    150     CASEERR1(ESOCKTNOSUPPORT)
    151     CASEERR1(EOPNOTSUPP)
    152     CASEERR1(EPFNOSUPPORT)
    153     CASEERR1(EAFNOSUPPORT)
    154     CASEERR1(EADDRINUSE)
    155     CASEERR1(EADDRNOTAVAIL)
    156     CASEERR1(ENETDOWN)
    157     CASEERR1(ENETUNREACH)
    158     CASEERR1(ENETRESET)
    159     CASEERR1(ECONNABORTED)
    160     CASEERR1(ECONNRESET)
    161     CASEERR1(ENOBUFS)
    162     CASEERR1(EISCONN)
    163     CASEERR1(ENOTCONN)
    164     CASEERR1(ESHUTDOWN)
    165     CASEERR1(ETOOMANYREFS)
    166     CASEERR1(ETIMEDOUT)
    167     CASEERR1(ECONNREFUSED)
    168     CASEERR1(ELOOP)
    169     CASEERR1(ENAMETOOLONG)
    170     CASEERR1(EHOSTDOWN)
    171     CASEERR1(EHOSTUNREACH)
    172 
    173     CASEERR1(ENOTEMPTY)
    174 //    CASEERR(EPROCLIM)
    175 //    CASEERR(EUSERS)
    176 //    CASEERR(EDQUOT)
    177 //    CASEERR(ESTALE)
    178 //    CASEERR(EREMOTE)
    179 //    CASEERR(EDISCON)
    180 
    181 
    182     default:
    183       dprintf(("WSOCK32: Unknown error condition: %d\n",
    184                iError));
    185       return iError;
    186   }
    187 }
    188 
    189 #endif
    190 
    191 
    192 
    193 
    194 
    195 
    196 
    197 /*****************************************************************************
    198  * Name      :
    199  * Purpose   :
    200  * Parameters:
    201  * Variables :
    202  * Result    :
    203  * Remark    :
    204  * Status    : UNTESTED STUB
    205  *
    206  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    207  *****************************************************************************/
    208 
    209 
    210 ODINPROCEDURE1(OS2WSASetLastError,
     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,
    211148               int,iError)
    212149{
    213150  // according to the docs, WSASetLastError() is just a call-through
    214151  // to SetLastError()
    215   WSASetLastError(iError);
    216152  SetLastError(iError);
    217153}
    218 
    219 
    220 /*****************************************************************************
    221  * Name      :
    222  * Purpose   :
    223  * Parameters:
    224  * Variables :
    225  * Result    :
    226  * Remark    :
    227  * Status    : UNTESTED STUB
    228  *
    229  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    230  *****************************************************************************/
    231 
    232 ODINFUNCTION0(int,OS2WSAGetLastError)
    233 {
    234   // according to the docs, WSASetLastError() is just a call-through
    235   // to SetLastError(). However, what can be implemented here?
    236   return WSAGetLastError();
    237 }
    238 
    239 
    240 /*****************************************************************************
    241  * Name      :
    242  * Purpose   :
    243  * Parameters:
    244  * Variables :
    245  * Result    :
    246  * Remark    :
    247  * Status    : UNTESTED STUB
    248  *
    249  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    250  *****************************************************************************/
    251 
    252 ODINFUNCTION2(int,OS2__WSAFDIsSet,SOCKET, s,
    253                                   fd_set*,fds)
    254 {
    255   return (__WSAFDIsSet(s,fds));
    256 }
    257 
    258 
    259 /*****************************************************************************
    260  * Name      :
    261  * Purpose   :
    262  * Parameters:
    263  * Variables :
    264  * Result    :
    265  * Remark    :
    266  * Status    : UNTESTED STUB
    267  *
    268  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    269  *****************************************************************************/
    270 
     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//******************************************************************************
    271439ODINFUNCTION3(SOCKET,OS2accept, SOCKET,           s,
    272440                                struct sockaddr *,addr,
    273441                                int *,            addrlen)
    274442{
    275   return(accept(s,addr,addrlen));
    276 }
    277 
    278 
    279 /*****************************************************************************
    280  * Name      :
    281  * Purpose   :
    282  * Parameters:
    283  * Variables :
    284  * Result    :
    285  * Remark    :
    286  * Status    : UNTESTED STUB
    287  *
    288  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    289  *****************************************************************************/
    290 
     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//******************************************************************************
    291485ODINFUNCTION3(int,OS2bind,
    292486              SOCKET ,s,
     
    294488              int, namelen)
    295489{
    296   return(bind(s,addr,namelen));
    297 }
    298 
    299 
    300 /*****************************************************************************
    301  * Name      :
    302  * Purpose   :
    303  * Parameters:
    304  * Variables :
    305  * Result    :
    306  * Remark    :
    307  * Status    : UNTESTED STUB
    308  *
    309  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    310  *****************************************************************************/
    311 
    312 ODINFUNCTION1(int,OS2closesocket,SOCKET, s)
    313 {
    314   return(closesocket(s));
    315 }
    316 
    317 
    318 /*****************************************************************************
    319  * Name      :
    320  * Purpose   :
    321  * Parameters:
    322  * Variables :
    323  * Result    :
    324  * Remark    :
    325  * Status    : UNTESTED STUB
    326  *
    327  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    328  *****************************************************************************/
    329 
    330 ODINFUNCTION3(int,OS2connect,
    331               SOCKET, s,
    332               const struct sockaddr *,name,
    333               int, namelen)
    334 {
    335   return(connect(s,name,namelen));
    336 }
    337 
    338 
    339 /*****************************************************************************
    340  * Name      :
    341  * Purpose   :
    342  * Parameters:
    343  * Variables :
    344  * Result    :
    345  * Remark    :
    346  * Status    : UNTESTED STUB
    347  *
    348  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    349  *****************************************************************************/
    350 
    351 ODINFUNCTION3(int,OS2ioctlsocket,
    352               SOCKET,s,
    353               long, cmd,
    354               u_long *,argp)
    355 {
    356   return(ioctlsocket(s,cmd,argp));
    357 }
    358 
    359 
    360 /*****************************************************************************
    361  * Name      :
    362  * Purpose   :
    363  * Parameters:
    364  * Variables :
    365  * Result    :
    366  * Remark    :
    367  * Status    : UNTESTED STUB
    368  *
    369  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    370  *****************************************************************************/
    371 
    372 ODINFUNCTION3(int,OS2getpeername,
    373               SOCKET, s,
    374               struct sockaddr *,name,
    375               int *, namelen)
    376 {
    377   return(getpeername(s,name,namelen));
    378 }
    379 
    380 
    381 /*****************************************************************************
    382  * Name      :
    383  * Purpose   :
    384  * Parameters:
    385  * Variables :
    386  * Result    :
    387  * Remark    :
    388  * Status    : UNTESTED STUB
    389  *
    390  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    391  *****************************************************************************/
    392 
    393 ODINFUNCTION3(int,OS2getsockname,
    394               SOCKET,s,
    395               struct sockaddr *,name,
    396               int *, namelen)
    397 {
    398   return(getsockname(s,name,namelen));
    399 }
    400 
    401 
    402 /*****************************************************************************
    403  * Name      :
    404  * Purpose   :
    405  * Parameters:
    406  * Variables :
    407  * Result    :
    408  * Remark    :
    409  * Status    : UNTESTED STUB
    410  *
    411  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    412  *****************************************************************************/
    413 
    414 ODINFUNCTION5(int,OS2getsockopt,
    415               SOCKET, s,
    416               int, level,
    417               int, optname,
    418               char *, optval,
    419               int *,optlen)
    420 {
    421   return(getsockopt(s,
    422                     level,
    423                     optname,
    424                     optval,
    425                     optlen));
    426 }
    427 
    428 
    429 /*****************************************************************************
    430  * Name      :
    431  * Purpose   :
    432  * Parameters:
    433  * Variables :
    434  * Result    :
    435  * Remark    :
    436  * Status    : UNTESTED STUB
    437  *
    438  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    439  *****************************************************************************/
    440 
    441 ODINFUNCTION1(u_long,OS2htonl,
    442               u_long,hostlong)
    443 {
    444   return(htonl(hostlong));
    445 }
    446 
    447 
    448 /*****************************************************************************
    449  * Name      :
    450  * Purpose   :
    451  * Parameters:
    452  * Variables :
    453  * Result    :
    454  * Remark    :
    455  * Status    : UNTESTED STUB
    456  *
    457  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    458  *****************************************************************************/
    459 
    460 ODINFUNCTION1(u_short,OS2htons,
    461               u_short,hostshort)
    462 {
    463   return(htons(hostshort));
    464 }
    465 
    466 
    467 /*****************************************************************************
    468  * Name      :
    469  * Purpose   :
    470  * Parameters:
    471  * Variables :
    472  * Result    :
    473  * Remark    :
    474  * Status    : UNTESTED STUB
    475  *
    476  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    477  *****************************************************************************/
    478 
    479 ODINFUNCTION1(unsigned long,OS2inet_addr,
    480               const char *, cp)
    481 {
    482   dprintf(("WSOCK32: OS2inet_addr(%s)\n",
    483            cp));
    484 
    485   return (inet_addr(cp));
    486 }
    487 
    488 
    489 /*****************************************************************************
    490  * Name      :
    491  * Purpose   :
    492  * Parameters:
    493  * Variables :
    494  * Result    :
    495  * Remark    :
    496  * Status    : UNTESTED STUB
    497  *
    498  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    499  *****************************************************************************/
    500 
    501 ODINFUNCTION1(char *,OS2inet_ntoa,
    502               struct in_addr, in)
    503 {
    504   return(inet_ntoa(in));
    505 }
    506 
    507 
    508 /*****************************************************************************
    509  * Name      :
    510  * Purpose   :
    511  * Parameters:
    512  * Variables :
    513  * Result    :
    514  * Remark    :
    515  * Status    : UNTESTED STUB
    516  *
    517  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    518  *****************************************************************************/
    519 
     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//******************************************************************************
    520516ODINFUNCTION2(int,OS2listen,
    521517              SOCKET, s,
    522518              int, backlog)
    523519{
    524   return(listen(s,backlog));
    525 }
    526 
    527 
    528 /*****************************************************************************
    529  * Name      :
    530  * Purpose   :
    531  * Parameters:
    532  * Variables :
    533  * Result    :
    534  * Remark    :
    535  * Status    : UNTESTED STUB
    536  *
    537  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    538  *****************************************************************************/
    539 
    540 ODINFUNCTION1(u_long,OS2ntohl,
    541               u_long,netlong)
    542 {
    543   return(ntohl(netlong));
    544 }
    545 
    546 
    547 /*****************************************************************************
    548  * Name      :
    549  * Purpose   :
    550  * Parameters:
    551  * Variables :
    552  * Result    :
    553  * Remark    :
    554  * Status    : UNTESTED STUB
    555  *
    556  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    557  *****************************************************************************/
    558 
    559 ODINFUNCTION1(u_short,OS2ntohs,
    560               u_short,netshort)
    561 {
    562   return(ntohs(netshort));
    563 }
    564 
    565 
    566 /*****************************************************************************
    567  * Name      :
    568  * Purpose   :
    569  * Parameters:
    570  * Variables :
    571  * Result    :
    572  * Remark    :
    573  * Status    : UNTESTED STUB
    574  *
    575  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    576  *****************************************************************************/
    577 
     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//******************************************************************************
    578558ODINFUNCTION4(int,OS2recv,
    579559              SOCKET,s,
     
    582562              int,flags)
    583563{
    584   return(recv(s,
    585               buf,
    586               len,
    587               flags));
    588 }
    589 
    590 
    591 /*****************************************************************************
    592  * Name      :
    593  * Purpose   :
    594  * Parameters:
    595  * Variables :
    596  * Result    :
    597  * Remark    :
    598  * Status    : UNTESTED STUB
    599  *
    600  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    601  *****************************************************************************/
    602 
     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//******************************************************************************
    603588ODINFUNCTION6(int,OS2recvfrom,
    604589              SOCKET,s,
     
    609594              int *,fromlen)
    610595{
    611 
    612   return(recvfrom(s,
    613                 buf,
    614                 len,
    615                 flags,
    616                 from,
    617                 fromlen));
    618 }
    619 
    620 
    621 /*****************************************************************************
    622  * Name      :
    623  * Purpose   :
    624  * Parameters:
    625  * Variables :
    626  * Result    :
    627  * Remark    :
    628  * Status    : UNTESTED STUB
    629  *
    630  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    631  *****************************************************************************/
    632 
    633 ODINFUNCTION5(int,OS2select,
    634               int,nfds,
    635               fd_set *,readfds,
    636               fd_set *,writefds,
    637               fd_set *,exceptfds,
    638               const struct timeval *,timeout)
    639 {
    640   return(select(nfds,
    641                 readfds,
    642                 writefds,
    643                 exceptfds,
    644                 timeout));
    645 }
    646 
    647 
    648 /*****************************************************************************
    649  * Name      :
    650  * Purpose   :
    651  * Parameters:
    652  * Variables :
    653  * Result    :
    654  * Remark    :
    655  * Status    : UNTESTED STUB
    656  *
    657  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    658  *****************************************************************************/
    659 
     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//******************************************************************************
    660625ODINFUNCTION4(int,OS2send,
    661626              SOCKET,s,
     
    664629              int,flags)
    665630{
    666   return(send(s,
    667               buf,
    668               len,
    669               flags));
    670 }
    671 
    672 
    673 /*****************************************************************************
    674  * Name      :
    675  * Purpose   :
    676  * Parameters:
    677  * Variables :
    678  * Result    :
    679  * Remark    :
    680  * Status    : UNTESTED STUB
    681  *
    682  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    683  *****************************************************************************/
    684 
     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//******************************************************************************
    685655ODINFUNCTION6(int,OS2sendto,
    686656              SOCKET,s,
     
    691661              int,tolen)
    692662{
    693   return(sendto(s,
    694               buf,
    695               len,
    696               flags,
    697               to,
    698               tolen));
    699 }
    700 
    701 
    702 /*****************************************************************************
    703  * Name      :
    704  * Purpose   :
    705  * Parameters:
    706  * Variables :
    707  * Result    :
    708  * Remark    :
    709  * Status    : UNTESTED STUB
    710  *
    711  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    712  *****************************************************************************/
    713 
     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//******************************************************************************
    714814ODINFUNCTION5(int,OS2setsockopt,
    715815              SOCKET,s,
     
    719819              int,optlen)
    720820{
    721   struct Wlinger *yy;
    722   struct linger xx;
    723   int    rc;
    724 
    725   if(level   == SOL_SOCKET &&
    726      optname == SO_LINGER)
    727   {
    728     yy = (struct Wlinger *)optval;
    729     xx.l_onoff = (int)yy->l_onoff;
    730     xx.l_linger = (int)yy->l_linger;
    731 
    732     rc = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
    733   }
    734   else
    735   if(level == SOL_SOCKET && (optname == SO_SNDBUF || optname == SO_RCVBUF)) {
    736         ULONG size;
    737 
    738         size = *(ULONG *)optval;
     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;
    739857tryagain:
    740         rc = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
    741         if(rc == SOCKET_ERROR && size > 65535) {
    742                 //SvL: Limit send & receive buffer length to 64k
    743                 //     (only happens with 16 bits tcpip stack?)
    744                 size = 65000;
    745                 goto tryagain;
    746         }
    747 
    748   }
    749   else {
    750     rc = setsockopt(s,level,optname,(char *)optval,optlen);
    751   }
    752 
    753   if (rc == SOCKET_ERROR)
    754     //OS2WSASetLastError(iTranslateSockErrToWSock(sock_errno()));
    755     OS2WSASetLastError(WSAEINVAL);
    756   else
    757     OS2WSASetLastError(ERROR_SUCCESS);
    758 
    759   return rc;
    760 }
    761 
    762 
    763 /*****************************************************************************
    764  * Name      :
    765  * Purpose   :
    766  * Parameters:
    767  * Variables :
    768  * Result    :
    769  * Remark    :
    770  * Status    : UNTESTED STUB
    771  *
    772  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    773  *****************************************************************************/
    774 
    775 ODINFUNCTION2(int,OS2shutdown,
    776               SOCKET,s,
    777               int,how)
    778 {
    779   return(shutdown(s,
    780                   how));
    781 }
    782 
    783 
    784 /*****************************************************************************
    785  * Name      :
    786  * Purpose   :
    787  * Parameters:
    788  * Variables :
    789  * Result    :
    790  * Remark    :
    791  * Status    : UNTESTED STUB
    792  *
    793  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    794  *****************************************************************************/
    795 
    796 ODINFUNCTION3(SOCKET,OS2socket,
    797               int,af,
    798               int,type,
    799               int,protocol)
    800 {
    801   return(socket(af,
    802                 type,
    803                 protocol));
    804 }
    805 
    806 
     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//******************************************************************************
    8071007/* Database function prototypes */
    808 
    809 /*****************************************************************************
    810  * Name      :
    811  * Purpose   :
    812  * Parameters:
    813  * Variables :
    814  * Result    :
    815  * Remark    :
    816  * Status    : UNTESTED STUB
    817  *
    818  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    819  *****************************************************************************/
    820 
    821 ODINFUNCTION3(struct Whostent *,OS2gethostbyaddr,
     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,
    8221027              const char *,addr,
    8231028              int,len,
    8241029              int,type)
    8251030{
    826   WHOSTENT         *yy;
    827   struct hostent   *xx;
    828   PWSOCKTHREADDATA pwstd;
    829 
    830   xx = gethostbyaddr((char *)addr,len,type);
    831   //PH: we assume PMWSOCK sets WSASetLastError correctly!
    832 
    833   if(xx == NULL)
    834      return (WHOSTENT *)NULL;
    835 
    836   // access current thread wsock data block
    837   pwstd = iQueryWsockThreadData();
    838 
    839   pwstd->whsnt.h_name      = xx->h_name;
    840   pwstd->whsnt.h_aliases   = xx->h_aliases;
    841   pwstd->whsnt.h_addrtype  = (short)xx->h_addrtype;
    842   pwstd->whsnt.h_length    = (short)xx->h_length;
    843   pwstd->whsnt.h_addr_list = xx->h_addr_list;
    844 
    845   return &pwstd->whsnt;
    846 }
    847 
    848 
    849 /*****************************************************************************
    850  * Name      :
    851  * Purpose   :
    852  * Parameters:
    853  * Variables :
    854  * Result    :
    855  * Remark    :
    856  * Status    : UNTESTED STUB
    857  *
    858  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    859  *****************************************************************************/
    860 
    861 ODINFUNCTION1(struct Whostent *,OS2gethostbyname,
     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,
    8621051              const char *,name)
    8631052{
    864   WHOSTENT         *yy;
    865   struct hostent   *xx;
    866   PWSOCKTHREADDATA pwstd;
    867 
    868 
    869   xx = gethostbyname((char *)name);
    870   //PH: we assume PMWSOCK sets WSASetLastError correctly!
    871 
    872   if(xx == NULL)
    873     return (WHOSTENT *)NULL;
    874 
    875   // access current thread wsock data block
    876   pwstd = iQueryWsockThreadData();
    877 
    878   pwstd->whsnt.h_name      = xx->h_name;
    879   pwstd->whsnt.h_aliases   = xx->h_aliases;
    880   pwstd->whsnt.h_addrtype  = (short)xx->h_addrtype;
    881   pwstd->whsnt.h_length    = (short)xx->h_length;
    882   pwstd->whsnt.h_addr_list = xx->h_addr_list;
    883 
    884   return &pwstd->whsnt;
    885 }
    886 
    887 
    888 /*****************************************************************************
    889  * Name      :
    890  * Purpose   :
    891  * Parameters:
    892  * Variables :
    893  * Result    :
    894  * Remark    :
    895  * Status    : UNTESTED STUB
    896  *
    897  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    898  *****************************************************************************/
    899 
    900 ODINFUNCTION2(int,OS2gethostname,
    901               char *,name,
    902               int,namelen)
    903 {
    904    //PH: we assume PMWSOCK sets WSASetLastError correctly!
    905    return(gethostname(name,
    906                      namelen));
    907 }
    908 
    909 
    910 /*****************************************************************************
    911  * Name      :
    912  * Purpose   :
    913  * Parameters:
    914  * Variables :
    915  * Result    :
    916  * Remark    :
    917  * Status    : UNTESTED STUB
    918  *
    919  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    920  *****************************************************************************/
    921 
    922 ODINFUNCTION2(struct Wservent *,OS2getservbyport,
     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,
    9231073              int,              port,
    9241074              const char *,     proto)
    9251075{
    926   struct servent   *xx;
    927   PWSOCKTHREADDATA pwstd;
    928 
    929   //PH: we assume PMWSOCK sets WSASetLastError correctly!
    930   xx = getservbyport(port,(char *)proto);
    931 
    932   if(xx == NULL)
    933     return (WSERVENT *)NULL;
    934 
    935   // access current thread wsock data block
    936   pwstd = iQueryWsockThreadData();
    937 
    938   pwstd->wsvnt.s_name    = xx->s_name;
    939   pwstd->wsvnt.s_aliases = xx->s_aliases;
    940   pwstd->wsvnt.s_port    = (short)xx->s_port;
    941   pwstd->wsvnt.s_proto   = xx->s_proto;
    942 
    943   return &pwstd->wsvnt;
    944 }
    945 
    946 
    947 /*****************************************************************************
    948  * Name      :
    949  * Purpose   :
    950  * Parameters:
    951  * Variables :
    952  * Result    :
    953  * Remark    :
    954  * Status    : UNTESTED STUB
    955  *
    956  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    957  *****************************************************************************/
    958 
    959 ODINFUNCTION2(struct Wservent *,OS2getservbyname,
     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,
    9601096              const char *,     name,
    9611097              const char *,     proto)
    9621098{
    963   WSERVENT         *yy;
    964   struct servent   *xx;
    965   PWSOCKTHREADDATA pwstd;
    966 
    967 
    968   //PH: we assume PMWSOCK sets WSASetLastError correctly!
    969   xx = getservbyname((char *)name,(char *)proto);
    970 
    971   if(xx == NULL)
    972     return (WSERVENT *)NULL;
    973 
    974   // access current thread wsock data block
    975   pwstd = iQueryWsockThreadData();
    976 
    977   pwstd->wsvnt.s_name    = xx->s_name;
    978   pwstd->wsvnt.s_aliases = xx->s_aliases;
    979   pwstd->wsvnt.s_port    = (short)xx->s_port;
    980   pwstd->wsvnt.s_proto   = xx->s_proto;
    981 
    982   return &pwstd->wsvnt;
    983 }
    984 
    985 
    986 /*****************************************************************************
    987  * Name      :
    988  * Purpose   :
    989  * Parameters:
    990  * Variables :
    991  * Result    :
    992  * Remark    :
    993  * Status    : UNTESTED STUB
    994  *
    995  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    996  *****************************************************************************/
    997 
    998 ODINFUNCTION1(struct Wprotoent *,OS2getprotobynumber,
    999               int,proto)
    1000 {
    1001   struct protoent  *xx;
    1002   PWSOCKTHREADDATA pwstd;
    1003 
    1004   //PH: we assume PMWSOCK sets WSASetLastError correctly!
    1005   xx = getprotobynumber(proto);
    1006 
    1007   if(xx == NULL)
    1008     return (WPROTOENT *)NULL;
    1009 
    1010   // access current thread wsock data block
    1011   pwstd = iQueryWsockThreadData();
    1012 
    1013   pwstd->wptnt.p_name    = xx->p_name;
    1014   pwstd->wptnt.p_aliases = xx->p_aliases;
    1015   pwstd->wptnt.p_proto   = (short)xx->p_proto;
    1016 
    1017   return &pwstd->wptnt;
    1018 }
    1019 
    1020 
    1021 /*****************************************************************************
    1022  * Name      :
    1023  * Purpose   :
    1024  * Parameters:
    1025  * Variables :
    1026  * Result    :
    1027  * Remark    :
    1028  * Status    : UNTESTED STUB
    1029  *
    1030  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1031  *****************************************************************************/
    1032 
    1033 ODINFUNCTION1(struct Wprotoent *,OS2getprotobyname,
     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,
    10341141              const char *,name)
    10351142{
    1036   struct protoent  *xx;
    1037   PWSOCKTHREADDATA pwstd;
    1038 
    1039   //PH: we assume PMWSOCK sets WSASetLastError correctly!
    1040   xx = getprotobyname((char *)name);
    1041 
    1042   if(xx == NULL)
    1043     return (WPROTOENT *)NULL;
    1044 
    1045   // access current thread wsock data block
    1046   pwstd = iQueryWsockThreadData();
    1047 
    1048   pwstd->wptnt.p_name    = xx->p_name;
    1049   pwstd->wptnt.p_aliases = xx->p_aliases;
    1050   pwstd->wptnt.p_proto   = (short)xx->p_proto;
    1051 
    1052   return &pwstd->wptnt;
    1053 }
    1054 
    1055 
    1056 
    1057 /* Microsoft Windows Extension function prototypes */
    1058 
    1059 /*****************************************************************************
    1060  * Name      :
    1061  * Purpose   :
    1062  * Parameters:
    1063  * Variables :
    1064  * Result    :
    1065  * Remark    :
    1066  * Status    : UNTESTED STUB
    1067  *
    1068  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1069  *****************************************************************************/
    1070 
    1071 ODINFUNCTION2(int,OS2WSAStartup,
    1072               USHORT,wVersionRequired,
    1073               LPWSADATA,lpWSAData)
    1074 {
    1075   fWSAInitialized = TRUE;
    1076   return(WSAStartup(wVersionRequired,
    1077                     lpWSAData));
    1078 }
    1079 
    1080 
    1081 /*****************************************************************************
    1082  * Name      :
    1083  * Purpose   :
    1084  * Parameters:
    1085  * Variables :
    1086  * Result    :
    1087  * Remark    :
    1088  * Status    : UNTESTED STUB
    1089  *
    1090  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1091  *****************************************************************************/
    1092 
    1093 ODINFUNCTION0(int,OS2WSACleanup)
    1094 {
    1095   fWSAInitialized = FALSE;
    1096   return(WSACleanup());
    1097 }
    1098 
    1099 
    1100 /*****************************************************************************
    1101  * Name      :
    1102  * Purpose   :
    1103  * Parameters:
    1104  * Variables :
    1105  * Result    :
    1106  * Remark    :
    1107  * Status    : UNTESTED STUB
    1108  *
    1109  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1110  *****************************************************************************/
    1111 
    1112 ODINFUNCTION0(BOOL,OS2WSAIsBlocking)
    1113 {
    1114   return WSAIsBlocking();
    1115 }
    1116 
    1117 
    1118 /*****************************************************************************
    1119  * Name      :
    1120  * Purpose   :
    1121  * Parameters:
    1122  * Variables :
    1123  * Result    :
    1124  * Remark    :
    1125  * Status    : UNTESTED STUB
    1126  *
    1127  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1128  *****************************************************************************/
    1129 
    1130 ODINFUNCTION0(int,OS2WSAUnhookBlockingHook)
    1131 {
    1132   return WSAUnhookBlockingHook();
    1133 }
    1134 
    1135 
    1136 /*****************************************************************************
    1137  * Name      :
    1138  * Purpose   :
    1139  * Parameters:
    1140  * Variables :
    1141  * Result    :
    1142  * Remark    :
    1143  * Status    : UNTESTED STUB
    1144  *
    1145  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1146  *****************************************************************************/
    1147 
    1148 ODINFUNCTION1(PFN,OS2WSASetBlockingHook,
    1149               PFN,lpBlockFunc)
    1150 {
    1151   return(WSASetBlockingHook(lpBlockFunc));
    1152 }
    1153 
    1154 
    1155 /*****************************************************************************
    1156  * Name      :
    1157  * Purpose   :
    1158  * Parameters:
    1159  * Variables :
    1160  * Result    :
    1161  * Remark    :
    1162  * Status    : UNTESTED STUB
    1163  *
    1164  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1165  *****************************************************************************/
    1166 
    1167 ODINFUNCTION0(int,OS2WSACancelBlockingCall)
    1168 {
    1169   return(WSACancelBlockingCall());
    1170 }
    1171 
    1172 
    1173 /*****************************************************************************
    1174  * Name      :
    1175  * Purpose   :
    1176  * Parameters:
    1177  * Variables :
    1178  * Result    :
    1179  * Remark    :
    1180  * Status    : UNTESTED STUB
    1181  *
    1182  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1183  *****************************************************************************/
    1184 
    1185 ODINFUNCTION6(LHANDLE,OS2WSAAsyncGetServByName,
    1186               HWND,hWnd,
    1187               u_int,wMsg,
    1188               const char *,name,
    1189               const char *,proto,
    1190               char *,buf,
    1191               int,buflen)
    1192 {
    1193   int   rc;
    1194   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1195   ULONG ulNewID;
    1196 
    1197   if (hwndRelay == NULL) // already initialized ?
    1198     hwndRelay = RelayInitialize(hwndOS2);
    1199 
    1200   // add entry to list, we need to store both our temp buffer and the apps buffer
    1201   ulNewID = RelayAlloc(hWnd,
    1202                        wMsg,
    1203                        ASYNCREQUEST_GETSERVBYNAME,
    1204                        NO_SOCKET,
    1205                        FALSE,
    1206                        buf);
    1207 
    1208   // call pmwsock function, will fill our temp buffer
    1209   rc = WSAAsyncGetServByName(hwndRelay,
    1210                               ulNewID,
    1211                               name,
    1212                               proto,
    1213                               buf,
    1214                               buflen);
    1215 
    1216   // if an error occurs, free the allocated relay entry
    1217   if (rc == SOCKET_ERROR)
    1218     RelayFree(ulNewID);
    1219 
    1220   return (rc);
    1221 }
    1222 
    1223 
    1224 /*****************************************************************************
    1225  * Name      :
    1226  * Purpose   :
    1227  * Parameters:
    1228  * Variables :
    1229  * Result    :
    1230  * Remark    :
    1231  * Status    : UNTESTED STUB
    1232  *
    1233  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1234  *****************************************************************************/
    1235 
    1236 ODINFUNCTION6(LHANDLE,OS2WSAAsyncGetServByPort,
    1237               HWND,hWnd,
    1238               u_int,wMsg,
    1239               int,port,
    1240               const char *,proto,
    1241               char *,buf,
    1242               int,buflen)
    1243 {
    1244   int   rc;
    1245   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1246   ULONG ulNewID;
    1247 
    1248   if (hwndRelay == NULL) // already initialized ?
    1249     hwndRelay = RelayInitialize(hwndOS2);
    1250 
    1251   // add entry to list, we need to store both our temp buffer and the apps buffer
    1252   ulNewID = RelayAlloc(hWnd,
    1253                        wMsg,
    1254                        ASYNCREQUEST_GETSERVBYPORT,
    1255                        NO_SOCKET,
    1256                        FALSE,
    1257                        buf);
    1258 
    1259   // call pmwsock function, will fill our temp buffer
    1260   rc = WSAAsyncGetServByPort(hwndRelay,
    1261                              ulNewID,
    1262                              port,
    1263                              proto,
    1264                              buf,
    1265                              buflen);
    1266 
    1267   // if an error occurs, free the allocated relay entry
    1268   if (rc == SOCKET_ERROR)
    1269     RelayFree(ulNewID);
    1270 
    1271   return rc;
    1272 }
    1273 
    1274 
    1275 /*****************************************************************************
    1276  * Name      :
    1277  * Purpose   :
    1278  * Parameters:
    1279  * Variables :
    1280  * Result    :
    1281  * Remark    :
    1282  * Status    : UNTESTED STUB
    1283  *
    1284  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1285  *****************************************************************************/
    1286 
    1287 ODINFUNCTION5(LHANDLE,OS2WSAAsyncGetProtoByName,
    1288               HWND,hWnd,
    1289               u_int,wMsg,
    1290               const char *,name,
    1291               char *,buf,
    1292               int,buflen)
    1293 {
    1294   int   rc;
    1295   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1296   ULONG ulNewID;
    1297 
    1298   if (hwndRelay == NULL) // already initialized ?
    1299     hwndRelay = RelayInitialize(hwndOS2);
    1300 
    1301   // add entry to list, we need to store both our temp buffer and the apps buffer
    1302   ulNewID = RelayAlloc(hWnd,
    1303                        wMsg,
    1304                        ASYNCREQUEST_GETPROTOBYNAME,
    1305                        NO_SOCKET,
    1306                        FALSE,
    1307                        buf);
    1308 
    1309   // call pmwsock function, will fill our temp buffer
    1310   rc = WSAAsyncGetProtoByName(hwndRelay,
    1311                               ulNewID,
    1312                               name,
    1313                               buf,
    1314                               buflen);
    1315 
    1316   // if an error occurs, free the allocated relay entry
    1317   if (rc == SOCKET_ERROR)
    1318     RelayFree(ulNewID);
    1319 
    1320   return (rc);
    1321 }
    1322 
    1323 
    1324 /*****************************************************************************
    1325  * Name      :
    1326  * Purpose   :
    1327  * Parameters:
    1328  * Variables :
    1329  * Result    :
    1330  * Remark    :
    1331  * Status    : UNTESTED STUB
    1332  *
    1333  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1334  *****************************************************************************/
    1335 
    1336 ODINFUNCTION5(LHANDLE,OS2WSAAsyncGetProtoByNumber,
    1337               HWND,hWnd,
    1338               u_int,wMsg,
    1339               int,number,
    1340               char *,buf,
    1341               int,buflen)
    1342 {
    1343   int   rc;
    1344   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1345   ULONG ulNewID;
    1346 
    1347   if (hwndRelay == NULL) // already initialized ?
    1348     hwndRelay = RelayInitialize(hwndOS2);
    1349 
    1350   // add entry to list, we need to store both our temp buffer and the apps buffer
    1351   ulNewID = RelayAlloc(hWnd,
    1352                        wMsg,
    1353                        ASYNCREQUEST_GETPROTOBYNUMBER,
    1354                        NO_SOCKET,
    1355                        FALSE,
    1356                        buf);
    1357 
    1358   // call pmwsock function, will fill our temp buffer
    1359   rc = WSAAsyncGetProtoByNumber(hwndRelay,
    1360                                 ulNewID,
    1361                                 number,
    1362                                 buf,
    1363                                 buflen);
    1364 
    1365   // if an error occurs, free the allocated relay entry
    1366   if (rc == SOCKET_ERROR)
    1367     RelayFree(ulNewID);
    1368 
    1369   return rc;
    1370 }
    1371 
    1372 
    1373 /*****************************************************************************
    1374  * Name      :
    1375  * Purpose   :
    1376  * Parameters:
    1377  * Variables :
    1378  * Result    :
    1379  * Remark    :
    1380  * Status    : UNTESTED STUB
    1381  *
    1382  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1383  *****************************************************************************/
    1384 
    1385 ODINFUNCTION5(LHANDLE,OS2WSAAsyncGetHostByName,
    1386               HWND,hWnd,
    1387               u_int,wMsg,
    1388               const char *,name,
    1389               char *,buf,
    1390               int,buflen)
    1391 {
    1392   int   rc;
    1393   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1394   ULONG ulNewID;
    1395 
    1396   dprintf(("WSAAsyncGetHostByName %s", name));
    1397 
    1398   if (hwndRelay == NULL) // already initialized ?
    1399     hwndRelay = RelayInitialize(hwndOS2);
    1400 
    1401   // add entry to list, we need to store both our temp buffer and the apps buffer
    1402   ulNewID = RelayAlloc(hWnd,
    1403                        wMsg,
    1404                        ASYNCREQUEST_GETHOSTBYNAME,
    1405                        NO_SOCKET,
    1406                        FALSE,
    1407                        (PVOID)buf, (PVOID)buflen);
    1408 
    1409   // call pmwsock function, will fill our temp buffer
    1410   rc = WSAAsyncGetHostByName(hwndRelay,
    1411                              ulNewID,
    1412                              name,
    1413                              buf,
    1414                              buflen);
    1415 
    1416   // if an error occurs, free the allocated relay entry
    1417   if (rc == SOCKET_ERROR)
    1418     RelayFree(ulNewID);
    1419 
    1420   return rc;
    1421 }
    1422 
    1423 
    1424 /*****************************************************************************
    1425  * Name      :
    1426  * Purpose   :
    1427  * Parameters:
    1428  * Variables :
    1429  * Result    :
    1430  * Remark    :
    1431  * Status    : UNTESTED STUB
    1432  *
    1433  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1434  *****************************************************************************/
    1435 
    1436 ODINFUNCTION7(LHANDLE,OS2WSAAsyncGetHostByAddr,
    1437               HWND,hWnd,
    1438               u_int,wMsg,
    1439               const char *,addr,
    1440               int,len,
    1441               int,type,
    1442               char *,buf,
    1443               int,buflen)
    1444 {
    1445   int   rc;
    1446   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1447   ULONG ulNewID;
    1448 
    1449   if (hwndRelay == NULL) // already initialized ?
    1450     hwndRelay = RelayInitialize(hwndOS2);
    1451 
    1452   // add entry to list, we need to store both our temp buffer and the apps buffer
    1453   ulNewID = RelayAlloc(hWnd,
    1454                        wMsg,
    1455                        ASYNCREQUEST_GETHOSTBYADDR,
    1456                        NO_SOCKET,
    1457                        FALSE,
    1458                        buf);
    1459 
    1460   // call pmwsock function, will fill our temp buffer
    1461   rc = WSAAsyncGetHostByAddr(hwndRelay,
    1462                              ulNewID,
    1463                              addr,
    1464                              len,
    1465                              type,
    1466                              buf,
    1467                              buflen);
    1468 
    1469   // if an error occurs, free the allocated relay entry
    1470   if (rc == SOCKET_ERROR)
    1471     RelayFree(ulNewID);
    1472 
    1473   return (rc);
    1474 }
    1475 
    1476 
    1477 /*****************************************************************************
    1478  * Name      :
    1479  * Purpose   :
    1480  * Parameters:
    1481  * Variables :
    1482  * Result    :
    1483  * Remark    :
    1484  * Status    : UNTESTED STUB
    1485  *
    1486  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1487  *****************************************************************************/
    1488 
    1489 ODINFUNCTION1(int,OS2WSACancelAsyncRequest,
    1490               LHANDLE,hAsyncTaskHandle)
    1491 {
    1492   return(WSACancelAsyncRequest(hAsyncTaskHandle));
    1493 }
    1494 
    1495 
    1496 /*****************************************************************************
    1497  * Name      :
    1498  * Purpose   :
    1499  * Parameters:
    1500  * Variables :
    1501  * Result    :
    1502  * Remark    :
    1503  * Status    : UNTESTED STUB
    1504  *
    1505  * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
    1506  *****************************************************************************/
    1507 
    1508 ODINFUNCTION4(int,OS2WSAAsyncSelect,
    1509               SOCKET,s,
    1510               HWND,hWnd,
    1511               u_int,wMsg,
    1512               long,lEvent)
    1513 {
    1514   int   rc;
    1515 //  int   iError;
    1516   HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
    1517   ULONG ulNewID;
    1518 
    1519   if (hwndRelay == NULL) // already initialized ?
    1520     hwndRelay = RelayInitialize(hwndOS2);
    1521 
    1522   /* @@@PH: our source window doesn't seem to have an anchor block.
    1523             Docs suggest we've missed to call WinInitialize on the
    1524             caller thread.
    1525 
    1526             Cause however is the Open32 handle is (of course!) invalid
    1527             in plain PM Window Manager! -> use DAPWSOCK
    1528 
    1529             Unfortunately, DAPWSOCK calls WinQueryAnchorBlock(hOpen32), too.
    1530             So, we're stuck until I resolve hWnd to it's valid PM
    1531             counterpart.
    1532 
    1533             new problem: we've ultimately got to use PostMessageA instead
    1534             anything else. => create invisible msg relay window:
    1535             - hMsg = registerMessage(hWnd, wMsg)
    1536             - call WSAAsyncSelect with object window handle
    1537             - overwrite hWnd relay for "same handles"
    1538    */
    1539 
    1540   // add event to list or remove any list entry in case of WSAAsyncSelect(hwnd,0,0)
    1541   if ( (wMsg == 0) && (lEvent == 0) )
    1542   {
    1543     // remove entry from list
    1544     RelayFreeByHwnd(s, hWnd);
    1545   }
    1546   else
    1547     // add entry to list
    1548     ulNewID = RelayAlloc(hWnd,
    1549                          wMsg,
    1550                          ASYNCREQUEST_SELECT,
    1551                          s,
    1552                          FALSE); //SvL: allow multiple selects -> pmwsock should fail if it not allowed
    1553 
    1554   rc = WSAAsyncSelect(s,
    1555                       hwndRelay,
    1556                       ulNewID,
    1557                       lEvent);
    1558 
    1559   // if an error occurs, free the allocated relay entry
    1560   if (rc == SOCKET_ERROR)
    1561     RelayFree(ulNewID);
    1562 
    1563   return (rc);
    1564 }
     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 TracChangeset for help on using the changeset viewer.