util/chpty.cc
/// Read from the pty, *appending* into string dst. Note that dst is
/// NOT initially cleared by this method.  Stop reading when no more
/// data is available within the read timeout, or once dst reaches
/// maxlen, an argument which should be less than string.max_size().
/// Return the total number of bytes in dst after reading is complete.
///
/// n.b. Most commonly the caller *will* incur at least one
/// Pty_controller read-timeout with this call since it lingers to
/// make sure nothing remains--so do not make that timeout too
/// long. Use the method set_read_timeout() if the default value is
/// inappropriate. Its also worth remembering that ptys are line
/// oriented, so a dangling fragment of a line might not be
/// transmitted until the remote side follows it with a newline.
///
/// * May throw Chpty_read_exception()
///
Read from the pty, *appending* into string dst. Note that dst is
NOT initially cleared by this method.  Stop reading when no more
data is available within the read timeout, or once dst reaches
maxlen, an argument which should be less than string.max_size().
Return the total number of bytes in dst after reading is complete.




Read from the pty * appending * into string dst . Note that dst is NOT initially cleared by this method . Stop reading when no more data is available within the read timeout or once dst reaches maxlen an argument which should be less than string . max_size () . Return the total number of bytes in dst after reading is complete .
ssize_t Pty_controller::read_nb( std::string &dst, ssize_t maxlen )
{
    if (non_fd == m_cfd) {
        throw Chpty_read_exception();
    }
    ssize_t ndst = static_cast<ssize_t>(dst.size());
    bool retry = false;
    while (ndst < maxlen) {
        if (not retry and (0 == can_read())) {  timeout of can_read
            break;
        }
        errno = 0;
        ssize_t rc = read( m_cfd, m_read_buf, sizeof(m_read_buf) );
        if (libc_err == rc) {
            if (EINTR == errno) {  interrupted: worth trying read again
                retry = true;
                continue;
            } else {      any other error will throw
                throw Chpty_read_exception();
            }
        }
        if (0 == rc) {    managed to read nothing: very unlikely
            break;        treat it like no-more-data and exit loop
        }
        dst.append( m_read_buf, static_cast<size_t>(rc) );
        ndst += rc;
    }
    return ndst;
}
ssize_t Pty_controller :: read_nb ( std :: string & dst , ssize_t maxlen ) { if ( non_fd == m_cfd ) { throw Chpty_read_exception ( ) ; } ssize_t ndst = static_cast < ssize_t > ( dst . size ( ) ) ; bool retry = false ; while ( ndst < maxlen ) { if ( not retry and ( 0 == can_read ( ) ) ) { break ; } errno = 0 ; ssize_t rc = read ( m_cfd , m_read_buf , sizeof ( m_read_buf ) ) ; if ( libc_err == rc ) { if ( EINTR == errno ) { retry = true ; continue ; } else { throw Chpty_read_exception ( ) ; } } if ( 0 == rc ) { break ; } dst . append ( m_read_buf , static_cast < size_t > ( rc ) ) ; ndst += rc ; } return ndst ; }
Read from the pty, *appending* into string dst.
Read from the pty * appending * into string dst .
// // timeout of can_read // interrupted: worth trying read again // any other error will throw // managed to read nothing: very unlikely // treat it like no-more-data and exit loop