The called side initiates listening for incoming calls by calling bind, supplying the called (local) DTE address (including subaddress, if any) and protocol identifier to be used for matching with incoming calls:
int s, error; CONN_DB bind_addr; error = bind(s, &bind_addr, sizeof(bind_addr));
Here, bind_addr contains the address and protocol identifier of the called side. The protocol identifier is specified in the data field of the CONN_DB structure and is matched with the user data in incoming calls. More information on how to specify the address and protocol identifier for the bind call, and how incoming calls are matched with bound addresses and protocol identifiers, follows.
After bind has been called, listen is called to begin waiting for incoming calls. Incoming calls will be queued until they are accepted by means of the accept call. backlog specifies the maximum number of incoming calls (no more than five) to queue (waiting for accept) before clearing additional incoming calls.
int s, backlog, error; error = listen(s, backlog);
Finally, accept is called to block until an incoming call is received that matches the address and protocol identifier specified in the bind call. accept is passed a pointer to a CONN_DB structure (and length), which will be filled in with the calling DTE's (remote) address and user data field. The user data field in an Incoming Call packet consists of a protocol identifier followed by any additional user data. After an incoming call matches the binding criteria, accept returns the socket news, to be used for data transfer. news inherits the process group ID from s.
int s, news; int from_addr_len; CONN_DB from; from_addr_len = sizeof(from); news = accept(s, &from, &from_addr_len);
The remote address returned in from will be exactly as received (that is, in exactly the same form as received in the calling address field in the Incoming Call packet).
Note that on entry into the accept call, from_addr_len should be set to the size of the CONN_DB structure. On return, it will be set to the length of the actual address returned in from.
A typical caller of accept would be a server process that forks a new process (after calling accept) to handle each new socket. The sample programs (see Chapter 13, Sockets Programming Example") provided with Solstice X.25 illustrate how this can be done.