Repository: microsoft/edit
File: src/sys/unix.rs (Rust)

Code before:
    unsafe {
        if STATE.inject_resize {
            timeout = time::Duration::ZERO;
        }

        let read_poll = timeout != time::Duration::MAX;
        let mut buf = Vec::new_in(arena);

        // We don't know if the input is valid UTF8, so we first use a Vec and then
        // later turn it into UTF8 using `from_utf8_lossy_owned`.
        // It is important that we allocate the buffer with an explicit capacity,
        // because we later use `spare_capacity_mut` to access it.
        buf.reserve(4 * KIBI);

        // We got some leftover broken UTF8 from a previous read? Prepend it.
        if STATE.utf8_len != 0 {
            STATE.utf8_len = 0;
            buf.extend_from_slice(&STATE.utf8_buf[..STATE.utf8_len]);
        }

        loop {
            if timeout != time::Duration::MAX {
                let beg = time::Instant::now();

                let mut pollfd = libc::pollfd { fd: STATE.stdin, events: libc::POLLIN, revents: 0 };
                let ret = libc::poll(&mut pollfd, 1, timeout.as_millis() as libc::c_int);
                if ret < 0 {
                    return None; // Error? Let's assume it's an EOF.
                }
                if ret == 0 {
                    break; // Timeout? We can stop reading.
                }

                timeout = timeout.saturating_sub(beg.elapsed());
            };

            // If we're asked for a non-blocking read we need
            // to manipulate `O_NONBLOCK` and vice versa.
            set_tty_nonblocking(read_poll);

            // Read from stdin.
            let spare = buf.spare_capacity_mut();
            let ret = libc::read(STATE.stdin, spare.as_mut_ptr() as *mut _, spare.len());
            if ret > 0 {
                buf.set_len(buf.len() + ret as usize);
                break;
            }
            if ret == 0 {
                return None; // EOF
            }
            if ret < 0 {

Review comment (suggestion):
I'd like to keep the old `ppoll` code for Linux. I think you could do it with something like
```rs
let ret;

#[cfg(target_os = "macos")]
{
    ret = libc::poll(&mut pollfd, 1, timeout.as_millis() as libc::c_int);
}
#[cfg(not(target_os = "macos"))]
{
    let ts = libc::timespec {
        tv_sec: timeout.as_secs() as libc::time_t,
        tv_nsec: timeout.subsec_nanos() as libc::c_long,
    };
    ret = libc::ppoll(&mut pollfd, 1, &ts, null());
}
```

Not sure if there's a better approach.

Code after:

        let read_poll = timeout != time::Duration::MAX;
        let mut buf = Vec::new_in(arena);

        // We don't know if the input is valid UTF8, so we first use a Vec and then
        // later turn it into UTF8 using `from_utf8_lossy_owned`.
        // It is important that we allocate the buffer with an explicit capacity,
        // because we later use `spare_capacity_mut` to access it.
        buf.reserve(4 * KIBI);

        // We got some leftover broken UTF8 from a previous read? Prepend it.
        if STATE.utf8_len != 0 {
            STATE.utf8_len = 0;
            buf.extend_from_slice(&STATE.utf8_buf[..STATE.utf8_len]);
        }

        loop {
            if timeout != time::Duration::MAX {
                let beg = time::Instant::now();

                let mut pollfd = libc::pollfd { fd: STATE.stdin, events: libc::POLLIN, revents: 0 };
                let ret;
                #[cfg(target_os = "linux")]
                {
                    let ts = libc::timespec {
                        tv_sec: timeout.as_secs() as libc::time_t,
                        tv_nsec: timeout.subsec_nanos() as libc::c_long,
                    };
                    ret = libc::ppoll(&mut pollfd, 1, &ts, ptr::null());
                }
                #[cfg(not(target_os = "linux"))]
                {
                    ret = libc::poll(&mut pollfd, 1, timeout.as_millis() as libc::c_int);
                }
                if ret < 0 {
                    return None; // Error? Let's assume it's an EOF.
                }
                if ret == 0 {
                    break; // Timeout? We can stop reading.
                }

                timeout = timeout.saturating_sub(beg.elapsed());
            };

            // If we're asked for a non-blocking read we need
            // to manipulate `O_NONBLOCK` and vice versa.
            set_tty_nonblocking(read_poll);

            // Read from stdin.
            let spare = buf.spare_capacity_mut();
            let ret = libc::read(STATE.stdin, spare.as_mut_ptr() as *mut _, spare.len());