diff --git a/Cargo.lock b/Cargo.lock index 646e4cd..d25923a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,7 +104,7 @@ version = "0.1.0" dependencies = [ "lib", "memmap2", - "nix", + "nix 0.20.0", "notify", ] @@ -113,6 +113,8 @@ name = "chapter11" version = "0.1.0" dependencies = [ "lib", + "nix 0.21.0", + "sysinfo", ] [[package]] @@ -237,6 +239,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" + [[package]] name = "crc32fast" version = "1.2.1" @@ -246,6 +254,62 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "filetime" version = "0.2.14" @@ -391,6 +455,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "lazycell" version = "1.3.0" @@ -408,9 +478,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" [[package]] name = "lock_api" @@ -445,6 +515,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + [[package]] name = "miniz_oxide" version = "0.4.4" @@ -543,6 +622,19 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + [[package]] name = "notify" version = "4.0.17" @@ -706,6 +798,31 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.8" @@ -802,6 +919,22 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "sysinfo" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3899fa43ce1ab71db79fda2a3fdb119a07e25a006677d46033c9d9051c82f019" +dependencies = [ + "cfg-if 1.0.0", + "core-foundation-sys", + "doc-comment", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi 0.3.9", +] + [[package]] name = "thiserror" version = "1.0.24" diff --git a/chapter11/Cargo.toml b/chapter11/Cargo.toml index 086d198..bc05717 100644 --- a/chapter11/Cargo.toml +++ b/chapter11/Cargo.toml @@ -7,4 +7,42 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lib = { path = "../lib" } \ No newline at end of file +lib = { path = "../lib" } +nix = "0.21.0" +sysinfo = "0.18.1" + +[[bin]] +name = "11_1_2" +path = "src/11_1_2/main.rs" + +[[bin]] +name = "11_1_3" +path = "src/11_1_3/main.rs" + +[[bin]] +name = "11_1_4" +path = "src/11_1_4/main.rs" + +[[bin]] +name = "11_1_5" +path = "src/11_1_5/main.rs" + +[[bin]] +name = "11_1_6" +path = "src/11_1_6/main.rs" + +[[bin]] +name = "11_2_1" +path = "src/11_2_1/main.rs" + +[[bin]] +name = "11_2_3" +path = "src/11_2_3/main.rs" + +[[bin]] +name = "11_3" +path = "src/11_3/main.rs" + +[[bin]] +name = "11_8" +path = "src/11_8/main.rs" \ No newline at end of file diff --git a/chapter11/src/11_1_2/main.rs b/chapter11/src/11_1_2/main.rs new file mode 100644 index 0000000..cab3a97 --- /dev/null +++ b/chapter11/src/11_1_2/main.rs @@ -0,0 +1,9 @@ +use nix::unistd::{getpid, getppid}; + +fn main() { + // nix を使用してもよい。 + println!("プロセス ID: {}", getpid()); + // あるいは、Rust の std::process::id を使用しても取得できる。 + // println!("プロセス ID: {}", std::process::id()); + println!("親プロセスID: {}", getppid()); +} diff --git a/chapter11/src/11_1_3/main.rs b/chapter11/src/11_1_3/main.rs new file mode 100644 index 0000000..027fc56 --- /dev/null +++ b/chapter11/src/11_1_3/main.rs @@ -0,0 +1,6 @@ +use nix::unistd::{getpgrp, getpid, getsid}; + +fn main() { + let sid = getsid(Some(getpid())).unwrap(); + println!("グループID: {}, セッションID: {}", getpgrp(), sid); +} diff --git a/chapter11/src/11_1_4/main.rs b/chapter11/src/11_1_4/main.rs new file mode 100644 index 0000000..d48ff7c --- /dev/null +++ b/chapter11/src/11_1_4/main.rs @@ -0,0 +1,18 @@ +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +use nix::unistd::getgroups; +use nix::unistd::{getgid, getuid}; + +fn main() { + println!("ユーザーID: {}", getuid()); + println!("グループID: {}", getgid()); + + // nix クレートにおける getgroups は Apple のプラットフォームでは実行できない。 + #[cfg(not(any(target_os = "ios", target_os = "macos")))] + get_groups(); +} + +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +fn get_groups() { + let groups = getgroups().unwrap(); + println!("サブグループID: {:?}", groups); +} diff --git a/chapter11/src/11_1_5/main.rs b/chapter11/src/11_1_5/main.rs new file mode 100644 index 0000000..e8982c2 --- /dev/null +++ b/chapter11/src/11_1_5/main.rs @@ -0,0 +1,8 @@ +use nix::unistd::{getegid, geteuid, getgid, getuid}; + +fn main() { + println!("ユーザー ID: {}", getuid()); + println!("グループID: {}", getgid()); + println!("実効ユーザーID: {}", geteuid()); + println!("実効グループID: {}", getegid()); +} diff --git a/chapter11/src/11_1_6/main.rs b/chapter11/src/11_1_6/main.rs new file mode 100644 index 0000000..7d3e855 --- /dev/null +++ b/chapter11/src/11_1_6/main.rs @@ -0,0 +1,9 @@ +use nix::unistd::getcwd; +use std::env::current_dir; + +fn main() { + // nix クレートを使用する場合は getcwd が使える。 + println!("{}", getcwd().unwrap().to_str().unwrap()); + // あるいは、Rust の std::env にある current_dir を使ってもよい。 + println!("{}", current_dir().unwrap().to_str().unwrap()); +} diff --git a/chapter11/src/11_2_1/main.rs b/chapter11/src/11_2_1/main.rs new file mode 100644 index 0000000..a34b3b2 --- /dev/null +++ b/chapter11/src/11_2_1/main.rs @@ -0,0 +1,7 @@ +fn main() { + let envs = std::env::vars(); + for (key, value) in envs { + println!("{}={}", key, value); + } + // os.ExpandEnv 関数は Rust には存在しない。 +} diff --git a/chapter11/src/11_2_3/main.rs b/chapter11/src/11_2_3/main.rs new file mode 100644 index 0000000..081ca86 --- /dev/null +++ b/chapter11/src/11_2_3/main.rs @@ -0,0 +1,3 @@ +fn main() { + std::process::exit(1); +} diff --git a/chapter11/src/11_3/main.rs b/chapter11/src/11_3/main.rs new file mode 100644 index 0000000..2d9e8ca --- /dev/null +++ b/chapter11/src/11_3/main.rs @@ -0,0 +1,18 @@ +use nix::libc::getppid; +// gopsutil の Rust バージョンとして rust-psutil というクレートを使用できそうだったが、 +// 実装がかなり不完全そうだった。 +// そこで、sysinfo というクレートを使っている。 +use sysinfo::{ProcessExt, System, SystemExt}; + +fn main() { + // get_process に libc の pid_t を要求するので、それを取得できるように nix::libc 経由で getppid を使っている。 + let pid = unsafe { getppid() }; + if let Some(process) = System::new_all().get_process(pid) { + println!( + "parent pid: {}, name: {}, cmd: {:?}", + process.pid(), + process.name(), + process.cmd() + ) + } +} diff --git a/chapter11/src/11_8/main.rs b/chapter11/src/11_8/main.rs new file mode 100644 index 0000000..20f9bd1 --- /dev/null +++ b/chapter11/src/11_8/main.rs @@ -0,0 +1,35 @@ +use nix::sys::wait::*; +use nix::unistd::{execve, fork, ForkResult}; +use std::env; +use std::ffi::CString; + +// Go のプログラミングでは触れることのない世界として言及されているが、Rust では触れることができる。 +// 本書の中で fork(2) と execve(3) が言及されていたので、それを使用したサンプルプログラムを掲載しておく。 +fn main() { + // fork + match unsafe { fork() }.expect("fork failed") { + ForkResult::Parent { child } => { + // waitpid + match waitpid(child, None).expect("wait_pid failed") { + WaitStatus::Exited(pid, status) => { + println!("exit!: pid={:?}, status={:?}", pid, status) + } + WaitStatus::Signaled(pid, status, _) => { + println!("signal!: pid={:?}, status={:?}", pid, status) + } + _ => println!("abnormal exit!"), + } + } + ForkResult::Child => { + // 引数の値を取得する。 + let args: Vec = env::args().collect(); + let dir = CString::new(args[1].to_string()).unwrap(); + let arg = CString::new(args[2].to_string()).unwrap(); + // env は仮で入れておく。 + let env = CString::new("ENV=prd".to_string()).unwrap(); + + // execv + execve(&dir, &[dir.clone(), arg], &[env]).expect("execution failed."); + } + } +} diff --git a/chapter11/src/main.rs b/chapter11/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/chapter11/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/chapter4/Cargo.toml b/chapter4/Cargo.toml index 7899466..ff046f8 100644 --- a/chapter4/Cargo.toml +++ b/chapter4/Cargo.toml @@ -26,6 +26,10 @@ path = "src/4_2_5/main.rs" name = "4_3_1" path = "src/4_3_1/main.rs" +[[bin]] +name = "4_5" +path = "src/4_5/main.rs" + [dependencies] lib = { path = "../lib" } tokio = { version = "1.5.0", features = ["full"] } diff --git a/chapter4/src/4_5/main.rs b/chapter4/src/4_5/main.rs new file mode 100644 index 0000000..f249f91 --- /dev/null +++ b/chapter4/src/4_5/main.rs @@ -0,0 +1,20 @@ +use tokio::time::{self, Duration}; + +// tokio::time::sleepを使って、決まった時間を図るタイマーを作る +#[tokio::main] +async fn main() { + let wait_sec = 5; + let (_, mut wait) = tokio::sync::oneshot::channel::<()>(); + let sleep = time::sleep(Duration::from_secs(wait_sec)); + tokio::pin!(sleep); + + loop { + tokio::select! { + _ = &mut sleep => { + println!("{} secondes elapsed", wait_sec); + break; + } + _ = &mut wait => {} + } + } +} diff --git a/chapter6/Cargo.toml b/chapter6/Cargo.toml index 3eb34de..65601c8 100644 --- a/chapter6/Cargo.toml +++ b/chapter6/Cargo.toml @@ -7,4 +7,24 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -lib = { path = "../lib" } \ No newline at end of file +lib = { path = "../lib" } + +[[bin]] +name = "6_5" +path = "src/6_5/main.rs" + +[[bin]] +name = "6_6" +path = "src/6_6/main.rs" + +[[bin]] +name = "6_7" +path = "src/6_7/main.rs" + +[[bin]] +name = "6_8" +path = "src/6_8/main.rs" + +[[bin]] +name = "6_9" +path = "src/6_9/main.rs" \ No newline at end of file diff --git a/chapter6/src/6_5/main.rs b/chapter6/src/6_5/main.rs new file mode 100644 index 0000000..0672e51 --- /dev/null +++ b/chapter6/src/6_5/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, World!"); +} diff --git a/chapter6/src/6_6/main.rs b/chapter6/src/6_6/main.rs new file mode 100644 index 0000000..0672e51 --- /dev/null +++ b/chapter6/src/6_6/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, World!"); +} diff --git a/chapter6/src/6_7/main.rs b/chapter6/src/6_7/main.rs new file mode 100644 index 0000000..0672e51 --- /dev/null +++ b/chapter6/src/6_7/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, World!"); +} diff --git a/chapter6/src/6_8/main.rs b/chapter6/src/6_8/main.rs new file mode 100644 index 0000000..0672e51 --- /dev/null +++ b/chapter6/src/6_8/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, World!"); +} diff --git a/chapter6/src/6_9/main.rs b/chapter6/src/6_9/main.rs new file mode 100644 index 0000000..0672e51 --- /dev/null +++ b/chapter6/src/6_9/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, World!"); +} diff --git a/chapter6/src/main.rs b/chapter6/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/chapter6/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}