Skip to content

Commit 4cf1ce4

Browse files
author
Michael Daffin
committed
Refactors losetup
It is now easier to read and follow making it a better example. Attach now accepts a quite flag and by default prints out the loop device that was attached.
1 parent 857d5b8 commit 4cf1ce4

File tree

2 files changed

+49
-54
lines changed

2 files changed

+49
-54
lines changed

losetup/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
authors = ["Michael Daffin <[email protected]>"]
33
name = "losetup"
44
version = "0.2.0"
5+
description = "Setup and control loopback devices"
56

67
[dependencies]
78
clap = "2.23.3"

losetup/src/main.rs

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,81 @@
22
extern crate clap;
33
extern crate loopdev;
44

5-
use std::io::Write;
5+
use std::io::{self, Write};
66
use std::process::exit;
77
use loopdev::{LoopControl, LoopDevice};
88

9-
macro_rules! exit_on_error {
10-
($e:expr) => ({match $e {
11-
Ok(d) => d,
12-
Err(err) => {
13-
writeln!(&mut std::io::stderr(), "{}", err).unwrap();
14-
exit(1)
15-
},
16-
}
17-
})
9+
fn find() -> io::Result<()> {
10+
let loopdev = LoopControl::open()?.next_free()?;
11+
println!("{}", loopdev.path().unwrap().display());
12+
Ok(())
1813
}
1914

20-
fn find() {
21-
match LoopControl::open().and_then(|lc| lc.next_free()) {
22-
Ok(ld) => println!("{}", ld.path().unwrap().display()),
23-
Err(err) => {
24-
writeln!(&mut std::io::stderr(), "{}", err).unwrap();
25-
exit(1)
26-
}
15+
fn attach(matches: &clap::ArgMatches) -> io::Result<()> {
16+
let quite = matches.is_present("quite");
17+
let image = matches.value_of("image").unwrap();
18+
let offset = value_t!(matches.value_of("offset"), u64).unwrap_or(0);
19+
let sizelimit = value_t!(matches.value_of("sizelimit"), u64).unwrap_or(0);
20+
let loopdev = match matches.value_of("loopdev") {
21+
Some(loopdev) => LoopDevice::open(&loopdev)?,
22+
None => LoopControl::open().and_then(|lc| lc.next_free())?,
23+
};
24+
loopdev.attach_with_sizelimit(&image, offset, sizelimit)?;
25+
if !quite {
26+
println!("{}", loopdev.path().unwrap().display());
2727
}
28+
Ok(())
2829
}
2930

30-
fn attach(image: &str, loopdev: Option<&str>, offset: u64, sizelimit: u64) {
31-
exit_on_error!(match loopdev {
32-
None => LoopControl::open().and_then(|lc| lc.next_free()),
33-
Some(dev) => LoopDevice::open(&dev),
34-
}
35-
.and_then(|ld| ld.attach_with_sizelimit(&image, offset, sizelimit)))
31+
fn detach(matches: &clap::ArgMatches) -> io::Result<()> {
32+
let loopdev = matches.value_of("file").unwrap();
33+
LoopDevice::open(loopdev)?.detach()
3634
}
3735

38-
fn detach(dev: &str) {
39-
exit_on_error!(LoopDevice::open(dev).and_then(|ld| ld.detach()))
40-
}
41-
42-
fn list(_free: bool, _used: bool) {
36+
fn list(matches: Option<&clap::ArgMatches>) -> io::Result<()> {
37+
let (_free, _used) = match matches {
38+
Some(matches) => (matches.is_present("free"), matches.is_present("used")),
39+
None => (false, false),
40+
};
4341
unimplemented!();
4442
}
4543

4644
fn main() {
4745
let matches = clap_app!(losetup =>
48-
(version: "0.1.2")
49-
(author: "Michael Daffin <[email protected]>")
50-
(about: "Setup and control loop devices")
46+
(version: crate_version!())
47+
(author: crate_authors!())
48+
(about: crate_description!())
5149
(@subcommand find =>
5250
(about: "find the next free loop device")
53-
)
51+
)
5452
(@subcommand attach =>
5553
(about: "attach the loop device to a backing file")
56-
(@arg image: +required "the backing file to attach")
57-
(@arg loopdev: "the loop device to attach")
54+
(@arg image: +required "the backing file to attach")
55+
(@arg loopdev: "the loop device to attach")
5856
(@arg offset: -o --offset +takes_value "the offset within the file to start at")
5957
(@arg sizelimit: -s --sizelimit +takes_value "the file is limited to this size")
60-
)
58+
(@arg quite: -q --quite "don't print the device name")
59+
)
6160
(@subcommand detach =>
6261
(about: "detach the loop device from the backing file")
63-
(@arg file: +required "The file to detach")
64-
)
62+
(@arg file: +required "The file to detach")
63+
)
6564
(@subcommand list =>
6665
(about: "list the available loop devices")
6766
(@arg free: -f --free "find free devices")
6867
(@arg used: -u --used "find used devices")
69-
)
70-
)
71-
.get_matches();
68+
)
69+
).get_matches();
70+
71+
let result = match matches.subcommand() {
72+
("find", _) => find(),
73+
("attach", Some(matches)) => attach(matches),
74+
("detach", Some(matches)) => detach(matches),
75+
(_, matches) => list(matches),
76+
};
7277

73-
if let Some(_) = matches.subcommand_matches("find") {
74-
find();
75-
} else if let Some(matches) = matches.subcommand_matches("attach") {
76-
let image = matches.value_of("image").unwrap();
77-
let loopdev = matches.value_of("loopdev");
78-
attach(image,
79-
loopdev,
80-
value_t!(matches.value_of("offset"), u64).unwrap_or(0),
81-
value_t!(matches.value_of("sizelimit"), u64).unwrap_or(0));
82-
} else if let Some(matches) = matches.subcommand_matches("detach") {
83-
let file = matches.value_of("file").unwrap();
84-
detach(file);
85-
} else {
86-
list(matches.is_present("free"), matches.is_present("used"));
78+
if let Err(err) = result {
79+
writeln!(&mut std::io::stderr(), "{}", err).unwrap();
80+
exit(1);
8781
}
8882
}

0 commit comments

Comments
 (0)