/* this was cut & pasted from InetStreamSocket;
 * is there a clean way to wrap ISS::accept()?
 */
const IOSocket CompressedInetStreamSocket::accept(const struct timespec* timeout)
{
    int clientfd;
    long msecs = 0;

    struct pollfd pfd[1];
    pfd[0].fd = socketParms().sd();
    pfd[0].events = POLLIN;

    if (timeout != 0)
    {
        msecs = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;

        if (poll(pfd, 1, msecs) != 1 || (pfd[0].revents & POLLIN) == 0 ||
                pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
            return IOSocket(new CompressedInetStreamSocket());
    }

    struct sockaddr sa;

    socklen_t sl = sizeof(sa);

    int e;

    do
    {
        clientfd = ::accept(socketParms().sd(), &sa, &sl);
        e = errno;
    }
    while (clientfd < 0 && (e == EINTR ||
#ifdef ERESTART
                            e == ERESTART ||
#endif
#ifdef ECONNABORTED
                            e == ECONNABORTED ||
#endif
                            false));

    if (clientfd < 0)
    {
        string msg = "CompressedInetStreamSocket::accept: accept() error: ";
        scoped_array<char> buf(new char[80]);
#if STRERROR_R_CHAR_P
        const char* p;

        if ((p = strerror_r(e, buf.get(), 80)) != 0)
            msg += p;

#else
        int p;

        if ((p = strerror_r(e, buf.get(), 80)) == 0)
            msg += buf.get();

#endif
        throw runtime_error(msg);
    }

    if (fSyncProto)
    {
        /* send a byte to artificially synchronize with connect() on the remote */
        char b = 'A';
        int ret;

        ret = ::send(clientfd, &b, 1, 0);
        e = errno;

        if (ret < 0)
        {
            ostringstream  os;
            char blah[80];
#if STRERROR_R_CHAR_P
            const char* p;

            if ((p = strerror_r(e, blah, 80)) != 0)
                os << "CompressedInetStreamSocket::accept sync: " << p;

#else
            int p;

            if ((p = strerror_r(e, blah, 80)) == 0)
                os << "CompressedInetStreamSocket::accept sync: " << blah;

#endif
            ::close(clientfd);
            throw runtime_error(os.str());
        }
        else if (ret == 0)
        {
            ::close(clientfd);
            throw runtime_error("CompressedInetStreamSocket::accept sync: got unexpected error code");
        }
    }

    CompressedInetStreamSocket* ciss = new CompressedInetStreamSocket();
    IOSocket ios;
    sockaddr_in* sin = (sockaddr_in*) &sa;

    if ((sin->sin_addr.s_addr == fSa.sin_addr.s_addr) ||
            sin->sin_addr.s_addr == inet_addr("127.0.0.1"))
        ciss->useCompression = false;

    ios.setSocketImpl(ciss);
    SocketParms sp;
    sp = ios.socketParms();
    sp.sd(clientfd);
    ios.socketParms(sp);
    ios.sa(&sa);
    return ios;
}