All Projects → vrmiguel → unixstring

vrmiguel / unixstring

Licence: other
An FFI-friendly null-terminated byte string

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to unixstring

uapi
Unix API
Stars: ✭ 18 (-5.26%)
Mutual labels:  unix, ffi
libserialport.dart
Serial Port for Dart
Stars: ✭ 51 (+168.42%)
Mutual labels:  ffi
OpenBSDFirewall
Simple OpenBSD Home Firewall Config for ALIX Board
Stars: ✭ 41 (+115.79%)
Mutual labels:  unix
expandvars
Expand system variables Unix style
Stars: ✭ 17 (-10.53%)
Mutual labels:  unix
jobflow
runs stuff in parallel (like GNU parallel, but much faster and memory-efficient)
Stars: ✭ 67 (+252.63%)
Mutual labels:  unix
findlargedir
find all "blackhole" directories with a huge amount of filesystem entries in a flat structure
Stars: ✭ 15 (-21.05%)
Mutual labels:  unix
PointerScript
Scripting language with pointers and native library access.
Stars: ✭ 26 (+36.84%)
Mutual labels:  ffi
skabus
A collection of tools to implement a simple Unix bus. https://skarnet.org/software/skabus/
Stars: ✭ 17 (-10.53%)
Mutual labels:  unix
swift-bridge
swift-bridge facilitates Rust and Swift interop.
Stars: ✭ 260 (+1268.42%)
Mutual labels:  ffi
generic-linked-in-driver
A generic non-blocking linked-in driver for interfacing Erlang and C
Stars: ✭ 46 (+142.11%)
Mutual labels:  ffi
pybluemonday
pybluemonday is a library for sanitizing HTML very quickly via bluemonday.
Stars: ✭ 25 (+31.58%)
Mutual labels:  ffi
bash-streams-handbook
💻 Learn Bash streams, pipelines and redirection, from beginner to advanced.
Stars: ✭ 153 (+705.26%)
Mutual labels:  unix
eta-ffi
A command line tool to automate the generation of ffi import code for the bindings of various Java libraries.
Stars: ✭ 19 (+0%)
Mutual labels:  ffi
php-rdkafka-ffi
PHP Kafka client - binding librdkafka via FFI
Stars: ✭ 49 (+157.89%)
Mutual labels:  ffi
apex
ANSI POSIX Environment neXt for Harvey OS
Stars: ✭ 25 (+31.58%)
Mutual labels:  unix
pv
Unix Pipe Viewer (pv) utility in Node.js
Stars: ✭ 20 (+5.26%)
Mutual labels:  unix
winsafe
Windows API and GUI in safe, idiomatic Rust.
Stars: ✭ 110 (+478.95%)
Mutual labels:  ffi
lsrootkit
Rootkit Detector for UNIX
Stars: ✭ 53 (+178.95%)
Mutual labels:  unix
PhpWebcam
This is a PHP library to capture webcam frames
Stars: ✭ 33 (+73.68%)
Mutual labels:  ffi
cffi
Safe* C foreign function interface for Rust, using proc macros and marshaling types.
Stars: ✭ 15 (-21.05%)
Mutual labels:  ffi

unixstring codecov Crates.io Docs

UnixString is an FFI-friendly null-terminated byte string that may be constructed from a String, a CString, a PathBuf, an OsString or a collection of bytes.

An UnixString can then be converted into a slice of CStr, Path or OsStr in infallible and zero-cost operations.

Why?

UnixString aims to be useful in any scenario where you'd like to use FFI (specially with C) on Unix systems. If you have a PathBuf, for example, you can send that data to a libc function, such as stat, but you'd have to first allocate a CString (or something analogous) to do so.

The same is true with OsString and String because these three types are allowed to have internal zero bytes and are not null-terminated.

A UnixString is very close to what a CString is but with increased flexibility and usability. A CString cannot be changed or increased after instantited, while UnixString is growable through its push and push_bytes methods, somewhat similar to OsString.

A CString also does not have direct reference conversions to anything but &[u8] or &CStr, while UnixString has those and more (described below).

Obtaining references from an UnixString

Into Function Notes
&CStr UnixString::as_c_str Available through AsRef as well
&Path UnixString::as_path Available through AsRef as well
&str UnixString::as_str Fails if the bytes of the UnixString aren't valid UTF-8
&[u8] UnixString::as_bytes Returns the bytes of the UnixString without the null terminator
&[u8] UnixString::as_bytes_with_nul Returns the bytes of the UnixString with the null terminator
&OsStr UnixString::as_os_str Available through AsRef as well
* const c_char UnixString::as_ptr

Creating an UnixString

From Potential failure Trait impl Function
CString Infallible From UnixString::from_cstring
PathBuf Fails if contains an interior zero byte TryFrom UnixString::from_pathbuf
String Fails if contains an interior zero byte TryFrom UnixString::from_string
Vec<u8> Fails if contains an interior zero byte TryFrom UnixString::from_bytes
OsString Fails if contains an interior zero byte TryFrom UnixString::from_os_string
* const c_char Unsafe, see the docs for more info None UnixString::from_ptr

Converting from an UnixString

Into Function Notes
CString UnixString::into_cstring
PathBuf UnixString::into_pathbuf
OsString UnixString::into_os_string
String UnixString::into_string Fails if the UnixString's bytes are not valid UTF-8
String UnixString::into_string_lossy
String UnixString::to_string_lossy Non-moving version of UnixString::into_string_lossy
String UnixString::into_string_unchecked Unsafe: creates a String without checking if the bytes are valid UTF-8
Vec<u8> UnixString::into_bytes Returns the bytes of the UnixString without the null terminator
Vec<u8> UnixString::into_bytes_with_nul Returns the bytes of the UnixString with the null terminator

All of the above are also available through .into().

Examples

Creating an UnixString with bytes received through FFI

use libc::{c_char, getcwd};
use unixstring::UnixString;

fn main() {
    const PATH_SIZ: usize = 1024;
    let mut buf: [c_char; 1024] = [0; 1024];

    let ptr = &mut buf as *mut c_char;

    unsafe { getcwd(ptr, PATH_SIZ) };

    if ptr.is_null() {
        panic!("getcwd failed");
    }

    let unix_string = unsafe { UnixString::from_ptr(ptr as *const c_char) };

    assert_eq!(unix_string.as_path(), std::env::current_dir().unwrap())
}

Using an UnixString to send bytes through FFI

use std::{convert::TryFrom, env};

use unixstring::UnixString;

fn stat(path: &UnixString) -> std::io::Result<libc::stat> {
    // Safety: The all-zero byte-pattern is a valid `struct stat`
    let mut stat_buf = unsafe { std::mem::zeroed() };

    if -1 == unsafe { libc::lstat(path.as_ptr(), &mut stat_buf) } {
        let io_err = std::io::Error::last_os_error();
        Err(io_err)
    } else {
        Ok(stat_buf)
    }
}


fn main() -> std::io::Result<()>{
    for arg in env::args_os().map(UnixString::try_from).flatten() {
        let stat = stat(&arg)?;
        
        let size = stat.st_size;

        println!("{} occupies {} bytes.", arg.as_path().display(), size);
    }

    Ok(())
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].