commit
1506a3f83d
3 changed files with 64 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -2522,6 +2522,7 @@ dependencies = [
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"futures",
|
"futures",
|
||||||
|
"libc",
|
||||||
"librqbit",
|
"librqbit",
|
||||||
"openssl",
|
"openssl",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ size_format = "1"
|
||||||
bytes = "1.5.0"
|
bytes = "1.5.0"
|
||||||
openssl = { version = "0.10", features = ["vendored"], optional = true }
|
openssl = { version = "0.10", features = ["vendored"], optional = true }
|
||||||
upnp-serve = { path = "../upnp-serve" }
|
upnp-serve = { path = "../upnp-serve" }
|
||||||
|
libc = "0.2.158"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
futures = { version = "0.3" }
|
futures = { version = "0.3" }
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,32 @@ enum LogLevel {
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
fn parse_umask(value: &str) -> anyhow::Result<libc::mode_t> {
|
||||||
|
fn parse_oct_digit(d: u8) -> Option<libc::mode_t> {
|
||||||
|
Some(match d {
|
||||||
|
b'0' => 0,
|
||||||
|
b'1' => 1,
|
||||||
|
b'2' => 2,
|
||||||
|
b'3' => 3,
|
||||||
|
b'4' => 4,
|
||||||
|
b'5' => 5,
|
||||||
|
b'6' => 6,
|
||||||
|
b'7' => 7,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if value.len() != 3 {
|
||||||
|
bail!("expected 3 digits")
|
||||||
|
}
|
||||||
|
let mut output = 0;
|
||||||
|
for digit in value.as_bytes() {
|
||||||
|
let digit = parse_oct_digit(*digit).context("expected 3 digits")?;
|
||||||
|
output = output * 8 + digit;
|
||||||
|
}
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(version, author, about)]
|
#[command(version, author, about)]
|
||||||
struct Opts {
|
struct Opts {
|
||||||
|
|
@ -162,6 +188,16 @@ struct Opts {
|
||||||
/// How many torrents can be initializing (rehashing) at the same time
|
/// How many torrents can be initializing (rehashing) at the same time
|
||||||
#[arg(long, default_value = "5", env = "RQBIT_CONCURRENT_INIT_LIMIT")]
|
#[arg(long, default_value = "5", env = "RQBIT_CONCURRENT_INIT_LIMIT")]
|
||||||
concurrent_init_limit: usize,
|
concurrent_init_limit: usize,
|
||||||
|
|
||||||
|
/// Set the process umask to this value.
|
||||||
|
///
|
||||||
|
/// Default is inherited from your environment (usually 022).
|
||||||
|
/// This will affect the file mode of created files.
|
||||||
|
///
|
||||||
|
/// Read more at https://man7.org/linux/man-pages/man2/umask.2.html
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
#[arg(long, env = "RQBIT_UMASK", value_parser=parse_umask)]
|
||||||
|
umask: Option<libc::mode_t>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
|
@ -294,6 +330,11 @@ fn _start_deadlock_detector_thread() {
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let opts = Opts::parse();
|
let opts = Opts::parse();
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
if let Some(umask) = opts.umask {
|
||||||
|
unsafe { libc::umask(umask) };
|
||||||
|
}
|
||||||
|
|
||||||
let mut rt_builder = match opts.single_thread_runtime {
|
let mut rt_builder = match opts.single_thread_runtime {
|
||||||
true => tokio::runtime::Builder::new_current_thread(),
|
true => tokio::runtime::Builder::new_current_thread(),
|
||||||
false => {
|
false => {
|
||||||
|
|
@ -714,3 +755,24 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
#[test]
|
||||||
|
fn test_parse_umask() {
|
||||||
|
use crate::parse_umask;
|
||||||
|
let range = b'0'..=b'7';
|
||||||
|
for d0 in range.clone() {
|
||||||
|
for d1 in range.clone() {
|
||||||
|
for d2 in range.clone() {
|
||||||
|
let inp = [d0, d1, d2];
|
||||||
|
let inp_str = std::str::from_utf8(&inp).unwrap();
|
||||||
|
let parsed = parse_umask(inp_str).expect(inp_str);
|
||||||
|
let expected = format!("{parsed:03o}");
|
||||||
|
assert_eq!(inp_str, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue