From f1c8051b85e2c309ff91e3432cec4bc0d986d051 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 16:02:52 +0100 Subject: [PATCH 01/16] Test on Windows --- .travis.yml | 3 +++ src/lib.rs | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f886114..6306d34 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,9 @@ jobs: - stage: test os: osx rust: stable + - stage: test + os: windows + rust: stable # Catch regressions in beta and nightly - stage: test diff --git a/src/lib.rs b/src/lib.rs index 2720c59..6a38c05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,6 @@ mod tests { use std::process::Command; #[test] - #[cfg(not(windows))] fn gethostname_matches_system_hostname() { let output = Command::new("hostname") .output() From 3401adc238827bc632cbf9440f0fb0c3e94a6dea Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 16:17:33 +0100 Subject: [PATCH 02/16] WIP: windows implementation --- Cargo.toml | 3 +++ src/lib.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 6e6f4bf..b95c5ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,6 @@ pretty_assertions = "^0.5" [target.'cfg(not(windows))'.dependencies] libc = "^0.2" + +[target.'cfg(windows)'.dependencies] +winapi = "^0.3" diff --git a/src/lib.rs b/src/lib.rs index 6a38c05..6793e33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,35 @@ pub fn gethostname() -> OsString { OsString::from_vec(buffer[0..end].to_vec()) } +#[cfg(windows)] +pub fn gethostname() -> OsString { + use std::os::windows::ffi::OsStringExt; + use winapi::ctypes::{c_ulong, wchar_t}; + use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, GetComputerNameExW}; + + let mut buffer_size: c_ulong = 0; + + unsafe { + GetComputerNameExW( + ComputerNamePhysicalDnsHostname, + std::ptr::null(), + &mut buffer_size, + ) + }; + + let mut buffer = vec![0 as wchar_t; buffer_size]; + + unsafe { + GetComputerNameExW( + ComputerNamePhysicalDnsHostname, + buffer.as_mut_ptr() as *mut wchar_t, + &mut buffer_size, + ) + }; + + OsString::from_wide(buffer) +} + #[cfg(test)] mod tests { use pretty_assertions::assert_eq; From 2f940c857ceae21155756a58b44bef6371600e2b Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 16:26:07 +0100 Subject: [PATCH 03/16] Lint on Windows --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6306d34..a026e35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,9 +41,14 @@ jobs: os: linux rust: nightly - # Run clippy after testing, with and without features. + # Run clippy after testing, on all platforms w/ dedicated implementations - stage: lint os: linux rust: stable before_script: rustup component add clippy script: cargo clippy --all-targets + - stage: lint + os: windows + rust: stable + before_script: rustup component add clippy + script: cargo clippy --all-targets From fee526055e6e09b5eca3178fb12a6b10b6f90515 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 16:56:14 +0100 Subject: [PATCH 04/16] Fix compiler erros --- Cargo.toml | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b95c5ad..907e2a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,4 @@ pretty_assertions = "^0.5" libc = "^0.2" [target.'cfg(windows)'.dependencies] -winapi = "^0.3" +winapi = {version = "^0.3", features = ["sysinfoapi"]} diff --git a/src/lib.rs b/src/lib.rs index 6793e33..11948e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,7 +69,7 @@ pub fn gethostname() -> OsString { ) }; - let mut buffer = vec![0 as wchar_t; buffer_size]; + let mut buffer = vec![0 as wchar_t; buffer_size as usize]; unsafe { GetComputerNameExW( From f231fa72f188b5bf6684207f2621bb1896fd5455 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 17:19:57 +0100 Subject: [PATCH 05/16] Fix mutability --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 11948e6..172032d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,7 +64,7 @@ pub fn gethostname() -> OsString { unsafe { GetComputerNameExW( ComputerNamePhysicalDnsHostname, - std::ptr::null(), + std::ptr::null_mut(), &mut buffer_size, ) }; @@ -79,7 +79,7 @@ pub fn gethostname() -> OsString { ) }; - OsString::from_wide(buffer) + OsString::from_wide(&buffer) } #[cfg(test)] From 7a8b292da1cdae50cf860a510e20a747c0283ddd Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 17:56:29 +0100 Subject: [PATCH 06/16] Document windows implementation --- src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 172032d..94699ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,6 +53,15 @@ pub fn gethostname() -> OsString { OsString::from_vec(buffer[0..end].to_vec()) } +/// Get the standard hostname for the current machine. +/// +/// Returns the DNS host name of the local computer, as returned by +/// [GetComputerNameExW] with `ComputerNamePhysicalDnsHostname` flag has name +/// type. This function may `panic!` if the internal buffer for the hostname is +/// too small. Since we try to allocate a buffer large enough to hold the host +/// name we consider panics a bug which you should report. +/// +/// [GetComputerNameExW]: https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getcomputernameexw #[cfg(windows)] pub fn gethostname() -> OsString { use std::os::windows::ffi::OsStringExt; From c55f11862670633672346224e3cca93122694cf3 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 18:01:17 +0100 Subject: [PATCH 07/16] panic! on erros --- Cargo.toml | 2 +- src/lib.rs | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 907e2a2..b463216 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,4 @@ pretty_assertions = "^0.5" libc = "^0.2" [target.'cfg(windows)'.dependencies] -winapi = {version = "^0.3", features = ["sysinfoapi"]} +winapi = {version = "^0.3", features = ["sysinfoapi", "errhandlingapi"]} diff --git a/src/lib.rs b/src/lib.rs index 94699ff..69c622b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,10 +22,10 @@ use std::ffi::OsString; /// Get the standard host name for the current machine. /// -/// Wraps POSIX [gethostname] in a safe interface. The function doesn’t fail but -/// it may `panic!` if the internal buffer for the hostname is too small, but we -/// use a buffer large enough to hold the maximum hostname, so we consider any -/// panics from this function as bug which you should report. +/// Wraps POSIX [gethostname] in a safe interface. The function may `panic!` if +/// the internal buffer for the hostname is too small, but we use a buffer large +/// enough to hold the maximum hostname, so we consider any panics from this +/// function as bug which you should report. /// /// [gethostname]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html #[cfg(not(windows))] @@ -66,21 +66,30 @@ pub fn gethostname() -> OsString { pub fn gethostname() -> OsString { use std::os::windows::ffi::OsStringExt; use winapi::ctypes::{c_ulong, wchar_t}; + use winapi::um::errhandlingapi::GetLastError; use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, GetComputerNameExW}; let mut buffer_size: c_ulong = 0; - unsafe { + let returncode = unsafe { GetComputerNameExW( ComputerNamePhysicalDnsHostname, std::ptr::null_mut(), &mut buffer_size, ) }; + if returncode != 0 { + let errorcode = GetLastError(); + panic!( + "GetComputerNameExW failed to read buffer size for host name: error code {}. +Please report this issue to !", + errorcode + ); + } let mut buffer = vec![0 as wchar_t; buffer_size as usize]; - unsafe { + let returncode = unsafe { GetComputerNameExW( ComputerNamePhysicalDnsHostname, buffer.as_mut_ptr() as *mut wchar_t, @@ -88,6 +97,15 @@ pub fn gethostname() -> OsString { ) }; + if returncode != 0 { + let errorcode = GetLastError(); + panic!( + "GetComputerNameExW failed to read hostname: error code {}. +Please report this issue to !", + errorcode + ); + } + OsString::from_wide(&buffer) } From b9cdf43eab1c7db75384d597295426e31651d3b0 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 18:36:20 +0100 Subject: [PATCH 08/16] Drop trailing nul byte on windows --- src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 69c622b..05b3d1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,7 +96,6 @@ Please report this issue to &mut buffer_size, ) }; - if returncode != 0 { let errorcode = GetLastError(); panic!( @@ -106,7 +105,12 @@ Please report this issue to ); } - OsString::from_wide(&buffer) + let end = buffer + .iter() + .position(|&b| b == 0) + .unwrap_or_else(|| buffer.len()); + + OsString::from_wide(buffer[0..end]) } #[cfg(test)] From ac16683a0231b0b11f0c76d0b56bf1b5a047cf5f Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 18:55:45 +0100 Subject: [PATCH 09/16] Fix reference --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 05b3d1d..9bc60c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,8 +109,7 @@ Please report this issue to .iter() .position(|&b| b == 0) .unwrap_or_else(|| buffer.len()); - - OsString::from_wide(buffer[0..end]) + OsString::from_wide(&buffer[0..end]) } #[cfg(test)] From fc8536ff344519ce22f1fe0b912d5fa777fd7887 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 19:15:31 +0100 Subject: [PATCH 10/16] Use Error instead of GetLastError --- Cargo.toml | 2 +- src/lib.rs | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b463216..907e2a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,4 @@ pretty_assertions = "^0.5" libc = "^0.2" [target.'cfg(windows)'.dependencies] -winapi = {version = "^0.3", features = ["sysinfoapi", "errhandlingapi"]} +winapi = {version = "^0.3", features = ["sysinfoapi"]} diff --git a/src/lib.rs b/src/lib.rs index 47f4ffd..0874e80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,7 +72,6 @@ pub fn gethostname() -> OsString { pub fn gethostname() -> OsString { use std::os::windows::ffi::OsStringExt; use winapi::ctypes::{c_ulong, wchar_t}; - use winapi::um::errhandlingapi::GetLastError; use winapi::um::sysinfoapi::{ComputerNamePhysicalDnsHostname, GetComputerNameExW}; let mut buffer_size: c_ulong = 0; @@ -85,11 +84,10 @@ pub fn gethostname() -> OsString { ) }; if returncode != 0 { - let errorcode = GetLastError(); panic!( - "GetComputerNameExW failed to read buffer size for host name: error code {}. + "GetComputerNameExW failed to read buffer size for host name: {} Please report this issue to !", - errorcode + Error::last_os_error() ); } @@ -103,11 +101,10 @@ Please report this issue to ) }; if returncode != 0 { - let errorcode = GetLastError(); panic!( - "GetComputerNameExW failed to read hostname: error code {}. + "GetComputerNameExW failed to read hostname: {} Please report this issue to !", - errorcode + Error::last_os_error() ); } From 920c71fc4feea8c55bac7a2fb1b07c461dd6a9f2 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 19:34:20 +0100 Subject: [PATCH 11/16] Don't panic on ERROR_MORE_DATA --- src/lib.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0874e80..fcf8d10 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,20 +76,15 @@ pub fn gethostname() -> OsString { let mut buffer_size: c_ulong = 0; - let returncode = unsafe { + unsafe { + // This call always fails with ERROR_MORE_DATA, because we pass NULL to + // get the required buffer size. GetComputerNameExW( ComputerNamePhysicalDnsHostname, std::ptr::null_mut(), &mut buffer_size, ) }; - if returncode != 0 { - panic!( - "GetComputerNameExW failed to read buffer size for host name: {} -Please report this issue to !", - Error::last_os_error() - ); - } let mut buffer = vec![0 as wchar_t; buffer_size as usize]; From 2e77ea741d8c2528cc41e38caf35e202ed8a427b Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 22:19:45 +0100 Subject: [PATCH 12/16] Fix return condition GetComputerNameExW returns non-zero on success! --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fcf8d10..f44e736 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,7 +87,6 @@ pub fn gethostname() -> OsString { }; let mut buffer = vec![0 as wchar_t; buffer_size as usize]; - let returncode = unsafe { GetComputerNameExW( ComputerNamePhysicalDnsHostname, @@ -95,7 +94,8 @@ pub fn gethostname() -> OsString { &mut buffer_size, ) }; - if returncode != 0 { + // GetComputerNameExW returns a non-zero value on success! + if returncode == 0 { panic!( "GetComputerNameExW failed to read hostname: {} Please report this issue to !", From df399e34eba04a6b86ff1d9e4611339ce8a2313d Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 19:19:44 +0100 Subject: [PATCH 13/16] Release 0.1.0 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 909bdd3..5fb8341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ 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). ## [Unreleased] +## 0.1.0 – 2019-01-20 Initial release. ### Added From 9ee160fae6ebf7405aa28237961a54c13dfc48f8 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 19:23:17 +0100 Subject: [PATCH 14/16] Fix badge URL --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c556e11..1ac0d3e 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ [![Current release](https://img.shields.io/crates/v/gethostname.svg)][crates] [![Documentation](https://docs.rs/gethostname/badge.svg)][docs] [![License](https://img.shields.io/github/license/lunaryorn/gethostname.rs.svg)][license] -[![Build status](https://img.shields.io/travis/lunaryorn/gethostname.rs/master.svg)][travis] +[![Build status](https://img.shields.io/travis/com/lunaryorn/gethostname.rs/master.svg)][travis] [gethostname()][ghn] for all platforms. [crates]: https://crates.io/crates/gethostname [docs]: https://docs.rs/gethostname [license]: https://github.com/lunaryorn/gethostname.rs/blob/master/LICENSE -[travis]: https://travis-ci.org/lunaryorn/gethostname.rs +[travis]: https://travis-ci.com/lunaryorn/gethostname.rs [ghn]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html ## Prior art From d4ffa6f0b955bac18324798f6bc83d721d5dd74f Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Sun, 20 Jan 2019 19:25:54 +0100 Subject: [PATCH 15/16] Add keywords and categories --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 907e2a2..6bdc50d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ version = "0.1.0" authors = ["Sebastian Wiesner "] edition = "2018" license = "Apache-2.0" +keywords = ["gethostname", "DNS", "hostname"] +categories = ["os", "api-bindings"] [dev-dependencies] pretty_assertions = "^0.5" From 93063d18298955e737da1dd78722e6fddda411d7 Mon Sep 17 00:00:00 2001 From: Sebastian Wiesner Date: Mon, 21 Jan 2019 22:54:45 +0100 Subject: [PATCH 16/16] Update changelog [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb8341..22aa951 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ 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). ## [Unreleased] +### Added +- Add Windows implementation (see [GH-1]). + +[Gh-1]: https://github.com/lunaryorn/gethostname.rs/pull/1 + ## 0.1.0 – 2019-01-20 Initial release.