Skip to content

Commit f0e35d4

Browse files
Get act running of GH Action locally running (#93)
* Change workflow name * Switch how rust is installed * Simplify printing of errors in doc test comment examples * Add description of using "act" tool to README * Fix warnings from doc comments and convert a couple to code references * Try /dev/console if /dev/kmsg fails to allow running in containers that don't allow access to /dev/kmsg * Get name test to pass * Qualify doc comment code reference that doesn't exist in linux * Fix use of std::process across mac and linux
1 parent d9506f6 commit f0e35d4

File tree

5 files changed

+50
-71
lines changed

5 files changed

+50
-71
lines changed

.github/workflows/rust.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Rust
1+
name: Build and Test
22

33
on:
44
push:
@@ -35,11 +35,13 @@ jobs:
3535

3636
steps:
3737
- uses: actions/checkout@v2
38+
39+
- name: Install latest nightly
40+
uses: actions-rs/toolchain@v1
3841
with:
39-
fetch-depth: 2
40-
- uses: hecrj/[email protected]
41-
with:
42-
rust-version: ${{ matrix.rust }}
42+
profile: minimal
43+
toolchain: nightly
44+
override: true
4345
components: clippy
4446

4547
- name: Clippy

README.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,26 @@ To build for versions prior to Mac OS 10.7 disable the default features by passi
9999
To build for Mac OS X 10.7 (or 10.8) you can enable that feature alone using
100100
--no-default-features --features "macosx_10_7"
101101

102-
# Build and Test
102+
# Build and Test Locally
103103
`cargo test` should build and test as usual for rust projects.
104104

105-
However, as some functions need to be run as `root` to work, I run travis-CI tests as `root`. So, when developing in local
106-
it's best if you use `sudo cargo test`. NOTE: This can get you into permissions problems when switching back and for
107-
between using `cargo test` and `sudo cargo test`. To fix that run `sudo cargo clean` and then build or test as you prefer.
105+
However, as some functions need to be run as `root` to work, CI tests are run as `root`.
106+
So, when developing in local it's best if you use `sudo cargo test`.
108107

109-
In order to have tests pass when run as `root` or not, some tests need to check if they are `root` at run-time
110-
(using our own `am_root()` function is handy) and avoid failing if *not* run as `root`.
108+
NOTE: This can get you into permissions problems when switching back and for
109+
between using `cargo test` and `sudo cargo test`.
110+
To fix that run `sudo cargo clean` and then build or test as you prefer.
111+
112+
In order to have tests pass when run as `root` or not, some tests need to check if they are `root`
113+
at run-time (using our own `am_root()` function is handy) and avoid failing if *not* run as `root`.
114+
115+
## Using "act" to run GH Actions CI workflows locally
116+
If you develop on macos but want to ensure code builds and tests pass on linux while making changes,
117+
you can use the [act](https://github.com/nektos/act) tool to run the Github Actions Workflows on
118+
the test matrix.
119+
120+
Just install "act" (`brew install act`) (previously install docker if you don't have it already,
121+
and make sure the daemon is running) then run `act` at the command line
111122

112123
## Macos: clang detection and header file finding
113124
Newer versions of `bindgen` have improved the detection of `clang` and hence macos header files.

src/libproc/kmesg_buffer.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ pub fn kmsgbuf() -> Result<String, String> {
5858
/// has blocked and can't send anymore. Returning will end the thread and the channel.
5959
#[cfg(target_os = "linux")]
6060
pub fn kmsgbuf() -> Result<String, String> {
61-
let file = File::open("/dev/kmsg").map_err(|_| "Could not open /dev/kmsg file '{}'")?;
61+
let mut file = File::open("/dev/kmsg");
62+
if file.is_err() {
63+
file = File::open("/dev/console");
64+
}
65+
let file = file.map_err(|_| "Could not open /dev/kmsg nor /dev/console file '{}'")?;
6266
let kmsg_channel = spawn_kmsg_channel(file);
6367
let duration = time::Duration::from_millis(1);
6468
let mut buf = String::new();
@@ -90,9 +94,6 @@ fn spawn_kmsg_channel(file: File) -> Receiver<String> {
9094

9195
#[cfg(test)]
9296
mod test {
93-
use std::io;
94-
use std::io::Write;
95-
9697
use crate::libproc::proc_pid::am_root;
9798

9899
use super::kmsgbuf;
@@ -105,7 +106,7 @@ mod test {
105106
Err(message) => panic!("{}", message)
106107
}
107108
} else {
108-
writeln!(&mut io::stdout(), "test libproc::kmesg_buffer::kmessage_buffer_test ... skipped as it needs to be run as root").unwrap();
109+
println!("test skipped as it needs to be run as root");
109110
}
110111
}
111112
}

src/libproc/proc_pid.rs

Lines changed: 17 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -163,21 +163,7 @@ impl From<ProcType> for processes::ProcFilter {
163163
///
164164
/// This function is deprecated in favor of
165165
/// [`libproc::processes::pids_by_type()`][crate::processes::pids_by_type],
166-
/// which lets you specify what PGRP / TTY / UID / RUID / PPID you want to
167-
/// filter by.
168-
///
169-
/// # Examples
170-
///
171-
/// Get the list of running process IDs using `listpids`
172-
///
173-
/// ```
174-
/// use std::io::Write;
175-
/// use libproc::libproc::proc_pid;
176-
///
177-
/// if let Ok(pids) = proc_pid::listpids(proc_pid::ProcType::ProcAllPIDS) {
178-
/// println!("Found {} processes using listpids()", pids.len());
179-
/// }
180-
/// ```
166+
/// which lets you specify what PGRP / TTY / UID / RUID / PPID you want to filter by
181167
#[deprecated(
182168
since = "0.13.0",
183169
note = "Please use `libproc::processes::pids_by_type()` instead."
@@ -233,7 +219,7 @@ pub fn listpidspath(proc_types: ProcType, path: &str) -> Result<Vec<u32>, String
233219
/// // Get the `BSDInfo` for Process of pid 0
234220
/// match pidinfo::<BSDInfo>(pid, 0) {
235221
/// Ok(info) => assert_eq!(info.pbi_pid as i32, pid),
236-
/// Err(err) => assert!(false, "Error retrieving process info: {}", err)
222+
/// Err(err) => eprintln!("Error retrieving process info: {}", err)
237223
/// };
238224
/// ```
239225
#[cfg(target_os = "macos")]
@@ -274,7 +260,7 @@ pub fn pidinfo<T: PIDInfo>(_pid: i32, _arg: u64) -> Result<T, String> {
274260
/// if am_root() {
275261
/// match regionfilename(1, 0) {
276262
/// Ok(regionfilename) => println!("Region Filename (at address = 0) of init process PID = 1 is '{}'", regionfilename),
277-
/// Err(message) => panic!(message)
263+
/// Err(err) => eprintln!("Error: {}", err)
278264
/// }
279265
/// }
280266
/// ```
@@ -305,7 +291,7 @@ pub fn regionfilename(pid: i32, address: u64) -> Result<String, String> {
305291
/// if am_root() {
306292
/// match regionfilename(1, 0) {
307293
/// Ok(regionfilename) => println!("Region Filename (at address = 0) of init process PID = 1 is '{}'", regionfilename),
308-
/// Err(message) => panic!(message)
294+
/// Err(err) => eprintln!("Error: {}", err)
309295
/// }
310296
/// }
311297
/// ```
@@ -323,7 +309,7 @@ pub fn regionfilename(_pid: i32, _address: u64) -> Result<String, String> {
323309
///
324310
/// match pidpath(1) {
325311
/// Ok(path) => println!("Path of init process with PID = 1 is '{}'", path),
326-
/// Err(message) => assert!(false, "{}", message)
312+
/// Err(err) => eprintln!("Error: {}", err)
327313
/// }
328314
/// ```
329315
#[cfg(target_os = "macos")]
@@ -350,8 +336,8 @@ pub fn pidpath(pid: i32) -> Result<String, String> {
350336
/// match pidpath(1) {
351337
/// Ok(path) => println!("Path of init process with PID = 1 is '{}'", path),
352338
/// Err(_) if !am_root() => println!("pidpath() needs to be run as root"),
353-
/// Err(message) if am_root() => assert!(false, "{}", message),
354-
/// _ => assert!(false, "Unknown error")
339+
/// Err(err) if am_root() => eprintln!("Error: {}", err),
340+
/// _ => panic!("Unknown error")
355341
/// }
356342
/// ```
357343
#[cfg(target_os = "linux")]
@@ -373,12 +359,11 @@ pub fn pidpath(pid: i32) -> Result<String, String> {
373359
/// # Examples
374360
///
375361
/// ```
376-
/// use std::io::Write;
377362
/// use libproc::libproc::proc_pid;
378363
///
379364
/// match proc_pid::libversion() {
380365
/// Ok((major, minor)) => println!("Libversion: {}.{}", major, minor),
381-
/// Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
366+
/// Err(err) => eprintln!("Error: {}", err)
382367
/// }
383368
/// ```
384369
#[cfg(target_os = "macos")]
@@ -404,30 +389,28 @@ pub fn libversion() -> Result<(i32, i32), String> {
404389
/// # Examples
405390
///
406391
/// ```
407-
/// use std::io::Write;
408392
/// use libproc::libproc::proc_pid;
409393
///
410394
/// match proc_pid::libversion() {
411395
/// Ok((major, minor)) => println!("Libversion: {}.{}", major, minor),
412-
/// Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
396+
/// Err(err) => eprintln!("Error: {}", err)
413397
/// }
414398
/// ```
415399
#[cfg(not(target_os = "macos"))]
416400
pub fn libversion() -> Result<(i32, i32), String> {
417401
Err("Linux does not use a library, so no library version number".to_owned())
418402
}
419403

420-
/// Get the name of a process
404+
/// Get the name of a process, using it's process id (pid)
421405
///
422406
/// # Examples
423407
///
424408
/// ```
425-
/// use std::io::Write;
426409
/// use libproc::libproc::proc_pid;
427410
///
428411
/// match proc_pid::name(1) {
429412
/// Ok(name) => println!("Name: {}", name),
430-
/// Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
413+
/// Err(err) => eprintln!("Error: {}", err)
431414
/// }
432415
/// ```
433416
#[cfg(target_os = "macos")]
@@ -456,7 +439,7 @@ pub fn name(pid: i32) -> Result<String, String> {
456439
}
457440

458441

459-
/// Get the name of a Process using it's Pid
442+
/// Get the name of a process, using it's process id (pid)
460443
#[cfg(target_os = "linux")]
461444
pub fn name(pid: i32) -> Result<String, String> {
462445
helpers::procfile_field(&format!("/proc/{pid}/status"), "Name")
@@ -470,7 +453,6 @@ pub fn name(pid: i32) -> Result<String, String> {
470453
/// # Examples
471454
///
472455
/// ```
473-
/// use std::io::Write;
474456
/// use libproc::libproc::proc_pid::{listpidinfo, pidinfo};
475457
/// use libproc::libproc::task_info::TaskAllInfo;
476458
/// use libproc::libproc::file_info::{ListFDs, ProcFDType};
@@ -524,12 +506,11 @@ pub fn listpidinfo<T: ListPIDInfo>(_pid: i32, _max_len: usize) -> Result<Vec<T::
524506
/// # Examples
525507
///
526508
/// ```
527-
/// use std::io::Write;
528509
/// use libproc::libproc::proc_pid::pidcwd;
529510
///
530511
/// match pidcwd(1) {
531512
/// Ok(cwd) => println!("The CWD of the process with pid=1 is '{}'", cwd.display()),
532-
/// Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
513+
/// Err(err) => eprintln!("Error: {}", err)
533514
/// }
534515
/// ```
535516
pub fn pidcwd(_pid: pid_t) -> Result<PathBuf, String> {
@@ -542,12 +523,11 @@ pub fn pidcwd(_pid: pid_t) -> Result<PathBuf, String> {
542523
/// # Examples
543524
///
544525
/// ```
545-
/// use std::io::Write;
546526
/// use libproc::libproc::proc_pid::pidcwd;
547527
///
548528
/// match pidcwd(1) {
549529
/// Ok(cwd) => println!("The CWD of the process with pid=1 is '{}'", cwd.display()),
550-
/// Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
530+
/// Err(err) => eprintln!("Error: {}", err)
551531
/// }
552532
/// ```
553533
pub fn pidcwd(pid: pid_t) -> Result<PathBuf, String> {
@@ -563,12 +543,11 @@ pub fn pidcwd(pid: pid_t) -> Result<PathBuf, String> {
563543
/// # Examples
564544
///
565545
/// ```
566-
/// use std::io::Write;
567546
/// use libproc::libproc::proc_pid::cwdself;
568547
///
569548
/// match cwdself() {
570549
/// Ok(cwd) => println!("The CWD of the current process is '{}'", cwd.display()),
571-
/// Err(err) => writeln!(&mut std::io::stderr(), "Error: {}", err).unwrap()
550+
/// Err(err) => eprintln!("Error: {}", err)
572551
/// }
573552
/// ```
574553
pub fn cwdself() -> Result<PathBuf, String> {
@@ -603,7 +582,6 @@ pub fn am_root() -> bool {
603582
// run tests with 'cargo test -- --nocapture' to see the test output
604583
#[cfg(test)]
605584
mod test {
606-
#[cfg(target_os = "linux")]
607585
use std::process;
608586
use std::env;
609587

@@ -632,7 +610,6 @@ mod test {
632610
#[cfg(target_os = "macos")]
633611
#[test]
634612
fn pidinfo_test() {
635-
use std::process;
636613
let pid = process::id() as i32;
637614

638615
match pidinfo::<BSDInfo>(pid, 0) {
@@ -644,7 +621,6 @@ mod test {
644621
#[cfg(target_os = "macos")]
645622
#[test]
646623
fn taskinfo_test() {
647-
use std::process;
648624
let pid = process::id() as i32;
649625

650626
match pidinfo::<TaskInfo>(pid, 0) {
@@ -656,7 +632,6 @@ mod test {
656632
#[cfg(target_os = "macos")]
657633
#[test]
658634
fn taskallinfo_test() {
659-
use std::process;
660635
let pid = process::id() as i32;
661636

662637
match pidinfo::<TaskAllInfo>(pid, 0) {
@@ -669,7 +644,6 @@ mod test {
669644
#[cfg(target_os = "macos")]
670645
#[test]
671646
fn threadinfo_test() {
672-
use std::process;
673647
let pid = process::id() as i32;
674648

675649
match pidinfo::<ThreadInfo>(pid, 0) {
@@ -682,7 +656,6 @@ mod test {
682656
#[cfg(target_os = "macos")]
683657
#[test]
684658
fn workqueueinfo_test() {
685-
use std::process;
686659
let pid = process::id() as i32;
687660

688661
match pidinfo::<WorkQueueInfo>(pid, 0) {
@@ -694,7 +667,6 @@ mod test {
694667
#[cfg(target_os = "macos")]
695668
#[test]
696669
fn listpidinfo_test() {
697-
use std::process;
698670
let pid = process::id() as i32;
699671

700672
if let Ok(info) = pidinfo::<TaskAllInfo>(pid, 0) {
@@ -715,16 +687,9 @@ mod test {
715687

716688
#[test]
717689
fn name_test() {
718-
#[cfg(target_os = "linux")]
719-
let expected_name = "systemd";
720-
#[cfg(target_os = "macos")]
721-
let expected_name = "launchd";
722-
723690
if am_root() || cfg!(target_os = "linux") {
724-
match name(1) {
725-
Ok(name) => assert_eq!(expected_name, name),
726-
Err(_) => panic!("Error retrieving process name")
727-
}
691+
assert!(&name(process::id() as i32).expect("Could not get the process name")
692+
.starts_with("libproc"), "Incorrect process name");
728693
} else {
729694
println!("Cannot run 'name_test' on macos unless run as root");
730695
}

src/processes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::path::Path;
44

55
use crate::libproc::sys::*;
66

7-
/// `ProcFilter` is used to filter process ids. See [`pids_by_type`] and
8-
/// [`pids_by_type_and_path`] for details.
7+
/// `ProcFilter` is used to filter process ids.
8+
/// See [`pids_by_type`] and `pids_by_type_and_path` (macos only) for details.
99
#[derive(Copy, Clone)]
1010
pub enum ProcFilter {
1111
/// All processes
@@ -41,7 +41,7 @@ pub enum ProcFilter {
4141
///
4242
/// # Examples
4343
///
44-
/// Get the list of all running process IDs using `pids_by_type` and `ProcFilter::All`:
44+
/// Get the list of all running process IDs using [`pids_by_type`] and [`ProcFilter::All`]:
4545
///
4646
/// ```
4747
/// use std::io::Write;

0 commit comments

Comments
 (0)