Example code

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;
}


[Back: Implementation considerations]
[Next: Notices]