Skip to content

API Request: expose getpwent and getgrent #1811

Open
@SteveLauC

Description

@SteveLauC

These two syscalls sequentially scan the /etc/passwd/ and /etc/group` databases and return all the entries in those files one by one.

Signature

pub fn getpwent() -> Result<Vec<User>, Errno>;
pub fn getgrent() -> Result<Vec<Group>, Errno>;

Implementation

On some OSes, we have non-reentrant functions getpwent_r() and getgrent_r(). If so, they will be used. Otherwise, will use getpwent() and getgrent().

Here is draft implementation of getgrent under Linux:

pub fn getgrent() -> Result<Vec<Group>, Errno> {
    let mut v: Vec<Group> = Vec::new();

    let mut gr_buf: group = unsafe { zeroed() };
    let mut gr_str_buf: [c_char; 4096] = [0; 4096];
    unsafe { setgrent() };

    loop {
        let mut result: *mut group = null_mut();
        let res: c_int = unsafe {
            getgrent_r(
                &mut gr_buf as *mut group,
                &mut gr_str_buf as *mut c_char,
                4096,
                &mut result as *mut *mut group,
            )
        };

        // no more entries
        if res == ENOENT {
            unsafe { endgrent() };
            break;
        }

        // error
        if res == ERANGE {
            return Err(Errno::from_i32(ERANGE));
        }

        // man page for `getgrent_r` only lists the two above erroneous cases.
        // In other cases, it should be successful.
        assert_eq!(res, 0);
        v.push(Group::from(&gr_buf));
    }

    Ok(v)
}

Note

  1. The above implementation calls setgrent and endgrent inside, which actually changes the semantics of this syscall.

  2. Due to Note 1, perhaps we can give a better name to those syscalls, like:

    impl User {
        pub fn all_users() -> Result<Vec<User>, Errno>;
    }
    impl Group {
        pub fn all_groups() -> Result<Vec<Group>, Errno>;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions