EIO_Status CConn_FtpStream::Drain(const STimeout* timeout) { const STimeout* r_timeout = kInfiniteTimeout/*0*/; const STimeout* w_timeout = kInfiniteTimeout/*0*/; CONN conn = GetCONN(); char block[1024]; if (conn) { size_t n; r_timeout = CONN_GetTimeout(conn, eIO_Read); w_timeout = CONN_GetTimeout(conn, eIO_Write); _VERIFY(SetTimeout(eIO_Read, timeout) == eIO_Success); _VERIFY(SetTimeout(eIO_Write, timeout) == eIO_Success); // Cause any upload-in-progress to abort CONN_Read (conn, block, sizeof(block), &n, eIO_ReadPlain); // Cause any command-in-progress to abort CONN_Write(conn, "NOOP\n", 5, &n, eIO_WritePersist); } clear(); while (read(block, sizeof(block))) ; if (!conn) return eIO_Closed; EIO_Status status; do { size_t n; status = CONN_Read(conn, block, sizeof(block), &n, eIO_ReadPersist); } while (status == eIO_Success); _VERIFY(CONN_SetTimeout(conn, eIO_Read, r_timeout) == eIO_Success); _VERIFY(CONN_SetTimeout(conn, eIO_Write, w_timeout) == eIO_Success); clear(); return status == eIO_Closed ? eIO_Success : status; }
const STimeout* CConn_IOStream::GetTimeout(EIO_Event direction) const { CONN conn = GET_CONN(m_CSb); return conn ? CONN_GetTimeout(conn, direction) : 0; }
streamsize CConn_Streambuf::showmanyc(void) { static const STimeout kZeroTmo = {0, 0}; _ASSERT(gptr() >= egptr()); if (!m_Conn) return -1L; // flush output buffer, if tied up to it if (m_Tie) x_sync(); const STimeout* tmo; const STimeout* timeout = CONN_GetTimeout(m_Conn, eIO_Read); if (timeout == kDefaultTimeout) { // HACK * HACK * HACK tmo = ((SMetaConnector*) m_Conn)->default_timeout; } else tmo = timeout; size_t x_read; bool backup = false; if (m_BufSize > 1) { if (eback() < gptr()) { x_Buf = gptr()[-1]; backup = true; } if (!tmo) _VERIFY(CONN_SetTimeout(m_Conn, eIO_Read, &kZeroTmo)==eIO_Success); m_Status = CONN_Read(m_Conn, m_ReadBuf + 1, m_BufSize - 1, &x_read, eIO_ReadPlain); if (!tmo) _VERIFY(CONN_SetTimeout(m_Conn, eIO_Read, timeout) ==eIO_Success); _ASSERT(x_read > 0 || m_Status != eIO_Success); } else { m_Status = CONN_Wait(m_Conn, eIO_Read, tmo ? tmo : &kZeroTmo); x_read = 0; } if (!x_read) { switch (m_Status) { case eIO_Success: _ASSERT(m_BufSize <= 1); return 1L; // can read at least 1 byte case eIO_Timeout: if (!tmo || !(tmo->sec | tmo->usec)) break; /*FALLTHRU*/ case eIO_Closed: return -1L; // EOF default: break; } return 0; // no data available immediately } m_ReadBuf[0] = x_Buf; _ASSERT(m_BufSize > 1); setg(m_ReadBuf + !backup, m_ReadBuf + 1, m_ReadBuf + 1 + x_read); x_GPos += x_read; return x_read; }