Skip to content

Commit

Permalink
Update docs, replace libc print macro, fix actual clippy lints
Browse files Browse the repository at this point in the history
  • Loading branch information
maxwase committed Aug 19, 2022
1 parent 3955dbf commit 7ca1e3b
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 45 deletions.
4 changes: 1 addition & 3 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Module initialization/teardown functions for Rust (like `__attribute__((constructor))` in C/C++) for Linux, OSX, FreeBSD, NetBSD, Illumos, OpenBSD, DragonFlyBSD, Android, iOS, and Windows.

This library currently requires **Rust > 1.31.0** at a minimum for the
This library currently requires **Rust > 1.38.0** at a minimum for the
procedural macro support.

Idea inspired by [this code](https://github.com/neon-bindings/neon/blob/2277e943a619579c144c1da543874f4a7ec39879/src/lib.rs#L42) in the Neon project.
Expand All @@ -26,9 +26,9 @@ this library explicitly subverts that. The code that runs in the `ctor`
and `dtor` functions should be careful to limit itself to `libc`
functions and code that does not rely on Rust's stdlib services.

For example, using stdout in a `dtor` function is a guaranteed panic. Consider
For example, using stdout in a `dtor` function before 1.48.0 is a guaranteed panic. Consider
using the [`libc-print` crate](https://crates.io/crates/libc-print) for output
to stderr/stdout during `#[ctor]` and `#[dtor]` methods. Other issues
to stderr/stdout during `#[dtor]` methods if you are using an old compiler. Other issues
may involve signal processing or panic handling in that early code.

In most cases, `sys_common::at_exit` is a better choice than `#[dtor]`. Caveat emptor!
Expand Down Expand Up @@ -73,7 +73,7 @@ some stdlib services at this time.
```rust
#[dtor]
unsafe fn shutdown() {
// Using println or eprintln here will panic as Rust has shut down
// Using println or eprintln here will panic as Rust has shut down before Rust 1.48.0
libc::printf("Shutting down!\n\0".as_ptr() as *const i8);
}
```
Expand Down
2 changes: 1 addition & 1 deletion ctor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ctor"
version = "0.1.23"
version = "0.1.24"
authors = ["Matt Mastracci <matthew@mastracci.com>"]
edition = "2018"
description = "__attribute__((constructor)) for Rust"
Expand Down
21 changes: 10 additions & 11 deletions ctor/src/example.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
extern crate ctor;
extern crate libc_print;

use ctor::*;
use libc_print::*;
use ctor::{ctor, dtor};
use libc_print::libc_eprintln;
use std::collections::HashMap;

#[ctor]
Expand All @@ -12,18 +12,18 @@ static STATIC_CTOR: HashMap<u32, &'static str> = {
m.insert(0, "foo");
m.insert(1, "bar");
m.insert(2, "baz");
libc_eprintln!("STATIC_CTOR");
eprintln!("STATIC_CTOR");
m
};

#[ctor]
fn ctor() {
libc_eprintln!("ctor");
eprintln!("ctor");
}

#[ctor]
unsafe fn ctor_unsafe() {
libc_eprintln!("ctor_unsafe");
eprintln!("ctor_unsafe");
}

#[dtor]
Expand All @@ -37,18 +37,17 @@ unsafe fn dtor_unsafe() {
}

mod module {
use ctor::*;
use libc_print::*;
use ctor::ctor;

#[ctor]
pub static STATIC_CTOR: u8 = {
libc_eprintln!("module::STATIC_CTOR");
eprintln!("module::STATIC_CTOR");
42
};
}

pub fn main() {
libc_eprintln!("main!");
libc_eprintln!("STATIC_CTOR = {:?}", *STATIC_CTOR);
libc_eprintln!("module::STATIC_CTOR = {:?}", *module::STATIC_CTOR);
eprintln!("main!");
eprintln!("STATIC_CTOR = {:?}", *STATIC_CTOR);
eprintln!("module::STATIC_CTOR = {:?}", *module::STATIC_CTOR);
}
18 changes: 7 additions & 11 deletions ctor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//!
//! This library works and is regularly tested on Linux, OSX and Windows, with both `+crt-static` and `-crt-static`.
//! Other platforms are supported but not tested as part of the automatic builds. This library will also work as expected in both
//! `bin` and `cdylib` outputs, ie: the `ctor` and `dtor` will run at executable or library
//! `bin` and `cdylib` outputs, ie: the `ctor` and `dtor` will run at executable or library
//! startup/shutdown respectively.
//!
//! This library currently requires Rust > `1.31.0` at a minimum for the
Expand Down Expand Up @@ -38,13 +38,9 @@ use proc_macro::TokenStream;
///
/// # Examples
///
/// Print a startup message (using `libc_print` for safety):
///
/// ```rust
/// # extern crate ctor;
/// # use ctor::*;
/// use libc_print::std_name::println;
///
/// # use ctor::ctor;
/// #[ctor]
/// fn foo() {
/// println!("Hello, world!");
Expand All @@ -59,7 +55,7 @@ use proc_macro::TokenStream;
///
/// ```rust
/// # extern crate ctor;
/// # use ctor::*;
/// # use ctor::ctor;
/// # use std::sync::atomic::{AtomicBool, Ordering};
/// static INITED: AtomicBool = AtomicBool::new(false);
///
Expand All @@ -74,7 +70,7 @@ use proc_macro::TokenStream;
/// ```rust
/// # extern crate ctor;
/// # use std::collections::HashMap;
/// # use ctor::*;
/// # use ctor::ctor;
/// #[ctor]
/// static STATIC_CTOR: HashMap<u32, String> = {
/// let mut m = HashMap::new();
Expand Down Expand Up @@ -188,7 +184,7 @@ pub fn ctor(_attribute: TokenStream, function: TokenStream) -> TokenStream {
..
} = var;

if let Some(_) = mutability {
if mutability.is_some() {
panic!("#[ctor]-annotated static objects must not be mutable");
}

Expand Down Expand Up @@ -275,7 +271,7 @@ pub fn ctor(_attribute: TokenStream, function: TokenStream) -> TokenStream {
///
/// ```rust
/// # extern crate ctor;
/// # use ctor::*;
/// # use ctor::{ctor, dtor};
/// # fn main() {}
///
/// #[dtor]
Expand Down Expand Up @@ -389,7 +385,7 @@ fn validate_item(typ: &str, item: &syn::ItemFn) {
}

// No parameters allowed
if sig.inputs.len() > 0 {
if !sig.inputs.is_empty() {
panic!("#[{}] methods may not have parameters", typ);
}

Expand Down
11 changes: 5 additions & 6 deletions tests/src/dylib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![allow(dead_code, unused_imports)]

use ctor::*;
use libc_print::*;
use ctor::{ctor, dtor};

#[cfg(windows)]
extern "C" {
Expand All @@ -20,7 +19,7 @@ unsafe fn sleep(seconds: u32) {

#[ctor]
pub static STATIC_INT: u8 = {
libc_ewriteln!("+++ ctor STATIC_INT");
eprintln!("+++ ctor STATIC_INT");
200
};

Expand All @@ -29,20 +28,20 @@ pub static STATIC_INT: u8 = {
#[cfg(target_feature = "crt-static")]
unsafe fn ctor() {
sleep(1);
libc_ewriteln!("+++ ctor lib (+crt-static)");
eprintln!("+++ ctor lib (+crt-static)");
}

#[ctor]
#[cfg(not(test))]
#[cfg(not(target_feature = "crt-static"))]
unsafe fn ctor() {
sleep(1);
libc_ewriteln!("+++ ctor lib (-crt-static)");
eprintln!("+++ ctor lib (-crt-static)");
}

#[dtor]
#[cfg(not(test))]
unsafe fn dtor() {
sleep(1);
libc_ewriteln!("--- dtor lib");
eprintln!("--- dtor lib");
}
10 changes: 5 additions & 5 deletions tests/src/dylib_load.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#![allow(unused_imports)]

use ctor::*;
use ctor::{ctor, dtor};
use dlopen::raw::Library;
use libc_print::*;
use libc_print::libc_ewriteln;

#[ctor]
#[cfg(not(test))]
unsafe fn ctor() {
sleep(1);
libc_ewriteln!("+ ctor bin");
eprintln!("+ ctor bin");
}

#[dtor]
Expand Down Expand Up @@ -91,7 +91,7 @@ unsafe fn sleep(seconds: u32) {
pub fn main() {
unsafe {
sleep(1);
libc_ewriteln!("++ main start");
eprintln!("++ main start");
let lib = Library::open(format!(
"target/debug/examples/{}dylib.{}",
prefix(),
Expand All @@ -100,6 +100,6 @@ pub fn main() {
.unwrap();
drop(lib);
sleep(1);
libc_ewriteln!("-- main end");
eprintln!("-- main end");
}
}
12 changes: 8 additions & 4 deletions tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extern crate ctor;

#[cfg(test)]
mod test {
use libc_print::*;
use libc_print::libc_eprintln;
use std::path::Path;
use std::process::Command;
use std::sync::atomic::{AtomicBool, Ordering};
Expand Down Expand Up @@ -37,8 +37,8 @@ mod test {
#[test]
fn test_initialized() {
// Test to see that the ctor ran
assert_eq!(true, INITED.load(Ordering::SeqCst));
assert_eq!(true, INITED_2.load(Ordering::SeqCst));
assert!(INITED.load(Ordering::SeqCst));
assert!(INITED_2.load(Ordering::SeqCst));
assert_eq!(*INITED_3, 42);
}

Expand Down Expand Up @@ -88,6 +88,10 @@ mod test {

// There are four possible outcomes for stderr, depending on the order
// that functions are called
assert!(a == s || b == s || c == s || d == s, "s was unexpected:\n{}", s.replace("\n", "\\n"));
assert!(
a == s || b == s || c == s || d == s,
"s was unexpected:\n{}",
s.replace('\n', "\\n")
);
}
}

0 comments on commit 7ca1e3b

Please sign in to comment.