aboutsummaryrefslogtreecommitdiff
path: root/nix-rust/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-09-10 21:55:32 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-11-26 22:07:28 +0100
commit8110b4ebb29174ecd4b22510da0285abf604b8a7 (patch)
tree7ff723411ee02a62de40e9e7e059809f45b3c1fa /nix-rust/src
parent343ebcc048c69e103db3f87a9339388bd5dd93cb (diff)
Rust cleanup
Diffstat (limited to 'nix-rust/src')
-rw-r--r--nix-rust/src/error.rs5
-rw-r--r--nix-rust/src/foreign.rs14
-rw-r--r--nix-rust/src/lib.rs68
-rw-r--r--nix-rust/src/tarfile.rs47
4 files changed, 72 insertions, 62 deletions
diff --git a/nix-rust/src/error.rs b/nix-rust/src/error.rs
new file mode 100644
index 000000000..28d0abdef
--- /dev/null
+++ b/nix-rust/src/error.rs
@@ -0,0 +1,5 @@
+#[derive(Debug)]
+pub enum Error {
+ Misc(String),
+ Foreign(libc::c_void), // == std::exception_ptr
+}
diff --git a/nix-rust/src/foreign.rs b/nix-rust/src/foreign.rs
new file mode 100644
index 000000000..7bce7753c
--- /dev/null
+++ b/nix-rust/src/foreign.rs
@@ -0,0 +1,14 @@
+/// A wrapper around Nix's Source class that provides the Read trait.
+#[repr(C)]
+pub struct Source {
+ fun: extern "C" fn(this: *mut libc::c_void, data: &mut [u8]) -> usize,
+ this: *mut libc::c_void,
+}
+
+impl std::io::Read for Source {
+ fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
+ let n = (self.fun)(self.this, buf);
+ assert!(n <= buf.len());
+ Ok(n)
+ }
+}
diff --git a/nix-rust/src/lib.rs b/nix-rust/src/lib.rs
index ac6dee543..192ca29e4 100644
--- a/nix-rust/src/lib.rs
+++ b/nix-rust/src/lib.rs
@@ -1,66 +1,10 @@
-extern crate libc;
-extern crate tar;
+mod error;
+mod foreign;
+mod tarfile;
-use std::fs;
-use std::io;
-use std::os::unix::fs::OpenOptionsExt;
-use std::path::Path;
-use tar::Archive;
-
-/// A wrapper around Nix's Source class that provides the Read trait.
-#[repr(C)]
-pub struct Source {
- fun: extern "C" fn(this: *mut libc::c_void, data: &mut [u8]) -> usize,
- this: *mut libc::c_void,
-}
-
-impl std::io::Read for Source {
- fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
- let n = (self.fun)(self.this, buf);
- assert!(n <= buf.len());
- Ok(n)
- }
-}
+pub use error::Error;
#[no_mangle]
-pub extern "C" fn unpack_tarfile(source: Source, dest_dir: &str) -> bool {
- // FIXME: handle errors.
-
- let dest_dir = Path::new(dest_dir);
-
- let mut tar = Archive::new(source);
-
- for file in tar.entries().unwrap() {
- let mut file = file.unwrap();
-
- let dest_file = dest_dir.join(file.path().unwrap());
-
- fs::create_dir_all(dest_file.parent().unwrap()).unwrap();
-
- match file.header().entry_type() {
- tar::EntryType::Directory => {
- fs::create_dir(dest_file).unwrap();
- }
- tar::EntryType::Regular => {
- let mode = if file.header().mode().unwrap() & libc::S_IXUSR == 0 {
- 0o666
- } else {
- 0o777
- };
- let mut f = fs::OpenOptions::new()
- .create(true)
- .write(true)
- .mode(mode)
- .open(dest_file)
- .unwrap();
- io::copy(&mut file, &mut f).unwrap();
- }
- tar::EntryType::Symlink => {
- std::os::unix::fs::symlink(file.header().link_name().unwrap().unwrap(), dest_file).unwrap();
- }
- t => panic!("Unsupported tar entry type '{:?}'.", t),
- }
- }
-
- true
+pub extern "C" fn unpack_tarfile(source: foreign::Source, dest_dir: &str) {
+ tarfile::unpack_tarfile(source, dest_dir).unwrap();
}
diff --git a/nix-rust/src/tarfile.rs b/nix-rust/src/tarfile.rs
new file mode 100644
index 000000000..696118e4d
--- /dev/null
+++ b/nix-rust/src/tarfile.rs
@@ -0,0 +1,47 @@
+use crate::{foreign::Source, Error};
+use std::fs;
+use std::io;
+use std::os::unix::fs::OpenOptionsExt;
+use std::path::Path;
+use tar::Archive;
+
+pub fn unpack_tarfile(source: Source, dest_dir: &str) -> Result<(), Error> {
+ let dest_dir = Path::new(dest_dir);
+
+ let mut tar = Archive::new(source);
+
+ for file in tar.entries().unwrap() {
+ let mut file = file.unwrap();
+
+ let dest_file = dest_dir.join(file.path().unwrap());
+
+ fs::create_dir_all(dest_file.parent().unwrap()).unwrap();
+
+ match file.header().entry_type() {
+ tar::EntryType::Directory => {
+ fs::create_dir(dest_file).unwrap();
+ }
+ tar::EntryType::Regular => {
+ let mode = if file.header().mode().unwrap() & libc::S_IXUSR == 0 {
+ 0o666
+ } else {
+ 0o777
+ };
+ let mut f = fs::OpenOptions::new()
+ .create(true)
+ .write(true)
+ .mode(mode)
+ .open(dest_file)
+ .unwrap();
+ io::copy(&mut file, &mut f).unwrap();
+ }
+ tar::EntryType::Symlink => {
+ std::os::unix::fs::symlink(file.header().link_name().unwrap().unwrap(), dest_file)
+ .unwrap();
+ }
+ t => return Err(Error::Misc(format!("unsupported tar entry type '{:?}'", t))),
+ }
+ }
+
+ Ok(())
+}