Skip to content

Commit

Permalink
examples: add simple Rust example
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
  • Loading branch information
cyphar committed Aug 3, 2024
1 parent 6710e83 commit 7a87785
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ jobs:
name: coverage-report
path: target/llvm-cov/html

examples:
name: smoke-test examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo build --examples
- run: make -C examples smoke-test-rust

fmt:
name: rustfmt
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ snafu = "^0.8"

[dev-dependencies]
anyhow = "^1"
clap = { version = "^4", features = ["cargo"] }
errno = "^0.3"
tempfile = "^3"
paste = "^1"
Expand Down
6 changes: 5 additions & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ smoke-test:
make -C c $@
make -C go $@
make -C python $@
make -C rust-cat $@
make smoke-test-rust

.PHONY: smoke-test-rust
smoke-test-rust:
make -C rust-cat smoke-test
27 changes: 27 additions & 0 deletions examples/rust-cat/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# libpathrs: safe path resolution on Linux
# Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
# Copyright (C) 2019-2024 SUSE LLC
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.

CARGO ?= cargo

EXAMPLE_NAME := $(basename $(shell basename $$PWD))

.PHONY: build
build:
$(CARGO) build --example $(EXAMPLE_NAME)

.PHONY: smoke-test
smoke-test: build
../../target/debug/examples/$(EXAMPLE_NAME) . ../../main.rs &>/dev/null
63 changes: 63 additions & 0 deletions examples/rust-cat/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2024 SUSE LLC
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this program. If not, see <https://www.gnu.org/licenses/>.
*/

/*
* File: examples/rust-cat/main.rs
*
* An example program which opens a file inside a root and outputs its contents
* using libpathrs.
*/

use pathrs::{flags::OpenFlags, Root};

use std::io::{prelude::*, BufReader};

use anyhow::{Context, Error};
use clap::{Arg, Command};

fn main() -> Result<(), Error> {
let m = Command::new("cat")
.author(clap::crate_authors!("\n"))
.version(clap::crate_version!())
.arg(Arg::new("root").value_name("ROOT"))
.arg(Arg::new("unsafe-path").value_name("PATH"))
.about("")
.get_matches();

let root_path = m
.get_one::<String>("root")
.context("required root argument not provided")?;
let unsafe_path = m
.get_one::<String>("unsafe-path")
.context("required unsafe-path argument not provided")?;

let root = Root::open(root_path).context("open root failed")?;
let handle = root
.resolve(unsafe_path)
.context("resolve unsafe path in root")?;

let file = handle
.reopen(OpenFlags::O_RDONLY)
.context("reopen path with O_RDONLY")?;

let reader = BufReader::new(file);
for line in reader.lines() {
println!("{}", line.context("read lines")?);
}
Ok(())
}

0 comments on commit 7a87785

Please sign in to comment.