ztmux 0.1.0

A Rust port of tmux — the full terminal multiplexer, server and client
Documentation
/// The `strlcpy()` function copies up to size - 1 characters from the NUL-terminated string src to dst,
/// NUL-terminating the result.
/// C `vendor/tmux/compat/strlcpy.c:30`: `size_t strlcpy(char *dst, const char *src, size_t siz)`
pub unsafe fn strlcpy(dst: *mut u8, src: *const u8, siz: usize) -> usize {
    unsafe {
        let len = crate::libc::strnlen(src, siz);
        core::ptr::copy_nonoverlapping(src, dst, len);
        *dst.add(len) = b'\0';

        len
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_strlcpy_full_copy() {
        // src fits: return value is the source length, result NUL-terminated.
        let src = crate::c!("hi");
        let mut dst = [0xffu8; 10];
        let ret = unsafe { strlcpy(dst.as_mut_ptr(), src, dst.len()) };
        assert_eq!(ret, 2);
        assert_eq!(&dst[..3], b"hi\0");
    }

    #[test]
    fn test_strlcpy_truncation() {
        // siz=3: at most 3 bytes copied, then NUL written at dst[3].
        let src = crate::c!("hello");
        let mut dst = [0xffu8; 8];
        let ret = unsafe { strlcpy(dst.as_mut_ptr(), src, 3) };
        assert_eq!(ret, 3);
        assert_eq!(&dst[..4], b"hel\0");
    }

    #[test]
    fn test_strlcpy_empty_src() {
        let src = crate::c!("");
        let mut dst = [0xffu8; 4];
        let ret = unsafe { strlcpy(dst.as_mut_ptr(), src, dst.len()) };
        assert_eq!(ret, 0);
        assert_eq!(dst[0], b'\0');
    }
}