Skip to content

Commit ecae58c

Browse files
authored
Merge pull request #102 from yuk1ty/feature/add_11
add 11_1 & 11_2 & 11_3 & 11_8
2 parents 8aa7b74 + 8028591 commit ecae58c

File tree

10 files changed

+224
-5
lines changed

10 files changed

+224
-5
lines changed

Cargo.lock

Lines changed: 110 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chapter11/Cargo.toml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ edition = "2018"
99
[dependencies]
1010
lib = { path = "../lib" }
1111
nix = "0.21.0"
12+
sysinfo = "0.18.1"
1213

1314
[[bin]]
1415
name = "11_1_2"
@@ -28,4 +29,20 @@ path = "src/11_1_5/main.rs"
2829

2930
[[bin]]
3031
name = "11_1_6"
31-
path = "src/11_1_6/main.rs"
32+
path = "src/11_1_6/main.rs"
33+
34+
[[bin]]
35+
name = "11_2_1"
36+
path = "src/11_2_1/main.rs"
37+
38+
[[bin]]
39+
name = "11_2_3"
40+
path = "src/11_2_3/main.rs"
41+
42+
[[bin]]
43+
name = "11_3"
44+
path = "src/11_3/main.rs"
45+
46+
[[bin]]
47+
name = "11_8"
48+
path = "src/11_8/main.rs"

chapter11/src/11_1_3/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use nix::unistd::{getpgrp, getpid, getsid};
2+
13
fn main() {
2-
println!("11_1_3");
4+
let sid = getsid(Some(getpid())).unwrap();
5+
println!("グループID: {}, セッションID: {}", getpgrp(), sid);
36
}

chapter11/src/11_1_4/main.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
2+
use nix::unistd::getgroups;
3+
use nix::unistd::{getgid, getuid};
4+
15
fn main() {
2-
println!("11_1_4");
6+
println!("ユーザーID: {}", getuid());
7+
println!("グループID: {}", getgid());
8+
9+
// nix クレートにおける getgroups は Apple のプラットフォームでは実行できない。
10+
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
11+
get_groups();
12+
}
13+
14+
#[cfg(not(any(target_os = "ios", target_os = "macos")))]
15+
fn get_groups() {
16+
let groups = getgroups().unwrap();
17+
println!("サブグループID: {:?}", groups);
318
}

chapter11/src/11_1_5/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
use nix::unistd::{getegid, geteuid, getgid, getuid};
2+
13
fn main() {
2-
println!("11_1_5");
4+
println!("ユーザー ID: {}", getuid());
5+
println!("グループID: {}", getgid());
6+
println!("実効ユーザーID: {}", geteuid());
7+
println!("実効グループID: {}", getegid());
38
}

chapter11/src/11_1_6/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use nix::unistd::getcwd;
2+
use std::env::current_dir;
3+
14
fn main() {
2-
println!("11_1_6");
5+
// nix クレートを使用する場合は getcwd が使える。
6+
println!("{}", getcwd().unwrap().to_str().unwrap());
7+
// あるいは、Rust の std::env にある current_dir を使ってもよい。
8+
println!("{}", current_dir().unwrap().to_str().unwrap());
39
}

chapter11/src/11_2_1/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
let envs = std::env::vars();
3+
for (key, value) in envs {
4+
println!("{}={}", key, value);
5+
}
6+
// os.ExpandEnv 関数は Rust には存在しない。
7+
}

chapter11/src/11_2_3/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
std::process::exit(1);
3+
}

chapter11/src/11_3/main.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use nix::libc::getppid;
2+
// gopsutil の Rust バージョンとして rust-psutil というクレートを使用できそうだったが、
3+
// 実装がかなり不完全そうだった。
4+
// そこで、sysinfo というクレートを使っている。
5+
use sysinfo::{ProcessExt, System, SystemExt};
6+
7+
fn main() {
8+
// get_process に libc の pid_t を要求するので、それを取得できるように nix::libc 経由で getppid を使っている。
9+
let pid = unsafe { getppid() };
10+
if let Some(process) = System::new_all().get_process(pid) {
11+
println!(
12+
"parent pid: {}, name: {}, cmd: {:?}",
13+
process.pid(),
14+
process.name(),
15+
process.cmd()
16+
)
17+
}
18+
}

chapter11/src/11_8/main.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use nix::sys::wait::*;
2+
use nix::unistd::{execve, fork, ForkResult};
3+
use std::env;
4+
use std::ffi::CString;
5+
6+
// Go のプログラミングでは触れることのない世界として言及されているが、Rust では触れることができる。
7+
// 本書の中で fork(2) と execve(3) が言及されていたので、それを使用したサンプルプログラムを掲載しておく。
8+
fn main() {
9+
// fork
10+
match unsafe { fork() }.expect("fork failed") {
11+
ForkResult::Parent { child } => {
12+
// waitpid
13+
match waitpid(child, None).expect("wait_pid failed") {
14+
WaitStatus::Exited(pid, status) => {
15+
println!("exit!: pid={:?}, status={:?}", pid, status)
16+
}
17+
WaitStatus::Signaled(pid, status, _) => {
18+
println!("signal!: pid={:?}, status={:?}", pid, status)
19+
}
20+
_ => println!("abnormal exit!"),
21+
}
22+
}
23+
ForkResult::Child => {
24+
// 引数の値を取得する。
25+
let args: Vec<String> = env::args().collect();
26+
let dir = CString::new(args[1].to_string()).unwrap();
27+
let arg = CString::new(args[2].to_string()).unwrap();
28+
// env は仮で入れておく。
29+
let env = CString::new("ENV=prd".to_string()).unwrap();
30+
31+
// execv
32+
execve(&dir, &[dir.clone(), arg], &[env]).expect("execution failed.");
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)