diff --git a/01_phase_rust_src/chpst/Cargo.toml b/01_phase_rust_src/chpst-rustit/Cargo.toml similarity index 87% rename from 01_phase_rust_src/chpst/Cargo.toml rename to 01_phase_rust_src/chpst-rustit/Cargo.toml index 5e25448..b02b937 100644 --- a/01_phase_rust_src/chpst/Cargo.toml +++ b/01_phase_rust_src/chpst-rustit/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "chpst" +name = "chpst-rustit" version = "0.1.0" edition = "2021" diff --git a/01_phase_rust_src/chpst/src/main.rs b/01_phase_rust_src/chpst-rustit/src/main.rs similarity index 100% rename from 01_phase_rust_src/chpst/src/main.rs rename to 01_phase_rust_src/chpst-rustit/src/main.rs diff --git a/01_phase_rust_src/sv/Cargo.toml b/01_phase_rust_src/sv-rustit/Cargo.toml similarity index 79% rename from 01_phase_rust_src/sv/Cargo.toml rename to 01_phase_rust_src/sv-rustit/Cargo.toml index 43f8a44..77d1906 100644 --- a/01_phase_rust_src/sv/Cargo.toml +++ b/01_phase_rust_src/sv-rustit/Cargo.toml @@ -1,9 +1,10 @@ [package] -name = "sv" +name = "sv-rustit" version = "0.2.0" -edition = "2024" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] tokio = { version = "1.37.0", features = ["full"] } +libc = "0.2" diff --git a/01_phase_rust_src/sv/src/executor.rs b/01_phase_rust_src/sv-rustit/src/executor.rs similarity index 100% rename from 01_phase_rust_src/sv/src/executor.rs rename to 01_phase_rust_src/sv-rustit/src/executor.rs diff --git a/01_phase_rust_src/sv-rustit/src/executor/sent_signal.rs b/01_phase_rust_src/sv-rustit/src/executor/sent_signal.rs new file mode 100644 index 0000000..9955f42 --- /dev/null +++ b/01_phase_rust_src/sv-rustit/src/executor/sent_signal.rs @@ -0,0 +1,85 @@ + +mod misc; + +use crate::status_obj; + +use std::thread::sleep; +use std::time::Duration; + +pub fn sent_signal( svwait_var: i32, verbose: i8, command: &str, mut sv: status_obj::StatusObj) -> i32 { + // Return 0 in case everything worked fine, return 1 if timeout or error. + + let mut time_wait = 0; + + // execute command. + if command == "s" { + // case command is status + return misc::print_status(sv); + } + + if command == "u" { + // case where command is up + if sv.sent_signal(b"u") { + if verbose == 1 { + loop { + let status = sv.update_status(); + if status == 1 { + return 1; + } + if sv.is_up() == true { + misc::print_status(sv); + return 0 + } + if time_wait >= svwait_var { + println!("fail: {}: timeout", sv.get_name()); + return 1 + } + + time_wait += 1; + sleep(Duration::from_secs(1)); + } + } else { + return 0; + } + } else { + return 1; + } + } + + if command == "d" { + // case where command is up + if sv.sent_signal(b"d") { + if verbose == 1 { + loop { + let status = sv.update_status(); + if status == 1 { + return 1; + } + if sv.is_up() == false { + misc::print_status(sv); + return 0 + } + if time_wait >= svwait_var { + println!("fail: {}: timeout", sv.get_name()); + return 1 + } + + time_wait += 1; + sleep(Duration::from_secs(1)); + } + } else { + return 0; + } + } else { + return 1; + } + } + + + // TODO + // sent the proper signal to supervise/control + // + // if verbose = 1, wait for the service to reach the proper state or timeout. + println!("Error, command not implemented."); + return 1; +} diff --git a/01_phase_rust_src/sv-rustit/src/executor/sent_signal/misc.rs b/01_phase_rust_src/sv-rustit/src/executor/sent_signal/misc.rs new file mode 100644 index 0000000..7a8e2a5 --- /dev/null +++ b/01_phase_rust_src/sv-rustit/src/executor/sent_signal/misc.rs @@ -0,0 +1,21 @@ + +use crate::status_obj; + +pub fn print_status(mut sv: status_obj::StatusObj) -> i32 { + // The status code is the one who will be + let mut status_sv = sv.get_status_string(); + let is_log = sv.get_log(); + if is_log { + let log_option = sv.get_obj_log(); + match log_option { + Some(mut log) => { + status_sv = status_sv + "; " + &log.get_status_string(); + }, + None => { + return 1 + }, + }; + } + println!("{}", status_sv); + return 0; +} diff --git a/01_phase_rust_src/sv/src/main.rs b/01_phase_rust_src/sv-rustit/src/main.rs similarity index 100% rename from 01_phase_rust_src/sv/src/main.rs rename to 01_phase_rust_src/sv-rustit/src/main.rs diff --git a/01_phase_rust_src/sv/src/parser.rs b/01_phase_rust_src/sv-rustit/src/parser.rs similarity index 100% rename from 01_phase_rust_src/sv/src/parser.rs rename to 01_phase_rust_src/sv-rustit/src/parser.rs diff --git a/01_phase_rust_src/sv/src/parser/misc.rs b/01_phase_rust_src/sv-rustit/src/parser/misc.rs similarity index 100% rename from 01_phase_rust_src/sv/src/parser/misc.rs rename to 01_phase_rust_src/sv-rustit/src/parser/misc.rs diff --git a/01_phase_rust_src/sv/src/status_obj.rs b/01_phase_rust_src/sv-rustit/src/status_obj.rs similarity index 71% rename from 01_phase_rust_src/sv/src/status_obj.rs rename to 01_phase_rust_src/sv-rustit/src/status_obj.rs index 8ca8c69..10a26b3 100644 --- a/01_phase_rust_src/sv/src/status_obj.rs +++ b/01_phase_rust_src/sv-rustit/src/status_obj.rs @@ -8,6 +8,7 @@ use std::io::prelude::*; use std::time::SystemTime; +#[derive(Debug)] pub struct StatusObj { svname: String, // Service name svpath: String, // Service path @@ -112,6 +113,57 @@ impl StatusObj { }) } + pub fn update_status(&mut self) -> u32 { + // Update only status related fields. + // return 1 in case there is a problem. + // return 0 if everything is altight. + let status_option = fs::OpenOptions::new().read(true).open("supervise/status"); + let mut status = match status_option { + Ok(file) => file, + Err(..) => { + println!("warning: {}: unable to open supervise/status: file does not exist", self.svname); + return 1; + }, + }; + let mut contents: Vec = Vec::new(); + let option_size = status.read_to_end(&mut contents); + + let size = match option_size { + Ok(size) => size, + Err(..) => { + println!("warning: {}: couldn't read supervise/status", self.svname); + return 1 + }, + }; + + if size != 20 { + println!("warning: {}: bad supervise/status format", self.svname); + return 1 + } + + let time_buf: Vec = contents[0..8].to_vec(); + //let nano_buf: Vec = contents[8..12].to_vec(); + let pid_buf: Vec = contents[12..16].to_vec(); + + let seconds = misc::return_u8_in_u64(time_buf); + //let nano = misc::return_u8_in_u32(nano_buf); + let pid_found = misc::return_reverse_u8_in_u32(pid_buf); + + let pause_run_raw = misc::make_pause_run(contents[16]); // done + let up_down_raw = misc::make_up_down(contents[17]); // done + let term_sig_raw = misc::make_term_sig(contents[18]); // done + let run_finish_raw = misc::make_run_finish(contents[19]); // done + + self.time = seconds; + self.pid = pid_found; + self.pause_run = pause_run_raw; + self.up_down = up_down_raw; + self.term_sig = term_sig_raw; + self.run_finish = run_finish_raw; + + return 0; + } + pub fn get_status_string(&mut self) -> String { // return the status for this service in particular. @@ -173,6 +225,22 @@ impl StatusObj { return return_string; } + pub fn sent_signal(&mut self, signal: &[u8]) -> bool { + return misc::sent_signal(signal); + } + + pub fn is_up(&mut self) -> bool { + return self.run_finish; + } + + pub fn get_name(&mut self) -> String { + return self.svname.clone(); + } + + pub fn get_path(&mut self) -> String { + return self.svpath.clone(); + } + pub fn get_log(&mut self) -> bool { return self.log; } @@ -180,5 +248,6 @@ impl StatusObj { pub fn get_obj_log(&mut self) -> Option { return StatusObj::new(self.svpath.clone() + "/log", "log".to_string()); } + } diff --git a/01_phase_rust_src/sv/src/status_obj/misc.rs b/01_phase_rust_src/sv-rustit/src/status_obj/misc.rs similarity index 55% rename from 01_phase_rust_src/sv/src/status_obj/misc.rs rename to 01_phase_rust_src/sv-rustit/src/status_obj/misc.rs index 85dbd6c..731d92f 100644 --- a/01_phase_rust_src/sv/src/status_obj/misc.rs +++ b/01_phase_rust_src/sv-rustit/src/status_obj/misc.rs @@ -1,8 +1,7 @@ -use std::io::ErrorKind; - use tokio::net::unix::pipe; use tokio::runtime::Runtime; +use std::io::ErrorKind; pub fn make_pause_run(pr_int: u8) -> bool { if pr_int == 0 { @@ -85,18 +84,50 @@ pub fn check_fifo(sv: String, path: &str) -> bool { let sender = pipe::OpenOptions::new().open_sender(path); match sender { - Ok(..) => {}, - Err(e) => match e.kind() { - ErrorKind::NotFound => { - println!("warning: {sv}: unable to open {path}: file does not exist"); - return false; - }, - _ => { - println!("fail: {sv}: runsv not running"); - return false; - } + Ok(..) => return true, + Err(e) if e.raw_os_error() == Some(libc::ENXIO) => { + println!("fail: {sv}: runsv not running"); + return false; + }, + Err(..) => { + println!("warning: {sv}: unable to open {path}: file does not exist"); + return false; + }, + }; +} + +pub fn sent_signal(signal: &[u8]) -> bool { + // sent the char to supervise/control. + // return true in case everything worked fine, false if there was any errors. + let rt = Runtime::new().unwrap(); + let _guard = rt.enter(); + + let sender = pipe::OpenOptions::new().open_sender("supervise/control"); + match sender { + Ok(tx) => { + loop { + match tx.try_write(signal) { + Ok(..) => { + return true; + }, + Err(e) if e.kind() == ErrorKind::WouldBlock => { + continue; + }, + Err(e) => { + dbg!(e); + println!("Impossible Error while writing on pipe."); + return false; + }, + }; + }; + }, + Err(e) if e.raw_os_error() == Some(libc::ENXIO) => { + println!("fail: sv: runsv not running"); + return false; + }, + Err(..) => { + println!("warning: sv: unable to open path: file does not exist"); + return false; }, }; - - return true } diff --git a/01_phase_rust_src/sv/src/executor/sent_signal.rs b/01_phase_rust_src/sv/src/executor/sent_signal.rs deleted file mode 100644 index bee4cb3..0000000 --- a/01_phase_rust_src/sv/src/executor/sent_signal.rs +++ /dev/null @@ -1,48 +0,0 @@ - - -use crate::status_obj; - -pub fn sent_signal( svwait_var: i32, verbose: i8, command: &str, mut sv: status_obj::StatusObj) -> i32 { - // Return 0 in case everything worked fine, return 1 if timeout or error. - - dbg!(svwait_var); - dbg!(verbose); - - // execute command. - if command == "s" { - // case command is status - let mut status_sv = sv.get_status_string(); - let is_log = sv.get_log(); - if is_log { - let log_option = sv.get_obj_log(); - match log_option { - Some(mut log) => { - status_sv = status_sv + "; " + &log.get_status_string(); - }, - None => {// TODO: Do nothing for now, eventually, increase by one exit code. - }, - }; - } - println!("{}", status_sv); - return 0; - } - - //let service = fs::OpenOptions::new().append(true).open("supervise/control"); - - //if ! service.is_ok() { - // println!("warning: {}: unable to append to supervise/control: file does not exist", sv.clone()); - // return make_exit_code(exit_code); - //} - //let mut control = match service { - // Ok(file) => file, - // Err(..) => panic!("Shouln't goes there, the programmer is trash."), - //}; - - - // TODO - // sent the proper signal to supervise/control - // - // if verbose = 1, wait for the service to reach the proper state or timeout. - println!("Error, command not implemented."); - return 1; -} diff --git a/01_phase_rust_src/svlogd/Cargo.toml b/01_phase_rust_src/svlogd-rustit/Cargo.toml similarity index 87% rename from 01_phase_rust_src/svlogd/Cargo.toml rename to 01_phase_rust_src/svlogd-rustit/Cargo.toml index 97e19c5..3d778a6 100644 --- a/01_phase_rust_src/svlogd/Cargo.toml +++ b/01_phase_rust_src/svlogd-rustit/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "svlogd" +name = "svlogd-rustit" version = "0.1.0" edition = "2021" diff --git a/01_phase_rust_src/svlogd/src/main.rs b/01_phase_rust_src/svlogd-rustit/src/main.rs similarity index 100% rename from 01_phase_rust_src/svlogd/src/main.rs rename to 01_phase_rust_src/svlogd-rustit/src/main.rs