Skip to content

Commit

Permalink
Merge pull request #17 from swsnr/rustix
Browse files Browse the repository at this point in the history
Replace libc with rustix
  • Loading branch information
swsnr authored Jul 6, 2024
2 parents c31b57e + 361da77 commit 925a932
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 56 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ jobs:
- run: cargo fmt --check
if: matrix.rust == 'stable'
- run: cargo doc
if: "!contains(matrix.os, 'windows')"
29 changes: 26 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- On Unix, use `rustix` to provide a simple implementation of `gethostname`
without `unsafe` (see [GH-10] and [GH-17]).

[GH-10]: https://github.com/swsnr/gethostname.rs/pull/10
[GH-17]: https://github.com/swsnr/gethostname.rs/pull/17

## [0.4.3] – 2023-05-13

### Changed
- Removed the `windows` dependency in favor of using embedded bindings, see [GH-11].

- Removed the `windows` dependency in favor of using embedded bindings, see
[GH-11].

[GH-11]: https://github.com/swsnr/gethostname.rs/pull/11

## [0.4.2] – 2023-04-13

### Changed

- Update dependencies.

## [0.4.1] – 2022-12-01
Expand All @@ -27,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.4.0] – 2022-10-28

### Changed

- Replace `winapi` with windows-rs, see [GH-7].
- Bump MSRV to 1.64 as required by windows-rs, see [GH-7].

Expand All @@ -35,30 +49,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.3.0] – 2022-10-09

### Changed

- Bump MSRV to 1.56.

## [0.2.3] – 2022-03-12

### Changed
- Limit `gethostname()` to `cfg(unix)` and `cfg(windows)` to provide more useful build failures on other platforms.

- Limit `gethostname()` to `cfg(unix)` and `cfg(windows)` to provide more useful
build failures on other platforms.

## [0.2.2] – 2022-01-14

## [0.2.1] – 2019-12-18

### Changed

- Consolidate documetation.
- Update crates.io metadata.

## [0.2.0] – 2019-01-22

### Added

- Add Windows implementation (see [GH-1]).

[GH-1]: https://github.com/swsnr/gethostname.rs/pull/1

### Changed

- Pin supported Rust version to 1.31

## 0.1.0 – 2019-01-20

Initial release.

### Added
Expand Down
46 changes: 45 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ categories = ["os", "api-bindings"]
rust-version = "1.64"

[target.'cfg(not(windows))'.dependencies]
libc = "0.2.141"
rustix = { version = "0.38.34", default-features = false, features = [
"system",
] }

[target.'cfg(windows)'.dependencies]
windows-targets = "0.52.4"
71 changes: 20 additions & 51 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,66 +28,35 @@ use std::ffi::OsString;

/// Get the standard host name for the current machine.
///
/// On Unix simply wrap POSIX [gethostname] in a safe interface. On Windows
/// return the DNS host name of the local computer, as returned by
/// [GetComputerNameExW] with `ComputerNamePhysicalDnsHostname` as `NameType`.
///
/// This function panics if the buffer allocated for the hostname result of the
/// operating system is too small; however we take great care to allocate a
/// buffer of sufficient size:
/// On Unix call [`rustix::system::uname`] to obtain the node name, see
/// [`rustix::system::Uname::nodename`].
///
/// * On Unix we allocate the buffer using the maximum permitted hostname size,
/// as returned by [sysconf] via `sysconf(_SC_HOST_NAME_MAX)`, plus an extra
/// byte for the trailing NUL byte. A hostname cannot exceed this limit, so
/// this function can't realistically panic.
/// * On Windows we call `GetComputerNameExW` with a NULL buffer first, which
/// makes it return the length of the current host name. We then use this
/// length to allocate a buffer for the actual result; this leaves a tiny
/// tiny race condition in case the hostname changes to a longer name right
/// in between those two calls but that's a risk we don't consider of any
/// practical relevance.
/// On Windows return the DNS host name of the local computer, as returned by
/// [GetComputerNameExW] with `ComputerNamePhysicalDnsHostname` as `NameType`.
/// We call this function twice to obtain the appropriate buffer size; there is
/// a race condition window between these two calls where a change to the node
/// name would result in a wrong buffer size which could cause this function to
/// panic.
///
/// Hence _if_ this function does panic please [report an issue][new].
/// Note that this host name does not have a well-defined meaning in terms of
/// network name resolution. Specifically, it's not guaranteed that the
/// returned name can be resolved in any particular way, e.g. DNS.
///
/// [gethostname]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html
/// [sysconf]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html
/// [GetComputerNameExW]: https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getcomputernameexw
/// [new]: https://github.com/swsnr/gethostname.rs/issues/new
pub fn gethostname() -> OsString {
gethostname_impl()
}

#[cfg(unix)]
#[inline]
fn gethostname_impl() -> OsString {
use libc::{c_char, sysconf, _SC_HOST_NAME_MAX};
use std::os::unix::ffi::OsStringExt;
// Get the maximum size of host names on this system, and account for the
// trailing NUL byte.
let hostname_max = unsafe { sysconf(_SC_HOST_NAME_MAX) };
let mut buffer = vec![0; (hostname_max as usize) + 1];
let returncode = unsafe { libc::gethostname(buffer.as_mut_ptr() as *mut c_char, buffer.len()) };
if returncode != 0 {
// There are no reasonable failures, so lets panic
panic!(
"gethostname failed: {}
Please report an issue to <https://github.com/swsnr/gethostname.rs/issues>!",
std::io::Error::last_os_error()
);
#[cfg(unix)]
{
use std::os::unix::ffi::OsStringExt;
OsString::from_vec(rustix::system::uname().nodename().to_bytes().to_vec())
}
#[cfg(windows)]
{
get_computer_physical_dns_hostname()
}
// We explicitly search for the trailing NUL byte and cap at the buffer
// length: If the buffer's too small (which shouldn't happen since we
// explicitly use the max hostname size above but just in case) POSIX
// doesn't specify whether there's a NUL byte at the end, so if we didn't
// check we might read from memory that's not ours.
let end = buffer.iter().position(|&b| b == 0).unwrap_or(buffer.len());
buffer.truncate(end);
OsString::from_vec(buffer)
}

#[cfg(windows)]
#[inline]
fn gethostname_impl() -> OsString {
fn get_computer_physical_dns_hostname() -> OsString {
use std::os::windows::ffi::OsStringExt;

// The DNS host name of the local computer. If the local computer is a node
Expand Down

0 comments on commit 925a932

Please sign in to comment.