rem: ListenData          *ldPtr;
context: Ns_SockListenCallback(char *addr, int port, Ns_SockProc *proc, void *arg){    Tcl_HashEntry      *hPtr;    Tcl_HashTable      *tablePtr;    SOCKET              new, sock;    ListenData          *ldPtr;    int                 status;    struct sockaddr_in  sa;    if (Ns_GetSockAddr(&sa, addr, port) != NS_OK) {        return NS_ERROR;    }    if (addr != NULL) {        /*	 * Make sure we can bind to the specified interface.	 */	        sa.sin_port = 0;        sock = Ns_SockBind(&sa);        if (sock == INVALID_SOCKET) {            return NS_ERROR;        }        ns_sockclose(sock);    }    status = NS_OK;    Ns_MutexLock(&lock);    /*     * Update the global hash table that keeps track of which ports     * we're listening on.     */      hPtr = Tcl_CreateHashEntry(&portsTable, (char *) port, &new);    if (new == 0) {        tablePtr = Tcl_GetHashValue(hPtr);    } else {        sock = Ns_SockListen(NULL, port);        if (sock == INVALID_SOCKET) {            Tcl_DeleteHashEntry(hPtr);            status = NS_ERROR;        } else {            Ns_SockSetNonBlocking(sock);            tablePtr = ns_malloc(sizeof(Tcl_HashTable));            Tcl_InitHashTable(tablePtr, TCL_ONE_WORD_KEYS);            Tcl_SetHashValue(hPtr, tablePtr);            Ns_SockCallback(sock, ListenCallback, tablePtr,			    NS_SOCK_READ | NS_SOCK_EXIT);        }    }    if (status == NS_OK) {        hPtr = Tcl_CreateHashEntry(tablePtr, (char *) sa.sin_addr.s_addr, &new);        if (!new) {            status = NS_ERROR;        } else {            ldPtr = ns_malloc(sizeof(ListenData));            ldPtr->proc = proc;            ldPtr->arg = arg;            Tcl_SetHashValue(hPtr, ldPtr);        }    }    Ns_MutexUnlock(&lock);        return status;}