From 674101a2834ab6a1975eedfedf31f3c64a3ab3b8 Mon Sep 17 00:00:00 2001 From: Erle Carrara Date: Sat, 1 Apr 2017 10:56:58 -0300 Subject: [PATCH] Initial commit :rocket: --- .gitignore | 3 +++ Cargo.toml | 13 +++++++++++++ LICENSE | 19 +++++++++++++++++++ README.md | 3 +++ rustfmt.toml | 1 + src/errors.rs | 6 ++++++ src/lib.rs | 12 ++++++++++++ src/utils.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ test_files/a.txt | 1 + 9 files changed, 107 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 rustfmt.toml create mode 100644 src/errors.rs create mode 100644 src/lib.rs create mode 100644 src/utils.rs create mode 100644 test_files/a.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4308d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target/ +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8743579 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "fsync" +version = "0.1.0" +authors = ["Erle Carrara "] +repository = "https://github.com/ecarrara/fsync-rs.git" +homepage = "https://github.com/ecarrara/fsync-rs" +license = "MIT" +readme = "README.md" +description = "Keeps files and directories synchronized." + +[dependencies] +libc = "0.2.21" +error-chain = "0.10.0" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..115fe0b --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2017 Erle Carrara + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bc1abe7 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# fsync + +Keeps files or directories in sync. diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..44148a2 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +reorder_imports = true diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..17d3681 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,6 @@ +error_chain! { + foreign_links { + Io(::std::io::Error); + SystemTimeError(::std::time::SystemTimeError); + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..749f2fb --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,12 @@ +//! Syncronize files and directories. +#![deny(missing_docs, + missing_debug_implementations, missing_copy_implementations, + trivial_casts, trivial_numeric_casts, + unused_import_braces, unused_qualifications)] + +#[macro_use] +extern crate error_chain; +extern crate libc; + +mod errors; +mod utils; diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..da41983 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,49 @@ +use errors::Result; +use libc::{futimens, timespec, c_long, time_t}; +use std::fs::File; +use std::io::Error as IOError; +use std::os::unix::io::AsRawFd; +use std::path::Path; +use std::time::{SystemTime, UNIX_EPOCH}; + + +/// Set file acessed and modified time. +pub fn set_file_times>(path: P, + atime: &SystemTime, + mtime: &SystemTime) + -> Result<()> { + let atime_since_epoch = atime.duration_since(UNIX_EPOCH)?; + let mtime_since_epoch = mtime.duration_since(UNIX_EPOCH)?; + + let times = [timespec { + tv_sec: atime_since_epoch.as_secs() as time_t, + tv_nsec: atime_since_epoch.subsec_nanos() as c_long, + }, + timespec { + tv_sec: mtime_since_epoch.as_secs() as time_t, + tv_nsec: mtime_since_epoch.subsec_nanos() as c_long, + }]; + + let file = File::open(path)?; + let ret = unsafe { futimens(file.as_raw_fd(), times.as_ptr()) }; + if ret == 0 { + Ok(()) + } else { + bail!(IOError::last_os_error()) + } +} + + +#[cfg(test)] +mod tests { + use std::time::{Duration, UNIX_EPOCH}; + use super::set_file_times; + + #[test] + fn test_set_file_times() { + // Oct, 27 -> a special date! :D + let atime = UNIX_EPOCH + Duration::from_secs(1509062400); + let mtime = UNIX_EPOCH + Duration::from_secs(1509105600); + set_file_times("./test_files/a.txt", &atime, &mtime).unwrap(); + } +} diff --git a/test_files/a.txt b/test_files/a.txt new file mode 100644 index 0000000..7898192 --- /dev/null +++ b/test_files/a.txt @@ -0,0 +1 @@ +a