The following code fragment shows an example of the implementation of the somsBind method of the TCPIPSockets subclass, for both AIX and OS/2. The sample illustrates that, for TCP/IP, the implementation is basically a one-to-one mapping of Sockets methods onto TCP/IP calls. For other transport protocols, the mapping from the socket abstraction to the protocol's API may be more difficult.
For AIX, the mapping from Sockets method to TCP/IP call is trivial.
SOM_Scope long SOMLINK somsBind(TCPIPSockets somSelf, Environment *ev, long s, Sockets_sockaddr* name, long namelen) { long rc; TCPIPSocketsMethodDebug("TCPIPSockets","somsBind"); rc = (long) bind((int)s, name, (int)namelen); if (rc == -1) __set_serrno(somSelf, ev, errno); return rc; }
On OS/2, however, the TCP/IP Release 1.2.1 library is a 16-bit library. Consequently, many of the method calls require conversion ("thunking") of 32-bit parameters into 16-bit parameters, before the actual TCP/IP calls can be invoked. For example, the function prototype for the somsBind method is defined as:
SOM_Scope long SOMLINK somsBind(TCPIPSockets somSelf, Environment *ev, long s, Sockets_sockaddr* name, long namelen);
whereas the file socket.h on OS/2 declares the bind function with the following prototype:
short _Far16 _Cdecl bind(short /*s*/, void * _Seg16 /*name*/, short /*len*/);
In this case, the pointer to the "name" structure, passed as a 32-bit address, cannot be used directly in the bind call: a 16-bit address must be passed instead. This can be accomplished by dereferencing the 32-bit pointer provided by the "name" parameter in the somsBind call, copying the caller's Sockets_sockaddr structure into a local structure ("name16"), and then passing the address of the local structure ("&name16") as a 16-bit address in the bind call.
SOM_Scope long SOMLINK somsBind(TCPIPSockets somSelf, Environment *ev, long s, Sockets_sockaddr* name, long namelen) { long rc; Sockets_sockaddr name16; TCPIPSocketsMethodDebug("TCPIPSockets","somsBind"); /* copy user's parameter into a local structure */ memcpy ((char *)&name16, (char *)((sockaddr32 *)name), namelen); rc = (long) bind((short)s, (void *)&name16, (short)namelen); if (rc == -1) __set_serrno(somSelf, ev, tcperrno()); return rc; }