The libc crate gives us access to the UNIX system calls. But calling these functions from Rust can be difficult. You will find yourself constantly converting between String / &str and char* and other C data types. Rust provides several wrappers that use idiomatic Rust data types and error handling. But they are sometimes hard to find. Here’s an index of some of the most commonly used libc calls and their higher level wrappers.

chdir

Use std::env::set_current_dir . Example:

env::set_current_dir( "/tmp" );

unlink

Use std::fs::remove_file . Example:

std ::fs::remove_file( "file.txt" );

rmdir

Use std::fs::remove_dir . Example:

if let Err(error) = std ::fs::remove_dir( "a_dir" ) { println!( "There was a problem: {}" , error); }

rename

Use std::fs::rename .

if let Err(e) = std ::fs::rename( "a_dir/file.txt" , "a_dir/new.txt" ) { println!( "Failed to rename file: {}" , e); }

getcwd

Use std::env::current_dir . In the example below we try to convert the current directory name to a UTF-8 encoded &str :

if let Ok(path_buf) = std ::env::current_dir() { if let Some(path_str) = path_buf.to_str() { println!( "Current dir: {}" , path_str); } else { println!( "Could not convert path name to UTF-8." ); } } else { println!( "Could not get current directory." ); }

stat

Use std::fs::metadata . UNIX specific data that is available from C’s struct stat can be accessed using the std::os::unix::fs::MetadataExt trait.

use std ::os::unix::fs::MetadataExt; fn main() { if let Ok(m) = std ::fs::metadata( "a_dir/file.txt" ) { println!( "File size: {}" , m.size()); println!( "Creation time: {}" , m.ctime()); println!( "Access time: {}" , m.atime()); } else { println!( "Failed to get stat." ); } }

chmod

The wrapper approach involves calling std::fs::set_permissions . But to construct a std::fs::Permissions using the UNIX mode flags you will need to bring the std::os::unix::prelude::PermissionsExt trait into scope.

use std ::os::unix::prelude::PermissionsExt; fn main() { if let Err(e) = std ::fs::set_permissions( "a_dir/file.txt" , std ::fs::Permissions::from_mode( 0 o666)) { println!( "Failed to chmod: {}" , e); } }

You can also call chmod directly from libc crate. But the function is in a strange module.

extern crate libc; use libc::funcs::posix88::stat_::chmod; use libc::types::os::arch::posix88::mode_t; fn easy_chmod(path: &str, mode: u64) -> bool { if let Ok(c_str) = std ::ffi::CString:: new (path) { unsafe { let result = chmod( c_str.as_ptr(), mode as mode_t); return result == 0 ; } } return false ; } fn main() { if !easy_chmod( "a_dir/file.txt" , 0 o666) { println!( "Failed to chmod." ); } }

mkdir

Use std::fs::create_dir . I find this utility method useful.

fn make_dir(path: &str) -> std ::io::Result<()> { let err = match std ::fs::create_dir(path) { Ok(_) => return Ok(()), Err(e) => e }; match err.kind() { ErrorKind::AlreadyExists => return Ok(()), _ => { println!( "Failed to create directory: {}" , path); return Err(err); } }; }

getenv

Use std::env:var.

if let Ok(val) = std ::env::var( "HOME" ) { println!( "Got variable: {}" , val); } else { println!( "Failed to get env variable" ); }

setenv

Use std:env:set_var .

std ::env::set_var( "GREET" , "Hola" );

link

Use std::fs::hard_link .

if let Err(e) = std ::fs::hard_link( "a_dir/file.txt" , "a_dir/another.txt" ) { println!( "Failed to create hard link: {}" , e); }

symlink

Use std::os::unix::fs::symlink .

if let Err(e) = std ::os::unix::fs::symlink( "a_dir/file.txt" , "a_dir/another.txt" ) { println!( "Failed to create soft link: {}" , e); }