Skip to content

Commit

Permalink
Enable ZMQ_HAVE_STRLCPY for GLIBC >= 2.38
Browse files Browse the repository at this point in the history
  • Loading branch information
jean-airoldie committed Aug 4, 2023
1 parent 5059cd7 commit d49008c
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ members = ["testcrate"]
[dependencies]
cc = { version = "1", features = ["parallel"] }
dircpy = "0.3.8"
libc = "0.2.147"

[dev-dependencies]
testcrate = { path = "./testcrate", features = ["libsodium"] }
88 changes: 86 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
env, fs,
fs::File,
env,
fs::{self, File},
io::Write,
path::{Path, PathBuf},
};
Expand Down Expand Up @@ -56,6 +56,84 @@ where
Err(())
}

#[cfg(target_env = "gnu")]
mod glibc {
use std::{cmp, ffi::CStr, num, str};

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub(crate) struct GlibcVersion {
major: u16,
minor: u16,
}

impl Ord for GlibcVersion {
fn cmp(&self, other: &Self) -> cmp::Ordering {
match self.major.cmp(&other.major) {
cmp::Ordering::Greater => return cmp::Ordering::Greater,
cmp::Ordering::Less => return cmp::Ordering::Less,
cmp::Ordering::Equal => (),
}
self.minor.cmp(&other.minor)
}
}

impl PartialOrd for GlibcVersion {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}

impl GlibcVersion {
#[inline]
const fn new(major: u16, minor: u16) -> Self {
Self { major, minor }
}

pub(crate) fn from_libc() -> Self {
// SAFETY Call to libc via ffi.
let ptr = unsafe { libc::gnu_get_libc_version() };

// SAFETY We're reading a static c string via ffi.
let cstr = unsafe { CStr::from_ptr(ptr) };
let string = cstr.to_str().expect("expected UTF8 string");
match string.parse() {
Ok(version) => version,
Err(_) => {
panic!("unable to parse glibc version, expect MAJOR.MINOR.PATCH, got {}", string);
}
}
}

pub(crate) fn has_strlcpy(self) -> bool {
// > * The strlcpy and strlcat functions have been added. They are derived
// from OpenBSD, and are expected to be added to a future POSIX version.
//
// https://sourceware.org/pipermail/libc-alpha/2023-July/150524.html
self >= GlibcVersion::new(2, 38)
}
}

#[derive(Debug)]
pub(crate) struct BadVersion(());

impl From<num::ParseIntError> for BadVersion {
fn from(_: num::ParseIntError) -> Self {
Self(())
}
}

impl str::FromStr for GlibcVersion {
type Err = BadVersion;
fn from_str(s: &str) -> Result<Self, BadVersion> {
let mut iter = s.split('.');
let major = iter.next().ok_or(BadVersion(()))?.parse()?;
let minor = iter.next().ok_or(BadVersion(()))?.parse()?;

Ok(Self { major, minor })
}
}
}

/// The location of a library.
#[derive(Debug, Clone)]
pub struct LibLocation {
Expand Down Expand Up @@ -395,6 +473,12 @@ impl Build {
build.define("ZMQ_HAVE_IPC", "1");
}

// https://github.com/jean-airoldie/zeromq-src-rs/issues/28
#[cfg(target_env = "gnu")]
if glibc::GlibcVersion::from_libc().has_strlcpy() {
build.define("ZMQ_HAVE_STRLCPY", "1");
}

let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let lib_dir = out_dir.join("lib");

Expand Down

0 comments on commit d49008c

Please sign in to comment.