Skip to content

Commit

Permalink
Auto merge of #2914 - SteveLauC:Wrong-getpwent_r-definition-on-solari…
Browse files Browse the repository at this point in the history
…sh-os, r=JohnTitor

fix wrong definitions of getpwent_r and getgrent_r on solarish os

Closes #2908

* [man page for `getpwent_r`](https://illumos.org/man/3C/getpwnam)
* [man page for `getgrent_r`](https://illumos.org/man/3C/getgrnam)

You may find the definitions for `getpwnam_r/getpwuid_r/getgrnam_r/getgruid_r` exposed by `libc` are also wrong:
```c
struct passwd *getpwnam_r(const char *name, struct passwd *pwd,
            char *buffer, int buflen);
```
```rust
pub fn getpwnam_r(
    name: *const ::c_char,
    pwd: *mut passwd,
    buf: *mut ::c_cha
    buflen: ::size_t,
    result: *mut *mut passwd,
) -> ::c_int;
```
But actually they are **correct** as there are the POSIX-conforming definitions (see `Standard conforming` section of above man pages):
```
Standard conforming

       cc [ flag...] file... -D_POSIX_PTHREAD_SEMANTICS [ library... ]

       int getpwnam_r(const char *name, struct passwd *pwd, char *buffer,
            size_t bufsize, struct passwd **result);

       int getpwuid_r(uid_t uid, struct passwd *pwd, char *buffer,
            size_t bufsize, struct passwd **result);
```

`getpwent_r/getgrent_r` don't get lucky, they do not have the POSIX-conforming alternatives.

To double check this, I searched its [source code](https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/gen/getpwnam_r.c):
```shell
$ rg "__posix_getpwnam_r"
port/mapfile-vers
1582:   __posix_getpwnam_r;

port/gen/getpwnam_r.c
152:__posix_getpwnam_r(const char *name, struct passwd *pwd, char *buffer,

$ rg "__posix_getpwent_r"

$
```
  • Loading branch information
bors committed Nov 3, 2022
2 parents 875f3a6 + 8a914ca commit 1ca1c41
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 14 deletions.
49 changes: 49 additions & 0 deletions src/unix/solarish/compat.rs
@@ -1,6 +1,7 @@
// Common functions that are unfortunately missing on illumos and
// Solaris, but often needed by other crates.

use core::cmp::min;
use unix::solarish::*;

const PTEM: &[u8] = b"ptem\0";
Expand Down Expand Up @@ -169,3 +170,51 @@ pub unsafe fn forkpty(

0
}

pub unsafe fn getpwent_r(
pwd: *mut passwd,
buf: *mut ::c_char,
buflen: ::size_t,
result: *mut *mut passwd,
) -> ::c_int {
let old_errno = *::___errno();
*::___errno() = 0;
*result = native_getpwent_r(
pwd,
buf,
min(buflen, ::c_int::max_value() as ::size_t) as ::c_int,
);

let ret = if (*result).is_null() {
*::___errno()
} else {
0
};
*::___errno() = old_errno;

ret
}

pub unsafe fn getgrent_r(
grp: *mut ::group,
buf: *mut ::c_char,
buflen: ::size_t,
result: *mut *mut ::group,
) -> ::c_int {
let old_errno = *::___errno();
*::___errno() = 0;
*result = native_getgrent_r(
grp,
buf,
min(buflen, ::c_int::max_value() as ::size_t) as ::c_int,
);

let ret = if (*result).is_null() {
*::___errno()
} else {
0
};
*::___errno() = old_errno;

ret
}
18 changes: 4 additions & 14 deletions src/unix/solarish/mod.rs
Expand Up @@ -3016,24 +3016,14 @@ extern "C" {
) -> ::c_int;
#[cfg_attr(
any(target_os = "solaris", target_os = "illumos"),
link_name = "__posix_getpwent_r"
link_name = "getpwent_r"
)]
pub fn getpwent_r(
pwd: *mut passwd,
buf: *mut ::c_char,
buflen: ::size_t,
result: *mut *mut passwd,
) -> ::c_int;
fn native_getpwent_r(pwd: *mut passwd, buf: *mut ::c_char, buflen: ::c_int) -> *mut passwd;
#[cfg_attr(
any(target_os = "solaris", target_os = "illumos"),
link_name = "__posix_getgrent_r"
link_name = "getgrent_r"
)]
pub fn getgrent_r(
grp: *mut ::group,
buf: *mut ::c_char,
buflen: ::size_t,
result: *mut *mut ::group,
) -> ::c_int;
fn native_getgrent_r(grp: *mut ::group, buf: *mut ::c_char, buflen: ::c_int) -> *mut ::group;
#[cfg_attr(
any(target_os = "solaris", target_os = "illumos"),
link_name = "__posix_sigwait"
Expand Down

0 comments on commit 1ca1c41

Please sign in to comment.