зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1825480 - Update crossbeam-epoch to 0.9.14 and minidump-writer to current master. r=gsvelto,supply-chain-reviewers
This updates memoffset to 0.8 and nix to 0.26. Differential Revision: https://phabricator.services.mozilla.com/D174055
This commit is contained in:
Родитель
93784bacca
Коммит
1de53ad3c6
|
@ -105,9 +105,9 @@ git = "https://github.com/mozilla/uniffi-rs.git"
|
|||
rev = "bc7ff8977bf38d0fdd1a458810b14f434d4dc4de"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/rust-minidump/minidump-writer.git?rev=7d76616d27b9dc87fe3a94639b8b4f947d52a6aa"]
|
||||
[source."git+https://github.com/rust-minidump/minidump-writer.git?rev=59179c83ba62e4378619c6967c0b8c0c077cac2d"]
|
||||
git = "https://github.com/rust-minidump/minidump-writer.git"
|
||||
rev = "7d76616d27b9dc87fe3a94639b8b4f947d52a6aa"
|
||||
rev = "59179c83ba62e4378619c6967c0b8c0c077cac2d"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."git+https://github.com/servo/rust-cssparser?rev=45bc47e2bcb846f1efb5aea156be5fe7d18624bf"]
|
||||
|
|
|
@ -960,14 +960,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.13"
|
||||
version = "0.9.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
|
||||
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
"memoffset 0.7.1",
|
||||
"memoffset 0.8.0",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
|
@ -3142,14 +3142,14 @@ dependencies = [
|
|||
name = "memoffset"
|
||||
version = "0.6.99"
|
||||
dependencies = [
|
||||
"memoffset 0.7.1",
|
||||
"memoffset 0.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -3228,7 +3228,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "minidump-writer"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/rust-minidump/minidump-writer.git?rev=7d76616d27b9dc87fe3a94639b8b4f947d52a6aa#7d76616d27b9dc87fe3a94639b8b4f947d52a6aa"
|
||||
source = "git+https://github.com/rust-minidump/minidump-writer.git?rev=59179c83ba62e4378619c6967c0b8c0c077cac2d#59179c83ba62e4378619c6967c0b8c0c077cac2d"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"cfg-if 1.0.0",
|
||||
|
@ -3237,9 +3237,9 @@ dependencies = [
|
|||
"libc",
|
||||
"mach2",
|
||||
"memmap2",
|
||||
"memoffset 0.7.1",
|
||||
"memoffset 0.8.0",
|
||||
"minidump-common",
|
||||
"nix 0.25.1",
|
||||
"nix 0.26.2",
|
||||
"scroll",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
|
@ -3618,19 +3618,19 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
|||
name = "nix"
|
||||
version = "0.24.99"
|
||||
dependencies = [
|
||||
"nix 0.25.1",
|
||||
"nix 0.26.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.25.1"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
|
||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -121,10 +121,10 @@ wasi = { path = "build/rust/wasi" }
|
|||
# Patch bindgen 0.63 to 0.64
|
||||
bindgen = { path = "build/rust/bindgen" }
|
||||
|
||||
# Patch memoffset 0.6 to 0.7
|
||||
# Patch memoffset 0.6 to 0.8
|
||||
memoffset = { path = "build/rust/memoffset" }
|
||||
|
||||
# Patch nix 0.24 to 0.25
|
||||
# Patch nix 0.24 to 0.26
|
||||
nix = { path = "build/rust/nix" }
|
||||
|
||||
# Patch hermit-abi 0.1 to 0.2
|
||||
|
@ -157,7 +157,7 @@ firefox-on-glean = { path = "toolkit/components/glean/api" }
|
|||
libudev-sys = { path = "dom/webauthn/libudev-sys" }
|
||||
packed_simd = { package = "packed_simd_2", git = "https://github.com/hsivonen/packed_simd", rev="412f9a0aa556611de021bde89dee8fefe6e0fbbd" }
|
||||
midir = { git = "https://github.com/mozilla/midir.git", rev = "519e651241e867af3391db08f9ae6400bc023e18" }
|
||||
minidump-writer = { git = "https://github.com/rust-minidump/minidump-writer.git", rev = "7d76616d27b9dc87fe3a94639b8b4f947d52a6aa" }
|
||||
minidump-writer = { git = "https://github.com/rust-minidump/minidump-writer.git", rev = "59179c83ba62e4378619c6967c0b8c0c077cac2d" }
|
||||
# warp 0.3.3 + https://github.com/seanmonstar/warp/pull/1007
|
||||
warp = { git = "https://github.com/glandium/warp", rev = "4af45fae95bc98b0eba1ef0db17e1dac471bb23d" }
|
||||
|
||||
|
|
|
@ -8,4 +8,4 @@ license = "MPL-2.0"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies.memoffset]
|
||||
version = "0.7"
|
||||
version = "0.8"
|
||||
|
|
|
@ -8,7 +8,7 @@ license = "MPL-2.0"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies.nix]
|
||||
version = "0.25"
|
||||
version = "0.26"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
|
|
|
@ -430,6 +430,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
|||
criteria = "safe-to-deploy"
|
||||
delta = "0.9.10 -> 0.9.13"
|
||||
|
||||
[[audits.crossbeam-epoch]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.9.13 -> 0.9.14"
|
||||
|
||||
[[audits.crossbeam-queue]]
|
||||
who = "Matthew Gregan <kinetik@flim.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
@ -1356,6 +1361,11 @@ criteria = "safe-to-deploy"
|
|||
version = "0.7.0"
|
||||
notes = "The code in this crate was written or reviewed by Mozilla employees, the crate it evolved from was written specifically for gecko."
|
||||
|
||||
[[audits.minidump-writer]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.7.0 -> 0.7.0@git:59179c83ba62e4378619c6967c0b8c0c077cac2d"
|
||||
|
||||
[[audits.minidump-writer]]
|
||||
who = "Bobby Holley <bobbyholley@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
@ -1474,6 +1484,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
|||
criteria = "safe-to-deploy"
|
||||
delta = "0.25.0 -> 0.25.1"
|
||||
|
||||
[[audits.nix]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.25.1 -> 0.26.2"
|
||||
|
||||
[[audits.nom]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -142,6 +142,12 @@ criteria = "safe-to-deploy"
|
|||
version = "0.2.5"
|
||||
notes = "I am the author of this crate."
|
||||
|
||||
[[audits.bytecode-alliance.audits.memoffset]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.7.1 -> 0.8.0"
|
||||
notes = "This was a small update to the crate which has to do with Rust language features and compiler versions, no substantial changes."
|
||||
|
||||
[[audits.bytecode-alliance.audits.peeking_take_while]]
|
||||
who = "Nick Fitzgerald <fitzgen@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"89683da081a7830300becd6e52f1996d37f018c60e7bc76902a21462d4e4ec0c","Cargo.lock":"5337104cfd3c43ac5c9c33db0ffdb0fcde7165be3cb5bfd74d2f0ecdc8d3061f","Cargo.toml":"3f6579af3614880f21730bbe8bef41accdca901fa37afb1ae9175df4893c2445","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"d67d0cf57751a019707dd95785345ee181a10ea80237789bc3c19bf28c0d45ca","benches/defer.rs":"c330b704d96b2ad1aed29f72c37a99da534adef8cb06a3976d5f93bf567abb20","benches/flush.rs":"0389ac6c473632f0e93c962f223404cc360257f6699b4ec90b9b3be16bb6d74f","benches/pin.rs":"2f649a5153745c7930efdb32a52f9dc522f7b8cf548a251c5e2c82ee25dc3fff","build-common.rs":"502cb7494549bed6fa10ac7bea36e880eeb60290dc69b679ac5c92b376469562","build.rs":"901be3c21843440be5c456ff049f57f72ee5ec365918a772ad2a4751e52f69c5","examples/sanitize.rs":"a39d1635fa61e643e59192d7a63becc97ff81f03c1f4e03d38cedefb1525026a","no_atomic.rs":"3314524d2afa0360c947455a6e6566fb54ebf909c99479ca3b7435741fd3293e","src/atomic.rs":"1bd4275c1411852024533e8a70959dfedf72029e3253544d1fbb0cc18b6fd519","src/collector.rs":"29e5911f61510247659b0090517bd1a38d11e1ed86e35811603cb599962d9a58","src/default.rs":"62edf5e1f934eb82d8d7f010d6f25366e6851145a6f0a162372202bb63da1f3a","src/deferred.rs":"0c87df5797212778edd3c2d5fcf0cc04e8b9ed100261ecf9522f74a90804a3d5","src/epoch.rs":"d31e66d8fe62299928e25867336d96391b26a4fe890a1cae0885dfcf36d6835b","src/guard.rs":"f4439909152d38c03b6dfb6eeba6c9f07c39962187d461c92a492c27c258670b","src/internal.rs":"ac40ce276f0ed3dfd561926b78f775592eabb90790e177edde41fe50c13b8256","src/lib.rs":"a036d73230d0574011e67be11d275fe46439a1b5fc3295cb242d9179e5e0a220","src/sync/list.rs":"10aa4c59845ab9ff1d8bcb6f594b70bbe23c320fa7a2b125fdf85df88b9d61e2","src/sync/mod.rs":"326e32489d467e974c441120640a8338aa55da55c24b20276075ce9053997326","src/sync/once_lock.rs":"c03dc9c05a817e087dccf8b682f7307501542805533551da3c2bab442bc40743","src/sync/queue.rs":"06173b2255677d0d39178ceb49876fda2878f491e907c595eb65643dbb43c9ba","tests/loom.rs":"db772f4478966de6ec98774ca4093171dc942da635822a0d2d3257d31188cb9b"},"package":"01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"}
|
||||
{"files":{"CHANGELOG.md":"41aadd10f28a79ac9a8f8960ed1d9b01b2c637a9c5d16c44632794ea154b195b","Cargo.lock":"6347500366837bb0270a958edbeaf955d148ffe9eaad4a4903cbb078e3d50852","Cargo.toml":"e829a9a24e8c67f588cc33360c98ecee410bb33204eab021d5a29e1c9370c342","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"d67d0cf57751a019707dd95785345ee181a10ea80237789bc3c19bf28c0d45ca","benches/defer.rs":"c330b704d96b2ad1aed29f72c37a99da534adef8cb06a3976d5f93bf567abb20","benches/flush.rs":"0389ac6c473632f0e93c962f223404cc360257f6699b4ec90b9b3be16bb6d74f","benches/pin.rs":"2f649a5153745c7930efdb32a52f9dc522f7b8cf548a251c5e2c82ee25dc3fff","build-common.rs":"502cb7494549bed6fa10ac7bea36e880eeb60290dc69b679ac5c92b376469562","build.rs":"901be3c21843440be5c456ff049f57f72ee5ec365918a772ad2a4751e52f69c5","examples/sanitize.rs":"a39d1635fa61e643e59192d7a63becc97ff81f03c1f4e03d38cedefb1525026a","no_atomic.rs":"c291992d273abba165579ada7873c34ce4f3674363a7c1ec092be856beac0355","src/atomic.rs":"1bd4275c1411852024533e8a70959dfedf72029e3253544d1fbb0cc18b6fd519","src/collector.rs":"29e5911f61510247659b0090517bd1a38d11e1ed86e35811603cb599962d9a58","src/default.rs":"62edf5e1f934eb82d8d7f010d6f25366e6851145a6f0a162372202bb63da1f3a","src/deferred.rs":"0c87df5797212778edd3c2d5fcf0cc04e8b9ed100261ecf9522f74a90804a3d5","src/epoch.rs":"d31e66d8fe62299928e25867336d96391b26a4fe890a1cae0885dfcf36d6835b","src/guard.rs":"f4439909152d38c03b6dfb6eeba6c9f07c39962187d461c92a492c27c258670b","src/internal.rs":"ac40ce276f0ed3dfd561926b78f775592eabb90790e177edde41fe50c13b8256","src/lib.rs":"a036d73230d0574011e67be11d275fe46439a1b5fc3295cb242d9179e5e0a220","src/sync/list.rs":"10aa4c59845ab9ff1d8bcb6f594b70bbe23c320fa7a2b125fdf85df88b9d61e2","src/sync/mod.rs":"326e32489d467e974c441120640a8338aa55da55c24b20276075ce9053997326","src/sync/once_lock.rs":"c03dc9c05a817e087dccf8b682f7307501542805533551da3c2bab442bc40743","src/sync/queue.rs":"06173b2255677d0d39178ceb49876fda2878f491e907c595eb65643dbb43c9ba","tests/loom.rs":"db772f4478966de6ec98774ca4093171dc942da635822a0d2d3257d31188cb9b"},"package":"46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"}
|
|
@ -1,3 +1,7 @@
|
|||
# Version 0.9.14
|
||||
|
||||
- Update `memoffset` to 0.8. (#955)
|
||||
|
||||
# Version 0.9.13
|
||||
|
||||
- Fix build script bug introduced in 0.9.12. (#932)
|
||||
|
|
|
@ -10,9 +10,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.77"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -22,7 +22,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.13"
|
||||
version = "0.9.14"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
|
@ -36,9 +36,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.14"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"loom",
|
||||
|
@ -46,9 +46,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.7.1"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7"
|
||||
checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -76,9 +76,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.137"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
|
@ -113,9 +113,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -132,9 +132,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.16.0"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
|
@ -156,18 +156,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -204,9 +204,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.0"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
@ -228,9 +228,9 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
|||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.9"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
|
||||
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
|
@ -261,9 +261,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.103"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -272,10 +272,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.4"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
|
@ -343,9 +344,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
|
@ -383,43 +384,66 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.32.0"
|
||||
version = "0.44.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
|
||||
checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.32.0"
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.32.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.32.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.32.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.32.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
edition = "2018"
|
||||
rust-version = "1.38"
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.13"
|
||||
version = "0.9.14"
|
||||
description = "Epoch-based garbage collection"
|
||||
homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch"
|
||||
readme = "README.md"
|
||||
|
@ -39,7 +39,7 @@ version = "0.8.5"
|
|||
default-features = false
|
||||
|
||||
[dependencies.memoffset]
|
||||
version = "0.7"
|
||||
version = "0.8"
|
||||
|
||||
[dependencies.scopeguard]
|
||||
version = "1.1"
|
||||
|
|
|
@ -28,6 +28,7 @@ const NO_ATOMIC_64: &[&str] = &[
|
|||
"armv5te-unknown-linux-musleabi",
|
||||
"armv5te-unknown-linux-uclibceabi",
|
||||
"armv6k-nintendo-3ds",
|
||||
"armv7-sony-vita-newlibeabihf",
|
||||
"armv7r-none-eabi",
|
||||
"armv7r-none-eabihf",
|
||||
"avr-unknown-gnu-atmega328",
|
||||
|
@ -74,6 +75,8 @@ const NO_ATOMIC_64: &[&str] = &[
|
|||
#[allow(dead_code)] // Only crossbeam-utils uses this.
|
||||
const NO_ATOMIC: &[&str] = &[
|
||||
"avr-unknown-gnu-atmega328",
|
||||
"bpfeb-unknown-none",
|
||||
"bpfel-unknown-none",
|
||||
"mipsel-sony-psx",
|
||||
"msp430-none-elf",
|
||||
"riscv32i-unknown-none-elf",
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"2122b76e5dff09497c7edf7f184155e456e44209c05e4f8abb01632be7241b56","LICENSE":"3234ac55816264ee7b6c7ee27efd61cf0a1fe775806870e3d9b4c41ea73c5cb1","README.md":"7a7935d96a1a40b56afeadca391c742f7ac3a6e0f1deab1d43430553f71b6d23","build.rs":"6d677e33a1c98d588c97ec7985d4d5c3b954683e0a73c3dc53d79db4fbb5e638","src/lib.rs":"e7976d295371a3c1e0cf31b0d50210cd6b1135caba3a5111403a97ec6175c0a2","src/offset_of.rs":"ea04e76e3ab1fa192618fffb0c6a047795c275f1deaf6c6617245badaba8660c","src/raw_field.rs":"ef54087d5f507c2b639a4f61f2881eb1e41a46e22191ffd0e23b2fe9e3f17c25","src/span_of.rs":"b900faef2b852b52c37c55a172c05c9144bfff7d84dbc06e943fb0453d68adfc"},"package":"5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"}
|
||||
{"files":{"Cargo.toml":"d1193e8d228ceb5aa5792b8170c0cec8802489d66eb590bae693ae0a009c3bb9","LICENSE":"3234ac55816264ee7b6c7ee27efd61cf0a1fe775806870e3d9b4c41ea73c5cb1","README.md":"a673f0b4b5ac46034590a670572bd1a87837fdedb5170dabbea08d392e6cfa4b","build.rs":"df34c830dbb08eba3474304eed481bc2c8a29e897bc50f46d37b5dbb6e443a2b","src/lib.rs":"cc7f53556da6f53e5818e31330b488ad0de8d58096edf05f9f27e7f1159d1bfe","src/offset_of.rs":"9a2f9e8a7739a615df214738302bb74df584a53485a7f3536c0aca17ce936db3","src/raw_field.rs":"ef54087d5f507c2b639a4f61f2881eb1e41a46e22191ffd0e23b2fe9e3f17c25","src/span_of.rs":"b900faef2b852b52c37c55a172c05c9144bfff7d84dbc06e943fb0453d68adfc"},"package":"d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"}
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
[package]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
version = "0.8.0"
|
||||
authors = ["Gilad Naaman <gilad.naaman@gmail.com>"]
|
||||
description = "offset_of functionality for Rust structs."
|
||||
readme = "README.md"
|
||||
|
|
|
@ -7,6 +7,7 @@ C-Like `offset_of` functionality for Rust structs.
|
|||
Introduces the following macros:
|
||||
* `offset_of!` for obtaining the offset of a member of a struct.
|
||||
* `offset_of_tuple!` for obtaining the offset of a member of a tuple. (Requires Rust 1.20+)
|
||||
* `offset_of_union!` for obtaining the offset of a member of a union.
|
||||
* `span_of!` for obtaining the range that a field, or fields, span.
|
||||
|
||||
`memoffset` works under `no_std` environments.
|
||||
|
@ -16,7 +17,7 @@ Add the following dependency to your `Cargo.toml`:
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
memoffset = "0.7"
|
||||
memoffset = "0.8"
|
||||
```
|
||||
|
||||
These versions will compile fine with rustc versions greater or equal to 1.19.
|
||||
|
@ -45,20 +46,39 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
## Feature flags ##
|
||||
## Usage in constants ##
|
||||
`memoffset` has support for compile-time `offset_of!` on rust>=1.65, or on older nightly compilers.
|
||||
|
||||
### Usage in constants ###
|
||||
`memoffset` has **experimental** support for compile-time `offset_of!` on a nightly compiler.
|
||||
### Usage on stable Rust ###
|
||||
Constant evaluation is automatically enabled and avilable on stable compilers starting with rustc 1.65.
|
||||
|
||||
In order to use it, you must enable the `unstable_const` crate feature and several compiler features.
|
||||
This is an incomplete implementation with one caveat:
|
||||
Due to dependence on [`#![feature(const_refs_to_cell)]`](https://github.com/rust-lang/rust/issues/80384), you cannot get the offset of a `Cell` field in a const-context.
|
||||
|
||||
This means that if need to get the offset of a cell, you'll have to remain on nightly for now.
|
||||
|
||||
### Usage on recent nightlies ###
|
||||
|
||||
If you're using a new-enough nightly and you require the ability to get the offset of a `Cell`,
|
||||
you'll have to enable the `unstable_const` cargo feature, as well as enabling `const_refs_to_cell` in your crate root.
|
||||
|
||||
Do note that `unstable_const` is an unstable feature that is set to be removed in a future version of `memoffset`.
|
||||
|
||||
Cargo.toml:
|
||||
```toml
|
||||
[dependencies.memoffset]
|
||||
version = "0.7"
|
||||
version = "0.8"
|
||||
features = ["unstable_const"]
|
||||
```
|
||||
|
||||
Your crate root: (`lib.rs`/`main.rs`)
|
||||
```rust,ignore
|
||||
#![feature(const_refs_to_cell)]
|
||||
```
|
||||
|
||||
### Usage on older nightlies ###
|
||||
In order to use it on an older nightly compiler, you must enable the `unstable_const` crate feature and several compiler features.
|
||||
|
||||
Your crate root: (`lib.rs`/`main.rs`)
|
||||
```rust,ignore
|
||||
#![feature(const_ptr_offset_from, const_refs_to_cell)]
|
||||
|
|
|
@ -19,4 +19,7 @@ fn main() {
|
|||
if ac.probe_rustc_version(1, 51) {
|
||||
println!("cargo:rustc-cfg=raw_ref_macros");
|
||||
}
|
||||
if ac.probe_rustc_version(1, 65) {
|
||||
println!("cargo:rustc-cfg=stable_const");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,9 +57,10 @@
|
|||
|
||||
#![no_std]
|
||||
#![cfg_attr(
|
||||
feature = "unstable_const",
|
||||
feature(const_ptr_offset_from, const_refs_to_cell)
|
||||
all(feature = "unstable_const", not(stable_const)),
|
||||
feature(const_ptr_offset_from)
|
||||
)]
|
||||
#![cfg_attr(feature = "unstable_const", feature(const_refs_to_cell))]
|
||||
|
||||
#[macro_use]
|
||||
#[cfg(doctests)]
|
||||
|
|
|
@ -46,7 +46,7 @@ macro_rules! _memoffset__let_base_ptr {
|
|||
}
|
||||
|
||||
/// Macro to compute the distance between two pointers.
|
||||
#[cfg(feature = "unstable_const")]
|
||||
#[cfg(any(feature = "unstable_const", stable_const))]
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! _memoffset_offset_from_unsafe {
|
||||
|
@ -58,7 +58,7 @@ macro_rules! _memoffset_offset_from_unsafe {
|
|||
unsafe { (field as *const u8).offset_from(base as *const u8) as usize }
|
||||
}};
|
||||
}
|
||||
#[cfg(not(feature = "unstable_const"))]
|
||||
#[cfg(not(any(feature = "unstable_const", stable_const)))]
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! _memoffset_offset_from_unsafe {
|
||||
|
@ -312,7 +312,7 @@ mod tests {
|
|||
assert_eq!(f_ptr as usize + 0, raw_field_union!(f_ptr, Foo, c) as usize);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable_const")]
|
||||
#[cfg(any(feature = "unstable_const", stable_const))]
|
||||
#[test]
|
||||
fn const_offset() {
|
||||
#[repr(C)]
|
||||
|
@ -337,7 +337,7 @@ mod tests {
|
|||
assert_eq!([0; offset_of!(Foo, b)].len(), 4);
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable_const")]
|
||||
#[cfg(any(feature = "unstable_const", stable_const))]
|
||||
#[test]
|
||||
fn const_fn_offset() {
|
||||
const fn test_fn() -> usize {
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: deny audit
|
||||
uses: EmbarkStudios/cargo-deny-action@v1
|
||||
with:
|
||||
|
|
|
@ -32,8 +32,8 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
job:
|
||||
- { os: ubuntu-20.04 , target: x86_64-unknown-linux-gnu }
|
||||
- { os: ubuntu-20.04, target: x86_64-unknown-linux-musl }
|
||||
- { os: ubuntu-22.04, target: x86_64-unknown-linux-gnu }
|
||||
- { os: ubuntu-22.04, target: x86_64-unknown-linux-musl }
|
||||
- { os: windows-2022, target: x86_64-pc-windows-msvc }
|
||||
- { os: macos-12, target: x86_64-apple-darwin }
|
||||
# TODO: Add macos aarch64 here once it becomes available as a runner
|
||||
|
@ -57,17 +57,17 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
job:
|
||||
- { os: ubuntu-latest, target: i686-unknown-linux-gnu, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: i686-unknown-linux-gnu, use-cross: true }
|
||||
#- { os: ubuntu-latest, target: i686-unknown-linux-musl, use-cross: true }
|
||||
- { os: ubuntu-latest, target: aarch64-unknown-linux-gnu, use-cross: true }
|
||||
- { os: ubuntu-latest, target: aarch64-unknown-linux-musl, use-cross: true }
|
||||
- { os: ubuntu-latest, target: aarch64-linux-android, use-cross: true }
|
||||
- { os: ubuntu-latest, target: arm-unknown-linux-gnueabi, use-cross: true }
|
||||
- { os: ubuntu-latest, target: arm-unknown-linux-musleabi, use-cross: true }
|
||||
- { os: ubuntu-latest, target: arm-linux-androideabi, use-cross: true }
|
||||
- { os: ubuntu-latest, target: arm-unknown-linux-gnueabihf, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: aarch64-unknown-linux-gnu, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: aarch64-unknown-linux-musl, use-cross: true }
|
||||
#- { os: ubuntu-22.04, target: aarch64-linux-android, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: arm-unknown-linux-gnueabi, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: arm-unknown-linux-musleabi, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: arm-linux-androideabi, use-cross: true }
|
||||
- { os: ubuntu-22.04, target: arm-unknown-linux-gnueabihf, use-cross: true }
|
||||
# TODO: Remove this when aarch64 macs can be used as runners
|
||||
- { os: macos-latest, target: aarch64-apple-darwin, use-cross: false }
|
||||
- { os: macos-12, target: aarch64-apple-darwin, use-cross: false }
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Rust
|
||||
|
|
|
@ -24,7 +24,7 @@ repository = "https://github.com/rust-minidump/minidump-writer"
|
|||
byteorder = "1.3.2"
|
||||
cfg-if = "1.0"
|
||||
crash-context = "0.5"
|
||||
memoffset = "0.7"
|
||||
memoffset = "0.8"
|
||||
minidump-common = "0.15"
|
||||
scroll = "0.11"
|
||||
tempfile = "3.1.0"
|
||||
|
@ -39,7 +39,7 @@ version = "0.3"
|
|||
features = ["executor"]
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"android\"))".dependencies.nix]
|
||||
version = "0.25"
|
||||
version = "0.26"
|
||||
features = [
|
||||
"mman",
|
||||
"process",
|
||||
|
@ -66,6 +66,7 @@ default-features = false
|
|||
[target."cfg(target_os = \"windows\")".dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = [
|
||||
"handleapi",
|
||||
"minwindef",
|
||||
"processthreadsapi",
|
||||
"winnt",
|
||||
|
|
|
@ -88,7 +88,7 @@ mod linux {
|
|||
fn test_file_id() -> Result<()> {
|
||||
let ppid = getppid().as_raw();
|
||||
let exe_link = format!("/proc/{}/exe", ppid);
|
||||
let exe_name = std::fs::read_link(&exe_link)?.into_os_string();
|
||||
let exe_name = std::fs::read_link(exe_link)?.into_os_string();
|
||||
let mut dumper = PtraceDumper::new(getppid().as_raw())?;
|
||||
let mut found_exe = None;
|
||||
for (idx, mapping) in dumper.mappings.iter().enumerate() {
|
||||
|
@ -207,11 +207,11 @@ mod linux {
|
|||
|
||||
fn spawn_mmap_wait() -> Result<()> {
|
||||
let page_size = nix::unistd::sysconf(nix::unistd::SysconfVar::PAGE_SIZE).unwrap();
|
||||
let memory_size = page_size.unwrap() as usize;
|
||||
let memory_size = std::num::NonZeroUsize::new(page_size.unwrap() as usize).unwrap();
|
||||
// Get some memory to be mapped by the child-process
|
||||
let mapped_mem = unsafe {
|
||||
mmap(
|
||||
std::ptr::null_mut(),
|
||||
None,
|
||||
memory_size,
|
||||
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
|
||||
MapFlags::MAP_PRIVATE | MapFlags::MAP_ANON,
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
mem_writer::{Buffer, MemoryArrayWriter, MemoryWriterError},
|
||||
minidump_format::MDRawDirectory,
|
||||
};
|
||||
use std::io::{Error, Seek, SeekFrom, Write};
|
||||
use std::io::{Error, Seek, Write};
|
||||
|
||||
pub type DumpBuf = Buffer;
|
||||
|
||||
|
@ -44,7 +44,7 @@ where
|
|||
Ok(Self {
|
||||
curr_idx: 0,
|
||||
section: dir_section,
|
||||
destination_start_offset: destination.seek(SeekFrom::Current(0))?,
|
||||
destination_start_offset: destination.stream_position()?,
|
||||
destination,
|
||||
last_position_written_to_file: 0,
|
||||
})
|
||||
|
@ -65,7 +65,7 @@ where
|
|||
// Now write it to file
|
||||
|
||||
// First get all the positions
|
||||
let curr_file_pos = self.destination.seek(SeekFrom::Current(0))?;
|
||||
let curr_file_pos = self.destination.stream_position()?;
|
||||
let idx_pos = self.section.location_of_index(self.curr_idx);
|
||||
self.curr_idx += 1;
|
||||
|
||||
|
|
|
@ -42,21 +42,21 @@ pub struct LinkMap {
|
|||
}
|
||||
|
||||
// COPY from <link.h>
|
||||
#[derive(Debug, Clone)]
|
||||
/// This state value describes the mapping change taking place when
|
||||
/// the `r_brk' address is called.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[allow(non_camel_case_types, unused)]
|
||||
#[repr(C)]
|
||||
enum RState {
|
||||
/* This state value describes the mapping change taking place when
|
||||
the `r_brk' address is called. */
|
||||
RT_CONSISTENT, /* Mapping change is complete. */
|
||||
RT_ADD, /* Beginning to add a new object. */
|
||||
RT_DELETE, /* Beginning to remove an object mapping. */
|
||||
}
|
||||
impl Default for RState {
|
||||
fn default() -> Self {
|
||||
RState::RT_CONSISTENT // RStates are not used anyway
|
||||
}
|
||||
/// Mapping change is complete.
|
||||
#[default]
|
||||
RT_CONSISTENT,
|
||||
/// Beginning to add a new object.
|
||||
RT_ADD,
|
||||
/// Beginning to remove an object mapping.
|
||||
RT_DELETE,
|
||||
}
|
||||
|
||||
// COPY from <link.h>
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[repr(C)]
|
||||
|
|
|
@ -156,7 +156,7 @@ impl MinidumpWriter {
|
|||
return true;
|
||||
}
|
||||
|
||||
let (stack_ptr, stack_len) = match dumper.get_stack_info(stack_pointer as usize) {
|
||||
let (stack_ptr, stack_len) = match dumper.get_stack_info(stack_pointer) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return false;
|
||||
|
@ -173,7 +173,7 @@ impl MinidumpWriter {
|
|||
}
|
||||
};
|
||||
|
||||
let sp_offset = stack_pointer as usize - stack_ptr;
|
||||
let sp_offset = stack_pointer - stack_ptr;
|
||||
self.principal_mapping
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
|
|
|
@ -213,7 +213,6 @@ impl PtraceDumper {
|
|||
if task_path.is_dir() {
|
||||
std::fs::read_dir(task_path)
|
||||
.map_err(|e| InitError::IOError(filename, e))?
|
||||
.into_iter()
|
||||
.filter_map(|entry| entry.ok()) // Filter out bad entries
|
||||
.filter_map(|entry| {
|
||||
entry
|
||||
|
@ -481,14 +480,14 @@ impl PtraceDumper {
|
|||
) -> Option<&'data [u8]> {
|
||||
if let Some(mut notes) = elf_obj.iter_note_headers(mem_slice) {
|
||||
while let Some(Ok(note)) = notes.next() {
|
||||
if note.n_type == elf::note::NT_GNU_BUILD_ID {
|
||||
if (note.name == "GNU") && (note.n_type == elf::note::NT_GNU_BUILD_ID) {
|
||||
return Some(note.desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(mut notes) = elf_obj.iter_note_sections(mem_slice, Some(".note.gnu.build-id")) {
|
||||
while let Some(Ok(note)) = notes.next() {
|
||||
if note.n_type == elf::note::NT_GNU_BUILD_ID {
|
||||
if (note.name == "GNU") && (note.n_type == elf::note::NT_GNU_BUILD_ID) {
|
||||
return Some(note.desc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ pub fn write(
|
|||
) -> Result<MDRawDirectory, errors::SectionExceptionStreamError> {
|
||||
let exception = if let Some(context) = &config.crash_context {
|
||||
MDException {
|
||||
exception_code: context.inner.siginfo.ssi_signo as u32,
|
||||
exception_code: context.inner.siginfo.ssi_signo,
|
||||
exception_flags: context.inner.siginfo.ssi_code as u32,
|
||||
exception_address: context.inner.siginfo.ssi_addr as u64,
|
||||
exception_address: context.inner.siginfo.ssi_addr,
|
||||
..Default::default()
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -74,8 +74,8 @@ pub fn write(
|
|||
// unhelpful.
|
||||
if config.crash_context.is_some() && thread.thread_id == config.blamed_thread as u32 {
|
||||
let crash_context = config.crash_context.as_ref().unwrap();
|
||||
let instruction_ptr = crash_context.get_instruction_pointer() as usize;
|
||||
let stack_pointer = crash_context.get_stack_pointer() as usize;
|
||||
let instruction_ptr = crash_context.get_instruction_pointer();
|
||||
let stack_pointer = crash_context.get_stack_pointer();
|
||||
fill_thread_stack(
|
||||
config,
|
||||
buffer,
|
||||
|
@ -142,7 +142,7 @@ pub fn write(
|
|||
} else {
|
||||
MaxStackLen::None // default to no maximum for this thread
|
||||
};
|
||||
let instruction_ptr = info.get_instruction_pointer() as usize;
|
||||
let instruction_ptr = info.get_instruction_pointer();
|
||||
fill_thread_stack(
|
||||
config,
|
||||
buffer,
|
||||
|
|
|
@ -118,7 +118,7 @@ where
|
|||
let position = buffer.reserve(size) as u32;
|
||||
|
||||
Ok(Self {
|
||||
position: position as u32,
|
||||
position,
|
||||
size,
|
||||
phantom: std::marker::PhantomData,
|
||||
})
|
||||
|
|
|
@ -114,8 +114,8 @@ fn test_linux_gate_mapping_id() {
|
|||
#[test]
|
||||
fn test_merged_mappings() {
|
||||
let page_size = nix::unistd::sysconf(nix::unistd::SysconfVar::PAGE_SIZE).unwrap();
|
||||
let page_size = page_size.unwrap() as usize;
|
||||
let map_size = 3 * page_size;
|
||||
let page_size = std::num::NonZeroUsize::new(page_size.unwrap() as usize).unwrap();
|
||||
let map_size = std::num::NonZeroUsize::new(3 * page_size.get()).unwrap();
|
||||
|
||||
let path: &'static str = std::env!("CARGO_BIN_EXE_test");
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
|
@ -124,7 +124,7 @@ fn test_merged_mappings() {
|
|||
// enclosed in the other, but with different protections.
|
||||
let mapped_mem = unsafe {
|
||||
mmap(
|
||||
std::ptr::null_mut(),
|
||||
None,
|
||||
map_size,
|
||||
ProtFlags::PROT_READ,
|
||||
MapFlags::MAP_SHARED,
|
||||
|
@ -137,14 +137,14 @@ fn test_merged_mappings() {
|
|||
// Carve a page out of the first mapping with different permissions.
|
||||
let _inside_mapping = unsafe {
|
||||
mmap(
|
||||
(mapped_mem as usize + 2 * page_size) as *mut libc::c_void,
|
||||
std::num::NonZeroUsize::new(mapped_mem as usize + 2 * page_size.get()),
|
||||
page_size,
|
||||
ProtFlags::PROT_NONE,
|
||||
MapFlags::MAP_SHARED | MapFlags::MAP_FIXED,
|
||||
file.as_raw_fd(),
|
||||
// Map a different offset just to
|
||||
// better test real-world conditions.
|
||||
page_size.try_into().unwrap(), // try_into() in order to work for 32 and 64 bit
|
||||
page_size.get().try_into().unwrap(), // try_into() in order to work for 32 and 64 bit
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -153,7 +153,7 @@ fn test_merged_mappings() {
|
|||
&[
|
||||
path,
|
||||
&format!("{}", mapped_mem as usize),
|
||||
&format!("{}", map_size),
|
||||
&format!("{map_size}"),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ fn test_sanitize_stack_copy() {
|
|||
}
|
||||
|
||||
// The instruction pointer definitely should point into an executable mapping.
|
||||
let instr_ptr = thread_info.get_instruction_pointer() as usize;
|
||||
let instr_ptr = thread_info.get_instruction_pointer();
|
||||
let mapping_info = dumper
|
||||
.find_mapping_no_bias(instr_ptr)
|
||||
.expect("Failed to find mapping info");
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -3,18 +3,70 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [0.25.1] - 2022-12-02
|
||||
## [0.26.2] - 2023-01-18
|
||||
### Fixed
|
||||
- Fix `SockaddrIn6` bug that was swapping flowinfo and scope_id byte ordering.
|
||||
([#1964](https://github.com/nix-rust/nix/pull/1964))
|
||||
|
||||
## [0.26.1] - 2022-11-29
|
||||
### Fixed
|
||||
- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`.
|
||||
([#1821](https://github.com/nix-rust/nix/pull/1821))
|
||||
|
||||
## [0.26.0] - 2022-11-29
|
||||
### Added
|
||||
|
||||
- Added `SockaddrStorage::{as_unix_addr, as_unix_addr_mut}`
|
||||
([#1871](https://github.com/nix-rust/nix/pull/1871))
|
||||
- Added `MntFlags` and `unmount` on all of the BSDs.
|
||||
- Added `any()` and `all()` to `poll::PollFd`.
|
||||
([#1877](https://github.com/nix-rust/nix/pull/1877))
|
||||
- Add `MntFlags` and `unmount` on all of the BSDs.
|
||||
([#1849](https://github.com/nix-rust/nix/pull/1849))
|
||||
- Added a `Statfs::flags` method.
|
||||
([#1849](https://github.com/nix-rust/nix/pull/1849))
|
||||
- Added `NSFS_MAGIC` FsType on Linux and Android.
|
||||
([#1829](https://github.com/nix-rust/nix/pull/1829))
|
||||
- Added `sched_getcpu` on platforms that support it.
|
||||
([#1825](https://github.com/nix-rust/nix/pull/1825))
|
||||
- Added `sched_getaffinity` and `sched_setaffinity` on FreeBSD.
|
||||
([#1804](https://github.com/nix-rust/nix/pull/1804))
|
||||
- Added `line_discipline` field to `Termios` on Linux, Android and Haiku
|
||||
([#1805](https://github.com/nix-rust/nix/pull/1805))
|
||||
- Expose the memfd module on FreeBSD (memfd was added in FreeBSD 13)
|
||||
([#1808](https://github.com/nix-rust/nix/pull/1808))
|
||||
- Added `domainname` field of `UtsName` on Android and Linux
|
||||
([#1817](https://github.com/nix-rust/nix/pull/1817))
|
||||
- Re-export `RLIM_INFINITY` from `libc`
|
||||
([#1831](https://github.com/nix-rust/nix/pull/1831))
|
||||
- Added `syncfs(2)` on Linux
|
||||
([#1833](https://github.com/nix-rust/nix/pull/1833))
|
||||
- Added `faccessat(2)` on illumos
|
||||
([#1841](https://github.com/nix-rust/nix/pull/1841))
|
||||
- Added `eaccess()` on FreeBSD, DragonFly and Linux (glibc and musl).
|
||||
([#1842](https://github.com/nix-rust/nix/pull/1842))
|
||||
- Added `IP_TOS` `SO_PRIORITY` and `IPV6_TCLASS` sockopts for Linux
|
||||
([#1853](https://github.com/nix-rust/nix/pull/1853))
|
||||
- Added `new_unnamed` and `is_unnamed` for `UnixAddr` on Linux and Android.
|
||||
([#1857](https://github.com/nix-rust/nix/pull/1857))
|
||||
- Added `SockProtocol::Raw` for raw sockets
|
||||
([#1848](https://github.com/nix-rust/nix/pull/1848))
|
||||
- added `IP_MTU` (`IpMtu`) `IPPROTO_IP` sockopt on Linux and Android.
|
||||
([#1865](https://github.com/nix-rust/nix/pull/1865))
|
||||
|
||||
### Changed
|
||||
|
||||
- The MSRV is now 1.56.1
|
||||
([#1792](https://github.com/nix-rust/nix/pull/1792))
|
||||
- The `addr` argument of `sys::mman::mmap` is now of type `Option<NonZeroUsize>`.
|
||||
([#1870](https://github.com/nix-rust/nix/pull/1870))
|
||||
- The `length` argument of `sys::mman::mmap` is now of type `NonZeroUsize`.
|
||||
([#1873](https://github.com/nix-rust/nix/pull/1873))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Workaround XNU bug causing netmasks returned by `getifaddrs` to misbehave.
|
||||
([#1788](https://github.com/nix-rust/nix/pull/1788))
|
||||
- Fixed using `SockaddrStorage` to store a Unix-domain socket address on Linux.
|
||||
([#1871](https://github.com/nix-rust/nix/pull/1871))
|
||||
- Fix microsecond calculation for `TimeSpec`.
|
||||
([#1801](https://github.com/nix-rust/nix/pull/1801))
|
||||
- Fix `User::from_name` and `Group::from_name` panicking
|
||||
|
@ -22,13 +74,14 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
([#1815](https://github.com/nix-rust/nix/pull/1815))
|
||||
- Fix `User::from_uid` and `User::from_name` crash on Android platform.
|
||||
([#1824](https://github.com/nix-rust/nix/pull/1824))
|
||||
- Fixed using `SockaddrStorage` to store a Unix-domain socket address on Linux.
|
||||
([#1871](https://github.com/nix-rust/nix/pull/1871))
|
||||
- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`.
|
||||
([#1821](https://github.com/nix-rust/nix/pull/1821))
|
||||
|
||||
- Workaround XNU bug causing netmasks returned by `getifaddrs` to misbehave.
|
||||
([#1788](https://github.com/nix-rust/nix/pull/1788))
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed deprecated error constants and conversions.
|
||||
([#1860](https://github.com/nix-rust/nix/pull/1860))
|
||||
|
||||
## [0.25.0] - 2022-08-13
|
||||
### Added
|
||||
|
||||
|
@ -70,6 +123,9 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
|
||||
### Changed
|
||||
|
||||
- Reimplemented sendmmsg/recvmmsg to avoid allocations and with better API
|
||||
(#[1744](https://github.com/nix-rust/nix/pull/1744))
|
||||
|
||||
- Rewrote the aio module. The new module:
|
||||
* Does more type checking at compile time rather than runtime.
|
||||
* Gives the caller control over whether and when to `Box` an aio operation.
|
||||
|
@ -339,6 +395,30 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
- Removed `SigevNotify` on OpenBSD and Redox.
|
||||
(#[1511](https://github.com/nix-rust/nix/pull/1511))
|
||||
|
||||
## [0.22.3] - 22 January 2022
|
||||
### Changed
|
||||
- Relaxed the bitflags requirement from 1.3.1 to 1.1. This partially reverts
|
||||
#1492. From now on, the MSRV is not guaranteed to work with all versions of
|
||||
all dependencies, just with some version of all dependencies.
|
||||
(#[1607](https://github.com/nix-rust/nix/pull/1607))
|
||||
|
||||
## [0.22.2] - 28 September 2021
|
||||
### Fixed
|
||||
- Fixed buffer overflow in `unistd::getgrouplist`.
|
||||
(#[1545](https://github.com/nix-rust/nix/pull/1545))
|
||||
- Added more errno definitions for better backwards compatibility with
|
||||
Nix 0.21.0.
|
||||
(#[1467](https://github.com/nix-rust/nix/pull/1467))
|
||||
|
||||
## [0.22.1] - 13 August 2021
|
||||
### Fixed
|
||||
- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
|
||||
|
||||
### Removed
|
||||
- Removed a couple of termios constants on redox that were never actually
|
||||
supported.
|
||||
(#[1483](https://github.com/nix-rust/nix/pull/1483))
|
||||
|
||||
## [0.22.0] - 9 July 2021
|
||||
### Added
|
||||
- Added `if_nameindex` (#[1445](https://github.com/nix-rust/nix/pull/1445))
|
||||
|
@ -364,8 +444,19 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
`nix::Error::EINVAL`.
|
||||
([#1446](https://github.com/nix-rust/nix/pull/1446))
|
||||
|
||||
## [0.21.2] - 29 September 2021
|
||||
### Fixed
|
||||
- Fixed buffer overflow in `unistd::getgrouplist`.
|
||||
(#[1545](https://github.com/nix-rust/nix/pull/1545))
|
||||
|
||||
## [0.21.1] - 13 August 2021
|
||||
### Fixed
|
||||
- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
|
||||
|
||||
### Removed
|
||||
- Removed a couple of termios constants on redox that were never actually
|
||||
supported.
|
||||
(#[1483](https://github.com/nix-rust/nix/pull/1483))
|
||||
|
||||
## [0.21.0] - 31 May 2021
|
||||
### Added
|
||||
|
@ -421,6 +512,20 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
- Removed some Errno values from platforms where they aren't actually defined.
|
||||
(#[1452](https://github.com/nix-rust/nix/pull/1452))
|
||||
|
||||
## [0.20.2] - 28 September 2021
|
||||
### Fixed
|
||||
- Fixed buffer overflow in `unistd::getgrouplist`.
|
||||
(#[1545](https://github.com/nix-rust/nix/pull/1545))
|
||||
|
||||
## [0.20.1] - 13 August 2021
|
||||
### Fixed
|
||||
- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
|
||||
|
||||
### Removed
|
||||
- Removed a couple of termios constants on redox that were never actually
|
||||
supported.
|
||||
(#[1483](https://github.com/nix-rust/nix/pull/1483))
|
||||
|
||||
## [0.20.0] - 20 February 2021
|
||||
### Added
|
||||
|
||||
|
@ -484,8 +589,6 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
(#[1278](https://github.com/nix-rust/nix/pull/1278))
|
||||
- Made `unistd::fork` an unsafe funtion, bringing it in line with [libstd's decision](https://github.com/rust-lang/rust/pull/58059).
|
||||
(#[1293](https://github.com/nix-rust/nix/pull/1293))
|
||||
### Fixed
|
||||
### Removed
|
||||
|
||||
## [0.18.0] - 26 July 2020
|
||||
### Added
|
||||
|
@ -598,22 +701,16 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
### Added
|
||||
- Add `CLK_TCK` to `SysconfVar`
|
||||
(#[1177](https://github.com/nix-rust/nix/pull/1177))
|
||||
### Changed
|
||||
### Fixed
|
||||
### Removed
|
||||
- Removed deprecated Error::description from error types
|
||||
(#[1175](https://github.com/nix-rust/nix/pull/1175))
|
||||
|
||||
## [0.16.1] - 23 December 2019
|
||||
### Added
|
||||
### Changed
|
||||
### Fixed
|
||||
|
||||
- Fixed the build for OpenBSD
|
||||
(#[1168](https://github.com/nix-rust/nix/pull/1168))
|
||||
|
||||
### Removed
|
||||
|
||||
## [0.16.0] - 1 December 2019
|
||||
### Added
|
||||
- Added `ptrace::seize()`: similar to `attach()` on Linux
|
||||
|
@ -741,8 +838,6 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
- Enabled `sched_yield` for all nix hosts.
|
||||
([#1090](https://github.com/nix-rust/nix/pull/1090))
|
||||
|
||||
### Removed
|
||||
|
||||
## [0.14.1] - 2019-06-06
|
||||
### Added
|
||||
- Macros exported by `nix` may now be imported via `use` on the Rust 2018
|
||||
|
@ -767,8 +862,6 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
- Fix the build on Android and Linux/mips with recent versions of libc.
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
|
||||
### Removed
|
||||
|
||||
## [0.14.0] - 2019-05-21
|
||||
### Added
|
||||
- Add IP_RECVIF & IP_RECVDSTADDR. Enable IP_PKTINFO and IP6_PKTINFO on netbsd/openbsd.
|
||||
|
@ -837,6 +930,23 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
should've been defined in the first place.
|
||||
([#1055](https://github.com/nix-rust/nix/pull/1055))
|
||||
|
||||
## [0.13.1] - 2019-06-10
|
||||
### Changed
|
||||
- Changed some public types from reexports of libc types like `uint32_t` to the
|
||||
native equivalents like `u32.`
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
|
||||
### Fixed
|
||||
- Fix the build on Android and Linux/mips with recent versions of libc.
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc
|
||||
([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973))
|
||||
|
||||
### Removed
|
||||
- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
|
||||
and iOS.
|
||||
([#1033](https://github.com/nix-rust/nix/pull/1033))
|
||||
|
||||
## [0.13.0] - 2019-01-15
|
||||
### Added
|
||||
- Added PKTINFO(V4) & V6PKTINFO cmsg support - Android/FreeBSD/iOS/Linux/MacOS.
|
||||
|
@ -854,14 +964,30 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
- Added an `mprotect` wrapper.
|
||||
([#991](https://github.com/nix-rust/nix/pull/991))
|
||||
|
||||
### Changed
|
||||
### Fixed
|
||||
- `lutimes` never worked on OpenBSD as it is not implemented on OpenBSD. It has
|
||||
been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
|
||||
- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
|
||||
either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
|
||||
|
||||
## [0.12.1] 2019-06-08
|
||||
### Changed
|
||||
- Changed some public types from reexports of libc types like `uint32_t` to the
|
||||
native equivalents like `u32.`
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
|
||||
### Fixed
|
||||
- Fix the build on Android and Linux/mips with recent versions of libc.
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc
|
||||
([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973))
|
||||
|
||||
### Removed
|
||||
- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
|
||||
either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
|
||||
- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
|
||||
and iOS.
|
||||
([#1033](https://github.com/nix-rust/nix/pull/1033))
|
||||
|
||||
## [0.12.0] 2018-11-28
|
||||
|
||||
|
@ -913,7 +1039,24 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|||
- Fixed passing multiple file descriptors over Unix Sockets.
|
||||
([#918](https://github.com/nix-rust/nix/pull/918))
|
||||
|
||||
## [0.11.1] 2019-06-06
|
||||
### Changed
|
||||
- Changed some public types from reexports of libc types like `uint32_t` to the
|
||||
native equivalents like `u32.`
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
|
||||
### Fixed
|
||||
- Fix the build on Android and Linux/mips with recent versions of libc.
|
||||
([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
|
||||
- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc
|
||||
([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973))
|
||||
|
||||
### Removed
|
||||
- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
|
||||
either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
|
||||
- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
|
||||
and iOS.
|
||||
([#1033](https://github.com/nix-rust/nix/pull/1033))
|
||||
|
||||
## [0.11.0] 2018-06-01
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.46"
|
||||
rust-version = "1.56"
|
||||
name = "nix"
|
||||
version = "0.25.1"
|
||||
version = "0.26.2"
|
||||
authors = ["The nix-rust Project Developers"]
|
||||
include = [
|
||||
"src/**/*",
|
||||
|
@ -75,13 +75,16 @@ version = "1.1"
|
|||
version = "1.0"
|
||||
|
||||
[dependencies.libc]
|
||||
version = "0.2.127"
|
||||
version = "0.2.137"
|
||||
features = ["extra_traits"]
|
||||
|
||||
[dependencies.pin-utils]
|
||||
version = "0.1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.static_assertions]
|
||||
version = "1"
|
||||
|
||||
[dev-dependencies.assert-impl]
|
||||
version = "0.1"
|
||||
|
||||
|
@ -89,7 +92,7 @@ version = "0.1"
|
|||
version = "1.4"
|
||||
|
||||
[dev-dependencies.parking_lot]
|
||||
version = "0.11.2"
|
||||
version = "0.12"
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.8"
|
||||
|
@ -100,9 +103,6 @@ version = "1.0.7"
|
|||
[dev-dependencies.tempfile]
|
||||
version = "3.3.0"
|
||||
|
||||
[build-dependencies.autocfg]
|
||||
version = "1.1.0"
|
||||
|
||||
[features]
|
||||
acct = []
|
||||
aio = ["pin-utils"]
|
||||
|
@ -178,7 +178,7 @@ zerocopy = [
|
|||
version = "0.5.3"
|
||||
|
||||
[target."cfg(not(target_os = \"redox\"))".dependencies.memoffset]
|
||||
version = "0.6.3"
|
||||
version = "0.7"
|
||||
optional = true
|
||||
|
||||
[target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl]
|
||||
|
|
|
@ -47,6 +47,7 @@ limitations. Support for platforms is split into three tiers:
|
|||
The following targets are supported by `nix`:
|
||||
|
||||
Tier 1:
|
||||
* aarch64-apple-darwin
|
||||
* aarch64-unknown-linux-gnu
|
||||
* arm-unknown-linux-gnueabi
|
||||
* armv7-unknown-linux-gnueabihf
|
||||
|
@ -58,13 +59,11 @@ Tier 1:
|
|||
* mips64el-unknown-linux-gnuabi64
|
||||
* mipsel-unknown-linux-gnu
|
||||
* powerpc64le-unknown-linux-gnu
|
||||
* x86_64-apple-darwin
|
||||
* x86_64-unknown-freebsd
|
||||
* x86_64-unknown-linux-gnu
|
||||
* x86_64-unknown-linux-musl
|
||||
|
||||
Tier 2:
|
||||
* aarch64-apple-darwin
|
||||
* aarch64-apple-ios
|
||||
* aarch64-linux-android
|
||||
* arm-linux-androideabi
|
||||
|
@ -75,6 +74,7 @@ Tier 2:
|
|||
* s390x-unknown-linux-gnu
|
||||
* x86_64-apple-ios
|
||||
* x86_64-linux-android
|
||||
* x86_64-apple-darwin
|
||||
* x86_64-unknown-illumos
|
||||
* x86_64-unknown-netbsd
|
||||
|
||||
|
@ -89,7 +89,7 @@ Tier 3:
|
|||
|
||||
## Minimum Supported Rust Version (MSRV)
|
||||
|
||||
nix is supported on Rust 1.46.0 and higher. Its MSRV will not be
|
||||
nix is supported on Rust 1.56.1 and higher. Its MSRV will not be
|
||||
changed in the future without bumping the major or minor version.
|
||||
|
||||
## Contributing
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
//! List directory contents
|
||||
|
||||
use crate::{Error, NixPath, Result};
|
||||
use crate::errno::Errno;
|
||||
use crate::fcntl::{self, OFlag};
|
||||
use crate::sys;
|
||||
use crate::{Error, NixPath, Result};
|
||||
use cfg_if::cfg_if;
|
||||
use std::ffi;
|
||||
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
|
||||
use std::ptr;
|
||||
use std::ffi;
|
||||
use crate::sys;
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::{dirent64 as dirent, readdir64_r as readdir_r};
|
||||
|
@ -29,21 +29,26 @@ use libc::{dirent, readdir_r};
|
|||
/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
|
||||
/// does).
|
||||
#[derive(Debug, Eq, Hash, PartialEq)]
|
||||
pub struct Dir(
|
||||
ptr::NonNull<libc::DIR>
|
||||
);
|
||||
pub struct Dir(ptr::NonNull<libc::DIR>);
|
||||
|
||||
impl Dir {
|
||||
/// Opens the given path as with `fcntl::open`.
|
||||
pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag,
|
||||
mode: sys::stat::Mode) -> Result<Self> {
|
||||
pub fn open<P: ?Sized + NixPath>(
|
||||
path: &P,
|
||||
oflag: OFlag,
|
||||
mode: sys::stat::Mode,
|
||||
) -> Result<Self> {
|
||||
let fd = fcntl::open(path, oflag, mode)?;
|
||||
Dir::from_fd(fd)
|
||||
}
|
||||
|
||||
/// Opens the given path as with `fcntl::openat`.
|
||||
pub fn openat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P, oflag: OFlag,
|
||||
mode: sys::stat::Mode) -> Result<Self> {
|
||||
pub fn openat<P: ?Sized + NixPath>(
|
||||
dirfd: RawFd,
|
||||
path: &P,
|
||||
oflag: OFlag,
|
||||
mode: sys::stat::Mode,
|
||||
) -> Result<Self> {
|
||||
let fd = fcntl::openat(dirfd, path, oflag, mode)?;
|
||||
Dir::from_fd(fd)
|
||||
}
|
||||
|
@ -55,13 +60,15 @@ impl Dir {
|
|||
}
|
||||
|
||||
/// Converts from a file descriptor, closing it on success or failure.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("fdopendir")))]
|
||||
#[doc(alias("fdopendir"))]
|
||||
pub fn from_fd(fd: RawFd) -> Result<Self> {
|
||||
let d = ptr::NonNull::new(unsafe { libc::fdopendir(fd) }).ok_or_else(|| {
|
||||
let e = Error::last();
|
||||
unsafe { libc::close(fd) };
|
||||
e
|
||||
})?;
|
||||
let d = ptr::NonNull::new(unsafe { libc::fdopendir(fd) }).ok_or_else(
|
||||
|| {
|
||||
let e = Error::last();
|
||||
unsafe { libc::close(fd) };
|
||||
e
|
||||
},
|
||||
)?;
|
||||
Ok(Dir(d))
|
||||
}
|
||||
|
||||
|
@ -103,9 +110,11 @@ fn next(dir: &mut Dir) -> Option<Result<Entry>> {
|
|||
// Probably fine here too then.
|
||||
let mut ent = std::mem::MaybeUninit::<dirent>::uninit();
|
||||
let mut result = ptr::null_mut();
|
||||
if let Err(e) = Errno::result(
|
||||
readdir_r(dir.0.as_ptr(), ent.as_mut_ptr(), &mut result))
|
||||
{
|
||||
if let Err(e) = Errno::result(readdir_r(
|
||||
dir.0.as_ptr(),
|
||||
ent.as_mut_ptr(),
|
||||
&mut result,
|
||||
)) {
|
||||
return Some(Err(e));
|
||||
}
|
||||
if result.is_null() {
|
||||
|
@ -207,7 +216,7 @@ pub enum Type {
|
|||
|
||||
impl Entry {
|
||||
/// Returns the inode number (`d_ino`) of the underlying `dirent`.
|
||||
#[allow(clippy::useless_conversion)] // Not useless on all OSes
|
||||
#[allow(clippy::useless_conversion)] // Not useless on all OSes
|
||||
// The cast is not unnecessary on all platforms.
|
||||
#[allow(clippy::unnecessary_cast)]
|
||||
pub fn ino(&self) -> u64 {
|
||||
|
@ -240,7 +249,11 @@ impl Entry {
|
|||
/// notably, some Linux filesystems don't implement this. The caller should use `stat` or
|
||||
/// `fstat` if this returns `None`.
|
||||
pub fn file_type(&self) -> Option<Type> {
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))]
|
||||
#[cfg(not(any(
|
||||
target_os = "illumos",
|
||||
target_os = "solaris",
|
||||
target_os = "haiku"
|
||||
)))]
|
||||
match self.0.d_type {
|
||||
libc::DT_FIFO => Some(Type::Fifo),
|
||||
libc::DT_CHR => Some(Type::CharacterDevice),
|
||||
|
@ -253,7 +266,11 @@ impl Entry {
|
|||
}
|
||||
|
||||
// illumos, Solaris, and Haiku systems do not have the d_type member at all:
|
||||
#[cfg(any(target_os = "illumos", target_os = "solaris", target_os = "haiku"))]
|
||||
#[cfg(any(
|
||||
target_os = "illumos",
|
||||
target_os = "solaris",
|
||||
target_os = "haiku"
|
||||
))]
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Error, Result};
|
||||
use crate::Result;
|
||||
use cfg_if::cfg_if;
|
||||
use libc::{c_int, c_void};
|
||||
use std::convert::TryFrom;
|
||||
|
@ -51,34 +51,6 @@ pub fn errno() -> i32 {
|
|||
}
|
||||
|
||||
impl Errno {
|
||||
/// Convert this `Error` to an [`Errno`](enum.Errno.html).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use nix::Error;
|
||||
/// # use nix::errno::Errno;
|
||||
/// let e = Error::from(Errno::EPERM);
|
||||
/// assert_eq!(Some(Errno::EPERM), e.as_errno());
|
||||
/// ```
|
||||
#[deprecated(since = "0.22.0", note = "It's a no-op now; just delete it.")]
|
||||
pub const fn as_errno(self) -> Option<Self> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
/// Create a nix Error from a given errno
|
||||
#[deprecated(since = "0.22.0", note = "It's a no-op now; just delete it.")]
|
||||
#[allow(clippy::wrong_self_convention)] // False positive
|
||||
pub fn from_errno(errno: Errno) -> Error {
|
||||
errno
|
||||
}
|
||||
|
||||
/// Create a new invalid argument error (`EINVAL`)
|
||||
#[deprecated(since = "0.22.0", note = "Use Errno::EINVAL instead")]
|
||||
pub const fn invalid_argument() -> Error {
|
||||
Errno::EINVAL
|
||||
}
|
||||
|
||||
pub fn last() -> Self {
|
||||
last()
|
||||
}
|
||||
|
@ -105,18 +77,6 @@ impl Errno {
|
|||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Backwards compatibility hack for Nix <= 0.21.0 users
|
||||
///
|
||||
/// In older versions of Nix, `Error::Sys` was an enum variant. Now it's a
|
||||
/// function, which is compatible with most of the former use cases of the
|
||||
/// enum variant. But you should use `Error(Errno::...)` instead.
|
||||
#[deprecated(since = "0.22.0", note = "Use Errno::... instead")]
|
||||
#[allow(non_snake_case)]
|
||||
#[inline]
|
||||
pub const fn Sys(errno: Errno) -> Error {
|
||||
errno
|
||||
}
|
||||
}
|
||||
|
||||
/// The sentinel value indicates that a function failed and more detailed
|
||||
|
@ -1297,22 +1257,6 @@ mod consts {
|
|||
EHWPOISON = libc::EHWPOISON,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EDEADLOCK instead"
|
||||
)]
|
||||
pub const EDEADLOCK: Errno = Errno::EDEADLK;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ENOTSUP instead"
|
||||
)]
|
||||
pub const ENOTSUP: Errno = Errno::EOPNOTSUPP;
|
||||
|
||||
impl Errno {
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
pub const EDEADLOCK: Errno = Errno::EDEADLK;
|
||||
|
@ -1576,22 +1520,6 @@ mod consts {
|
|||
EQFULL = libc::EQFULL,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ELAST instead"
|
||||
)]
|
||||
pub const ELAST: Errno = Errno::EQFULL;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EDEADLOCK instead"
|
||||
)]
|
||||
pub const EDEADLOCK: Errno = Errno::EDEADLK;
|
||||
|
||||
impl Errno {
|
||||
pub const ELAST: Errno = Errno::EQFULL;
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
@ -1818,27 +1746,6 @@ mod consts {
|
|||
EOWNERDEAD = libc::EOWNERDEAD,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ELAST instead"
|
||||
)]
|
||||
pub const ELAST: Errno = Errno::EOWNERDEAD;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EDEADLOCK instead"
|
||||
)]
|
||||
pub const EDEADLOCK: Errno = Errno::EDEADLK;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EOPNOTSUPP instead"
|
||||
)]
|
||||
pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
|
||||
|
||||
impl Errno {
|
||||
pub const ELAST: Errno = Errno::EOWNERDEAD;
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
@ -2056,27 +1963,6 @@ mod consts {
|
|||
EASYNC = libc::EASYNC,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ELAST instead"
|
||||
)]
|
||||
pub const ELAST: Errno = Errno::EASYNC;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EDEADLOCK instead"
|
||||
)]
|
||||
pub const EDEADLOCK: Errno = Errno::EDEADLK;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EOPNOTSUPP instead"
|
||||
)]
|
||||
pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
|
||||
|
||||
impl Errno {
|
||||
pub const ELAST: Errno = Errno::EASYNC;
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
@ -2291,17 +2177,6 @@ mod consts {
|
|||
EPROTO = libc::EPROTO,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ELAST instead"
|
||||
)]
|
||||
pub const ELAST: Errno = Errno::ENOTSUP;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
||||
impl Errno {
|
||||
pub const ELAST: Errno = Errno::ENOTSUP;
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
@ -2516,17 +2391,6 @@ mod consts {
|
|||
EPROTO = libc::EPROTO,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ELAST instead"
|
||||
)]
|
||||
pub const ELAST: Errno = Errno::ENOTSUP;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
||||
impl Errno {
|
||||
pub const ELAST: Errno = Errno::ENOTSUP;
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
@ -2731,12 +2595,6 @@ mod consts {
|
|||
EPROTO = libc::EPROTO,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
||||
impl Errno {
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
}
|
||||
|
@ -2965,17 +2823,6 @@ mod consts {
|
|||
ESTALE = libc::ESTALE,
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::ELAST instead"
|
||||
)]
|
||||
pub const ELAST: Errno = Errno::ELAST;
|
||||
#[deprecated(
|
||||
since = "0.22.1",
|
||||
note = "use nix::errno::Errno::EWOULDBLOCK instead"
|
||||
)]
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
||||
impl Errno {
|
||||
pub const ELAST: Errno = Errno::ESTALE;
|
||||
pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
|
||||
|
|
|
@ -3,9 +3,9 @@ pub use self::os::*;
|
|||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
mod os {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use crate::sys::utsname::uname;
|
||||
use crate::Result;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
// Features:
|
||||
// * atomic cloexec on socket: 2.6.27
|
||||
|
@ -13,10 +13,10 @@ mod os {
|
|||
// * accept4: 2.6.28
|
||||
|
||||
static VERS_UNKNOWN: usize = 1;
|
||||
static VERS_2_6_18: usize = 2;
|
||||
static VERS_2_6_27: usize = 3;
|
||||
static VERS_2_6_28: usize = 4;
|
||||
static VERS_3: usize = 5;
|
||||
static VERS_2_6_18: usize = 2;
|
||||
static VERS_2_6_27: usize = 3;
|
||||
static VERS_2_6_28: usize = 4;
|
||||
static VERS_3: usize = 5;
|
||||
|
||||
#[inline]
|
||||
fn digit(dst: &mut usize, b: u8) {
|
||||
|
@ -27,7 +27,7 @@ mod os {
|
|||
fn parse_kernel_version() -> Result<usize> {
|
||||
let u = uname()?;
|
||||
|
||||
let mut curr: usize = 0;
|
||||
let mut curr: usize = 0;
|
||||
let mut major: usize = 0;
|
||||
let mut minor: usize = 0;
|
||||
let mut patch: usize = 0;
|
||||
|
@ -41,13 +41,11 @@ mod os {
|
|||
b'.' | b'-' => {
|
||||
curr += 1;
|
||||
}
|
||||
b'0'..=b'9' => {
|
||||
match curr {
|
||||
0 => digit(&mut major, b),
|
||||
1 => digit(&mut minor, b),
|
||||
_ => digit(&mut patch, b),
|
||||
}
|
||||
}
|
||||
b'0'..=b'9' => match curr {
|
||||
0 => digit(&mut major, b),
|
||||
1 => digit(&mut minor, b),
|
||||
_ => digit(&mut patch, b),
|
||||
},
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +85,9 @@ mod os {
|
|||
|
||||
/// Check if the OS supports atomic close-on-exec for sockets
|
||||
pub fn socket_atomic_cloexec() -> bool {
|
||||
kernel_version().map(|version| version >= VERS_2_6_27).unwrap_or(false)
|
||||
kernel_version()
|
||||
.map(|version| version >= VERS_2_6_27)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -111,11 +111,13 @@ mod os {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "fuchsia",
|
||||
target_os = "haiku",
|
||||
target_os = "solaris"))]
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "fuchsia",
|
||||
target_os = "haiku",
|
||||
target_os = "solaris"
|
||||
))]
|
||||
mod os {
|
||||
/// Check if the OS supports atomic close-on-exec for sockets
|
||||
pub const fn socket_atomic_cloexec() -> bool {
|
||||
|
|
|
@ -11,9 +11,9 @@ use std::iter::Iterator;
|
|||
use std::mem;
|
||||
use std::option::Option;
|
||||
|
||||
use crate::{Result, Errno};
|
||||
use crate::sys::socket::{SockaddrLike, SockaddrStorage};
|
||||
use crate::net::if_::*;
|
||||
use crate::sys::socket::{SockaddrLike, SockaddrStorage};
|
||||
use crate::{Errno, Result};
|
||||
|
||||
/// Describes a single address for an interface as returned by `getifaddrs`.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
|
|
|
@ -79,7 +79,11 @@ libc_bitflags!(
|
|||
/// ```
|
||||
///
|
||||
/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
|
||||
pub fn finit_module<T: AsRawFd>(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> {
|
||||
pub fn finit_module<T: AsRawFd>(
|
||||
fd: &T,
|
||||
param_values: &CStr,
|
||||
flags: ModuleInitFlags,
|
||||
) -> Result<()> {
|
||||
let res = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_finit_module,
|
||||
|
@ -116,7 +120,9 @@ libc_bitflags!(
|
|||
///
|
||||
/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
|
||||
pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
|
||||
let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) };
|
||||
let res = unsafe {
|
||||
libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits())
|
||||
};
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@ feature! {
|
|||
#[allow(missing_docs)]
|
||||
pub mod kmod;
|
||||
}
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
feature! {
|
||||
#![feature = "mount"]
|
||||
pub mod mount;
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
use crate::{
|
||||
Error,
|
||||
Errno,
|
||||
NixPath,
|
||||
Result,
|
||||
};
|
||||
use libc::{c_char, c_int, c_uint, c_void};
|
||||
#[cfg(target_os = "freebsd")]
|
||||
use crate::Error;
|
||||
use crate::{Errno, NixPath, Result};
|
||||
use libc::c_int;
|
||||
#[cfg(target_os = "freebsd")]
|
||||
use libc::{c_char, c_uint, c_void};
|
||||
#[cfg(target_os = "freebsd")]
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
ffi::{CString, CStr},
|
||||
fmt,
|
||||
io,
|
||||
ffi::{CStr, CString},
|
||||
fmt, io,
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
|
||||
libc_bitflags!(
|
||||
/// Used with [`Nmount::nmount`].
|
||||
pub struct MntFlags: c_int {
|
||||
|
@ -105,17 +103,18 @@ libc_bitflags!(
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
/// The Error type of [`Nmount::nmount`].
|
||||
///
|
||||
/// It wraps an [`Errno`], but also may contain an additional message returned
|
||||
/// by `nmount(2)`.
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[derive(Debug)]
|
||||
pub struct NmountError {
|
||||
errno: Error,
|
||||
errmsg: Option<String>
|
||||
errmsg: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
impl NmountError {
|
||||
/// Returns the additional error string sometimes generated by `nmount(2)`.
|
||||
pub fn errmsg(&self) -> Option<&str> {
|
||||
|
@ -130,13 +129,15 @@ impl NmountError {
|
|||
fn new(error: Error, errmsg: Option<&CStr>) -> Self {
|
||||
Self {
|
||||
errno: error,
|
||||
errmsg: errmsg.map(CStr::to_string_lossy).map(Cow::into_owned)
|
||||
errmsg: errmsg.map(CStr::to_string_lossy).map(Cow::into_owned),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
impl std::error::Error for NmountError {}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
impl fmt::Display for NmountError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(errmsg) = &self.errmsg {
|
||||
|
@ -147,6 +148,7 @@ impl fmt::Display for NmountError {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
impl From<NmountError> for io::Error {
|
||||
fn from(err: NmountError) -> Self {
|
||||
err.errno.into()
|
||||
|
@ -154,6 +156,7 @@ impl From<NmountError> for io::Error {
|
|||
}
|
||||
|
||||
/// Result type of [`Nmount::nmount`].
|
||||
#[cfg(target_os = "freebsd")]
|
||||
pub type NmountResult = std::result::Result<(), NmountError>;
|
||||
|
||||
/// Mount a FreeBSD file system.
|
||||
|
@ -187,7 +190,7 @@ pub type NmountResult = std::result::Result<(), NmountError>;
|
|||
/// .str_opt_owned("fspath", mountpoint.path().to_str().unwrap())
|
||||
/// .str_opt_owned("target", target.path().to_str().unwrap())
|
||||
/// .nmount(MntFlags::empty()).unwrap();
|
||||
///
|
||||
///
|
||||
/// unmount(mountpoint.path(), MntFlags::empty()).unwrap();
|
||||
/// ```
|
||||
///
|
||||
|
@ -197,7 +200,7 @@ pub type NmountResult = std::result::Result<(), NmountError>;
|
|||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Nmount<'a>{
|
||||
pub struct Nmount<'a> {
|
||||
// n.b. notgull: In reality, this is a list that contains
|
||||
// both mutable and immutable pointers.
|
||||
// Be careful using this.
|
||||
|
@ -219,7 +222,12 @@ impl<'a> Nmount<'a> {
|
|||
}
|
||||
|
||||
/// Helper function to push a pointer and its length onto the `iov` array.
|
||||
fn push_pointer_and_length(&mut self, val: *const u8, len: usize, is_owned: bool) {
|
||||
fn push_pointer_and_length(
|
||||
&mut self,
|
||||
val: *const u8,
|
||||
len: usize,
|
||||
is_owned: bool,
|
||||
) {
|
||||
self.iov.push(libc::iovec {
|
||||
iov_base: val as *mut _,
|
||||
iov_len: len,
|
||||
|
@ -234,7 +242,8 @@ impl<'a> Nmount<'a> {
|
|||
let ptr = s.to_owned().into_raw() as *const u8;
|
||||
|
||||
self.push_pointer_and_length(ptr, len, true);
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Add an opaque mount option.
|
||||
|
@ -268,9 +277,8 @@ impl<'a> Nmount<'a> {
|
|||
&mut self,
|
||||
name: &'a CStr,
|
||||
val: *mut c_void,
|
||||
len: usize
|
||||
) -> &mut Self
|
||||
{
|
||||
len: usize,
|
||||
) -> &mut Self {
|
||||
self.push_slice(name.to_bytes_with_nul(), false);
|
||||
self.push_pointer_and_length(val.cast(), len, false);
|
||||
self
|
||||
|
@ -309,8 +317,10 @@ impl<'a> Nmount<'a> {
|
|||
/// let mut nmount: Nmount<'static> = Nmount::new();
|
||||
/// nmount.null_opt_owned(read_only);
|
||||
/// ```
|
||||
pub fn null_opt_owned<P: ?Sized + NixPath>(&mut self, name: &P) -> &mut Self
|
||||
{
|
||||
pub fn null_opt_owned<P: ?Sized + NixPath>(
|
||||
&mut self,
|
||||
name: &P,
|
||||
) -> &mut Self {
|
||||
self.push_nix_path(name);
|
||||
self.push_slice(&[], false);
|
||||
self
|
||||
|
@ -328,12 +338,7 @@ impl<'a> Nmount<'a> {
|
|||
/// Nmount::new()
|
||||
/// .str_opt(&fstype, &nullfs);
|
||||
/// ```
|
||||
pub fn str_opt(
|
||||
&mut self,
|
||||
name: &'a CStr,
|
||||
val: &'a CStr
|
||||
) -> &mut Self
|
||||
{
|
||||
pub fn str_opt(&mut self, name: &'a CStr, val: &'a CStr) -> &mut Self {
|
||||
self.push_slice(name.to_bytes_with_nul(), false);
|
||||
self.push_slice(val.to_bytes_with_nul(), false);
|
||||
self
|
||||
|
@ -355,8 +360,9 @@ impl<'a> Nmount<'a> {
|
|||
/// .str_opt_owned("fspath", mountpoint.to_str().unwrap());
|
||||
/// ```
|
||||
pub fn str_opt_owned<P1, P2>(&mut self, name: &P1, val: &P2) -> &mut Self
|
||||
where P1: ?Sized + NixPath,
|
||||
P2: ?Sized + NixPath
|
||||
where
|
||||
P1: ?Sized + NixPath,
|
||||
P2: ?Sized + NixPath,
|
||||
{
|
||||
self.push_nix_path(name);
|
||||
self.push_nix_path(val);
|
||||
|
@ -386,9 +392,7 @@ impl<'a> Nmount<'a> {
|
|||
|
||||
let niov = self.iov.len() as c_uint;
|
||||
let iovp = self.iov.as_mut_ptr() as *mut libc::iovec;
|
||||
let res = unsafe {
|
||||
libc::nmount(iovp, niov, flags.bits)
|
||||
};
|
||||
let res = unsafe { libc::nmount(iovp, niov, flags.bits) };
|
||||
match Errno::result(res) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(error) => {
|
||||
|
@ -425,18 +429,24 @@ impl<'a> Drop for Nmount<'a> {
|
|||
///
|
||||
/// Useful flags include
|
||||
/// * `MNT_FORCE` - Unmount even if still in use.
|
||||
/// * `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID
|
||||
/// encoded as `FSID:val0:val1`, where `val0` and `val1`
|
||||
/// are the contents of the `fsid_t val[]` array in decimal.
|
||||
/// The file system that has the specified file system ID
|
||||
/// will be unmounted. See
|
||||
/// [`statfs`](crate::sys::statfs::statfs) to determine the
|
||||
/// `fsid`.
|
||||
#[cfg_attr(
|
||||
target_os = "freebsd",
|
||||
doc = "
|
||||
* `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID
|
||||
encoded as `FSID:val0:val1`, where `val0` and `val1`
|
||||
are the contents of the `fsid_t val[]` array in decimal.
|
||||
The file system that has the specified file system ID
|
||||
will be unmounted. See
|
||||
[`statfs`](crate::sys::statfs::statfs) to determine the
|
||||
`fsid`.
|
||||
"
|
||||
)]
|
||||
pub fn unmount<P>(mountpoint: &P, flags: MntFlags) -> Result<()>
|
||||
where P: ?Sized + NixPath
|
||||
where
|
||||
P: ?Sized + NixPath,
|
||||
{
|
||||
let res = mountpoint.with_nix_path(|cstr| {
|
||||
unsafe { libc::unmount(cstr.as_ptr(), flags.bits) }
|
||||
let res = mountpoint.with_nix_path(|cstr| unsafe {
|
||||
libc::unmount(cstr.as_ptr(), flags.bits)
|
||||
})?;
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(missing_docs)]
|
||||
use libc::{self, c_ulong, c_int};
|
||||
use crate::{Result, NixPath};
|
||||
use crate::errno::Errno;
|
||||
use crate::{NixPath, Result};
|
||||
use libc::{self, c_int, c_ulong};
|
||||
|
||||
libc_bitflags!(
|
||||
pub struct MsFlags: c_ulong {
|
||||
|
@ -57,36 +57,40 @@ libc_bitflags!(
|
|||
}
|
||||
);
|
||||
|
||||
pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P4: ?Sized + NixPath>(
|
||||
source: Option<&P1>,
|
||||
target: &P2,
|
||||
fstype: Option<&P3>,
|
||||
flags: MsFlags,
|
||||
data: Option<&P4>) -> Result<()> {
|
||||
|
||||
pub fn mount<
|
||||
P1: ?Sized + NixPath,
|
||||
P2: ?Sized + NixPath,
|
||||
P3: ?Sized + NixPath,
|
||||
P4: ?Sized + NixPath,
|
||||
>(
|
||||
source: Option<&P1>,
|
||||
target: &P2,
|
||||
fstype: Option<&P3>,
|
||||
flags: MsFlags,
|
||||
data: Option<&P4>,
|
||||
) -> Result<()> {
|
||||
fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
|
||||
where P: ?Sized + NixPath,
|
||||
F: FnOnce(*const libc::c_char) -> T
|
||||
where
|
||||
P: ?Sized + NixPath,
|
||||
F: FnOnce(*const libc::c_char) -> T,
|
||||
{
|
||||
match p {
|
||||
Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
|
||||
None => Ok(f(std::ptr::null()))
|
||||
None => Ok(f(std::ptr::null())),
|
||||
}
|
||||
}
|
||||
|
||||
let res = with_opt_nix_path(source, |s| {
|
||||
target.with_nix_path(|t| {
|
||||
with_opt_nix_path(fstype, |ty| {
|
||||
with_opt_nix_path(data, |d| {
|
||||
unsafe {
|
||||
libc::mount(
|
||||
s,
|
||||
t.as_ptr(),
|
||||
ty,
|
||||
flags.bits,
|
||||
d as *const libc::c_void
|
||||
)
|
||||
}
|
||||
with_opt_nix_path(data, |d| unsafe {
|
||||
libc::mount(
|
||||
s,
|
||||
t.as_ptr(),
|
||||
ty,
|
||||
flags.bits,
|
||||
d as *const libc::c_void,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -96,16 +100,15 @@ pub fn mount<P1: ?Sized + NixPath, P2: ?Sized + NixPath, P3: ?Sized + NixPath, P
|
|||
}
|
||||
|
||||
pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
|
||||
let res = target.with_nix_path(|cstr| {
|
||||
unsafe { libc::umount(cstr.as_ptr()) }
|
||||
})?;
|
||||
let res =
|
||||
target.with_nix_path(|cstr| unsafe { libc::umount(cstr.as_ptr()) })?;
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
||||
pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
|
||||
let res = target.with_nix_path(|cstr| {
|
||||
unsafe { libc::umount2(cstr.as_ptr(), flags.bits) }
|
||||
let res = target.with_nix_path(|cstr| unsafe {
|
||||
libc::umount2(cstr.as_ptr(), flags.bits)
|
||||
})?;
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
|
|
|
@ -6,18 +6,21 @@ mod linux;
|
|||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub use self::linux::*;
|
||||
|
||||
#[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
mod bsd;
|
||||
|
||||
#[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub use self::bsd::*;
|
||||
|
|
|
@ -30,15 +30,15 @@
|
|||
//! ```
|
||||
//! [Further reading and details on the C API](https://man7.org/linux/man-pages/man7/mq_overview.7.html)
|
||||
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
|
||||
use crate::sys::stat::Mode;
|
||||
use libc::{self, c_char, mqd_t, size_t};
|
||||
use std::ffi::CStr;
|
||||
use crate::sys::stat::Mode;
|
||||
use std::mem;
|
||||
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
/// Used with [`mq_open`].
|
||||
pub struct MQ_OFlag: libc::c_int {
|
||||
/// Open the message queue for receiving messages.
|
||||
|
@ -96,12 +96,12 @@ impl MqAttr {
|
|||
/// - `mq_maxmsg`: Maximum number of messages on the queue.
|
||||
/// - `mq_msgsize`: Maximum message size in bytes.
|
||||
/// - `mq_curmsgs`: Number of messages currently in the queue.
|
||||
pub fn new(mq_flags: mq_attr_member_t,
|
||||
mq_maxmsg: mq_attr_member_t,
|
||||
mq_msgsize: mq_attr_member_t,
|
||||
mq_curmsgs: mq_attr_member_t)
|
||||
-> MqAttr
|
||||
{
|
||||
pub fn new(
|
||||
mq_flags: mq_attr_member_t,
|
||||
mq_maxmsg: mq_attr_member_t,
|
||||
mq_msgsize: mq_attr_member_t,
|
||||
mq_curmsgs: mq_attr_member_t,
|
||||
) -> MqAttr {
|
||||
let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
|
||||
unsafe {
|
||||
let p = attr.as_mut_ptr();
|
||||
|
@ -109,7 +109,9 @@ impl MqAttr {
|
|||
(*p).mq_maxmsg = mq_maxmsg;
|
||||
(*p).mq_msgsize = mq_msgsize;
|
||||
(*p).mq_curmsgs = mq_curmsgs;
|
||||
MqAttr { mq_attr: attr.assume_init() }
|
||||
MqAttr {
|
||||
mq_attr: attr.assume_init(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,23 +136,25 @@ impl MqAttr {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Open a message queue
|
||||
///
|
||||
/// See also [`mq_open(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html)
|
||||
// The mode.bits cast is only lossless on some OSes
|
||||
#[allow(clippy::cast_lossless)]
|
||||
pub fn mq_open(name: &CStr,
|
||||
oflag: MQ_OFlag,
|
||||
mode: Mode,
|
||||
attr: Option<&MqAttr>)
|
||||
-> Result<MqdT> {
|
||||
pub fn mq_open(
|
||||
name: &CStr,
|
||||
oflag: MQ_OFlag,
|
||||
mode: Mode,
|
||||
attr: Option<&MqAttr>,
|
||||
) -> Result<MqdT> {
|
||||
let res = match attr {
|
||||
Some(mq_attr) => unsafe {
|
||||
libc::mq_open(name.as_ptr(),
|
||||
oflag.bits(),
|
||||
mode.bits() as libc::c_int,
|
||||
&mq_attr.mq_attr as *const libc::mq_attr)
|
||||
libc::mq_open(
|
||||
name.as_ptr(),
|
||||
oflag.bits(),
|
||||
mode.bits() as libc::c_int,
|
||||
&mq_attr.mq_attr as *const libc::mq_attr,
|
||||
)
|
||||
},
|
||||
None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) },
|
||||
};
|
||||
|
@ -176,13 +180,19 @@ pub fn mq_close(mqdes: MqdT) -> Result<()> {
|
|||
/// Receive a message from a message queue
|
||||
///
|
||||
/// See also [`mq_receive(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
|
||||
pub fn mq_receive(mqdes: &MqdT, message: &mut [u8], msg_prio: &mut u32) -> Result<usize> {
|
||||
pub fn mq_receive(
|
||||
mqdes: &MqdT,
|
||||
message: &mut [u8],
|
||||
msg_prio: &mut u32,
|
||||
) -> Result<usize> {
|
||||
let len = message.len() as size_t;
|
||||
let res = unsafe {
|
||||
libc::mq_receive(mqdes.0,
|
||||
message.as_mut_ptr() as *mut c_char,
|
||||
len,
|
||||
msg_prio as *mut u32)
|
||||
libc::mq_receive(
|
||||
mqdes.0,
|
||||
message.as_mut_ptr() as *mut c_char,
|
||||
len,
|
||||
msg_prio as *mut u32,
|
||||
)
|
||||
};
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
}
|
||||
|
@ -192,10 +202,12 @@ pub fn mq_receive(mqdes: &MqdT, message: &mut [u8], msg_prio: &mut u32) -> Resul
|
|||
/// See also [`mq_send(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
|
||||
pub fn mq_send(mqdes: &MqdT, message: &[u8], msq_prio: u32) -> Result<()> {
|
||||
let res = unsafe {
|
||||
libc::mq_send(mqdes.0,
|
||||
message.as_ptr() as *const c_char,
|
||||
message.len(),
|
||||
msq_prio)
|
||||
libc::mq_send(
|
||||
mqdes.0,
|
||||
message.as_ptr() as *const c_char,
|
||||
message.len(),
|
||||
msq_prio,
|
||||
)
|
||||
};
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
@ -206,7 +218,11 @@ pub fn mq_send(mqdes: &MqdT, message: &[u8], msq_prio: u32) -> Result<()> {
|
|||
pub fn mq_getattr(mqd: &MqdT) -> Result<MqAttr> {
|
||||
let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
|
||||
let res = unsafe { libc::mq_getattr(mqd.0, attr.as_mut_ptr()) };
|
||||
Errno::result(res).map(|_| unsafe{MqAttr { mq_attr: attr.assume_init() }})
|
||||
Errno::result(res).map(|_| unsafe {
|
||||
MqAttr {
|
||||
mq_attr: attr.assume_init(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored
|
||||
|
@ -217,21 +233,31 @@ pub fn mq_getattr(mqd: &MqdT) -> Result<MqAttr> {
|
|||
pub fn mq_setattr(mqd: &MqdT, newattr: &MqAttr) -> Result<MqAttr> {
|
||||
let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
|
||||
let res = unsafe {
|
||||
libc::mq_setattr(mqd.0, &newattr.mq_attr as *const libc::mq_attr, attr.as_mut_ptr())
|
||||
libc::mq_setattr(
|
||||
mqd.0,
|
||||
&newattr.mq_attr as *const libc::mq_attr,
|
||||
attr.as_mut_ptr(),
|
||||
)
|
||||
};
|
||||
Errno::result(res).map(|_| unsafe{ MqAttr { mq_attr: attr.assume_init() }})
|
||||
Errno::result(res).map(|_| unsafe {
|
||||
MqAttr {
|
||||
mq_attr: attr.assume_init(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Convenience function.
|
||||
/// Sets the `O_NONBLOCK` attribute for a given message queue descriptor
|
||||
/// Returns the old attributes
|
||||
#[allow(clippy::useless_conversion)] // Not useless on all OSes
|
||||
#[allow(clippy::useless_conversion)] // Not useless on all OSes
|
||||
pub fn mq_set_nonblock(mqd: &MqdT) -> Result<MqAttr> {
|
||||
let oldattr = mq_getattr(mqd)?;
|
||||
let newattr = MqAttr::new(mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()),
|
||||
oldattr.mq_attr.mq_maxmsg,
|
||||
oldattr.mq_attr.mq_msgsize,
|
||||
oldattr.mq_attr.mq_curmsgs);
|
||||
let newattr = MqAttr::new(
|
||||
mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()),
|
||||
oldattr.mq_attr.mq_maxmsg,
|
||||
oldattr.mq_attr.mq_msgsize,
|
||||
oldattr.mq_attr.mq_curmsgs,
|
||||
);
|
||||
mq_setattr(mqd, &newattr)
|
||||
}
|
||||
|
||||
|
@ -240,9 +266,11 @@ pub fn mq_set_nonblock(mqd: &MqdT) -> Result<MqAttr> {
|
|||
/// Returns the old attributes
|
||||
pub fn mq_remove_nonblock(mqd: &MqdT) -> Result<MqAttr> {
|
||||
let oldattr = mq_getattr(mqd)?;
|
||||
let newattr = MqAttr::new(0,
|
||||
oldattr.mq_attr.mq_maxmsg,
|
||||
oldattr.mq_attr.mq_msgsize,
|
||||
oldattr.mq_attr.mq_curmsgs);
|
||||
let newattr = MqAttr::new(
|
||||
0,
|
||||
oldattr.mq_attr.mq_maxmsg,
|
||||
oldattr.mq_attr.mq_msgsize,
|
||||
oldattr.mq_attr.mq_curmsgs,
|
||||
);
|
||||
mq_setattr(mqd, &newattr)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ use libc::c_uint;
|
|||
|
||||
/// Resolve an interface into a interface number.
|
||||
pub fn if_nametoindex<P: ?Sized + NixPath>(name: &P) -> Result<c_uint> {
|
||||
let if_index = name.with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?;
|
||||
let if_index = name
|
||||
.with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?;
|
||||
|
||||
if if_index == 0 {
|
||||
Err(Error::last())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Wait for events to trigger on specific file descriptors
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
|
||||
/// This is a wrapper around `libc::pollfd`.
|
||||
///
|
||||
|
@ -37,6 +37,26 @@ impl PollFd {
|
|||
PollFlags::from_bits(self.pollfd.revents)
|
||||
}
|
||||
|
||||
/// Returns if any of the events of interest occured in the last call to `poll` or `ppoll`. Will
|
||||
/// only return `None` if the kernel provides status flags that Nix does not know about.
|
||||
///
|
||||
/// Equivalent to `x.revents()? != PollFlags::empty()`.
|
||||
///
|
||||
/// This is marginally more efficient than [`PollFd::all`].
|
||||
pub fn any(self) -> Option<bool> {
|
||||
Some(self.revents()? != PollFlags::empty())
|
||||
}
|
||||
|
||||
/// Returns if all the events of interest occured in the last call to `poll` or `ppoll`. Will
|
||||
/// only return `None` if the kernel provides status flags that Nix does not know about.
|
||||
///
|
||||
/// Equivalent to `x.revents()? & x.events() == x.events()`.
|
||||
///
|
||||
/// This is marginally less efficient than [`PollFd::any`].
|
||||
pub fn all(self) -> Option<bool> {
|
||||
Some(self.revents()? & self.events() == self.events())
|
||||
}
|
||||
|
||||
/// The events of interest for this `PollFd`.
|
||||
pub fn events(self) -> PollFlags {
|
||||
PollFlags::from_bits(self.pollfd.events).unwrap()
|
||||
|
@ -134,9 +154,11 @@ libc_bitflags! {
|
|||
/// ready.
|
||||
pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
|
||||
let res = unsafe {
|
||||
libc::poll(fds.as_mut_ptr() as *mut libc::pollfd,
|
||||
fds.len() as libc::nfds_t,
|
||||
timeout)
|
||||
libc::poll(
|
||||
fds.as_mut_ptr() as *mut libc::pollfd,
|
||||
fds.len() as libc::nfds_t,
|
||||
timeout,
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res)
|
||||
|
|
|
@ -8,11 +8,11 @@ use std::io;
|
|||
use std::mem;
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
use crate::errno::Errno;
|
||||
use crate::sys::termios::Termios;
|
||||
#[cfg(feature = "process")]
|
||||
use crate::unistd::{ForkResult, Pid};
|
||||
use crate::{Result, fcntl, unistd};
|
||||
use crate::errno::Errno;
|
||||
use crate::{fcntl, unistd, Result};
|
||||
|
||||
/// Representation of a master/slave pty pair
|
||||
///
|
||||
|
@ -41,7 +41,6 @@ pub struct ForkptyResult {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Representation of the Master device in a master/slave pty pair
|
||||
///
|
||||
/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
|
||||
|
@ -159,9 +158,7 @@ pub fn grantpt(fd: &PtyMaster) -> Result<()> {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn posix_openpt(flags: fcntl::OFlag) -> Result<PtyMaster> {
|
||||
let fd = unsafe {
|
||||
libc::posix_openpt(flags.bits())
|
||||
};
|
||||
let fd = unsafe { libc::posix_openpt(flags.bits()) };
|
||||
|
||||
if fd < 0 {
|
||||
return Err(Errno::last());
|
||||
|
@ -239,7 +236,6 @@ pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
/// Create a new pseudoterminal, returning the slave and master file descriptors
|
||||
/// in `OpenptyResult`
|
||||
/// (see [`openpty`](https://man7.org/linux/man-pages/man3/openpty.3.html)).
|
||||
|
@ -248,7 +244,15 @@ pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
|
|||
/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
|
||||
/// terminal settings of the slave will be set to the values in `termios`.
|
||||
#[inline]
|
||||
pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(winsize: T, termios: U) -> Result<OpenptyResult> {
|
||||
pub fn openpty<
|
||||
'a,
|
||||
'b,
|
||||
T: Into<Option<&'a Winsize>>,
|
||||
U: Into<Option<&'b Termios>>,
|
||||
>(
|
||||
winsize: T,
|
||||
termios: U,
|
||||
) -> Result<OpenptyResult> {
|
||||
use std::ptr;
|
||||
|
||||
let mut slave = mem::MaybeUninit::<libc::c_int>::uninit();
|
||||
|
@ -267,17 +271,15 @@ pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
|
|||
)
|
||||
}
|
||||
}
|
||||
(None, Some(winsize)) => {
|
||||
unsafe {
|
||||
libc::openpty(
|
||||
master.as_mut_ptr(),
|
||||
slave.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
winsize as *const Winsize as *mut _,
|
||||
)
|
||||
}
|
||||
}
|
||||
(None, Some(winsize)) => unsafe {
|
||||
libc::openpty(
|
||||
master.as_mut_ptr(),
|
||||
slave.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
winsize as *const Winsize as *mut _,
|
||||
)
|
||||
},
|
||||
(Some(termios), None) => {
|
||||
let inner_termios = termios.get_libc_termios();
|
||||
unsafe {
|
||||
|
@ -290,17 +292,15 @@ pub fn openpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>
|
|||
)
|
||||
}
|
||||
}
|
||||
(None, None) => {
|
||||
unsafe {
|
||||
libc::openpty(
|
||||
master.as_mut_ptr(),
|
||||
slave.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
}
|
||||
(None, None) => unsafe {
|
||||
libc::openpty(
|
||||
master.as_mut_ptr(),
|
||||
slave.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
)
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ pub use self::sched_linux_like::*;
|
|||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
mod sched_linux_like {
|
||||
use crate::errno::Errno;
|
||||
use crate::unistd::Pid;
|
||||
use crate::Result;
|
||||
use libc::{self, c_int, c_void};
|
||||
use std::mem;
|
||||
use std::option::Option;
|
||||
use std::os::unix::io::RawFd;
|
||||
use crate::unistd::Pid;
|
||||
use crate::Result;
|
||||
|
||||
// For some functions taking with a parameter of type CloneFlags,
|
||||
// only a subset of these flags have an effect.
|
||||
|
@ -112,7 +112,8 @@ mod sched_linux_like {
|
|||
let ptr_aligned = ptr.sub(ptr as usize % 16);
|
||||
libc::clone(
|
||||
mem::transmute(
|
||||
callback as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
|
||||
callback
|
||||
as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
|
||||
),
|
||||
ptr_aligned as *mut c_void,
|
||||
combined,
|
||||
|
@ -142,25 +143,38 @@ mod sched_linux_like {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux"
|
||||
))]
|
||||
pub use self::sched_affinity::*;
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "linux"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux"
|
||||
))]
|
||||
mod sched_affinity {
|
||||
use crate::errno::Errno;
|
||||
use std::mem;
|
||||
use crate::unistd::Pid;
|
||||
use crate::Result;
|
||||
use std::mem;
|
||||
|
||||
/// CpuSet represent a bit-mask of CPUs.
|
||||
/// CpuSets are used by sched_setaffinity and
|
||||
/// sched_getaffinity for example.
|
||||
///
|
||||
/// This is a wrapper around `libc::cpu_set_t`.
|
||||
#[repr(C)]
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct CpuSet {
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
cpu_set: libc::cpu_set_t,
|
||||
#[cfg(target_os = "freebsd")]
|
||||
cpu_set: libc::cpuset_t,
|
||||
}
|
||||
|
||||
impl CpuSet {
|
||||
|
@ -187,7 +201,9 @@ mod sched_affinity {
|
|||
if field >= CpuSet::count() {
|
||||
Err(Errno::EINVAL)
|
||||
} else {
|
||||
unsafe { libc::CPU_SET(field, &mut self.cpu_set); }
|
||||
unsafe {
|
||||
libc::CPU_SET(field, &mut self.cpu_set);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -198,14 +214,21 @@ mod sched_affinity {
|
|||
if field >= CpuSet::count() {
|
||||
Err(Errno::EINVAL)
|
||||
} else {
|
||||
unsafe { libc::CPU_CLR(field, &mut self.cpu_set);}
|
||||
unsafe {
|
||||
libc::CPU_CLR(field, &mut self.cpu_set);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the maximum number of CPU in CpuSet
|
||||
pub const fn count() -> usize {
|
||||
8 * mem::size_of::<libc::cpu_set_t>()
|
||||
#[cfg(not(target_os = "freebsd"))]
|
||||
let bytes = mem::size_of::<libc::cpu_set_t>();
|
||||
#[cfg(target_os = "freebsd")]
|
||||
let bytes = mem::size_of::<libc::cpuset_t>();
|
||||
|
||||
8 * bytes
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,6 +305,13 @@ mod sched_affinity {
|
|||
|
||||
Errno::result(res).and(Ok(cpuset))
|
||||
}
|
||||
|
||||
/// Determines the CPU on which the calling thread is running.
|
||||
pub fn sched_getcpu() -> Result<usize> {
|
||||
let res = unsafe { libc::sched_getcpu() };
|
||||
|
||||
Errno::result(res).map(|int| int as usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Explicitly yield the processor to other threads.
|
||||
|
|
|
@ -32,8 +32,7 @@ use std::{
|
|||
mem,
|
||||
os::unix::io::RawFd,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
thread,
|
||||
ptr, thread,
|
||||
};
|
||||
|
||||
use libc::{c_void, off_t};
|
||||
|
@ -107,7 +106,7 @@ unsafe impl Sync for LibcAiocb {}
|
|||
// polymorphism is at the level of `Futures`.
|
||||
#[repr(C)]
|
||||
struct AioCb {
|
||||
aiocb: LibcAiocb,
|
||||
aiocb: LibcAiocb,
|
||||
/// Could this `AioCb` potentially have any in-kernel state?
|
||||
// It would be really nice to perform the in-progress check entirely at
|
||||
// compile time. But I can't figure out how, because:
|
||||
|
@ -153,7 +152,7 @@ impl AioCb {
|
|||
a.aio_reqprio = prio;
|
||||
a.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
|
||||
AioCb {
|
||||
aiocb: LibcAiocb(a),
|
||||
aiocb: LibcAiocb(a),
|
||||
in_progress: false,
|
||||
}
|
||||
}
|
||||
|
@ -432,7 +431,7 @@ macro_rules! aio_methods {
|
|||
#[repr(transparent)]
|
||||
pub struct AioFsync {
|
||||
aiocb: AioCb,
|
||||
_pin: PhantomPinned,
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
|
||||
impl AioFsync {
|
||||
|
@ -546,7 +545,7 @@ impl AsRef<libc::aiocb> for AioFsync {
|
|||
pub struct AioRead<'a> {
|
||||
aiocb: AioCb,
|
||||
_data: PhantomData<&'a [u8]>,
|
||||
_pin: PhantomPinned,
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
|
||||
impl<'a> AioRead<'a> {
|
||||
|
@ -667,7 +666,7 @@ impl<'a> AsRef<libc::aiocb> for AioRead<'a> {
|
|||
pub struct AioReadv<'a> {
|
||||
aiocb: AioCb,
|
||||
_data: PhantomData<&'a [&'a [u8]]>,
|
||||
_pin: PhantomPinned,
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
|
@ -778,7 +777,7 @@ impl<'a> AsRef<libc::aiocb> for AioReadv<'a> {
|
|||
pub struct AioWrite<'a> {
|
||||
aiocb: AioCb,
|
||||
_data: PhantomData<&'a [u8]>,
|
||||
_pin: PhantomPinned,
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
|
||||
impl<'a> AioWrite<'a> {
|
||||
|
@ -896,7 +895,7 @@ impl<'a> AsRef<libc::aiocb> for AioWrite<'a> {
|
|||
pub struct AioWritev<'a> {
|
||||
aiocb: AioCb,
|
||||
_data: PhantomData<&'a [&'a [u8]]>,
|
||||
_pin: PhantomPinned,
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
|
@ -1053,8 +1052,7 @@ pub fn aio_suspend(
|
|||
timeout: Option<TimeSpec>,
|
||||
) -> Result<()> {
|
||||
let p = list as *const [&dyn AsRef<libc::aiocb>]
|
||||
as *const [*const libc::aiocb]
|
||||
as *const *const libc::aiocb;
|
||||
as *const [*const libc::aiocb] as *const *const libc::aiocb;
|
||||
let timep = match timeout {
|
||||
None => ptr::null::<libc::timespec>(),
|
||||
Some(x) => x.as_ref() as *const libc::timespec,
|
||||
|
@ -1180,8 +1178,7 @@ pub fn lio_listio(
|
|||
sigev_notify: SigevNotify,
|
||||
) -> Result<()> {
|
||||
let p = list as *mut [Pin<&mut dyn AsMut<libc::aiocb>>]
|
||||
as *mut [*mut libc::aiocb]
|
||||
as *mut *mut libc::aiocb;
|
||||
as *mut [*mut libc::aiocb] as *mut *mut libc::aiocb;
|
||||
let sigev = SigEvent::new(sigev_notify);
|
||||
let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
|
||||
Errno::result(unsafe {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
use libc::{self, c_int};
|
||||
use std::mem;
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
|
||||
libc_bitflags!(
|
||||
pub struct EpollFlags: c_int {
|
||||
|
@ -35,7 +35,7 @@ pub enum EpollOp {
|
|||
EpollCtlMod = libc::EPOLL_CTL_MOD,
|
||||
}
|
||||
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
pub struct EpollCreateFlags: c_int {
|
||||
EPOLL_CLOEXEC;
|
||||
}
|
||||
|
@ -49,7 +49,12 @@ pub struct EpollEvent {
|
|||
|
||||
impl EpollEvent {
|
||||
pub fn new(events: EpollFlags, data: u64) -> Self {
|
||||
EpollEvent { event: libc::epoll_event { events: events.bits() as u32, u64: data } }
|
||||
EpollEvent {
|
||||
event: libc::epoll_event {
|
||||
events: events.bits() as u32,
|
||||
u64: data,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
|
@ -80,8 +85,14 @@ pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()>
|
||||
where T: Into<Option<&'a mut EpollEvent>>
|
||||
pub fn epoll_ctl<'a, T>(
|
||||
epfd: RawFd,
|
||||
op: EpollOp,
|
||||
fd: RawFd,
|
||||
event: T,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: Into<Option<&'a mut EpollEvent>>,
|
||||
{
|
||||
let mut event: Option<&mut EpollEvent> = event.into();
|
||||
if event.is_none() && op != EpollOp::EpollCtlDel {
|
||||
|
@ -99,9 +110,18 @@ pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn epoll_wait(epfd: RawFd, events: &mut [EpollEvent], timeout_ms: isize) -> Result<usize> {
|
||||
pub fn epoll_wait(
|
||||
epfd: RawFd,
|
||||
events: &mut [EpollEvent],
|
||||
timeout_ms: isize,
|
||||
) -> Result<usize> {
|
||||
let res = unsafe {
|
||||
libc::epoll_wait(epfd, events.as_mut_ptr() as *mut libc::epoll_event, events.len() as c_int, timeout_ms as c_int)
|
||||
libc::epoll_wait(
|
||||
epfd,
|
||||
events.as_mut_ptr() as *mut libc::epoll_event,
|
||||
events.len() as c_int,
|
||||
timeout_ms as c_int,
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
use crate::{Errno, Result};
|
||||
#[cfg(not(target_os = "netbsd"))]
|
||||
use libc::{timespec, time_t, c_int, c_long, intptr_t, uintptr_t};
|
||||
use libc::{c_int, c_long, intptr_t, time_t, timespec, uintptr_t};
|
||||
#[cfg(target_os = "netbsd")]
|
||||
use libc::{timespec, time_t, c_long, intptr_t, uintptr_t, size_t};
|
||||
use libc::{c_long, intptr_t, size_t, time_t, timespec, uintptr_t};
|
||||
use std::convert::TryInto;
|
||||
use std::mem;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
@ -18,9 +18,13 @@ pub struct KEvent {
|
|||
kevent: libc::kevent,
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
|
||||
target_os = "ios", target_os = "macos",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
type type_of_udata = *mut libc::c_void;
|
||||
#[cfg(any(target_os = "netbsd"))]
|
||||
type type_of_udata = intptr_t;
|
||||
|
@ -75,13 +79,17 @@ libc_enum! {
|
|||
impl TryFrom<type_of_event_filter>
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
|
||||
target_os = "ios", target_os = "macos",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub type type_of_event_flag = u16;
|
||||
#[cfg(any(target_os = "netbsd"))]
|
||||
pub type type_of_event_flag = u32;
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
pub struct EventFlag: type_of_event_flag {
|
||||
EV_ADD;
|
||||
EV_CLEAR;
|
||||
|
@ -205,27 +213,33 @@ pub fn kqueue() -> Result<RawFd> {
|
|||
Errno::result(res)
|
||||
}
|
||||
|
||||
|
||||
// KEvent can't derive Send because on some operating systems, udata is defined
|
||||
// as a void*. However, KEvent's public API always treats udata as an intptr_t,
|
||||
// which is safe to Send.
|
||||
unsafe impl Send for KEvent {
|
||||
}
|
||||
unsafe impl Send for KEvent {}
|
||||
|
||||
impl KEvent {
|
||||
#[allow(clippy::needless_update)] // Not needless on all platforms.
|
||||
pub fn new(ident: uintptr_t, filter: EventFilter, flags: EventFlag,
|
||||
fflags:FilterFlag, data: intptr_t, udata: intptr_t) -> KEvent {
|
||||
KEvent { kevent: libc::kevent {
|
||||
ident,
|
||||
filter: filter as type_of_event_filter,
|
||||
flags: flags.bits(),
|
||||
fflags: fflags.bits(),
|
||||
// data can be either i64 or intptr_t, depending on platform
|
||||
data: data as _,
|
||||
udata: udata as type_of_udata,
|
||||
.. unsafe { mem::zeroed() }
|
||||
} }
|
||||
#[allow(clippy::needless_update)] // Not needless on all platforms.
|
||||
pub fn new(
|
||||
ident: uintptr_t,
|
||||
filter: EventFilter,
|
||||
flags: EventFlag,
|
||||
fflags: FilterFlag,
|
||||
data: intptr_t,
|
||||
udata: intptr_t,
|
||||
) -> KEvent {
|
||||
KEvent {
|
||||
kevent: libc::kevent {
|
||||
ident,
|
||||
filter: filter as type_of_event_filter,
|
||||
flags: flags.bits(),
|
||||
fflags: fflags.bits(),
|
||||
// data can be either i64 or intptr_t, depending on platform
|
||||
data: data as _,
|
||||
udata: udata as type_of_udata,
|
||||
..unsafe { mem::zeroed() }
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ident(&self) -> uintptr_t {
|
||||
|
@ -253,34 +267,38 @@ impl KEvent {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn kevent(kq: RawFd,
|
||||
changelist: &[KEvent],
|
||||
eventlist: &mut [KEvent],
|
||||
timeout_ms: usize) -> Result<usize> {
|
||||
|
||||
pub fn kevent(
|
||||
kq: RawFd,
|
||||
changelist: &[KEvent],
|
||||
eventlist: &mut [KEvent],
|
||||
timeout_ms: usize,
|
||||
) -> Result<usize> {
|
||||
// Convert ms to timespec
|
||||
let timeout = timespec {
|
||||
tv_sec: (timeout_ms / 1000) as time_t,
|
||||
tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long
|
||||
tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long,
|
||||
};
|
||||
|
||||
kevent_ts(kq, changelist, eventlist, Some(timeout))
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
type type_of_nchanges = c_int;
|
||||
#[cfg(target_os = "netbsd")]
|
||||
type type_of_nchanges = size_t;
|
||||
|
||||
pub fn kevent_ts(kq: RawFd,
|
||||
changelist: &[KEvent],
|
||||
eventlist: &mut [KEvent],
|
||||
timeout_opt: Option<timespec>) -> Result<usize> {
|
||||
|
||||
pub fn kevent_ts(
|
||||
kq: RawFd,
|
||||
changelist: &[KEvent],
|
||||
eventlist: &mut [KEvent],
|
||||
timeout_opt: Option<timespec>,
|
||||
) -> Result<usize> {
|
||||
let res = unsafe {
|
||||
libc::kevent(
|
||||
kq,
|
||||
|
@ -288,40 +306,48 @@ pub fn kevent_ts(kq: RawFd,
|
|||
changelist.len() as type_of_nchanges,
|
||||
eventlist.as_mut_ptr() as *mut libc::kevent,
|
||||
eventlist.len() as type_of_nchanges,
|
||||
if let Some(ref timeout) = timeout_opt {timeout as *const timespec} else {ptr::null()})
|
||||
if let Some(ref timeout) = timeout_opt {
|
||||
timeout as *const timespec
|
||||
} else {
|
||||
ptr::null()
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ev_set(ev: &mut KEvent,
|
||||
ident: usize,
|
||||
filter: EventFilter,
|
||||
flags: EventFlag,
|
||||
fflags: FilterFlag,
|
||||
udata: intptr_t) {
|
||||
|
||||
ev.kevent.ident = ident as uintptr_t;
|
||||
pub fn ev_set(
|
||||
ev: &mut KEvent,
|
||||
ident: usize,
|
||||
filter: EventFilter,
|
||||
flags: EventFlag,
|
||||
fflags: FilterFlag,
|
||||
udata: intptr_t,
|
||||
) {
|
||||
ev.kevent.ident = ident as uintptr_t;
|
||||
ev.kevent.filter = filter as type_of_event_filter;
|
||||
ev.kevent.flags = flags.bits();
|
||||
ev.kevent.flags = flags.bits();
|
||||
ev.kevent.fflags = fflags.bits();
|
||||
ev.kevent.data = 0;
|
||||
ev.kevent.udata = udata as type_of_udata;
|
||||
ev.kevent.data = 0;
|
||||
ev.kevent.udata = udata as type_of_udata;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_struct_kevent() {
|
||||
use std::mem;
|
||||
|
||||
let udata : intptr_t = 12345;
|
||||
let udata: intptr_t = 12345;
|
||||
|
||||
let actual = KEvent::new(0xdead_beef,
|
||||
EventFilter::EVFILT_READ,
|
||||
EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
|
||||
FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
|
||||
0x1337,
|
||||
udata);
|
||||
let actual = KEvent::new(
|
||||
0xdead_beef,
|
||||
EventFilter::EVFILT_READ,
|
||||
EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
|
||||
FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
|
||||
0x1337,
|
||||
udata,
|
||||
);
|
||||
assert_eq!(0xdead_beef, actual.ident());
|
||||
let filter = actual.kevent.filter;
|
||||
assert_eq!(libc::EVFILT_READ, filter);
|
||||
|
@ -334,13 +360,15 @@ fn test_struct_kevent() {
|
|||
|
||||
#[test]
|
||||
fn test_kevent_filter() {
|
||||
let udata : intptr_t = 12345;
|
||||
let udata: intptr_t = 12345;
|
||||
|
||||
let actual = KEvent::new(0xdead_beef,
|
||||
EventFilter::EVFILT_READ,
|
||||
EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
|
||||
FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
|
||||
0x1337,
|
||||
udata);
|
||||
let actual = KEvent::new(
|
||||
0xdead_beef,
|
||||
EventFilter::EVFILT_READ,
|
||||
EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
|
||||
FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
|
||||
0x1337,
|
||||
udata,
|
||||
);
|
||||
assert_eq!(EventFilter::EVFILT_READ, actual.filter().unwrap());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::os::unix::io::RawFd;
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
libc_bitflags! {
|
||||
pub struct EfdFlags: libc::c_int {
|
||||
|
|
|
@ -23,20 +23,17 @@
|
|||
//! }
|
||||
//! ```
|
||||
|
||||
use libc::{
|
||||
c_char,
|
||||
c_int,
|
||||
};
|
||||
use std::ffi::{OsString,OsStr,CStr};
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::mem::{MaybeUninit, size_of};
|
||||
use std::os::unix::io::{RawFd,AsRawFd,FromRawFd};
|
||||
use std::ptr;
|
||||
use crate::unistd::read;
|
||||
use crate::Result;
|
||||
use crate::NixPath;
|
||||
use crate::errno::Errno;
|
||||
use crate::unistd::read;
|
||||
use crate::NixPath;
|
||||
use crate::Result;
|
||||
use cfg_if::cfg_if;
|
||||
use libc::{c_char, c_int};
|
||||
use std::ffi::{CStr, OsStr, OsString};
|
||||
use std::mem::{size_of, MaybeUninit};
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||
use std::ptr;
|
||||
|
||||
libc_bitflags! {
|
||||
/// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html).
|
||||
|
@ -106,7 +103,7 @@ libc_bitflags! {
|
|||
/// other interfaces consuming file descriptors, epoll for example.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Inotify {
|
||||
fd: RawFd
|
||||
fd: RawFd,
|
||||
}
|
||||
|
||||
/// This object is returned when you create a new watch on an inotify instance.
|
||||
|
@ -114,7 +111,7 @@ pub struct Inotify {
|
|||
/// know which watch triggered which event.
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct WatchDescriptor {
|
||||
wd: i32
|
||||
wd: i32,
|
||||
}
|
||||
|
||||
/// A single inotify event.
|
||||
|
@ -134,7 +131,7 @@ pub struct InotifyEvent {
|
|||
pub cookie: u32,
|
||||
/// Filename. This field exists only if the event was triggered for a file
|
||||
/// inside the watched directory.
|
||||
pub name: Option<OsString>
|
||||
pub name: Option<OsString>,
|
||||
}
|
||||
|
||||
impl Inotify {
|
||||
|
@ -144,9 +141,7 @@ impl Inotify {
|
|||
///
|
||||
/// For more information see, [inotify_init(2)](https://man7.org/linux/man-pages/man2/inotify_init.2.html).
|
||||
pub fn init(flags: InitFlags) -> Result<Inotify> {
|
||||
let res = Errno::result(unsafe {
|
||||
libc::inotify_init1(flags.bits())
|
||||
});
|
||||
let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) });
|
||||
|
||||
res.map(|fd| Inotify { fd })
|
||||
}
|
||||
|
@ -156,15 +151,13 @@ impl Inotify {
|
|||
/// Returns a watch descriptor. This is not a File Descriptor!
|
||||
///
|
||||
/// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
|
||||
pub fn add_watch<P: ?Sized + NixPath>(self,
|
||||
path: &P,
|
||||
mask: AddWatchFlags)
|
||||
-> Result<WatchDescriptor>
|
||||
{
|
||||
let res = path.with_nix_path(|cstr| {
|
||||
unsafe {
|
||||
libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
|
||||
}
|
||||
pub fn add_watch<P: ?Sized + NixPath>(
|
||||
self,
|
||||
path: &P,
|
||||
mask: AddWatchFlags,
|
||||
) -> Result<WatchDescriptor> {
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
|
||||
})?;
|
||||
|
||||
Errno::result(res).map(|wd| WatchDescriptor { wd })
|
||||
|
@ -210,7 +203,7 @@ impl Inotify {
|
|||
ptr::copy_nonoverlapping(
|
||||
buffer.as_ptr().add(offset),
|
||||
event.as_mut_ptr() as *mut u8,
|
||||
(BUFSIZ - offset).min(header_size)
|
||||
(BUFSIZ - offset).min(header_size),
|
||||
);
|
||||
event.assume_init()
|
||||
};
|
||||
|
@ -219,9 +212,7 @@ impl Inotify {
|
|||
0 => None,
|
||||
_ => {
|
||||
let ptr = unsafe {
|
||||
buffer
|
||||
.as_ptr()
|
||||
.add(offset + header_size)
|
||||
buffer.as_ptr().add(offset + header_size)
|
||||
as *const c_char
|
||||
};
|
||||
let cstr = unsafe { CStr::from_ptr(ptr) };
|
||||
|
@ -234,7 +225,7 @@ impl Inotify {
|
|||
wd: WatchDescriptor { wd: event.wd },
|
||||
mask: AddWatchFlags::from_bits_truncate(event.mask),
|
||||
cookie: event.cookie,
|
||||
name
|
||||
name,
|
||||
});
|
||||
|
||||
offset += header_size + event.len as usize;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
//! Interfaces for managing memory-backed files.
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use std::os::unix::io::RawFd;
|
||||
use crate::Result;
|
||||
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
use std::ffi::CStr;
|
||||
|
||||
libc_bitflags!(
|
||||
|
@ -40,7 +42,22 @@ libc_bitflags!(
|
|||
/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
|
||||
pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
|
||||
let res = unsafe {
|
||||
libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits())
|
||||
cfg_if! {
|
||||
if #[cfg(all(
|
||||
// Android does not have a memfd_create symbol
|
||||
not(target_os = "android"),
|
||||
any(
|
||||
target_os = "freebsd",
|
||||
// If the OS is Linux, gnu and musl expose a memfd_create symbol but not uclibc
|
||||
target_env = "gnu",
|
||||
target_env = "musl",
|
||||
)))]
|
||||
{
|
||||
libc::memfd_create(name.as_ptr(), flags.bits())
|
||||
} else {
|
||||
libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as RawFd)
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
//! Memory management declarations.
|
||||
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
use crate::NixPath;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
#[cfg(feature = "fs")]
|
||||
use crate::{fcntl::OFlag, sys::stat::Mode};
|
||||
use libc::{self, c_int, c_void, size_t, off_t};
|
||||
use std::os::unix::io::RawFd;
|
||||
use libc::{self, c_int, c_void, off_t, size_t};
|
||||
use std::{os::unix::io::RawFd, num::NonZeroUsize};
|
||||
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
/// Desired memory protection of a memory mapping.
|
||||
pub struct ProtFlags: c_int {
|
||||
/// Pages cannot be accessed.
|
||||
|
@ -32,7 +32,7 @@ libc_bitflags!{
|
|||
}
|
||||
}
|
||||
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
/// Additional parameters for [`mmap`].
|
||||
pub struct MapFlags: c_int {
|
||||
/// Compatibility flag. Ignored.
|
||||
|
@ -188,7 +188,7 @@ libc_bitflags!{
|
|||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "netbsd"))]
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
/// Options for [`mremap`].
|
||||
pub struct MRemapFlags: c_int {
|
||||
/// Permit the kernel to relocate the mapping to a new virtual address, if necessary.
|
||||
|
@ -210,7 +210,7 @@ libc_bitflags!{
|
|||
}
|
||||
}
|
||||
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
/// Usage information for a range of memory to allow for performance optimizations by the kernel.
|
||||
///
|
||||
/// Used by [`madvise`].
|
||||
|
@ -331,7 +331,7 @@ libc_enum!{
|
|||
}
|
||||
}
|
||||
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
/// Configuration flags for [`msync`].
|
||||
pub struct MsFlags: c_int {
|
||||
/// Schedule an update but return immediately.
|
||||
|
@ -352,7 +352,7 @@ libc_bitflags!{
|
|||
}
|
||||
|
||||
#[cfg(not(target_os = "haiku"))]
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
/// Flags for [`mlockall`].
|
||||
pub struct MlockAllFlags: c_int {
|
||||
/// Lock pages that are currently mapped into the address space of the process.
|
||||
|
@ -416,8 +416,20 @@ pub fn munlockall() -> Result<()> {
|
|||
/// See the [`mmap(2)`] man page for detailed requirements.
|
||||
///
|
||||
/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||
pub unsafe fn mmap(addr: *mut c_void, length: size_t, prot: ProtFlags, flags: MapFlags, fd: RawFd, offset: off_t) -> Result<*mut c_void> {
|
||||
let ret = libc::mmap(addr, length, prot.bits(), flags.bits(), fd, offset);
|
||||
pub unsafe fn mmap(
|
||||
addr: Option<NonZeroUsize>,
|
||||
length: NonZeroUsize,
|
||||
prot: ProtFlags,
|
||||
flags: MapFlags,
|
||||
fd: RawFd,
|
||||
offset: off_t,
|
||||
) -> Result<*mut c_void> {
|
||||
let ptr = addr.map_or(
|
||||
std::ptr::null_mut(),
|
||||
|a| usize::from(a) as *mut c_void
|
||||
);
|
||||
|
||||
let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset);
|
||||
|
||||
if ret == libc::MAP_FAILED {
|
||||
Err(Errno::last())
|
||||
|
@ -439,10 +451,16 @@ pub unsafe fn mremap(
|
|||
old_size: size_t,
|
||||
new_size: size_t,
|
||||
flags: MRemapFlags,
|
||||
new_address: Option<* mut c_void>,
|
||||
new_address: Option<*mut c_void>,
|
||||
) -> Result<*mut c_void> {
|
||||
#[cfg(target_os = "linux")]
|
||||
let ret = libc::mremap(addr, old_size, new_size, flags.bits(), new_address.unwrap_or(std::ptr::null_mut()));
|
||||
let ret = libc::mremap(
|
||||
addr,
|
||||
old_size,
|
||||
new_size,
|
||||
flags.bits(),
|
||||
new_address.unwrap_or(std::ptr::null_mut()),
|
||||
);
|
||||
#[cfg(target_os = "netbsd")]
|
||||
let ret = libc::mremap(
|
||||
addr,
|
||||
|
@ -450,7 +468,7 @@ pub unsafe fn mremap(
|
|||
new_address.unwrap_or(std::ptr::null_mut()),
|
||||
new_size,
|
||||
flags.bits(),
|
||||
);
|
||||
);
|
||||
|
||||
if ret == libc::MAP_FAILED {
|
||||
Err(Errno::last())
|
||||
|
@ -479,7 +497,11 @@ pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
|
|||
/// [`MmapAdvise::MADV_FREE`].
|
||||
///
|
||||
/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html
|
||||
pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) -> Result<()> {
|
||||
pub unsafe fn madvise(
|
||||
addr: *mut c_void,
|
||||
length: size_t,
|
||||
advise: MmapAdvise,
|
||||
) -> Result<()> {
|
||||
Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
|
||||
}
|
||||
|
||||
|
@ -498,8 +520,9 @@ pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) ->
|
|||
/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
|
||||
/// # use std::ptr;
|
||||
/// const ONE_K: size_t = 1024;
|
||||
/// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap();
|
||||
/// let mut slice: &mut [u8] = unsafe {
|
||||
/// let mem = mmap(ptr::null_mut(), ONE_K, ProtFlags::PROT_NONE,
|
||||
/// let mem = mmap(None, one_k_non_zero, ProtFlags::PROT_NONE,
|
||||
/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap();
|
||||
/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
|
||||
/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
|
||||
|
@ -508,7 +531,11 @@ pub unsafe fn madvise(addr: *mut c_void, length: size_t, advise: MmapAdvise) ->
|
|||
/// slice[0] = 0xFF;
|
||||
/// assert_eq!(slice[0], 0xFF);
|
||||
/// ```
|
||||
pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Result<()> {
|
||||
pub unsafe fn mprotect(
|
||||
addr: *mut c_void,
|
||||
length: size_t,
|
||||
prot: ProtFlags,
|
||||
) -> Result<()> {
|
||||
Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
|
||||
}
|
||||
|
||||
|
@ -520,7 +547,11 @@ pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: ProtFlags) -> Re
|
|||
/// page.
|
||||
///
|
||||
/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html
|
||||
pub unsafe fn msync(addr: *mut c_void, length: size_t, flags: MsFlags) -> Result<()> {
|
||||
pub unsafe fn msync(
|
||||
addr: *mut c_void,
|
||||
length: size_t,
|
||||
flags: MsFlags,
|
||||
) -> Result<()> {
|
||||
Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
|
||||
}
|
||||
|
||||
|
@ -561,9 +592,8 @@ pub fn shm_open<P>(
|
|||
/// [`shm_unlink(3)`]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html
|
||||
#[cfg(not(target_os = "android"))]
|
||||
pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
|
||||
let ret = name.with_nix_path(|cstr| {
|
||||
unsafe { libc::shm_unlink(cstr.as_ptr()) }
|
||||
})?;
|
||||
let ret =
|
||||
name.with_nix_path(|cstr| unsafe { libc::shm_unlink(cstr.as_ptr()) })?;
|
||||
|
||||
Errno::result(ret).map(drop)
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ feature! {
|
|||
#[macro_use]
|
||||
pub mod ioctl;
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
feature! {
|
||||
#![feature = "fs"]
|
||||
pub mod memfd;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Process execution domains
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
|
||||
use libc::{self, c_int, c_ulong};
|
||||
|
||||
|
@ -62,9 +62,7 @@ libc_bitflags! {
|
|||
/// assert!(!pers.contains(Persona::WHOLE_SECONDS));
|
||||
/// ```
|
||||
pub fn get() -> Result<Persona> {
|
||||
let res = unsafe {
|
||||
libc::personality(0xFFFFFFFF)
|
||||
};
|
||||
let res = unsafe { libc::personality(0xFFFFFFFF) };
|
||||
|
||||
Errno::result(res).map(Persona::from_bits_truncate)
|
||||
}
|
||||
|
@ -89,9 +87,7 @@ pub fn get() -> Result<Persona> {
|
|||
/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE).unwrap();
|
||||
/// ```
|
||||
pub fn set(persona: Persona) -> Result<Persona> {
|
||||
let res = unsafe {
|
||||
libc::personality(persona.bits() as c_ulong)
|
||||
};
|
||||
let res = unsafe { libc::personality(persona.bits() as c_ulong) };
|
||||
|
||||
Errno::result(res).map(Persona::from_bits_truncate)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use cfg_if::cfg_if;
|
||||
use crate::errno::Errno;
|
||||
use libc::{self, c_int};
|
||||
use std::ptr;
|
||||
use crate::sys::signal::Signal;
|
||||
use crate::unistd::Pid;
|
||||
use crate::Result;
|
||||
use cfg_if::cfg_if;
|
||||
use libc::{self, c_int};
|
||||
use std::ptr;
|
||||
|
||||
pub type RequestType = c_int;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
if #[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "openbsd"))] {
|
||||
#[doc(hidden)]
|
||||
|
@ -71,7 +71,8 @@ unsafe fn ptrace_other(
|
|||
libc::pid_t::from(pid),
|
||||
addr,
|
||||
data,
|
||||
)).map(|_| 0)
|
||||
))
|
||||
.map(|_| 0)
|
||||
}
|
||||
|
||||
/// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)`
|
||||
|
@ -79,14 +80,19 @@ unsafe fn ptrace_other(
|
|||
/// Indicates that this process is to be traced by its parent.
|
||||
/// This is the only ptrace request to be issued by the tracee.
|
||||
pub fn traceme() -> Result<()> {
|
||||
unsafe { ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0).map(drop) }
|
||||
unsafe {
|
||||
ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0)
|
||||
.map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
/// Attach to a running process, as with `ptrace(PT_ATTACH, ...)`
|
||||
///
|
||||
/// Attaches to the process specified by `pid`, making it a tracee of the calling process.
|
||||
pub fn attach(pid: Pid) -> Result<()> {
|
||||
unsafe { ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop) }
|
||||
unsafe {
|
||||
ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
/// Detaches the current running process, as with `ptrace(PT_DETACH, ...)`
|
||||
|
@ -114,13 +120,14 @@ pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
};
|
||||
unsafe {
|
||||
// Ignore the useless return value
|
||||
ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data).map(drop)
|
||||
ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data)
|
||||
.map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
/// Issues a kill request as with `ptrace(PT_KILL, ...)`
|
||||
///
|
||||
/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);`
|
||||
/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);`
|
||||
pub fn kill(pid: Pid) -> Result<()> {
|
||||
unsafe {
|
||||
ptrace_other(Request::PT_KILL, pid, 0 as AddressType, 0).map(drop)
|
||||
|
@ -149,21 +156,22 @@ pub fn kill(pid: Pid) -> Result<()> {
|
|||
/// _ => {},
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(
|
||||
any(
|
||||
any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"),
|
||||
all(target_os = "openbsd", target_arch = "x86_64"),
|
||||
all(target_os = "netbsd",
|
||||
any(target_arch = "x86_64", target_arch = "powerpc")
|
||||
)
|
||||
#[cfg(any(
|
||||
any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"),
|
||||
all(target_os = "openbsd", target_arch = "x86_64"),
|
||||
all(
|
||||
target_os = "netbsd",
|
||||
any(target_arch = "x86_64", target_arch = "powerpc")
|
||||
)
|
||||
)]
|
||||
))]
|
||||
pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
||||
let data = match sig.into() {
|
||||
Some(s) => s as c_int,
|
||||
None => 0,
|
||||
};
|
||||
unsafe { ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop) }
|
||||
unsafe {
|
||||
ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a word from a processes memory at the given address
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
//! For detailed description of the ptrace requests, consult `man ptrace`.
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use std::{mem, ptr};
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use libc::{self, c_void, c_long, siginfo_t};
|
||||
use crate::unistd::Pid;
|
||||
use crate::sys::signal::Signal;
|
||||
use crate::unistd::Pid;
|
||||
use crate::Result;
|
||||
use cfg_if::cfg_if;
|
||||
use libc::{self, c_long, c_void, siginfo_t};
|
||||
use std::{mem, ptr};
|
||||
|
||||
pub type AddressType = *mut ::libc::c_void;
|
||||
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
any(all(target_arch = "x86_64",
|
||||
any(target_env = "gnu", target_env = "musl")),
|
||||
all(target_arch = "x86", target_env = "gnu"))
|
||||
any(
|
||||
all(
|
||||
target_arch = "x86_64",
|
||||
any(target_env = "gnu", target_env = "musl")
|
||||
),
|
||||
all(target_arch = "x86", target_env = "gnu")
|
||||
)
|
||||
))]
|
||||
use libc::user_regs_struct;
|
||||
|
||||
|
@ -30,7 +34,7 @@ cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
#[cfg_attr(not(any(target_env = "musl", target_env = "uclibc", target_os = "android")), repr(u32))]
|
||||
#[cfg_attr(any(target_env = "musl", target_env = "uclibc", target_os = "android"), repr(i32))]
|
||||
/// Ptrace Request enum defining the action to be taken.
|
||||
|
@ -120,7 +124,7 @@ libc_enum!{
|
|||
}
|
||||
}
|
||||
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
#[repr(i32)]
|
||||
/// Using the ptrace options the tracer can configure the tracee to stop
|
||||
/// at certain events. This enum is used to define those events as defined
|
||||
|
@ -178,7 +182,12 @@ libc_bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
|
||||
fn ptrace_peek(
|
||||
request: Request,
|
||||
pid: Pid,
|
||||
addr: AddressType,
|
||||
data: *mut c_void,
|
||||
) -> Result<c_long> {
|
||||
let ret = unsafe {
|
||||
Errno::clear();
|
||||
libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)
|
||||
|
@ -192,9 +201,13 @@ fn ptrace_peek(request: Request, pid: Pid, addr: AddressType, data: *mut c_void)
|
|||
/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
any(all(target_arch = "x86_64",
|
||||
any(target_env = "gnu", target_env = "musl")),
|
||||
all(target_arch = "x86", target_env = "gnu"))
|
||||
any(
|
||||
all(
|
||||
target_arch = "x86_64",
|
||||
any(target_env = "gnu", target_env = "musl")
|
||||
),
|
||||
all(target_arch = "x86", target_env = "gnu")
|
||||
)
|
||||
))]
|
||||
pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
|
||||
ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
|
||||
|
@ -203,16 +216,22 @@ pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
|
|||
/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
any(all(target_arch = "x86_64",
|
||||
any(target_env = "gnu", target_env = "musl")),
|
||||
all(target_arch = "x86", target_env = "gnu"))
|
||||
any(
|
||||
all(
|
||||
target_arch = "x86_64",
|
||||
any(target_env = "gnu", target_env = "musl")
|
||||
),
|
||||
all(target_arch = "x86", target_env = "gnu")
|
||||
)
|
||||
))]
|
||||
pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
|
||||
let res = unsafe {
|
||||
libc::ptrace(Request::PTRACE_SETREGS as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<c_void>(),
|
||||
®s as *const _ as *const c_void)
|
||||
libc::ptrace(
|
||||
Request::PTRACE_SETREGS as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<c_void>(),
|
||||
®s as *const _ as *const c_void,
|
||||
)
|
||||
};
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
@ -224,26 +243,41 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
|
|||
fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
|
||||
let mut data = mem::MaybeUninit::uninit();
|
||||
let res = unsafe {
|
||||
libc::ptrace(request as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<T>(),
|
||||
data.as_mut_ptr() as *const _ as *const c_void)
|
||||
libc::ptrace(
|
||||
request as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<T>(),
|
||||
data.as_mut_ptr() as *const _ as *const c_void,
|
||||
)
|
||||
};
|
||||
Errno::result(res)?;
|
||||
Ok(unsafe{ data.assume_init() })
|
||||
Ok(unsafe { data.assume_init() })
|
||||
}
|
||||
|
||||
unsafe fn ptrace_other(request: Request, pid: Pid, addr: AddressType, data: *mut c_void) -> Result<c_long> {
|
||||
Errno::result(libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)).map(|_| 0)
|
||||
unsafe fn ptrace_other(
|
||||
request: Request,
|
||||
pid: Pid,
|
||||
addr: AddressType,
|
||||
data: *mut c_void,
|
||||
) -> Result<c_long> {
|
||||
Errno::result(libc::ptrace(
|
||||
request as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
addr,
|
||||
data,
|
||||
))
|
||||
.map(|_| 0)
|
||||
}
|
||||
|
||||
/// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`.
|
||||
pub fn setoptions(pid: Pid, options: Options) -> Result<()> {
|
||||
let res = unsafe {
|
||||
libc::ptrace(Request::PTRACE_SETOPTIONS as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<c_void>(),
|
||||
options.bits() as *mut c_void)
|
||||
libc::ptrace(
|
||||
Request::PTRACE_SETOPTIONS as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<c_void>(),
|
||||
options.bits() as *mut c_void,
|
||||
)
|
||||
};
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
@ -260,12 +294,14 @@ pub fn getsiginfo(pid: Pid) -> Result<siginfo_t> {
|
|||
|
||||
/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)`
|
||||
pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> {
|
||||
let ret = unsafe{
|
||||
let ret = unsafe {
|
||||
Errno::clear();
|
||||
libc::ptrace(Request::PTRACE_SETSIGINFO as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<c_void>(),
|
||||
sig as *const _ as *const c_void)
|
||||
libc::ptrace(
|
||||
Request::PTRACE_SETSIGINFO as RequestType,
|
||||
libc::pid_t::from(pid),
|
||||
ptr::null_mut::<c_void>(),
|
||||
sig as *const _ as *const c_void,
|
||||
)
|
||||
};
|
||||
match Errno::result(ret) {
|
||||
Ok(_) => Ok(()),
|
||||
|
@ -284,7 +320,8 @@ pub fn traceme() -> Result<()> {
|
|||
Pid::from_raw(0),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
).map(drop) // ignore the useless return value
|
||||
)
|
||||
.map(drop) // ignore the useless return value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,12 +335,8 @@ pub fn syscall<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
None => ptr::null_mut(),
|
||||
};
|
||||
unsafe {
|
||||
ptrace_other(
|
||||
Request::PTRACE_SYSCALL,
|
||||
pid,
|
||||
ptr::null_mut(),
|
||||
data,
|
||||
).map(drop) // ignore the useless return value
|
||||
ptrace_other(Request::PTRACE_SYSCALL, pid, ptr::null_mut(), data)
|
||||
.map(drop) // ignore the useless return value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,14 +345,19 @@ pub fn syscall<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
/// In contrast to the `syscall` function, the syscall stopped at will not be executed.
|
||||
/// Thus the the tracee will only be stopped once per syscall,
|
||||
/// optionally delivering a signal specified by `sig`.
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
target_env = "gnu",
|
||||
any(target_arch = "x86", target_arch = "x86_64")
|
||||
))]
|
||||
pub fn sysemu<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
||||
let data = match sig.into() {
|
||||
Some(s) => s as i32 as *mut c_void,
|
||||
None => ptr::null_mut(),
|
||||
};
|
||||
unsafe {
|
||||
ptrace_other(Request::PTRACE_SYSEMU, pid, ptr::null_mut(), data).map(drop)
|
||||
ptrace_other(Request::PTRACE_SYSEMU, pid, ptr::null_mut(), data)
|
||||
.map(drop)
|
||||
// ignore the useless return value
|
||||
}
|
||||
}
|
||||
|
@ -334,7 +372,8 @@ pub fn attach(pid: Pid) -> Result<()> {
|
|||
pid,
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
).map(drop) // ignore the useless return value
|
||||
)
|
||||
.map(drop) // ignore the useless return value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,7 +389,8 @@ pub fn seize(pid: Pid, options: Options) -> Result<()> {
|
|||
pid,
|
||||
ptr::null_mut(),
|
||||
options.bits() as *mut c_void,
|
||||
).map(drop) // ignore the useless return value
|
||||
)
|
||||
.map(drop) // ignore the useless return value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,12 +404,8 @@ pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
None => ptr::null_mut(),
|
||||
};
|
||||
unsafe {
|
||||
ptrace_other(
|
||||
Request::PTRACE_DETACH,
|
||||
pid,
|
||||
ptr::null_mut(),
|
||||
data
|
||||
).map(drop)
|
||||
ptrace_other(Request::PTRACE_DETACH, pid, ptr::null_mut(), data)
|
||||
.map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,7 +419,8 @@ pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
None => ptr::null_mut(),
|
||||
};
|
||||
unsafe {
|
||||
ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop) // ignore the useless return value
|
||||
ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop)
|
||||
// ignore the useless return value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +431,13 @@ pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn interrupt(pid: Pid) -> Result<()> {
|
||||
unsafe {
|
||||
ptrace_other(Request::PTRACE_INTERRUPT, pid, ptr::null_mut(), ptr::null_mut()).map(drop)
|
||||
ptrace_other(
|
||||
Request::PTRACE_INTERRUPT,
|
||||
pid,
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,7 +446,13 @@ pub fn interrupt(pid: Pid) -> Result<()> {
|
|||
/// This request is equivalent to `ptrace(PTRACE_CONT, ..., SIGKILL);`
|
||||
pub fn kill(pid: Pid) -> Result<()> {
|
||||
unsafe {
|
||||
ptrace_other(Request::PTRACE_KILL, pid, ptr::null_mut(), ptr::null_mut()).map(drop)
|
||||
ptrace_other(
|
||||
Request::PTRACE_KILL,
|
||||
pid,
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,7 +485,8 @@ pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
None => ptr::null_mut(),
|
||||
};
|
||||
unsafe {
|
||||
ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data).map(drop)
|
||||
ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data)
|
||||
.map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,7 +496,11 @@ pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
|||
/// Advances the execution by a single step or until the next syscall.
|
||||
/// In case the tracee is stopped at a syscall, the syscall will not be executed.
|
||||
/// Optionally, the signal specified by `sig` is delivered to the tracee upon continuation.
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu", any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
target_env = "gnu",
|
||||
any(target_arch = "x86", target_arch = "x86_64")
|
||||
))]
|
||||
pub fn sysemu_step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
|
||||
let data = match sig.into() {
|
||||
Some(s) => s as i32 as *mut c_void,
|
||||
|
@ -477,8 +531,8 @@ pub fn read(pid: Pid, addr: AddressType) -> Result<c_long> {
|
|||
pub unsafe fn write(
|
||||
pid: Pid,
|
||||
addr: AddressType,
|
||||
data: *mut c_void) -> Result<()>
|
||||
{
|
||||
data: *mut c_void,
|
||||
) -> Result<()> {
|
||||
ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
|
||||
}
|
||||
|
||||
|
@ -498,7 +552,7 @@ pub fn read_user(pid: Pid, offset: AddressType) -> Result<c_long> {
|
|||
pub unsafe fn write_user(
|
||||
pid: Pid,
|
||||
offset: AddressType,
|
||||
data: *mut c_void) -> Result<()>
|
||||
{
|
||||
data: *mut c_void,
|
||||
) -> Result<()> {
|
||||
ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
///! Provides helpers for making ptrace system calls
|
||||
///! Provides helpers for making ptrace system calls
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
mod linux;
|
||||
|
@ -6,17 +6,20 @@ mod linux;
|
|||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub use self::linux::*;
|
||||
|
||||
#[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
mod bsd;
|
||||
|
||||
#[cfg(any(target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub use self::bsd::*;
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
//! dqblk.set_blocks_soft_limit(8000);
|
||||
//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS).unwrap();
|
||||
//! ```
|
||||
use crate::errno::Errno;
|
||||
use crate::{NixPath, Result};
|
||||
use libc::{self, c_char, c_int};
|
||||
use std::default::Default;
|
||||
use std::{mem, ptr};
|
||||
use libc::{self, c_int, c_char};
|
||||
use crate::{Result, NixPath};
|
||||
use crate::errno::Errno;
|
||||
|
||||
struct QuotaCmd(QuotaSubCmd, QuotaType);
|
||||
|
||||
|
@ -28,7 +28,7 @@ impl QuotaCmd {
|
|||
}
|
||||
|
||||
// linux quota version >= 2
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
#[repr(i32)]
|
||||
enum QuotaSubCmd {
|
||||
Q_SYNC,
|
||||
|
@ -39,7 +39,7 @@ libc_enum!{
|
|||
}
|
||||
}
|
||||
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
/// The scope of the quota.
|
||||
#[repr(i32)]
|
||||
#[non_exhaustive]
|
||||
|
@ -51,7 +51,7 @@ libc_enum!{
|
|||
}
|
||||
}
|
||||
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
/// The type of quota format to use.
|
||||
#[repr(i32)]
|
||||
#[non_exhaustive]
|
||||
|
@ -120,7 +120,8 @@ impl Default for Dqblk {
|
|||
impl Dqblk {
|
||||
/// The absolute limit on disk quota blocks allocated.
|
||||
pub fn blocks_hard_limit(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
|
||||
Some(self.0.dqb_bhardlimit)
|
||||
} else {
|
||||
|
@ -135,7 +136,8 @@ impl Dqblk {
|
|||
|
||||
/// Preferred limit on disk quota blocks
|
||||
pub fn blocks_soft_limit(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
|
||||
Some(self.0.dqb_bsoftlimit)
|
||||
} else {
|
||||
|
@ -150,7 +152,8 @@ impl Dqblk {
|
|||
|
||||
/// Current occupied space (bytes).
|
||||
pub fn occupied_space(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_SPACE) {
|
||||
Some(self.0.dqb_curspace)
|
||||
} else {
|
||||
|
@ -160,7 +163,8 @@ impl Dqblk {
|
|||
|
||||
/// Maximum number of allocated inodes.
|
||||
pub fn inodes_hard_limit(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
|
||||
Some(self.0.dqb_ihardlimit)
|
||||
} else {
|
||||
|
@ -175,7 +179,8 @@ impl Dqblk {
|
|||
|
||||
/// Preferred inode limit
|
||||
pub fn inodes_soft_limit(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
|
||||
Some(self.0.dqb_isoftlimit)
|
||||
} else {
|
||||
|
@ -190,7 +195,8 @@ impl Dqblk {
|
|||
|
||||
/// Current number of allocated inodes.
|
||||
pub fn allocated_inodes(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_INODES) {
|
||||
Some(self.0.dqb_curinodes)
|
||||
} else {
|
||||
|
@ -200,7 +206,8 @@ impl Dqblk {
|
|||
|
||||
/// Time limit for excessive disk use.
|
||||
pub fn block_time_limit(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_BTIME) {
|
||||
Some(self.0.dqb_btime)
|
||||
} else {
|
||||
|
@ -215,7 +222,8 @@ impl Dqblk {
|
|||
|
||||
/// Time limit for excessive files.
|
||||
pub fn inode_time_limit(&self) -> Option<u64> {
|
||||
let valid_fields = QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
let valid_fields =
|
||||
QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
|
||||
if valid_fields.contains(QuotaValidFlags::QIF_ITIME) {
|
||||
Some(self.0.dqb_itime)
|
||||
} else {
|
||||
|
@ -229,11 +237,18 @@ impl Dqblk {
|
|||
}
|
||||
}
|
||||
|
||||
fn quotactl<P: ?Sized + NixPath>(cmd: QuotaCmd, special: Option<&P>, id: c_int, addr: *mut c_char) -> Result<()> {
|
||||
fn quotactl<P: ?Sized + NixPath>(
|
||||
cmd: QuotaCmd,
|
||||
special: Option<&P>,
|
||||
id: c_int,
|
||||
addr: *mut c_char,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
Errno::clear();
|
||||
let res = match special {
|
||||
Some(dev) => dev.with_nix_path(|path| libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)),
|
||||
Some(dev) => dev.with_nix_path(|path| {
|
||||
libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)
|
||||
}),
|
||||
None => Ok(libc::quotactl(cmd.as_int(), ptr::null(), id, addr)),
|
||||
}?;
|
||||
|
||||
|
@ -242,36 +257,82 @@ fn quotactl<P: ?Sized + NixPath>(cmd: QuotaCmd, special: Option<&P>, id: c_int,
|
|||
}
|
||||
|
||||
/// Turn on disk quotas for a block device.
|
||||
pub fn quotactl_on<P: ?Sized + NixPath>(which: QuotaType, special: &P, format: QuotaFmt, quota_file: &P) -> Result<()> {
|
||||
pub fn quotactl_on<P: ?Sized + NixPath>(
|
||||
which: QuotaType,
|
||||
special: &P,
|
||||
format: QuotaFmt,
|
||||
quota_file: &P,
|
||||
) -> Result<()> {
|
||||
quota_file.with_nix_path(|path| {
|
||||
let mut path_copy = path.to_bytes_with_nul().to_owned();
|
||||
let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char;
|
||||
quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAON, which), Some(special), format as c_int, p)
|
||||
quotactl(
|
||||
QuotaCmd(QuotaSubCmd::Q_QUOTAON, which),
|
||||
Some(special),
|
||||
format as c_int,
|
||||
p,
|
||||
)
|
||||
})?
|
||||
}
|
||||
|
||||
/// Disable disk quotas for a block device.
|
||||
pub fn quotactl_off<P: ?Sized + NixPath>(which: QuotaType, special: &P) -> Result<()> {
|
||||
quotactl(QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which), Some(special), 0, ptr::null_mut())
|
||||
pub fn quotactl_off<P: ?Sized + NixPath>(
|
||||
which: QuotaType,
|
||||
special: &P,
|
||||
) -> Result<()> {
|
||||
quotactl(
|
||||
QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which),
|
||||
Some(special),
|
||||
0,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Update the on-disk copy of quota usages for a filesystem.
|
||||
///
|
||||
/// If `special` is `None`, then all file systems with active quotas are sync'd.
|
||||
pub fn quotactl_sync<P: ?Sized + NixPath>(which: QuotaType, special: Option<&P>) -> Result<()> {
|
||||
quotactl(QuotaCmd(QuotaSubCmd::Q_SYNC, which), special, 0, ptr::null_mut())
|
||||
pub fn quotactl_sync<P: ?Sized + NixPath>(
|
||||
which: QuotaType,
|
||||
special: Option<&P>,
|
||||
) -> Result<()> {
|
||||
quotactl(
|
||||
QuotaCmd(QuotaSubCmd::Q_SYNC, which),
|
||||
special,
|
||||
0,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get disk quota limits and current usage for the given user/group id.
|
||||
pub fn quotactl_get<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int) -> Result<Dqblk> {
|
||||
pub fn quotactl_get<P: ?Sized + NixPath>(
|
||||
which: QuotaType,
|
||||
special: &P,
|
||||
id: c_int,
|
||||
) -> Result<Dqblk> {
|
||||
let mut dqblk = mem::MaybeUninit::uninit();
|
||||
quotactl(QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which), Some(special), id, dqblk.as_mut_ptr() as *mut c_char)?;
|
||||
Ok(unsafe{ Dqblk(dqblk.assume_init())})
|
||||
quotactl(
|
||||
QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which),
|
||||
Some(special),
|
||||
id,
|
||||
dqblk.as_mut_ptr() as *mut c_char,
|
||||
)?;
|
||||
Ok(unsafe { Dqblk(dqblk.assume_init()) })
|
||||
}
|
||||
|
||||
/// Configure quota values for the specified fields for a given user/group id.
|
||||
pub fn quotactl_set<P: ?Sized + NixPath>(which: QuotaType, special: &P, id: c_int, dqblk: &Dqblk, fields: QuotaValidFlags) -> Result<()> {
|
||||
pub fn quotactl_set<P: ?Sized + NixPath>(
|
||||
which: QuotaType,
|
||||
special: &P,
|
||||
id: c_int,
|
||||
dqblk: &Dqblk,
|
||||
fields: QuotaValidFlags,
|
||||
) -> Result<()> {
|
||||
let mut dqblk_copy = *dqblk;
|
||||
dqblk_copy.0.dqb_valid = fields.bits();
|
||||
quotactl(QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which), Some(special), id, &mut dqblk_copy as *mut _ as *mut c_char)
|
||||
quotactl(
|
||||
QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which),
|
||||
Some(special),
|
||||
id,
|
||||
&mut dqblk_copy as *mut _ as *mut c_char,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
|
||||
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
use std::convert::Infallible;
|
||||
use std::mem::drop;
|
||||
|
||||
|
@ -30,9 +30,7 @@ libc_enum! {
|
|||
|
||||
/// Reboots or shuts down the system.
|
||||
pub fn reboot(how: RebootMode) -> Result<Infallible> {
|
||||
unsafe {
|
||||
libc::reboot(how as libc::c_int)
|
||||
};
|
||||
unsafe { libc::reboot(how as libc::c_int) };
|
||||
Err(Errno::last())
|
||||
}
|
||||
|
||||
|
@ -45,8 +43,6 @@ pub fn set_cad_enabled(enable: bool) -> Result<()> {
|
|||
} else {
|
||||
libc::RB_DISABLE_CAD
|
||||
};
|
||||
let res = unsafe {
|
||||
libc::reboot(cmd)
|
||||
};
|
||||
let res = unsafe { libc::reboot(cmd) };
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::errno::Errno;
|
|||
use crate::sys::time::TimeVal;
|
||||
use crate::Result;
|
||||
pub use libc::rlim_t;
|
||||
pub use libc::RLIM_INFINITY;
|
||||
use std::mem;
|
||||
|
||||
cfg_if! {
|
||||
|
@ -175,7 +176,7 @@ libc_enum! {
|
|||
|
||||
/// Get the current processes resource limits
|
||||
///
|
||||
/// The special value `RLIM_INFINITY` indicates that no limit will be
|
||||
/// The special value [`RLIM_INFINITY`] indicates that no limit will be
|
||||
/// enforced.
|
||||
///
|
||||
/// # Parameters
|
||||
|
@ -224,7 +225,7 @@ pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> {
|
|||
/// * `hard_limit`: The ceiling for the soft limit. Must be lower or equal to
|
||||
/// the current hard limit for non-root users.
|
||||
///
|
||||
/// The special value `RLIM_INFINITY` indicates that no limit will be
|
||||
/// The special value [`RLIM_INFINITY`] indicates that no limit will be
|
||||
/// enforced.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -244,7 +245,11 @@ pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> {
|
|||
/// [`Resource`]: enum.Resource.html
|
||||
///
|
||||
/// Note: `setrlimit` provides a safe wrapper to libc's `setrlimit`.
|
||||
pub fn setrlimit(resource: Resource, soft_limit: rlim_t, hard_limit: rlim_t) -> Result<()> {
|
||||
pub fn setrlimit(
|
||||
resource: Resource,
|
||||
soft_limit: rlim_t,
|
||||
hard_limit: rlim_t,
|
||||
) -> Result<()> {
|
||||
let new_rlim = rlimit {
|
||||
rlim_cur: soft_limit,
|
||||
rlim_max: hard_limit,
|
||||
|
@ -426,7 +431,8 @@ mod test {
|
|||
// thing away. Replace the assert with test::black_box once stabilized.
|
||||
assert_eq!(numbers[100..200].iter().sum::<i32>(), 30_100);
|
||||
|
||||
let usage = getrusage(UsageWho::RUSAGE_SELF).expect("Failed to call getrusage for SELF");
|
||||
let usage = getrusage(UsageWho::RUSAGE_SELF)
|
||||
.expect("Failed to call getrusage for SELF");
|
||||
let rusage = usage.as_ref();
|
||||
|
||||
let user = usage.user_time();
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
//! Portably monitor a group of file descriptors for readiness.
|
||||
use crate::errno::Errno;
|
||||
use crate::sys::time::{TimeSpec, TimeVal};
|
||||
use crate::Result;
|
||||
use libc::{self, c_int};
|
||||
use std::convert::TryFrom;
|
||||
use std::iter::FusedIterator;
|
||||
use std::mem;
|
||||
use std::ops::Range;
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::ptr::{null, null_mut};
|
||||
use libc::{self, c_int};
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::sys::time::{TimeSpec, TimeVal};
|
||||
|
||||
pub use libc::FD_SETSIZE;
|
||||
|
||||
|
@ -173,11 +173,13 @@ impl<'a> FusedIterator for Fds<'a> {}
|
|||
/// [select(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html)
|
||||
///
|
||||
/// [`FdSet::highest`]: struct.FdSet.html#method.highest
|
||||
pub fn select<'a, N, R, W, E, T>(nfds: N,
|
||||
pub fn select<'a, N, R, W, E, T>(
|
||||
nfds: N,
|
||||
readfds: R,
|
||||
writefds: W,
|
||||
errorfds: E,
|
||||
timeout: T) -> Result<c_int>
|
||||
timeout: T,
|
||||
) -> Result<c_int>
|
||||
where
|
||||
N: Into<Option<c_int>>,
|
||||
R: Into<Option<&'a mut FdSet>>,
|
||||
|
@ -191,23 +193,31 @@ where
|
|||
let timeout = timeout.into();
|
||||
|
||||
let nfds = nfds.into().unwrap_or_else(|| {
|
||||
readfds.iter_mut()
|
||||
readfds
|
||||
.iter_mut()
|
||||
.chain(writefds.iter_mut())
|
||||
.chain(errorfds.iter_mut())
|
||||
.map(|set| set.highest().unwrap_or(-1))
|
||||
.max()
|
||||
.unwrap_or(-1) + 1
|
||||
.unwrap_or(-1)
|
||||
+ 1
|
||||
});
|
||||
|
||||
let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
|
||||
let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
|
||||
let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
|
||||
let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval)
|
||||
let readfds = readfds
|
||||
.map(|set| set as *mut _ as *mut libc::fd_set)
|
||||
.unwrap_or(null_mut());
|
||||
let writefds = writefds
|
||||
.map(|set| set as *mut _ as *mut libc::fd_set)
|
||||
.unwrap_or(null_mut());
|
||||
let errorfds = errorfds
|
||||
.map(|set| set as *mut _ as *mut libc::fd_set)
|
||||
.unwrap_or(null_mut());
|
||||
let timeout = timeout
|
||||
.map(|tv| tv as *mut _ as *mut libc::timeval)
|
||||
.unwrap_or(null_mut());
|
||||
|
||||
let res = unsafe {
|
||||
libc::select(nfds, readfds, writefds, errorfds, timeout)
|
||||
};
|
||||
let res =
|
||||
unsafe { libc::select(nfds, readfds, writefds, errorfds, timeout) };
|
||||
|
||||
Errno::result(res)
|
||||
}
|
||||
|
@ -292,9 +302,9 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::os::unix::io::RawFd;
|
||||
use crate::sys::time::{TimeVal, TimeValLike};
|
||||
use crate::unistd::{write, pipe};
|
||||
use crate::unistd::{pipe, write};
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
#[test]
|
||||
fn fdset_insert() {
|
||||
|
@ -383,11 +393,10 @@ mod tests {
|
|||
fd_set.insert(r2);
|
||||
|
||||
let mut timeout = TimeVal::seconds(10);
|
||||
assert_eq!(1, select(None,
|
||||
&mut fd_set,
|
||||
None,
|
||||
None,
|
||||
&mut timeout).unwrap());
|
||||
assert_eq!(
|
||||
1,
|
||||
select(None, &mut fd_set, None, None, &mut timeout).unwrap()
|
||||
);
|
||||
assert!(fd_set.contains(r1));
|
||||
assert!(!fd_set.contains(r2));
|
||||
}
|
||||
|
@ -403,11 +412,17 @@ mod tests {
|
|||
fd_set.insert(r2);
|
||||
|
||||
let mut timeout = TimeVal::seconds(10);
|
||||
assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1),
|
||||
assert_eq!(
|
||||
1,
|
||||
select(
|
||||
Some(fd_set.highest().unwrap() + 1),
|
||||
&mut fd_set,
|
||||
None,
|
||||
None,
|
||||
&mut timeout).unwrap());
|
||||
&mut timeout
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
assert!(fd_set.contains(r1));
|
||||
assert!(!fd_set.contains(r2));
|
||||
}
|
||||
|
@ -423,11 +438,17 @@ mod tests {
|
|||
fd_set.insert(r2);
|
||||
|
||||
let mut timeout = TimeVal::seconds(10);
|
||||
assert_eq!(1, select(::std::cmp::max(r1, r2) + 1,
|
||||
assert_eq!(
|
||||
1,
|
||||
select(
|
||||
::std::cmp::max(r1, r2) + 1,
|
||||
&mut fd_set,
|
||||
None,
|
||||
None,
|
||||
&mut timeout).unwrap());
|
||||
&mut timeout
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
assert!(fd_set.contains(r1));
|
||||
assert!(!fd_set.contains(r2));
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::ptr;
|
|||
|
||||
use libc::{self, off_t};
|
||||
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
|
||||
/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`.
|
||||
///
|
||||
|
|
|
@ -475,7 +475,7 @@ pub struct SigSet {
|
|||
|
||||
impl SigSet {
|
||||
/// Initialize to include all signals.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("sigfillset")))]
|
||||
#[doc(alias("sigfillset"))]
|
||||
pub fn all() -> SigSet {
|
||||
let mut sigset = mem::MaybeUninit::uninit();
|
||||
let _ = unsafe { libc::sigfillset(sigset.as_mut_ptr()) };
|
||||
|
@ -484,7 +484,7 @@ impl SigSet {
|
|||
}
|
||||
|
||||
/// Initialize to include nothing.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("sigemptyset")))]
|
||||
#[doc(alias("sigemptyset"))]
|
||||
pub fn empty() -> SigSet {
|
||||
let mut sigset = mem::MaybeUninit::uninit();
|
||||
let _ = unsafe { libc::sigemptyset(sigset.as_mut_ptr()) };
|
||||
|
@ -493,25 +493,25 @@ impl SigSet {
|
|||
}
|
||||
|
||||
/// Add the specified signal to the set.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("sigaddset")))]
|
||||
#[doc(alias("sigaddset"))]
|
||||
pub fn add(&mut self, signal: Signal) {
|
||||
unsafe { libc::sigaddset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) };
|
||||
}
|
||||
|
||||
/// Remove all signals from this set.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("sigemptyset")))]
|
||||
#[doc(alias("sigemptyset"))]
|
||||
pub fn clear(&mut self) {
|
||||
unsafe { libc::sigemptyset(&mut self.sigset as *mut libc::sigset_t) };
|
||||
}
|
||||
|
||||
/// Remove the specified signal from this set.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("sigdelset")))]
|
||||
#[doc(alias("sigdelset"))]
|
||||
pub fn remove(&mut self, signal: Signal) {
|
||||
unsafe { libc::sigdelset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) };
|
||||
}
|
||||
|
||||
/// Return whether this set includes the specified signal.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("sigismember")))]
|
||||
#[doc(alias("sigismember"))]
|
||||
pub fn contains(&self, signal: Signal) -> bool {
|
||||
let res = unsafe { libc::sigismember(&self.sigset as *const libc::sigset_t, signal as libc::c_int) };
|
||||
|
||||
|
@ -911,10 +911,11 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `pid` - Specifies which processes should receive the signal.
|
||||
/// - If positive, specifies an individual process
|
||||
/// - If positive, specifies an individual process.
|
||||
/// - If zero, the signal will be sent to all processes whose group
|
||||
/// ID is equal to the process group ID of the sender. This is a
|
||||
/// variant of [`killpg`].
|
||||
#[cfg_attr(target_os = "fuchsia", doc = "variant of `killpg`.")]
|
||||
#[cfg_attr(not(target_os = "fuchsia"), doc = "variant of [`killpg`].")]
|
||||
/// - If `-1` and the process has super-user privileges, the signal
|
||||
/// is sent to all processes exclusing system processes.
|
||||
/// - If less than `-1`, the signal is sent to all processes whose
|
||||
|
|
|
@ -15,17 +15,16 @@
|
|||
//!
|
||||
//! Please note that signal discarding is not specific to `signalfd`, but also happens with regular
|
||||
//! signal handlers.
|
||||
use crate::unistd;
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
pub use crate::sys::signal::{self, SigSet};
|
||||
use crate::unistd;
|
||||
use crate::Result;
|
||||
pub use libc::signalfd_siginfo as siginfo;
|
||||
|
||||
use std::os::unix::io::{RawFd, AsRawFd};
|
||||
use std::mem;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
|
||||
|
||||
libc_bitflags!{
|
||||
libc_bitflags! {
|
||||
pub struct SfdFlags: libc::c_int {
|
||||
SFD_NONBLOCK;
|
||||
SFD_CLOEXEC;
|
||||
|
@ -49,7 +48,11 @@ pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();
|
|||
/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
|
||||
pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
|
||||
unsafe {
|
||||
Errno::result(libc::signalfd(fd as libc::c_int, mask.as_ref(), flags.bits()))
|
||||
Errno::result(libc::signalfd(
|
||||
fd as libc::c_int,
|
||||
mask.as_ref(),
|
||||
flags.bits(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,12 +106,13 @@ impl SignalFd {
|
|||
let size = mem::size_of_val(&buffer);
|
||||
let res = Errno::result(unsafe {
|
||||
libc::read(self.0, buffer.as_mut_ptr() as *mut libc::c_void, size)
|
||||
}).map(|r| r as usize);
|
||||
})
|
||||
.map(|r| r as usize);
|
||||
match res {
|
||||
Ok(x) if x == size => Ok(Some(unsafe { buffer.assume_init() })),
|
||||
Ok(_) => unreachable!("partial read on signalfd"),
|
||||
Err(Errno::EAGAIN) => Ok(None),
|
||||
Err(error) => Err(error)
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +143,6 @@ impl Iterator for SignalFd {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -163,7 +166,8 @@ mod tests {
|
|||
#[test]
|
||||
fn read_empty_signalfd() {
|
||||
let mask = SigSet::empty();
|
||||
let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
|
||||
let mut fd =
|
||||
SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
|
||||
|
||||
let res = fd.read_signal();
|
||||
assert!(res.unwrap().is_none());
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,19 +1,18 @@
|
|||
//! Socket options as used by `setsockopt` and `getsockopt`.
|
||||
use cfg_if::cfg_if;
|
||||
use super::{GetSockOpt, SetSockOpt};
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::sys::time::TimeVal;
|
||||
use crate::Result;
|
||||
use cfg_if::cfg_if;
|
||||
use libc::{self, c_int, c_void, socklen_t};
|
||||
use std::convert::TryFrom;
|
||||
use std::mem::{
|
||||
self,
|
||||
MaybeUninit
|
||||
};
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
mem::{self, MaybeUninit}
|
||||
};
|
||||
#[cfg(target_family = "unix")]
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
// Constants
|
||||
// TCP_CA_NAME_MAX isn't defined in user space include files
|
||||
|
@ -52,14 +51,18 @@ macro_rules! setsockopt_impl {
|
|||
unsafe {
|
||||
let setter: $setter = Set::new(val);
|
||||
|
||||
let res = libc::setsockopt(fd, $level, $flag,
|
||||
setter.ffi_ptr(),
|
||||
setter.ffi_len());
|
||||
let res = libc::setsockopt(
|
||||
fd,
|
||||
$level,
|
||||
$flag,
|
||||
setter.ffi_ptr(),
|
||||
setter.ffi_len(),
|
||||
);
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper for implementing `GetSockOpt` for a given socket option. See
|
||||
|
@ -93,9 +96,13 @@ macro_rules! getsockopt_impl {
|
|||
unsafe {
|
||||
let mut getter: $getter = Get::uninit();
|
||||
|
||||
let res = libc::getsockopt(fd, $level, $flag,
|
||||
getter.ffi_ptr(),
|
||||
getter.ffi_len());
|
||||
let res = libc::getsockopt(
|
||||
fd,
|
||||
$level,
|
||||
$flag,
|
||||
getter.ffi_ptr(),
|
||||
getter.ffi_len(),
|
||||
);
|
||||
Errno::result(res)?;
|
||||
|
||||
match <$ty>::try_from(getter.assume_init()) {
|
||||
|
@ -105,7 +112,7 @@ macro_rules! getsockopt_impl {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Helper to generate the sockopt accessors. See
|
||||
|
@ -252,13 +259,22 @@ macro_rules! sockopt_impl {
|
|||
|
||||
sockopt_impl!(
|
||||
/// Enables local address reuse
|
||||
ReuseAddr, Both, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool
|
||||
ReuseAddr,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_REUSEADDR,
|
||||
bool
|
||||
);
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
|
||||
sockopt_impl!(
|
||||
/// Permits multiple AF_INET or AF_INET6 sockets to be bound to an
|
||||
/// identical socket address.
|
||||
ReusePort, Both, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool);
|
||||
ReusePort,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_REUSEPORT,
|
||||
bool
|
||||
);
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
|
@ -269,24 +285,42 @@ sockopt_impl!(
|
|||
/// send a stream of mouse events which receive no replies, this
|
||||
/// packetization may cause significant delays. The boolean option
|
||||
/// TCP_NODELAY defeats this algorithm.
|
||||
TcpNoDelay, Both, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool);
|
||||
TcpNoDelay,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_NODELAY,
|
||||
bool
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// When enabled, a close(2) or shutdown(2) will not return until all
|
||||
/// queued messages for the socket have been successfully sent or the
|
||||
/// linger timeout has been reached.
|
||||
Linger, Both, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger);
|
||||
Linger,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_LINGER,
|
||||
libc::linger
|
||||
);
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Join a multicast group
|
||||
IpAddMembership, SetOnly, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP,
|
||||
super::IpMembershipRequest);
|
||||
IpAddMembership,
|
||||
SetOnly,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_ADD_MEMBERSHIP,
|
||||
super::IpMembershipRequest
|
||||
);
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Leave a multicast group.
|
||||
IpDropMembership, SetOnly, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP,
|
||||
super::IpMembershipRequest);
|
||||
IpDropMembership,
|
||||
SetOnly,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_DROP_MEMBERSHIP,
|
||||
super::IpMembershipRequest
|
||||
);
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "android", target_os = "linux"))] {
|
||||
#[cfg(feature = "net")]
|
||||
|
@ -326,74 +360,180 @@ sockopt_impl!(
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Set or read the time-to-live value of outgoing multicast packets for
|
||||
/// this socket.
|
||||
IpMulticastTtl, Both, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8);
|
||||
IpMulticastTtl,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_MULTICAST_TTL,
|
||||
u8
|
||||
);
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Set or read a boolean integer argument that determines whether sent
|
||||
/// multicast packets should be looped back to the local sockets.
|
||||
IpMulticastLoop, Both, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool);
|
||||
IpMulticastLoop,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_MULTICAST_LOOP,
|
||||
bool
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Set the protocol-defined priority for all packets to be
|
||||
/// sent on this socket
|
||||
Priority,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_PRIORITY,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Set or receive the Type-Of-Service (TOS) field that is
|
||||
/// sent with every IP packet originating from this socket
|
||||
IpTos,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_TOS,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Traffic class associated with outgoing packets
|
||||
Ipv6TClass,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_TCLASS,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// If enabled, this boolean option allows binding to an IP address that
|
||||
/// is nonlocal or does not (yet) exist.
|
||||
IpFreebind, Both, libc::IPPROTO_IP, libc::IP_FREEBIND, bool);
|
||||
IpFreebind,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_FREEBIND,
|
||||
bool
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Specify the receiving timeout until reporting an error.
|
||||
ReceiveTimeout, Both, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal);
|
||||
ReceiveTimeout,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_RCVTIMEO,
|
||||
TimeVal
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Specify the sending timeout until reporting an error.
|
||||
SendTimeout, Both, libc::SOL_SOCKET, libc::SO_SNDTIMEO, TimeVal);
|
||||
SendTimeout,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_SNDTIMEO,
|
||||
TimeVal
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Set or get the broadcast flag.
|
||||
Broadcast, Both, libc::SOL_SOCKET, libc::SO_BROADCAST, bool);
|
||||
Broadcast,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_BROADCAST,
|
||||
bool
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// If this option is enabled, out-of-band data is directly placed into
|
||||
/// the receive data stream.
|
||||
OobInline, Both, libc::SOL_SOCKET, libc::SO_OOBINLINE, bool);
|
||||
OobInline,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_OOBINLINE,
|
||||
bool
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Get and clear the pending socket error.
|
||||
SocketError, GetOnly, libc::SOL_SOCKET, libc::SO_ERROR, i32);
|
||||
SocketError,
|
||||
GetOnly,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_ERROR,
|
||||
i32
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Set or get the don't route flag.
|
||||
DontRoute, Both, libc::SOL_SOCKET, libc::SO_DONTROUTE, bool);
|
||||
DontRoute,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_DONTROUTE,
|
||||
bool
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Enable sending of keep-alive messages on connection-oriented sockets.
|
||||
KeepAlive, Both, libc::SOL_SOCKET, libc::SO_KEEPALIVE, bool);
|
||||
KeepAlive,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_KEEPALIVE,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "ios"
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "ios"
|
||||
))]
|
||||
sockopt_impl!(
|
||||
/// Get the credentials of the peer process of a connected unix domain
|
||||
/// socket.
|
||||
LocalPeerCred, GetOnly, 0, libc::LOCAL_PEERCRED, super::XuCred);
|
||||
LocalPeerCred,
|
||||
GetOnly,
|
||||
0,
|
||||
libc::LOCAL_PEERCRED,
|
||||
super::XuCred
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Return the credentials of the foreign process connected to this socket.
|
||||
PeerCredentials, GetOnly, libc::SOL_SOCKET, libc::SO_PEERCRED, super::UnixCredentials);
|
||||
#[cfg(any(target_os = "ios",
|
||||
target_os = "macos"))]
|
||||
PeerCredentials,
|
||||
GetOnly,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_PEERCRED,
|
||||
super::UnixCredentials
|
||||
);
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Specify the amount of time, in seconds, that the connection must be idle
|
||||
/// before keepalive probes (if enabled) are sent.
|
||||
TcpKeepAlive, Both, libc::IPPROTO_TCP, libc::TCP_KEEPALIVE, u32);
|
||||
#[cfg(any(target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux"))]
|
||||
TcpKeepAlive,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_KEEPALIVE,
|
||||
u32
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux"
|
||||
))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The time (in seconds) the connection needs to remain idle before TCP
|
||||
/// starts sending keepalive probes
|
||||
TcpKeepIdle, Both, libc::IPPROTO_TCP, libc::TCP_KEEPIDLE, u32);
|
||||
TcpKeepIdle,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_KEEPIDLE,
|
||||
u32
|
||||
);
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "android", target_os = "linux"))] {
|
||||
sockopt_impl!(
|
||||
|
@ -411,20 +551,33 @@ sockopt_impl!(
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The maximum number of keepalive probes TCP should send before
|
||||
/// dropping the connection.
|
||||
TcpKeepCount, Both, libc::IPPROTO_TCP, libc::TCP_KEEPCNT, u32);
|
||||
#[cfg(any(target_os = "android",
|
||||
target_os = "fuchsia",
|
||||
target_os = "linux"))]
|
||||
TcpKeepCount,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_KEEPCNT,
|
||||
u32
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
#[allow(missing_docs)]
|
||||
// Not documented by Linux!
|
||||
TcpRepair, Both, libc::IPPROTO_TCP, libc::TCP_REPAIR, u32);
|
||||
TcpRepair,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_REPAIR,
|
||||
u32
|
||||
);
|
||||
#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The time (in seconds) between individual keepalive probes.
|
||||
TcpKeepInterval, Both, libc::IPPROTO_TCP, libc::TCP_KEEPINTVL, u32);
|
||||
TcpKeepInterval,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_KEEPINTVL,
|
||||
u32
|
||||
);
|
||||
#[cfg(any(target_os = "fuchsia", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
|
@ -432,98 +585,194 @@ sockopt_impl!(
|
|||
/// Specifies the maximum amount of time in milliseconds that transmitted
|
||||
/// data may remain unacknowledged before TCP will forcibly close the
|
||||
/// corresponding connection
|
||||
TcpUserTimeout, Both, libc::IPPROTO_TCP, libc::TCP_USER_TIMEOUT, u32);
|
||||
TcpUserTimeout,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_USER_TIMEOUT,
|
||||
u32
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Sets or gets the maximum socket receive buffer in bytes.
|
||||
RcvBuf, Both, libc::SOL_SOCKET, libc::SO_RCVBUF, usize);
|
||||
RcvBuf,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_RCVBUF,
|
||||
usize
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Sets or gets the maximum socket send buffer in bytes.
|
||||
SndBuf, Both, libc::SOL_SOCKET, libc::SO_SNDBUF, usize);
|
||||
SndBuf,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_SNDBUF,
|
||||
usize
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
|
||||
/// perform the same task as `SO_RCVBUF`, but the `rmem_max limit` can be
|
||||
/// overridden.
|
||||
RcvBufForce, SetOnly, libc::SOL_SOCKET, libc::SO_RCVBUFFORCE, usize);
|
||||
RcvBufForce,
|
||||
SetOnly,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_RCVBUFFORCE,
|
||||
usize
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
|
||||
/// perform the same task as `SO_SNDBUF`, but the `wmem_max` limit can be
|
||||
/// overridden.
|
||||
SndBufForce, SetOnly, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize);
|
||||
SndBufForce,
|
||||
SetOnly,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_SNDBUFFORCE,
|
||||
usize
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Gets the socket type as an integer.
|
||||
SockType, GetOnly, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType, GetStruct<i32>);
|
||||
SockType,
|
||||
GetOnly,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_TYPE,
|
||||
super::SockType,
|
||||
GetStruct<i32>
|
||||
);
|
||||
sockopt_impl!(
|
||||
/// Returns a value indicating whether or not this socket has been marked to
|
||||
/// accept connections with `listen(2)`.
|
||||
AcceptConn, GetOnly, libc::SOL_SOCKET, libc::SO_ACCEPTCONN, bool);
|
||||
AcceptConn,
|
||||
GetOnly,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_ACCEPTCONN,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Bind this socket to a particular device like “eth0”.
|
||||
BindToDevice, Both, libc::SOL_SOCKET, libc::SO_BINDTODEVICE, OsString<[u8; libc::IFNAMSIZ]>);
|
||||
BindToDevice,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_BINDTODEVICE,
|
||||
OsString<[u8; libc::IFNAMSIZ]>
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
#[allow(missing_docs)]
|
||||
// Not documented by Linux!
|
||||
OriginalDst, GetOnly, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::sockaddr_in);
|
||||
OriginalDst,
|
||||
GetOnly,
|
||||
libc::SOL_IP,
|
||||
libc::SO_ORIGINAL_DST,
|
||||
libc::sockaddr_in
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
#[allow(missing_docs)]
|
||||
// Not documented by Linux!
|
||||
Ip6tOriginalDst, GetOnly, libc::SOL_IPV6, libc::IP6T_SO_ORIGINAL_DST, libc::sockaddr_in6);
|
||||
Ip6tOriginalDst,
|
||||
GetOnly,
|
||||
libc::SOL_IPV6,
|
||||
libc::IP6T_SO_ORIGINAL_DST,
|
||||
libc::sockaddr_in6
|
||||
);
|
||||
#[cfg(any(target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Specifies exact type of timestamping information collected by the kernel
|
||||
/// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
|
||||
Timestamping, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPING, super::TimestampingFlag);
|
||||
Timestamping,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_TIMESTAMPING,
|
||||
super::TimestampingFlag
|
||||
);
|
||||
#[cfg(not(target_os = "haiku"))]
|
||||
sockopt_impl!(
|
||||
/// Enable or disable the receiving of the `SO_TIMESTAMP` control message.
|
||||
ReceiveTimestamp, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
|
||||
ReceiveTimestamp,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_TIMESTAMP,
|
||||
bool
|
||||
);
|
||||
#[cfg(all(target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Enable or disable the receiving of the `SO_TIMESTAMPNS` control message.
|
||||
ReceiveTimestampns, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPNS, bool);
|
||||
ReceiveTimestampns,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_TIMESTAMPNS,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Setting this boolean option enables transparent proxying on this socket.
|
||||
IpTransparent, Both, libc::SOL_IP, libc::IP_TRANSPARENT, bool);
|
||||
IpTransparent,
|
||||
Both,
|
||||
libc::SOL_IP,
|
||||
libc::IP_TRANSPARENT,
|
||||
bool
|
||||
);
|
||||
#[cfg(target_os = "openbsd")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Allows the socket to be bound to addresses which are not local to the
|
||||
/// machine, so it can be used to make a transparent proxy.
|
||||
BindAny, Both, libc::SOL_SOCKET, libc::SO_BINDANY, bool);
|
||||
BindAny,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_BINDANY,
|
||||
bool
|
||||
);
|
||||
#[cfg(target_os = "freebsd")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Can `bind(2)` to any address, even one not bound to any available
|
||||
/// network interface in the system.
|
||||
BindAny, Both, libc::IPPROTO_IP, libc::IP_BINDANY, bool);
|
||||
BindAny,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_BINDANY,
|
||||
bool
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
sockopt_impl!(
|
||||
/// Set the mark for each packet sent through this socket (similar to the
|
||||
/// netfilter MARK target but socket-based).
|
||||
Mark, Both, libc::SOL_SOCKET, libc::SO_MARK, u32);
|
||||
Mark,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_MARK,
|
||||
u32
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Enable or disable the receiving of the `SCM_CREDENTIALS` control
|
||||
/// message.
|
||||
PassCred, Both, libc::SOL_SOCKET, libc::SO_PASSCRED, bool);
|
||||
PassCred,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_PASSCRED,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// This option allows the caller to set the TCP congestion control
|
||||
/// algorithm to be used, on a per-socket basis.
|
||||
TcpCongestion, Both, libc::IPPROTO_TCP, libc::TCP_CONGESTION, OsString<[u8; TCP_CA_NAME_MAX]>);
|
||||
TcpCongestion,
|
||||
Both,
|
||||
libc::IPPROTO_TCP,
|
||||
libc::TCP_CONGESTION,
|
||||
OsString<[u8; TCP_CA_NAME_MAX]>
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
|
@ -536,7 +785,12 @@ sockopt_impl!(
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Pass an `IP_PKTINFO` ancillary message that contains a pktinfo
|
||||
/// structure that supplies some information about the incoming packet.
|
||||
Ipv4PacketInfo, Both, libc::IPPROTO_IP, libc::IP_PKTINFO, bool);
|
||||
Ipv4PacketInfo,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_PKTINFO,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
|
@ -551,7 +805,12 @@ sockopt_impl!(
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// Set delivery of the `IPV6_PKTINFO` control message on incoming
|
||||
/// datagrams.
|
||||
Ipv6RecvPacketInfo, Both, libc::IPPROTO_IPV6, libc::IPV6_RECVPKTINFO, bool);
|
||||
Ipv6RecvPacketInfo,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_RECVPKTINFO,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
|
@ -564,7 +823,12 @@ sockopt_impl!(
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The `recvmsg(2)` call returns a `struct sockaddr_dl` corresponding to
|
||||
/// the interface on which the packet was received.
|
||||
Ipv4RecvIf, Both, libc::IPPROTO_IP, libc::IP_RECVIF, bool);
|
||||
Ipv4RecvIf,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_RECVIF,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "ios",
|
||||
|
@ -577,72 +841,146 @@ sockopt_impl!(
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The `recvmsg(2)` call will return the destination IP address for a UDP
|
||||
/// datagram.
|
||||
Ipv4RecvDstAddr, Both, libc::IPPROTO_IP, libc::IP_RECVDSTADDR, bool);
|
||||
Ipv4RecvDstAddr,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_RECVDSTADDR,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The `recvmsg(2)` call will return the destination IP address for a UDP
|
||||
/// datagram.
|
||||
Ipv4OrigDstAddr, Both, libc::IPPROTO_IP, libc::IP_ORIGDSTADDR, bool);
|
||||
Ipv4OrigDstAddr,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_ORIGDSTADDR,
|
||||
bool
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
#[allow(missing_docs)]
|
||||
// Not documented by Linux!
|
||||
UdpGsoSegment, Both, libc::SOL_UDP, libc::UDP_SEGMENT, libc::c_int);
|
||||
UdpGsoSegment,
|
||||
Both,
|
||||
libc::SOL_UDP,
|
||||
libc::UDP_SEGMENT,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
#[allow(missing_docs)]
|
||||
// Not documented by Linux!
|
||||
UdpGroSegment, Both, libc::IPPROTO_UDP, libc::UDP_GRO, bool);
|
||||
UdpGroSegment,
|
||||
Both,
|
||||
libc::IPPROTO_UDP,
|
||||
libc::UDP_GRO,
|
||||
bool
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
sockopt_impl!(
|
||||
/// Configures the behavior of time-based transmission of packets, for use
|
||||
/// with the `TxTime` control message.
|
||||
TxTime, Both, libc::SOL_SOCKET, libc::SO_TXTIME, libc::sock_txtime);
|
||||
TxTime,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_TXTIME,
|
||||
libc::sock_txtime
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Indicates that an unsigned 32-bit value ancillary message (cmsg) should
|
||||
/// be attached to received skbs indicating the number of packets dropped by
|
||||
/// the socket since its creation.
|
||||
RxqOvfl, Both, libc::SOL_SOCKET, libc::SO_RXQ_OVFL, libc::c_int);
|
||||
RxqOvfl,
|
||||
Both,
|
||||
libc::SOL_SOCKET,
|
||||
libc::SO_RXQ_OVFL,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The socket is restricted to sending and receiving IPv6 packets only.
|
||||
Ipv6V6Only, Both, libc::IPPROTO_IPV6, libc::IPV6_V6ONLY, bool);
|
||||
Ipv6V6Only,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_V6ONLY,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Enable extended reliable error message passing.
|
||||
Ipv4RecvErr, Both, libc::IPPROTO_IP, libc::IP_RECVERR, bool);
|
||||
Ipv4RecvErr,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_RECVERR,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Control receiving of asynchronous error options.
|
||||
Ipv6RecvErr, Both, libc::IPPROTO_IPV6, libc::IPV6_RECVERR, bool);
|
||||
Ipv6RecvErr,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_RECVERR,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Fetch the current system-estimated Path MTU.
|
||||
IpMtu,
|
||||
GetOnly,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_MTU,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Set or retrieve the current time-to-live field that is used in every
|
||||
/// packet sent from this socket.
|
||||
Ipv4Ttl, Both, libc::IPPROTO_IP, libc::IP_TTL, libc::c_int);
|
||||
Ipv4Ttl,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_TTL,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
sockopt_impl!(
|
||||
/// Set the unicast hop limit for the socket.
|
||||
Ipv6Ttl, Both, libc::IPPROTO_IPV6, libc::IPV6_UNICAST_HOPS, libc::c_int);
|
||||
Ipv6Ttl,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_UNICAST_HOPS,
|
||||
libc::c_int
|
||||
);
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
#[cfg(feature = "net")]
|
||||
sockopt_impl!(
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
|
||||
/// The `recvmsg(2)` call will return the destination IP address for a UDP
|
||||
/// datagram.
|
||||
Ipv6OrigDstAddr, Both, libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR, bool);
|
||||
Ipv6OrigDstAddr,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_ORIGDSTADDR,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
sockopt_impl!(
|
||||
/// Set "don't fragment packet" flag on the IP packet.
|
||||
IpDontFrag, Both, libc::IPPROTO_IP, libc::IP_DONTFRAG, bool);
|
||||
IpDontFrag,
|
||||
Both,
|
||||
libc::IPPROTO_IP,
|
||||
libc::IP_DONTFRAG,
|
||||
bool
|
||||
);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
|
@ -651,7 +989,12 @@ sockopt_impl!(
|
|||
))]
|
||||
sockopt_impl!(
|
||||
/// Set "don't fragment packet" flag on the IPv6 packet.
|
||||
Ipv6DontFrag, Both, libc::IPPROTO_IPV6, libc::IPV6_DONTFRAG, bool);
|
||||
Ipv6DontFrag,
|
||||
Both,
|
||||
libc::IPPROTO_IPV6,
|
||||
libc::IPV6_DONTFRAG,
|
||||
bool
|
||||
);
|
||||
|
||||
#[allow(missing_docs)]
|
||||
// Not documented by Linux!
|
||||
|
@ -667,11 +1010,13 @@ impl SetSockOpt for AlgSetAeadAuthSize {
|
|||
|
||||
fn set(&self, fd: RawFd, val: &usize) -> Result<()> {
|
||||
unsafe {
|
||||
let res = libc::setsockopt(fd,
|
||||
libc::SOL_ALG,
|
||||
libc::ALG_SET_AEAD_AUTHSIZE,
|
||||
::std::ptr::null(),
|
||||
*val as libc::socklen_t);
|
||||
let res = libc::setsockopt(
|
||||
fd,
|
||||
libc::SOL_ALG,
|
||||
libc::ALG_SET_AEAD_AUTHSIZE,
|
||||
::std::ptr::null(),
|
||||
*val as libc::socklen_t,
|
||||
);
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
}
|
||||
|
@ -691,16 +1036,21 @@ impl<T> Default for AlgSetKey<T> {
|
|||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
impl<T> SetSockOpt for AlgSetKey<T> where T: AsRef<[u8]> + Clone {
|
||||
impl<T> SetSockOpt for AlgSetKey<T>
|
||||
where
|
||||
T: AsRef<[u8]> + Clone,
|
||||
{
|
||||
type Val = T;
|
||||
|
||||
fn set(&self, fd: RawFd, val: &T) -> Result<()> {
|
||||
unsafe {
|
||||
let res = libc::setsockopt(fd,
|
||||
libc::SOL_ALG,
|
||||
libc::ALG_SET_KEY,
|
||||
val.as_ref().as_ptr() as *const _,
|
||||
val.as_ref().len() as libc::socklen_t);
|
||||
let res = libc::setsockopt(
|
||||
fd,
|
||||
libc::SOL_ALG,
|
||||
libc::ALG_SET_KEY,
|
||||
val.as_ref().as_ptr() as *const _,
|
||||
val.as_ref().len() as libc::socklen_t,
|
||||
);
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
}
|
||||
|
@ -761,7 +1111,11 @@ impl<T> Get<T> for GetStruct<T> {
|
|||
}
|
||||
|
||||
unsafe fn assume_init(self) -> T {
|
||||
assert_eq!(self.len as usize, mem::size_of::<T>(), "invalid getsockopt implementation");
|
||||
assert_eq!(
|
||||
self.len as usize,
|
||||
mem::size_of::<T>(),
|
||||
"invalid getsockopt implementation"
|
||||
);
|
||||
self.val.assume_init()
|
||||
}
|
||||
}
|
||||
|
@ -808,7 +1162,11 @@ impl Get<bool> for GetBool {
|
|||
}
|
||||
|
||||
unsafe fn assume_init(self) -> bool {
|
||||
assert_eq!(self.len as usize, mem::size_of::<c_int>(), "invalid getsockopt implementation");
|
||||
assert_eq!(
|
||||
self.len as usize,
|
||||
mem::size_of::<c_int>(),
|
||||
"invalid getsockopt implementation"
|
||||
);
|
||||
self.val.assume_init() != 0
|
||||
}
|
||||
}
|
||||
|
@ -820,7 +1178,9 @@ struct SetBool {
|
|||
|
||||
impl<'a> Set<'a, bool> for SetBool {
|
||||
fn new(val: &'a bool) -> SetBool {
|
||||
SetBool { val: i32::from(*val) }
|
||||
SetBool {
|
||||
val: i32::from(*val),
|
||||
}
|
||||
}
|
||||
|
||||
fn ffi_ptr(&self) -> *const c_void {
|
||||
|
@ -855,7 +1215,11 @@ impl Get<u8> for GetU8 {
|
|||
}
|
||||
|
||||
unsafe fn assume_init(self) -> u8 {
|
||||
assert_eq!(self.len as usize, mem::size_of::<u8>(), "invalid getsockopt implementation");
|
||||
assert_eq!(
|
||||
self.len as usize,
|
||||
mem::size_of::<u8>(),
|
||||
"invalid getsockopt implementation"
|
||||
);
|
||||
self.val.assume_init()
|
||||
}
|
||||
}
|
||||
|
@ -902,7 +1266,11 @@ impl Get<usize> for GetUsize {
|
|||
}
|
||||
|
||||
unsafe fn assume_init(self) -> usize {
|
||||
assert_eq!(self.len as usize, mem::size_of::<c_int>(), "invalid getsockopt implementation");
|
||||
assert_eq!(
|
||||
self.len as usize,
|
||||
mem::size_of::<c_int>(),
|
||||
"invalid getsockopt implementation"
|
||||
);
|
||||
self.val.assume_init() as usize
|
||||
}
|
||||
}
|
||||
|
@ -962,7 +1330,9 @@ struct SetOsString<'a> {
|
|||
|
||||
impl<'a> Set<'a, OsString> for SetOsString<'a> {
|
||||
fn new(val: &'a OsString) -> SetOsString {
|
||||
SetOsString { val: val.as_os_str() }
|
||||
SetOsString {
|
||||
val: val.as_os_str(),
|
||||
}
|
||||
}
|
||||
|
||||
fn ffi_ptr(&self) -> *const c_void {
|
||||
|
@ -974,7 +1344,6 @@ impl<'a> Set<'a, OsString> for SetOsString<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
|
@ -982,7 +1351,13 @@ mod test {
|
|||
fn can_get_peercred_on_unix_socket() {
|
||||
use super::super::*;
|
||||
|
||||
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
|
||||
let (a, b) = socketpair(
|
||||
AddressFamily::Unix,
|
||||
SockType::Stream,
|
||||
None,
|
||||
SockFlag::empty(),
|
||||
)
|
||||
.unwrap();
|
||||
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
|
||||
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
|
||||
assert_eq!(a_cred, b_cred);
|
||||
|
@ -994,7 +1369,13 @@ mod test {
|
|||
use super::super::*;
|
||||
use crate::unistd::close;
|
||||
|
||||
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
|
||||
let (a, b) = socketpair(
|
||||
AddressFamily::Unix,
|
||||
SockType::Stream,
|
||||
None,
|
||||
SockFlag::empty(),
|
||||
)
|
||||
.unwrap();
|
||||
let a_type = getsockopt(a, super::SockType).unwrap();
|
||||
assert_eq!(a_type, SockType::Stream);
|
||||
close(a).unwrap();
|
||||
|
@ -1006,20 +1387,31 @@ mod test {
|
|||
use super::super::*;
|
||||
use crate::unistd::close;
|
||||
|
||||
let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
|
||||
let s = socket(
|
||||
AddressFamily::Inet,
|
||||
SockType::Datagram,
|
||||
SockFlag::empty(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let s_type = getsockopt(s, super::SockType).unwrap();
|
||||
assert_eq!(s_type, SockType::Datagram);
|
||||
close(s).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "freebsd",
|
||||
target_os = "linux"))]
|
||||
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
|
||||
#[test]
|
||||
fn can_get_listen_on_tcp_socket() {
|
||||
use super::super::*;
|
||||
use crate::unistd::close;
|
||||
|
||||
let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
|
||||
let s = socket(
|
||||
AddressFamily::Inet,
|
||||
SockType::Stream,
|
||||
SockFlag::empty(),
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let s_listening = getsockopt(s, super::AcceptConn).unwrap();
|
||||
assert!(!s_listening);
|
||||
listen(s, 10).unwrap();
|
||||
|
@ -1027,5 +1419,4 @@ mod test {
|
|||
assert!(s_listening2);
|
||||
close(s).unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
pub use libc::{dev_t, mode_t};
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))]
|
||||
pub use libc::c_uint;
|
||||
#[cfg(any(
|
||||
|
@ -8,13 +7,14 @@ pub use libc::c_uint;
|
|||
))]
|
||||
pub use libc::c_ulong;
|
||||
pub use libc::stat as FileStat;
|
||||
pub use libc::{dev_t, mode_t};
|
||||
|
||||
use crate::{Result, NixPath, errno::Errno};
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
use crate::fcntl::{AtFlags, at_rawfd};
|
||||
use crate::fcntl::{at_rawfd, AtFlags};
|
||||
use crate::sys::time::{TimeSpec, TimeVal};
|
||||
use crate::{errno::Errno, NixPath, Result};
|
||||
use std::mem;
|
||||
use std::os::unix::io::RawFd;
|
||||
use crate::sys::time::{TimeSpec, TimeVal};
|
||||
|
||||
libc_bitflags!(
|
||||
/// "File type" flags for `mknod` and related functions.
|
||||
|
@ -33,25 +33,39 @@ libc_bitflags!(
|
|||
libc_bitflags! {
|
||||
/// "File mode / permissions" flags.
|
||||
pub struct Mode: mode_t {
|
||||
/// Read, write and execute for owner.
|
||||
S_IRWXU;
|
||||
/// Read for owner.
|
||||
S_IRUSR;
|
||||
/// Write for owner.
|
||||
S_IWUSR;
|
||||
/// Execute for owner.
|
||||
S_IXUSR;
|
||||
/// Read write and execute for group.
|
||||
S_IRWXG;
|
||||
/// Read fr group.
|
||||
S_IRGRP;
|
||||
/// Write for group.
|
||||
S_IWGRP;
|
||||
/// Execute for group.
|
||||
S_IXGRP;
|
||||
/// Read, write and execute for other.
|
||||
S_IRWXO;
|
||||
/// Read for other.
|
||||
S_IROTH;
|
||||
/// Write for other.
|
||||
S_IWOTH;
|
||||
/// Execute for other.
|
||||
S_IXOTH;
|
||||
/// Set user id on execution.
|
||||
S_ISUID as mode_t;
|
||||
/// Set group id on execution.
|
||||
S_ISGID as mode_t;
|
||||
S_ISVTX as mode_t;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os="openbsd"))]
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))]
|
||||
pub type type_of_file_flag = c_uint;
|
||||
#[cfg(any(
|
||||
target_os = "netbsd",
|
||||
|
@ -156,7 +170,12 @@ libc_bitflags! {
|
|||
}
|
||||
|
||||
/// Create a special or ordinary file, by pathname.
|
||||
pub fn mknod<P: ?Sized + NixPath>(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> {
|
||||
pub fn mknod<P: ?Sized + NixPath>(
|
||||
path: &P,
|
||||
kind: SFlag,
|
||||
perm: Mode,
|
||||
dev: dev_t,
|
||||
) -> Result<()> {
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
|
||||
})?;
|
||||
|
@ -165,7 +184,12 @@ pub fn mknod<P: ?Sized + NixPath>(path: &P, kind: SFlag, perm: Mode, dev: dev_t)
|
|||
}
|
||||
|
||||
/// Create a special or ordinary file, relative to a given directory.
|
||||
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "redox",
|
||||
target_os = "haiku"
|
||||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn mknodat<P: ?Sized + NixPath>(
|
||||
dirfd: RawFd,
|
||||
|
@ -175,7 +199,12 @@ pub fn mknodat<P: ?Sized + NixPath>(
|
|||
dev: dev_t,
|
||||
) -> Result<()> {
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::mknodat(dirfd, cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
|
||||
libc::mknodat(
|
||||
dirfd,
|
||||
cstr.as_ptr(),
|
||||
kind.bits | perm.bits() as mode_t,
|
||||
dev,
|
||||
)
|
||||
})?;
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
|
@ -184,24 +213,22 @@ pub fn mknodat<P: ?Sized + NixPath>(
|
|||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const fn major(dev: dev_t) -> u64 {
|
||||
((dev >> 32) & 0xffff_f000) |
|
||||
((dev >> 8) & 0x0000_0fff)
|
||||
((dev >> 32) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const fn minor(dev: dev_t) -> u64 {
|
||||
((dev >> 12) & 0xffff_ff00) |
|
||||
((dev ) & 0x0000_00ff)
|
||||
((dev >> 12) & 0xffff_ff00) | ((dev) & 0x0000_00ff)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const fn makedev(major: u64, minor: u64) -> dev_t {
|
||||
((major & 0xffff_f000) << 32) |
|
||||
((major & 0x0000_0fff) << 8) |
|
||||
((minor & 0xffff_ff00) << 12) |
|
||||
(minor & 0x0000_00ff)
|
||||
((major & 0xffff_f000) << 32)
|
||||
| ((major & 0x0000_0fff) << 8)
|
||||
| ((minor & 0xffff_ff00) << 12)
|
||||
| (minor & 0x0000_00ff)
|
||||
}
|
||||
|
||||
pub fn umask(mode: Mode) -> Mode {
|
||||
|
@ -211,28 +238,24 @@ pub fn umask(mode: Mode) -> Mode {
|
|||
|
||||
pub fn stat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
|
||||
let mut dst = mem::MaybeUninit::uninit();
|
||||
let res = path.with_nix_path(|cstr| {
|
||||
unsafe {
|
||||
libc::stat(cstr.as_ptr(), dst.as_mut_ptr())
|
||||
}
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::stat(cstr.as_ptr(), dst.as_mut_ptr())
|
||||
})?;
|
||||
|
||||
Errno::result(res)?;
|
||||
|
||||
Ok(unsafe{dst.assume_init()})
|
||||
Ok(unsafe { dst.assume_init() })
|
||||
}
|
||||
|
||||
pub fn lstat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
|
||||
let mut dst = mem::MaybeUninit::uninit();
|
||||
let res = path.with_nix_path(|cstr| {
|
||||
unsafe {
|
||||
libc::lstat(cstr.as_ptr(), dst.as_mut_ptr())
|
||||
}
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::lstat(cstr.as_ptr(), dst.as_mut_ptr())
|
||||
})?;
|
||||
|
||||
Errno::result(res)?;
|
||||
|
||||
Ok(unsafe{dst.assume_init()})
|
||||
Ok(unsafe { dst.assume_init() })
|
||||
}
|
||||
|
||||
pub fn fstat(fd: RawFd) -> Result<FileStat> {
|
||||
|
@ -241,20 +264,29 @@ pub fn fstat(fd: RawFd) -> Result<FileStat> {
|
|||
|
||||
Errno::result(res)?;
|
||||
|
||||
Ok(unsafe{dst.assume_init()})
|
||||
Ok(unsafe { dst.assume_init() })
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn fstatat<P: ?Sized + NixPath>(dirfd: RawFd, pathname: &P, f: AtFlags) -> Result<FileStat> {
|
||||
pub fn fstatat<P: ?Sized + NixPath>(
|
||||
dirfd: RawFd,
|
||||
pathname: &P,
|
||||
f: AtFlags,
|
||||
) -> Result<FileStat> {
|
||||
let mut dst = mem::MaybeUninit::uninit();
|
||||
let res = pathname.with_nix_path(|cstr| {
|
||||
unsafe { libc::fstatat(dirfd, cstr.as_ptr(), dst.as_mut_ptr(), f.bits() as libc::c_int) }
|
||||
let res = pathname.with_nix_path(|cstr| unsafe {
|
||||
libc::fstatat(
|
||||
dirfd,
|
||||
cstr.as_ptr(),
|
||||
dst.as_mut_ptr(),
|
||||
f.bits() as libc::c_int,
|
||||
)
|
||||
})?;
|
||||
|
||||
Errno::result(res)?;
|
||||
|
||||
Ok(unsafe{dst.assume_init()})
|
||||
Ok(unsafe { dst.assume_init() })
|
||||
}
|
||||
|
||||
/// Change the file permission bits of the file specified by a file descriptor.
|
||||
|
@ -299,11 +331,10 @@ pub fn fchmodat<P: ?Sized + NixPath>(
|
|||
mode: Mode,
|
||||
flag: FchmodatFlags,
|
||||
) -> Result<()> {
|
||||
let atflag =
|
||||
match flag {
|
||||
FchmodatFlags::FollowSymlink => AtFlags::empty(),
|
||||
FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
|
||||
};
|
||||
let atflag = match flag {
|
||||
FchmodatFlags::FollowSymlink => AtFlags::empty(),
|
||||
FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
|
||||
};
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::fchmodat(
|
||||
at_rawfd(dirfd),
|
||||
|
@ -326,7 +357,11 @@ pub fn fchmodat<P: ?Sized + NixPath>(
|
|||
/// # References
|
||||
///
|
||||
/// [utimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html).
|
||||
pub fn utimes<P: ?Sized + NixPath>(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> {
|
||||
pub fn utimes<P: ?Sized + NixPath>(
|
||||
path: &P,
|
||||
atime: &TimeVal,
|
||||
mtime: &TimeVal,
|
||||
) -> Result<()> {
|
||||
let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::utimes(cstr.as_ptr(), ×[0])
|
||||
|
@ -345,14 +380,20 @@ pub fn utimes<P: ?Sized + NixPath>(path: &P, atime: &TimeVal, mtime: &TimeVal) -
|
|||
/// # References
|
||||
///
|
||||
/// [lutimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lutimes.html).
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "haiku",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "haiku",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn lutimes<P: ?Sized + NixPath>(path: &P, atime: &TimeVal, mtime: &TimeVal) -> Result<()> {
|
||||
pub fn lutimes<P: ?Sized + NixPath>(
|
||||
path: &P,
|
||||
atime: &TimeVal,
|
||||
mtime: &TimeVal,
|
||||
) -> Result<()> {
|
||||
let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::lutimes(cstr.as_ptr(), ×[0])
|
||||
|
@ -405,13 +446,12 @@ pub fn utimensat<P: ?Sized + NixPath>(
|
|||
path: &P,
|
||||
atime: &TimeSpec,
|
||||
mtime: &TimeSpec,
|
||||
flag: UtimensatFlags
|
||||
flag: UtimensatFlags,
|
||||
) -> Result<()> {
|
||||
let atflag =
|
||||
match flag {
|
||||
UtimensatFlags::FollowSymlink => AtFlags::empty(),
|
||||
UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
|
||||
};
|
||||
let atflag = match flag {
|
||||
UtimensatFlags::FollowSymlink => AtFlags::empty(),
|
||||
UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
|
||||
};
|
||||
let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()];
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::utimensat(
|
||||
|
@ -427,9 +467,13 @@ pub fn utimensat<P: ?Sized + NixPath>(
|
|||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn mkdirat<P: ?Sized + NixPath>(fd: RawFd, path: &P, mode: Mode) -> Result<()> {
|
||||
let res = path.with_nix_path(|cstr| {
|
||||
unsafe { libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t) }
|
||||
pub fn mkdirat<P: ?Sized + NixPath>(
|
||||
fd: RawFd,
|
||||
path: &P,
|
||||
mode: Mode,
|
||||
) -> Result<()> {
|
||||
let res = path.with_nix_path(|cstr| unsafe {
|
||||
libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t)
|
||||
})?;
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
//! Get filesystem statistics, non-portably
|
||||
//!
|
||||
//! See [`statvfs`](crate::sys::statvfs) for a portable alternative.
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
use std::ffi::CStr;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::mem;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
use std::ffi::CStr;
|
||||
|
||||
use crate::{NixPath, Result, errno::Errno};
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
#[cfg(all(
|
||||
feature = "mount",
|
||||
any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)
|
||||
))]
|
||||
use crate::mount::MntFlags;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::sys::statvfs::FsFlags;
|
||||
use crate::{errno::Errno, NixPath, Result};
|
||||
|
||||
/// Identifies a mounted file system
|
||||
#[cfg(target_os = "android")]
|
||||
|
@ -18,10 +33,30 @@ pub type fsid_t = libc::__fsid_t;
|
|||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub type fsid_t = libc::fsid_t;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] {
|
||||
type type_of_statfs = libc::statfs64;
|
||||
const LIBC_FSTATFS: unsafe extern fn
|
||||
(fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
|
||||
= libc::fstatfs64;
|
||||
const LIBC_STATFS: unsafe extern fn
|
||||
(path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int
|
||||
= libc::statfs64;
|
||||
} else {
|
||||
type type_of_statfs = libc::statfs;
|
||||
const LIBC_FSTATFS: unsafe extern fn
|
||||
(fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
|
||||
= libc::fstatfs;
|
||||
const LIBC_STATFS: unsafe extern fn
|
||||
(path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int
|
||||
= libc::statfs;
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes a mounted file system
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Statfs(libc::statfs);
|
||||
pub struct Statfs(type_of_statfs);
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
type fs_type_t = u32;
|
||||
|
@ -33,7 +68,14 @@ type fs_type_t = libc::c_uint;
|
|||
type fs_type_t = libc::c_ulong;
|
||||
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
|
||||
type fs_type_t = libc::c_int;
|
||||
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))]
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
not(any(
|
||||
target_arch = "s390x",
|
||||
target_env = "musl",
|
||||
target_env = "uclibc"
|
||||
))
|
||||
))]
|
||||
type fs_type_t = libc::__fsword_t;
|
||||
|
||||
/// Describes the file system type as known by the operating system.
|
||||
|
@ -42,7 +84,10 @@ type fs_type_t = libc::__fsword_t;
|
|||
target_os = "android",
|
||||
all(target_os = "linux", target_arch = "s390x"),
|
||||
all(target_os = "linux", target_env = "musl"),
|
||||
all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl"))),
|
||||
all(
|
||||
target_os = "linux",
|
||||
not(any(target_arch = "s390x", target_env = "musl"))
|
||||
),
|
||||
))]
|
||||
#[derive(Eq, Copy, Clone, PartialEq, Debug)]
|
||||
pub struct FsType(pub fs_type_t);
|
||||
|
@ -51,31 +96,38 @@ pub struct FsType(pub fs_type_t);
|
|||
// can't very well document them here.
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const ADFS_SUPER_MAGIC: FsType = FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const ADFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const AFFS_SUPER_MAGIC: FsType = FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const AFFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const AFS_SUPER_MAGIC: FsType = FsType(libc::AFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const AUTOFS_SUPER_MAGIC: FsType = FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const AUTOFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const BPF_FS_MAGIC: FsType = FsType(libc::BPF_FS_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const BTRFS_SUPER_MAGIC: FsType = FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const BTRFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const CGROUP2_SUPER_MAGIC: FsType = FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
|
||||
pub const CGROUP2_SUPER_MAGIC: FsType =
|
||||
FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const CGROUP_SUPER_MAGIC: FsType = FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
|
||||
pub const CGROUP_SUPER_MAGIC: FsType =
|
||||
FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const CODA_SUPER_MAGIC: FsType = FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
|
||||
pub const CODA_SUPER_MAGIC: FsType =
|
||||
FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
|
||||
|
@ -84,64 +136,82 @@ pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
|
|||
pub const DEBUGFS_MAGIC: FsType = FsType(libc::DEBUGFS_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const DEVPTS_SUPER_MAGIC: FsType = FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t);
|
||||
pub const DEVPTS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const ECRYPTFS_SUPER_MAGIC: FsType = FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const ECRYPTFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const EXT2_SUPER_MAGIC: FsType = FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
|
||||
pub const EXT2_SUPER_MAGIC: FsType =
|
||||
FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const EXT3_SUPER_MAGIC: FsType = FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
|
||||
pub const EXT3_SUPER_MAGIC: FsType =
|
||||
FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const EXT4_SUPER_MAGIC: FsType = FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
|
||||
pub const EXT4_SUPER_MAGIC: FsType =
|
||||
FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const F2FS_SUPER_MAGIC: FsType = FsType(libc::F2FS_SUPER_MAGIC as fs_type_t);
|
||||
pub const F2FS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::F2FS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const FUSE_SUPER_MAGIC: FsType = FsType(libc::FUSE_SUPER_MAGIC as fs_type_t);
|
||||
pub const FUSE_SUPER_MAGIC: FsType =
|
||||
FsType(libc::FUSE_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const FUTEXFS_SUPER_MAGIC: FsType = FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const FUTEXFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const HOSTFS_SUPER_MAGIC: FsType = FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const HOSTFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const HPFS_SUPER_MAGIC: FsType = FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const HPFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const ISOFS_SUPER_MAGIC: FsType = FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const ISOFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const JFFS2_SUPER_MAGIC: FsType = FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
|
||||
pub const JFFS2_SUPER_MAGIC: FsType =
|
||||
FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const MINIX2_SUPER_MAGIC2: FsType = FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
|
||||
pub const MINIX2_SUPER_MAGIC2: FsType =
|
||||
FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const MINIX2_SUPER_MAGIC: FsType = FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
|
||||
pub const MINIX2_SUPER_MAGIC: FsType =
|
||||
FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const MINIX3_SUPER_MAGIC: FsType = FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t);
|
||||
pub const MINIX3_SUPER_MAGIC: FsType =
|
||||
FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const MINIX_SUPER_MAGIC2: FsType = FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
|
||||
pub const MINIX_SUPER_MAGIC2: FsType =
|
||||
FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const MINIX_SUPER_MAGIC: FsType = FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
|
||||
pub const MINIX_SUPER_MAGIC: FsType =
|
||||
FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const MSDOS_SUPER_MAGIC: FsType = FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
|
||||
pub const MSDOS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
|
||||
|
@ -150,34 +220,44 @@ pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
|
|||
pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const NILFS_SUPER_MAGIC: FsType = FsType(libc::NILFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const NILFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::NILFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const OCFS2_SUPER_MAGIC: FsType = FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t);
|
||||
pub const OCFS2_SUPER_MAGIC: FsType =
|
||||
FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const OPENPROM_SUPER_MAGIC: FsType = FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
|
||||
pub const OPENPROM_SUPER_MAGIC: FsType =
|
||||
FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const OVERLAYFS_SUPER_MAGIC: FsType = FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const OVERLAYFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const PROC_SUPER_MAGIC: FsType = FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
|
||||
pub const PROC_SUPER_MAGIC: FsType =
|
||||
FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const QNX4_SUPER_MAGIC: FsType = FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
|
||||
pub const QNX4_SUPER_MAGIC: FsType =
|
||||
FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const QNX6_SUPER_MAGIC: FsType = FsType(libc::QNX6_SUPER_MAGIC as fs_type_t);
|
||||
pub const QNX6_SUPER_MAGIC: FsType =
|
||||
FsType(libc::QNX6_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const RDTGROUP_SUPER_MAGIC: FsType = FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t);
|
||||
pub const RDTGROUP_SUPER_MAGIC: FsType =
|
||||
FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const REISERFS_SUPER_MAGIC: FsType = FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
|
||||
pub const REISERFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const SECURITYFS_MAGIC: FsType = FsType(libc::SECURITYFS_MAGIC as fs_type_t);
|
||||
pub const SECURITYFS_MAGIC: FsType =
|
||||
FsType(libc::SECURITYFS_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const SELINUX_MAGIC: FsType = FsType(libc::SELINUX_MAGIC as fs_type_t);
|
||||
|
@ -201,11 +281,21 @@ pub const TRACEFS_MAGIC: FsType = FsType(libc::TRACEFS_MAGIC as fs_type_t);
|
|||
pub const UDF_SUPER_MAGIC: FsType = FsType(libc::UDF_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const USBDEVICE_SUPER_MAGIC: FsType = FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
|
||||
pub const USBDEVICE_SUPER_MAGIC: FsType =
|
||||
FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const XENFS_SUPER_MAGIC: FsType = FsType(libc::XENFS_SUPER_MAGIC as fs_type_t);
|
||||
|
||||
pub const XENFS_SUPER_MAGIC: FsType =
|
||||
FsType(libc::XENFS_SUPER_MAGIC as fs_type_t);
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[allow(missing_docs)]
|
||||
pub const NSFS_MAGIC: FsType = FsType(libc::NSFS_MAGIC as fs_type_t);
|
||||
#[cfg(all(
|
||||
any(target_os = "linux", target_os = "android"),
|
||||
not(target_env = "musl")
|
||||
))]
|
||||
#[allow(missing_docs)]
|
||||
pub const XFS_SUPER_MAGIC: FsType = FsType(libc::XFS_SUPER_MAGIC as fs_type_t);
|
||||
|
||||
impl Statfs {
|
||||
/// Magic code defining system type
|
||||
|
@ -260,7 +350,14 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Optimal transfer block size
|
||||
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))]
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
not(any(
|
||||
target_arch = "s390x",
|
||||
target_env = "musl",
|
||||
target_env = "uclibc"
|
||||
))
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn optimal_transfer_size(&self) -> libc::__fsword_t {
|
||||
self.0.f_bsize
|
||||
|
@ -320,7 +417,14 @@ impl Statfs {
|
|||
|
||||
/// Size of a block
|
||||
// f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
|
||||
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))]
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
not(any(
|
||||
target_arch = "s390x",
|
||||
target_env = "musl",
|
||||
target_env = "uclibc"
|
||||
))
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn block_size(&self) -> libc::__fsword_t {
|
||||
self.0.f_bsize
|
||||
|
@ -347,6 +451,32 @@ impl Statfs {
|
|||
self.0.f_bsize
|
||||
}
|
||||
|
||||
/// Get the mount flags
|
||||
#[cfg(all(
|
||||
feature = "mount",
|
||||
any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
#[allow(clippy::unnecessary_cast)] // Not unnecessary on all arches
|
||||
pub fn flags(&self) -> MntFlags {
|
||||
MntFlags::from_bits_truncate(self.0.f_flags as i32)
|
||||
}
|
||||
|
||||
/// Get the mount flags
|
||||
// The f_flags field exists on Android and Fuchsia too, but without man
|
||||
// pages I can't tell if it can be cast to FsFlags.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn flags(&self) -> FsFlags {
|
||||
FsFlags::from_bits_truncate(self.0.f_flags as libc::c_ulong)
|
||||
}
|
||||
|
||||
/// Maximum length of filenames
|
||||
#[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
|
@ -376,7 +506,14 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Maximum length of filenames
|
||||
#[cfg(all(target_os = "linux", not(any(target_arch = "s390x", target_env = "musl", target_env = "uclibc"))))]
|
||||
#[cfg(all(
|
||||
target_os = "linux",
|
||||
not(any(
|
||||
target_arch = "s390x",
|
||||
target_env = "musl",
|
||||
target_env = "uclibc"
|
||||
))
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn maximum_name_length(&self) -> libc::__fsword_t {
|
||||
self.0.f_namelen
|
||||
|
@ -395,7 +532,9 @@ impl Statfs {
|
|||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "openbsd",
|
||||
target_os = "linux",
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks(&self) -> u64 {
|
||||
|
@ -410,24 +549,9 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Total data blocks in filesystem
|
||||
#[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks(&self) -> u64 {
|
||||
self.0.f_blocks
|
||||
}
|
||||
|
||||
/// Total data blocks in filesystem
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
|
||||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks(&self) -> libc::c_ulong {
|
||||
pub fn blocks(&self) -> u32 {
|
||||
self.0.f_blocks
|
||||
}
|
||||
|
||||
|
@ -437,7 +561,9 @@ impl Statfs {
|
|||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "openbsd",
|
||||
target_os = "linux",
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks_free(&self) -> u64 {
|
||||
|
@ -452,29 +578,20 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Free blocks in filesystem
|
||||
#[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks_free(&self) -> u64 {
|
||||
self.0.f_bfree
|
||||
}
|
||||
|
||||
/// Free blocks in filesystem
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
|
||||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks_free(&self) -> libc::c_ulong {
|
||||
pub fn blocks_free(&self) -> u32 {
|
||||
self.0.f_bfree
|
||||
}
|
||||
|
||||
/// Free blocks available to unprivileged user
|
||||
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "android"))]
|
||||
#[cfg(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "fuchsia",
|
||||
target_os = "linux",
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks_available(&self) -> u64 {
|
||||
self.0.f_bavail
|
||||
|
@ -495,24 +612,9 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Free blocks available to unprivileged user
|
||||
#[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks_available(&self) -> u64 {
|
||||
self.0.f_bavail
|
||||
}
|
||||
|
||||
/// Free blocks available to unprivileged user
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
|
||||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn blocks_available(&self) -> libc::c_ulong {
|
||||
pub fn blocks_available(&self) -> u32 {
|
||||
self.0.f_bavail
|
||||
}
|
||||
|
||||
|
@ -522,7 +624,9 @@ impl Statfs {
|
|||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
target_os = "openbsd",
|
||||
target_os = "linux",
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn files(&self) -> u64 {
|
||||
|
@ -537,33 +641,20 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Total file nodes in filesystem
|
||||
#[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn files(&self) -> libc::fsfilcnt_t {
|
||||
self.0.f_files
|
||||
}
|
||||
|
||||
/// Total file nodes in filesystem
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
|
||||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn files(&self) -> libc::c_ulong {
|
||||
pub fn files(&self) -> u32 {
|
||||
self.0.f_files
|
||||
}
|
||||
|
||||
/// Free file nodes in filesystem
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "openbsd"
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "fuchsia",
|
||||
target_os = "openbsd",
|
||||
target_os = "linux",
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn files_free(&self) -> u64 {
|
||||
|
@ -585,24 +676,9 @@ impl Statfs {
|
|||
}
|
||||
|
||||
/// Free file nodes in filesystem
|
||||
#[cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32"))))]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn files_free(&self) -> libc::fsfilcnt_t {
|
||||
self.0.f_ffree
|
||||
}
|
||||
|
||||
/// Free file nodes in filesystem
|
||||
#[cfg(not(any(
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "android",
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
all(target_os = "linux", any(target_env = "musl", target_arch = "riscv32", all(target_arch = "x86_64", target_pointer_width = "32")))
|
||||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn files_free(&self) -> libc::c_ulong {
|
||||
pub fn files_free(&self) -> u32 {
|
||||
self.0.f_ffree
|
||||
}
|
||||
|
||||
|
@ -614,16 +690,27 @@ impl Statfs {
|
|||
|
||||
impl Debug for Statfs {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Statfs")
|
||||
.field("optimal_transfer_size", &self.optimal_transfer_size())
|
||||
.field("block_size", &self.block_size())
|
||||
.field("blocks", &self.blocks())
|
||||
.field("blocks_free", &self.blocks_free())
|
||||
.field("blocks_available", &self.blocks_available())
|
||||
.field("files", &self.files())
|
||||
.field("files_free", &self.files_free())
|
||||
.field("filesystem_id", &self.filesystem_id())
|
||||
.finish()
|
||||
let mut ds = f.debug_struct("Statfs");
|
||||
ds.field("optimal_transfer_size", &self.optimal_transfer_size());
|
||||
ds.field("block_size", &self.block_size());
|
||||
ds.field("blocks", &self.blocks());
|
||||
ds.field("blocks_free", &self.blocks_free());
|
||||
ds.field("blocks_available", &self.blocks_available());
|
||||
ds.field("files", &self.files());
|
||||
ds.field("files_free", &self.files_free());
|
||||
ds.field("filesystem_id", &self.filesystem_id());
|
||||
#[cfg(all(
|
||||
feature = "mount",
|
||||
any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)
|
||||
))]
|
||||
ds.field("flags", &self.flags());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,8 +724,10 @@ impl Debug for Statfs {
|
|||
/// `path` - Path to any file within the file system to describe
|
||||
pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
|
||||
unsafe {
|
||||
let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
|
||||
let res = path.with_nix_path(|path| libc::statfs(path.as_ptr(), stat.as_mut_ptr()))?;
|
||||
let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
|
||||
let res = path.with_nix_path(|path| {
|
||||
LIBC_STATFS(path.as_ptr(), stat.as_mut_ptr())
|
||||
})?;
|
||||
Errno::result(res).map(|_| Statfs(stat.assume_init()))
|
||||
}
|
||||
}
|
||||
|
@ -653,8 +742,8 @@ pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
|
|||
/// `fd` - File descriptor of any open file within the file system to describe
|
||||
pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
|
||||
unsafe {
|
||||
let mut stat = mem::MaybeUninit::<libc::statfs>::uninit();
|
||||
Errno::result(libc::fstatfs(fd.as_raw_fd(), stat.as_mut_ptr()))
|
||||
let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
|
||||
Errno::result(LIBC_FSTATFS(fd.as_raw_fd(), stat.as_mut_ptr()))
|
||||
.map(|_| Statfs(stat.assume_init()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::os::unix::io::AsRawFd;
|
|||
|
||||
use libc::{self, c_ulong};
|
||||
|
||||
use crate::{Result, NixPath, errno::Errno};
|
||||
use crate::{errno::Errno, NixPath, Result};
|
||||
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
libc_bitflags!(
|
||||
|
@ -130,7 +130,6 @@ impl Statvfs {
|
|||
pub fn name_max(&self) -> c_ulong {
|
||||
self.0.f_namemax
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Return a `Statvfs` object with information about the `path`
|
||||
|
@ -138,9 +137,9 @@ pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
|
|||
unsafe {
|
||||
Errno::clear();
|
||||
let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
|
||||
let res = path.with_nix_path(|path|
|
||||
let res = path.with_nix_path(|path| {
|
||||
libc::statvfs(path.as_ptr(), stat.as_mut_ptr())
|
||||
)?;
|
||||
})?;
|
||||
|
||||
Errno::result(res).map(|_| Statvfs(stat.assume_init()))
|
||||
}
|
||||
|
@ -158,8 +157,8 @@ pub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::fs::File;
|
||||
use crate::sys::statvfs::*;
|
||||
use std::fs::File;
|
||||
|
||||
#[test]
|
||||
fn statvfs_call() {
|
||||
|
|
|
@ -85,12 +85,28 @@
|
|||
//!
|
||||
//! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`:
|
||||
//!
|
||||
#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
|
||||
doc = " ```rust,ignore")]
|
||||
#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
|
||||
doc = " ```rust")]
|
||||
#![cfg_attr(
|
||||
any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
doc = " ```rust,ignore"
|
||||
)]
|
||||
#![cfg_attr(
|
||||
not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)),
|
||||
doc = " ```rust"
|
||||
)]
|
||||
//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
|
||||
//! # fn main() {
|
||||
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
|
||||
|
@ -102,12 +118,28 @@
|
|||
//!
|
||||
//! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s:
|
||||
//!
|
||||
#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
|
||||
doc = " ```rust")]
|
||||
#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
|
||||
doc = " ```rust,ignore")]
|
||||
#![cfg_attr(
|
||||
any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
doc = " ```rust"
|
||||
)]
|
||||
#![cfg_attr(
|
||||
not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)),
|
||||
doc = " ```rust,ignore"
|
||||
)]
|
||||
//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
|
||||
//! # fn main() {
|
||||
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
|
||||
|
@ -119,12 +151,28 @@
|
|||
//!
|
||||
//! It's trivial to convert from a `BaudRate` to a `u32` on BSDs:
|
||||
//!
|
||||
#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
|
||||
doc = " ```rust")]
|
||||
#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
|
||||
doc = " ```rust,ignore")]
|
||||
#![cfg_attr(
|
||||
any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
doc = " ```rust"
|
||||
)]
|
||||
#![cfg_attr(
|
||||
not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)),
|
||||
doc = " ```rust,ignore"
|
||||
)]
|
||||
//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios};
|
||||
//! # fn main() {
|
||||
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
|
||||
|
@ -137,12 +185,28 @@
|
|||
//! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support)
|
||||
//! by specifying baud rates directly using `u32`s:
|
||||
//!
|
||||
#![cfg_attr(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd"),
|
||||
doc = " ```rust")]
|
||||
#![cfg_attr(not(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
|
||||
target_os = "macos", target_os = "netbsd", target_os = "openbsd")),
|
||||
doc = " ```rust,ignore")]
|
||||
#![cfg_attr(
|
||||
any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
doc = " ```rust"
|
||||
)]
|
||||
#![cfg_attr(
|
||||
not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)),
|
||||
doc = " ```rust,ignore"
|
||||
)]
|
||||
//! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios};
|
||||
//! # fn main() {
|
||||
//! # let mut t: Termios = unsafe { std::mem::zeroed() };
|
||||
|
@ -151,9 +215,9 @@
|
|||
//! cfsetspeed(&mut t, 9600u32);
|
||||
//! # }
|
||||
//! ```
|
||||
use cfg_if::cfg_if;
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use crate::Result;
|
||||
use cfg_if::cfg_if;
|
||||
use libc::{self, c_int, tcflag_t};
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::convert::From;
|
||||
|
@ -181,6 +245,12 @@ pub struct Termios {
|
|||
pub local_flags: LocalFlags,
|
||||
/// Control characters (see `termios.c_cc` documentation)
|
||||
pub control_chars: [libc::cc_t; NCCS],
|
||||
/// Line discipline (see `termios.c_line` documentation)
|
||||
#[cfg(any(target_os = "linux", target_os = "android",))]
|
||||
pub line_discipline: libc::cc_t,
|
||||
/// Line discipline (see `termios.c_line` documentation)
|
||||
#[cfg(target_os = "haiku")]
|
||||
pub line_discipline: libc::c_char,
|
||||
}
|
||||
|
||||
impl Termios {
|
||||
|
@ -196,6 +266,14 @@ impl Termios {
|
|||
termios.c_cflag = self.control_flags.bits();
|
||||
termios.c_lflag = self.local_flags.bits();
|
||||
termios.c_cc = self.control_chars;
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "haiku",
|
||||
))]
|
||||
{
|
||||
termios.c_line = self.line_discipline;
|
||||
}
|
||||
}
|
||||
self.inner.borrow()
|
||||
}
|
||||
|
@ -214,6 +292,14 @@ impl Termios {
|
|||
termios.c_cflag = self.control_flags.bits();
|
||||
termios.c_lflag = self.local_flags.bits();
|
||||
termios.c_cc = self.control_chars;
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "haiku",
|
||||
))]
|
||||
{
|
||||
termios.c_line = self.line_discipline;
|
||||
}
|
||||
}
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
@ -226,6 +312,14 @@ impl Termios {
|
|||
self.control_flags = ControlFlags::from_bits_truncate(termios.c_cflag);
|
||||
self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag);
|
||||
self.control_chars = termios.c_cc;
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "haiku",
|
||||
))]
|
||||
{
|
||||
self.line_discipline = termios.c_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +332,12 @@ impl From<libc::termios> for Termios {
|
|||
control_flags: ControlFlags::from_bits_truncate(termios.c_cflag),
|
||||
local_flags: LocalFlags::from_bits_truncate(termios.c_lflag),
|
||||
control_chars: termios.c_cc,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "android",
|
||||
target_os = "haiku",
|
||||
))]
|
||||
line_discipline: termios.c_line,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +348,7 @@ impl From<Termios> for libc::termios {
|
|||
}
|
||||
}
|
||||
|
||||
libc_enum!{
|
||||
libc_enum! {
|
||||
/// Baud rates supported by the system.
|
||||
///
|
||||
/// For the BSDs, arbitrary baud rates can be specified by using `u32`s directly instead of this
|
||||
|
@ -363,12 +463,14 @@ libc_enum!{
|
|||
impl TryFrom<libc::speed_t>
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
impl From<BaudRate> for u32 {
|
||||
fn from(b: BaudRate) -> u32 {
|
||||
b as u32
|
||||
|
@ -382,7 +484,6 @@ impl From<BaudRate> for u8 {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add TCSASOFT, which will require treating this as a bitfield.
|
||||
libc_enum! {
|
||||
/// Specify when a port configuration change should occur.
|
||||
|
@ -499,21 +600,26 @@ libc_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(all(target_os = "linux", target_arch = "sparc64"),
|
||||
target_os = "illumos", target_os = "solaris"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "linux", target_arch = "sparc64"),
|
||||
target_os = "illumos",
|
||||
target_os = "solaris"
|
||||
))]
|
||||
impl SpecialCharacterIndices {
|
||||
pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF;
|
||||
pub const VTIME: SpecialCharacterIndices = SpecialCharacterIndices::VEOL;
|
||||
}
|
||||
|
||||
pub use libc::NCCS;
|
||||
#[cfg(any(target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub use libc::_POSIX_VDISABLE;
|
||||
|
||||
|
@ -883,7 +989,7 @@ libc_bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
cfg_if!{
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "ios",
|
||||
|
@ -1055,7 +1161,10 @@ pub fn tcgetattr(fd: RawFd) -> Result<Termios> {
|
|||
/// *any* of the parameters were successfully set, not only if all were set successfully.
|
||||
pub fn tcsetattr(fd: RawFd, actions: SetArg, termios: &Termios) -> Result<()> {
|
||||
let inner_termios = termios.get_libc_termios();
|
||||
Errno::result(unsafe { libc::tcsetattr(fd, actions as c_int, &*inner_termios) }).map(drop)
|
||||
Errno::result(unsafe {
|
||||
libc::tcsetattr(fd, actions as c_int, &*inner_termios)
|
||||
})
|
||||
.map(drop)
|
||||
}
|
||||
|
||||
/// Block until all output data is written (see
|
||||
|
|
|
@ -6,9 +6,12 @@ use std::convert::From;
|
|||
use std::time::Duration;
|
||||
use std::{cmp, fmt, ops};
|
||||
|
||||
const TIMESPEC_ZERO: libc::timespec = unsafe {
|
||||
std::mem::transmute([0u8; std::mem::size_of::<libc::timespec>()])
|
||||
};
|
||||
const fn zero_init_timespec() -> timespec {
|
||||
// `std::mem::MaybeUninit::zeroed()` is not yet a const fn
|
||||
// (https://github.com/rust-lang/rust/issues/91850) so we will instead initialize an array of
|
||||
// the appropriate size to zero and then transmute it to a timespec value.
|
||||
unsafe { std::mem::transmute([0u8; std::mem::size_of::<timespec>()]) }
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
all(feature = "time", any(target_os = "android", target_os = "linux")),
|
||||
|
@ -24,7 +27,7 @@ const TIMESPEC_ZERO: libc::timespec = unsafe {
|
|||
)
|
||||
))]
|
||||
pub(crate) mod timer {
|
||||
use crate::sys::time::{TimeSpec, TIMESPEC_ZERO};
|
||||
use crate::sys::time::{zero_init_timespec, TimeSpec};
|
||||
use bitflags::bitflags;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -33,8 +36,8 @@ pub(crate) mod timer {
|
|||
impl TimerSpec {
|
||||
pub const fn none() -> Self {
|
||||
Self(libc::itimerspec {
|
||||
it_interval: TIMESPEC_ZERO,
|
||||
it_value: TIMESPEC_ZERO,
|
||||
it_interval: zero_init_timespec(),
|
||||
it_value: zero_init_timespec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +58,7 @@ pub(crate) mod timer {
|
|||
fn from(expiration: Expiration) -> TimerSpec {
|
||||
match expiration {
|
||||
Expiration::OneShot(t) => TimerSpec(libc::itimerspec {
|
||||
it_interval: TIMESPEC_ZERO,
|
||||
it_interval: zero_init_timespec(),
|
||||
it_value: *t.as_ref(),
|
||||
}),
|
||||
Expiration::IntervalDelayed(start, interval) => {
|
||||
|
@ -261,9 +264,8 @@ impl TimeValLike for TimeSpec {
|
|||
"TimeSpec out of bounds; seconds={}",
|
||||
seconds
|
||||
);
|
||||
let mut ts = TIMESPEC_ZERO;
|
||||
let mut ts = zero_init_timespec();
|
||||
ts.tv_sec = seconds as time_t;
|
||||
ts.tv_nsec = 0;
|
||||
TimeSpec(ts)
|
||||
}
|
||||
|
||||
|
@ -296,7 +298,7 @@ impl TimeValLike for TimeSpec {
|
|||
(TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs),
|
||||
"TimeSpec out of bounds"
|
||||
);
|
||||
let mut ts = TIMESPEC_ZERO;
|
||||
let mut ts = zero_init_timespec();
|
||||
ts.tv_sec = secs as time_t;
|
||||
ts.tv_nsec = nanos as timespec_tv_nsec_t;
|
||||
TimeSpec(ts)
|
||||
|
@ -333,7 +335,7 @@ impl TimeSpec {
|
|||
/// Construct a new `TimeSpec` from its components
|
||||
#[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
|
||||
pub const fn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self {
|
||||
let mut ts = TIMESPEC_ZERO;
|
||||
let mut ts = zero_init_timespec();
|
||||
ts.tv_sec = seconds;
|
||||
ts.tv_nsec = nanoseconds;
|
||||
Self(ts)
|
||||
|
@ -359,7 +361,7 @@ impl TimeSpec {
|
|||
#[cfg_attr(target_env = "musl", allow(deprecated))]
|
||||
// https://github.com/rust-lang/libc/issues/1848
|
||||
pub const fn from_duration(duration: Duration) -> Self {
|
||||
let mut ts = TIMESPEC_ZERO;
|
||||
let mut ts = zero_init_timespec();
|
||||
ts.tv_sec = duration.as_secs() as time_t;
|
||||
ts.tv_nsec = duration.subsec_nanos() as timespec_tv_nsec_t;
|
||||
TimeSpec(ts)
|
||||
|
|
|
@ -70,9 +70,10 @@ pub struct Timer(libc::timer_t);
|
|||
impl Timer {
|
||||
/// Creates a new timer based on the clock defined by `clockid`. The details
|
||||
/// of the signal and its handler are defined by the passed `sigevent`.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timer_create")))]
|
||||
#[doc(alias("timer_create"))]
|
||||
pub fn new(clockid: ClockId, mut sigevent: SigEvent) -> Result<Self> {
|
||||
let mut timer_id: mem::MaybeUninit<libc::timer_t> = mem::MaybeUninit::uninit();
|
||||
let mut timer_id: mem::MaybeUninit<libc::timer_t> =
|
||||
mem::MaybeUninit::uninit();
|
||||
Errno::result(unsafe {
|
||||
libc::timer_create(
|
||||
clockid.as_raw(),
|
||||
|
@ -123,8 +124,12 @@ impl Timer {
|
|||
///
|
||||
/// Note: Setting a one shot alarm with a 0s TimeSpec disable the alarm
|
||||
/// altogether.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timer_settime")))]
|
||||
pub fn set(&mut self, expiration: Expiration, flags: TimerSetTimeFlags) -> Result<()> {
|
||||
#[doc(alias("timer_settime"))]
|
||||
pub fn set(
|
||||
&mut self,
|
||||
expiration: Expiration,
|
||||
flags: TimerSetTimeFlags,
|
||||
) -> Result<()> {
|
||||
let timerspec: TimerSpec = expiration.into();
|
||||
Errno::result(unsafe {
|
||||
libc::timer_settime(
|
||||
|
@ -138,10 +143,13 @@ impl Timer {
|
|||
}
|
||||
|
||||
/// Get the parameters for the alarm currently set, if any.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timer_gettime")))]
|
||||
#[doc(alias("timer_gettime"))]
|
||||
pub fn get(&self) -> Result<Option<Expiration>> {
|
||||
let mut timerspec = TimerSpec::none();
|
||||
Errno::result(unsafe { libc::timer_gettime(self.0, timerspec.as_mut()) }).map(|_| {
|
||||
Errno::result(unsafe {
|
||||
libc::timer_gettime(self.0, timerspec.as_mut())
|
||||
})
|
||||
.map(|_| {
|
||||
if timerspec.as_ref().it_interval.tv_sec == 0
|
||||
&& timerspec.as_ref().it_interval.tv_nsec == 0
|
||||
&& timerspec.as_ref().it_value.tv_sec == 0
|
||||
|
@ -161,7 +169,7 @@ impl Timer {
|
|||
/// 'overrun'. This function returns how many times that has happened to
|
||||
/// this timer, up to `libc::DELAYTIMER_MAX`. If more than the maximum
|
||||
/// number of overruns have happened the return is capped to the maximum.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timer_getoverrun")))]
|
||||
#[doc(alias("timer_getoverrun"))]
|
||||
pub fn overruns(&self) -> i32 {
|
||||
unsafe { libc::timer_getoverrun(self.0) }
|
||||
}
|
||||
|
|
|
@ -92,10 +92,12 @@ impl TimerFd {
|
|||
/// Creates a new timer based on the clock defined by `clockid`. The
|
||||
/// underlying fd can be assigned specific flags with `flags` (CLOEXEC,
|
||||
/// NONBLOCK). The underlying fd will be closed on drop.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timerfd_create")))]
|
||||
#[doc(alias("timerfd_create"))]
|
||||
pub fn new(clockid: ClockId, flags: TimerFlags) -> Result<Self> {
|
||||
Errno::result(unsafe { libc::timerfd_create(clockid as i32, flags.bits()) })
|
||||
.map(|fd| Self { fd })
|
||||
Errno::result(unsafe {
|
||||
libc::timerfd_create(clockid as i32, flags.bits())
|
||||
})
|
||||
.map(|fd| Self { fd })
|
||||
}
|
||||
|
||||
/// Sets a new alarm on the timer.
|
||||
|
@ -134,8 +136,12 @@ impl TimerFd {
|
|||
///
|
||||
/// Note: Setting a one shot alarm with a 0s TimeSpec disables the alarm
|
||||
/// altogether.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timerfd_settime")))]
|
||||
pub fn set(&self, expiration: Expiration, flags: TimerSetTimeFlags) -> Result<()> {
|
||||
#[doc(alias("timerfd_settime"))]
|
||||
pub fn set(
|
||||
&self,
|
||||
expiration: Expiration,
|
||||
flags: TimerSetTimeFlags,
|
||||
) -> Result<()> {
|
||||
let timerspec: TimerSpec = expiration.into();
|
||||
Errno::result(unsafe {
|
||||
libc::timerfd_settime(
|
||||
|
@ -149,10 +155,13 @@ impl TimerFd {
|
|||
}
|
||||
|
||||
/// Get the parameters for the alarm currently set, if any.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timerfd_gettime")))]
|
||||
#[doc(alias("timerfd_gettime"))]
|
||||
pub fn get(&self) -> Result<Option<Expiration>> {
|
||||
let mut timerspec = TimerSpec::none();
|
||||
Errno::result(unsafe { libc::timerfd_gettime(self.fd, timerspec.as_mut()) }).map(|_| {
|
||||
Errno::result(unsafe {
|
||||
libc::timerfd_gettime(self.fd, timerspec.as_mut())
|
||||
})
|
||||
.map(|_| {
|
||||
if timerspec.as_ref().it_interval.tv_sec == 0
|
||||
&& timerspec.as_ref().it_interval.tv_nsec == 0
|
||||
&& timerspec.as_ref().it_value.tv_sec == 0
|
||||
|
@ -166,7 +175,7 @@ impl TimerFd {
|
|||
}
|
||||
|
||||
/// Remove the alarm if any is set.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("timerfd_settime")))]
|
||||
#[doc(alias("timerfd_settime"))]
|
||||
pub fn unset(&self) -> Result<()> {
|
||||
Errno::result(unsafe {
|
||||
libc::timerfd_settime(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Vectored I/O
|
||||
|
||||
use crate::Result;
|
||||
use crate::errno::Errno;
|
||||
use libc::{self, c_int, c_void, size_t, off_t};
|
||||
use crate::Result;
|
||||
use libc::{self, c_int, c_void, off_t, size_t};
|
||||
use std::io::{IoSlice, IoSliceMut};
|
||||
use std::marker::PhantomData;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
@ -12,13 +12,15 @@ use std::os::unix::io::RawFd;
|
|||
/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html)
|
||||
pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
|
||||
// SAFETY: to quote the documentation for `IoSlice`:
|
||||
//
|
||||
// [IoSlice] is semantically a wrapper around a &[u8], but is
|
||||
//
|
||||
// [IoSlice] is semantically a wrapper around a &[u8], but is
|
||||
// guaranteed to be ABI compatible with the iovec type on Unix
|
||||
// platforms.
|
||||
//
|
||||
// Because it is ABI compatible, a pointer cast here is valid
|
||||
let res = unsafe { libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) };
|
||||
let res = unsafe {
|
||||
libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
}
|
||||
|
@ -28,7 +30,9 @@ pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
|
|||
/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html)
|
||||
pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
|
||||
// SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec
|
||||
let res = unsafe { libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int) };
|
||||
let res = unsafe {
|
||||
libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
}
|
||||
|
@ -41,15 +45,18 @@ pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
|
|||
/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html)
|
||||
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>],
|
||||
offset: off_t) -> Result<usize> {
|
||||
|
||||
pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
|
||||
#[cfg(target_env = "uclibc")]
|
||||
let offset = offset as libc::off64_t; // uclibc doesn't use off_t
|
||||
|
||||
// SAFETY: same as in writev()
|
||||
let res = unsafe {
|
||||
libc::pwritev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset)
|
||||
libc::pwritev(
|
||||
fd,
|
||||
iov.as_ptr() as *const libc::iovec,
|
||||
iov.len() as c_int,
|
||||
offset,
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
|
@ -64,14 +71,22 @@ pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>],
|
|||
/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html)
|
||||
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn preadv(fd: RawFd, iov: &mut [IoSliceMut<'_>],
|
||||
offset: off_t) -> Result<usize> {
|
||||
pub fn preadv(
|
||||
fd: RawFd,
|
||||
iov: &mut [IoSliceMut<'_>],
|
||||
offset: off_t,
|
||||
) -> Result<usize> {
|
||||
#[cfg(target_env = "uclibc")]
|
||||
let offset = offset as libc::off64_t; // uclibc doesn't use off_t
|
||||
|
||||
// SAFETY: same as in readv()
|
||||
let res = unsafe {
|
||||
libc::preadv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int, offset)
|
||||
libc::preadv(
|
||||
fd,
|
||||
iov.as_ptr() as *const libc::iovec,
|
||||
iov.len() as c_int,
|
||||
offset,
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
|
@ -83,8 +98,12 @@ pub fn preadv(fd: RawFd, iov: &mut [IoSliceMut<'_>],
|
|||
// TODO: move to unistd
|
||||
pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
|
||||
let res = unsafe {
|
||||
libc::pwrite(fd, buf.as_ptr() as *const c_void, buf.len() as size_t,
|
||||
offset)
|
||||
libc::pwrite(
|
||||
fd,
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len() as size_t,
|
||||
offset,
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
|
@ -94,10 +113,14 @@ pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
|
|||
///
|
||||
/// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html)
|
||||
// TODO: move to unistd
|
||||
pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize>{
|
||||
pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize> {
|
||||
let res = unsafe {
|
||||
libc::pread(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t,
|
||||
offset)
|
||||
libc::pread(
|
||||
fd,
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len() as size_t,
|
||||
offset,
|
||||
)
|
||||
};
|
||||
|
||||
Errno::result(res).map(|r| r as usize)
|
||||
|
@ -151,9 +174,7 @@ impl<T> IoVec<T> {
|
|||
use std::slice;
|
||||
|
||||
unsafe {
|
||||
slice::from_raw_parts(
|
||||
self.0.iov_base as *const u8,
|
||||
self.0.iov_len)
|
||||
slice::from_raw_parts(self.0.iov_base as *const u8, self.0.iov_len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,30 +182,30 @@ impl<T> IoVec<T> {
|
|||
#[allow(deprecated)]
|
||||
impl<'a> IoVec<&'a [u8]> {
|
||||
/// Create an `IoVec` from a Rust slice.
|
||||
#[deprecated(
|
||||
since = "0.24.0",
|
||||
note = "Use `IoSlice::new` instead"
|
||||
)]
|
||||
#[deprecated(since = "0.24.0", note = "Use `IoSlice::new` instead")]
|
||||
pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> {
|
||||
IoVec(libc::iovec {
|
||||
iov_base: buf.as_ptr() as *mut c_void,
|
||||
iov_len: buf.len() as size_t,
|
||||
}, PhantomData)
|
||||
IoVec(
|
||||
libc::iovec {
|
||||
iov_base: buf.as_ptr() as *mut c_void,
|
||||
iov_len: buf.len() as size_t,
|
||||
},
|
||||
PhantomData,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a> IoVec<&'a mut [u8]> {
|
||||
/// Create an `IoVec` from a mutable Rust slice.
|
||||
#[deprecated(
|
||||
since = "0.24.0",
|
||||
note = "Use `IoSliceMut::new` instead"
|
||||
)]
|
||||
#[deprecated(since = "0.24.0", note = "Use `IoSliceMut::new` instead")]
|
||||
pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> {
|
||||
IoVec(libc::iovec {
|
||||
iov_base: buf.as_ptr() as *mut c_void,
|
||||
iov_len: buf.len() as size_t,
|
||||
}, PhantomData)
|
||||
IoVec(
|
||||
libc::iovec {
|
||||
iov_base: buf.as_ptr() as *mut c_void,
|
||||
iov_len: buf.len() as size_t,
|
||||
},
|
||||
PhantomData,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Get system identification
|
||||
use crate::{Errno, Result};
|
||||
use libc::c_char;
|
||||
use std::ffi::OsStr;
|
||||
use std::mem;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::ffi::OsStr;
|
||||
use libc::c_char;
|
||||
use crate::{Errno, Result};
|
||||
|
||||
/// Describes the running system. Return type of [`uname`].
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
|
@ -35,6 +35,12 @@ impl UtsName {
|
|||
pub fn machine(&self) -> &OsStr {
|
||||
cast_and_trim(&self.0.machine)
|
||||
}
|
||||
|
||||
/// NIS or YP domain name of this machine.
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub fn domainname(&self) -> &OsStr {
|
||||
cast_and_trim(&self.0.domainname)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get system identification
|
||||
|
@ -47,10 +53,12 @@ pub fn uname() -> Result<UtsName> {
|
|||
}
|
||||
|
||||
fn cast_and_trim(slice: &[c_char]) -> &OsStr {
|
||||
let length = slice.iter().position(|&byte| byte == 0).unwrap_or(slice.len());
|
||||
let bytes = unsafe {
|
||||
std::slice::from_raw_parts(slice.as_ptr().cast(), length)
|
||||
};
|
||||
let length = slice
|
||||
.iter()
|
||||
.position(|&byte| byte == 0)
|
||||
.unwrap_or(slice.len());
|
||||
let bytes =
|
||||
unsafe { std::slice::from_raw_parts(slice.as_ptr().cast(), length) };
|
||||
|
||||
OsStr::from_bytes(bytes)
|
||||
}
|
||||
|
|
|
@ -135,7 +135,9 @@ impl WaitStatus {
|
|||
pub fn pid(&self) -> Option<Pid> {
|
||||
use self::WaitStatus::*;
|
||||
match *self {
|
||||
Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => Some(p),
|
||||
Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => {
|
||||
Some(p)
|
||||
}
|
||||
StillAlive => None,
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p),
|
||||
|
@ -274,7 +276,9 @@ impl WaitStatus {
|
|||
Signal::try_from(si_status)?,
|
||||
siginfo.si_code == libc::CLD_DUMPED,
|
||||
),
|
||||
libc::CLD_STOPPED => WaitStatus::Stopped(pid, Signal::try_from(si_status)?),
|
||||
libc::CLD_STOPPED => {
|
||||
WaitStatus::Stopped(pid, Signal::try_from(si_status)?)
|
||||
}
|
||||
libc::CLD_CONTINUED => WaitStatus::Continued(pid),
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
libc::CLD_TRAPPED => {
|
||||
|
@ -298,7 +302,10 @@ impl WaitStatus {
|
|||
/// Wait for a process to change status
|
||||
///
|
||||
/// See also [waitpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html)
|
||||
pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Result<WaitStatus> {
|
||||
pub fn waitpid<P: Into<Option<Pid>>>(
|
||||
pid: P,
|
||||
options: Option<WaitPidFlag>,
|
||||
) -> Result<WaitStatus> {
|
||||
use self::WaitStatus::*;
|
||||
|
||||
let mut status: i32 = 0;
|
||||
|
|
|
@ -85,7 +85,8 @@ impl ClockId {
|
|||
target_os = "linux"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_BOOTTIME_ALARM: ClockId = ClockId(libc::CLOCK_BOOTTIME_ALARM);
|
||||
pub const CLOCK_BOOTTIME_ALARM: ClockId =
|
||||
ClockId(libc::CLOCK_BOOTTIME_ALARM);
|
||||
pub const CLOCK_MONOTONIC: ClockId = ClockId(libc::CLOCK_MONOTONIC);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
|
@ -94,13 +95,16 @@ impl ClockId {
|
|||
target_os = "linux"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_MONOTONIC_COARSE: ClockId = ClockId(libc::CLOCK_MONOTONIC_COARSE);
|
||||
pub const CLOCK_MONOTONIC_COARSE: ClockId =
|
||||
ClockId(libc::CLOCK_MONOTONIC_COARSE);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_MONOTONIC_FAST: ClockId = ClockId(libc::CLOCK_MONOTONIC_FAST);
|
||||
pub const CLOCK_MONOTONIC_FAST: ClockId =
|
||||
ClockId(libc::CLOCK_MONOTONIC_FAST);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_MONOTONIC_PRECISE: ClockId = ClockId(libc::CLOCK_MONOTONIC_PRECISE);
|
||||
pub const CLOCK_MONOTONIC_PRECISE: ClockId =
|
||||
ClockId(libc::CLOCK_MONOTONIC_PRECISE);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "emscripten",
|
||||
|
@ -121,7 +125,8 @@ impl ClockId {
|
|||
target_os = "linux"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_PROCESS_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_PROCESS_CPUTIME_ID);
|
||||
pub const CLOCK_PROCESS_CPUTIME_ID: ClockId =
|
||||
ClockId(libc::CLOCK_PROCESS_CPUTIME_ID);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_PROF: ClockId = ClockId(libc::CLOCK_PROF);
|
||||
|
@ -133,7 +138,8 @@ impl ClockId {
|
|||
target_os = "linux"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_REALTIME_ALARM: ClockId = ClockId(libc::CLOCK_REALTIME_ALARM);
|
||||
pub const CLOCK_REALTIME_ALARM: ClockId =
|
||||
ClockId(libc::CLOCK_REALTIME_ALARM);
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "emscripten",
|
||||
|
@ -141,13 +147,15 @@ impl ClockId {
|
|||
target_os = "linux"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_REALTIME_COARSE: ClockId = ClockId(libc::CLOCK_REALTIME_COARSE);
|
||||
pub const CLOCK_REALTIME_COARSE: ClockId =
|
||||
ClockId(libc::CLOCK_REALTIME_COARSE);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_REALTIME_FAST: ClockId = ClockId(libc::CLOCK_REALTIME_FAST);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_REALTIME_PRECISE: ClockId = ClockId(libc::CLOCK_REALTIME_PRECISE);
|
||||
pub const CLOCK_REALTIME_PRECISE: ClockId =
|
||||
ClockId(libc::CLOCK_REALTIME_PRECISE);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_SECOND: ClockId = ClockId(libc::CLOCK_SECOND);
|
||||
|
@ -177,7 +185,8 @@ impl ClockId {
|
|||
target_os = "linux"
|
||||
))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_THREAD_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_THREAD_CPUTIME_ID);
|
||||
pub const CLOCK_THREAD_CPUTIME_ID: ClockId =
|
||||
ClockId(libc::CLOCK_THREAD_CPUTIME_ID);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_UPTIME: ClockId = ClockId(libc::CLOCK_UPTIME);
|
||||
|
@ -186,7 +195,8 @@ impl ClockId {
|
|||
pub const CLOCK_UPTIME_FAST: ClockId = ClockId(libc::CLOCK_UPTIME_FAST);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_UPTIME_PRECISE: ClockId = ClockId(libc::CLOCK_UPTIME_PRECISE);
|
||||
pub const CLOCK_UPTIME_PRECISE: ClockId =
|
||||
ClockId(libc::CLOCK_UPTIME_PRECISE);
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub const CLOCK_VIRTUAL: ClockId = ClockId(libc::CLOCK_VIRTUAL);
|
||||
|
@ -216,7 +226,8 @@ impl std::fmt::Display for ClockId {
|
|||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn clock_getres(clock_id: ClockId) -> Result<TimeSpec> {
|
||||
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
|
||||
let ret = unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) };
|
||||
let ret =
|
||||
unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) };
|
||||
Errno::result(ret)?;
|
||||
let res = unsafe { c_time.assume_init() };
|
||||
Ok(TimeSpec::from(res))
|
||||
|
@ -226,7 +237,8 @@ pub fn clock_getres(clock_id: ClockId) -> Result<TimeSpec> {
|
|||
/// [clock_gettime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_gettime.html)).
|
||||
pub fn clock_gettime(clock_id: ClockId) -> Result<TimeSpec> {
|
||||
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
|
||||
let ret = unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) };
|
||||
let ret =
|
||||
unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) };
|
||||
Errno::result(ret)?;
|
||||
let res = unsafe { c_time.assume_init() };
|
||||
Ok(TimeSpec::from(res))
|
||||
|
@ -242,7 +254,8 @@ pub fn clock_gettime(clock_id: ClockId) -> Result<TimeSpec> {
|
|||
)))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all())))]
|
||||
pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> {
|
||||
let ret = unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) };
|
||||
let ret =
|
||||
unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) };
|
||||
Errno::result(ret).map(drop)
|
||||
}
|
||||
|
||||
|
@ -259,7 +272,8 @@ pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> {
|
|||
#[cfg_attr(docsrs, doc(cfg(feature = "process")))]
|
||||
pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> {
|
||||
let mut clk_id: MaybeUninit<libc::clockid_t> = MaybeUninit::uninit();
|
||||
let ret = unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) };
|
||||
let ret =
|
||||
unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) };
|
||||
if ret == 0 {
|
||||
let res = unsafe { clk_id.assume_init() };
|
||||
Ok(ClockId::from(res))
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#[cfg(not(target_env = "musl"))]
|
||||
use crate::errno::Errno;
|
||||
use crate::sys::signal::SigSet;
|
||||
#[cfg(not(target_env = "musl"))]
|
||||
use crate::Result;
|
||||
#[cfg(not(target_env = "musl"))]
|
||||
use crate::errno::Errno;
|
||||
#[cfg(not(target_env = "musl"))]
|
||||
use std::mem;
|
||||
use crate::sys::signal::SigSet;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct UContext {
|
||||
|
@ -17,7 +17,9 @@ impl UContext {
|
|||
let mut context = mem::MaybeUninit::<libc::ucontext_t>::uninit();
|
||||
let res = unsafe { libc::getcontext(context.as_mut_ptr()) };
|
||||
Errno::result(res).map(|_| unsafe {
|
||||
UContext { context: context.assume_init()}
|
||||
UContext {
|
||||
context: context.assume_init(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -31,13 +33,15 @@ impl UContext {
|
|||
|
||||
pub fn sigmask_mut(&mut self) -> &mut SigSet {
|
||||
unsafe {
|
||||
&mut *(&mut self.context.uc_sigmask as *mut libc::sigset_t as *mut SigSet)
|
||||
&mut *(&mut self.context.uc_sigmask as *mut libc::sigset_t
|
||||
as *mut SigSet)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sigmask(&self) -> &SigSet {
|
||||
unsafe {
|
||||
&*(&self.context.uc_sigmask as *const libc::sigset_t as *const SigSet)
|
||||
&*(&self.context.uc_sigmask as *const libc::sigset_t
|
||||
as *const SigSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,13 +79,13 @@ impl Uid {
|
|||
}
|
||||
|
||||
/// Returns Uid of calling process. This is practically a more Rusty alias for `getuid`.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("getuid")))]
|
||||
#[doc(alias("getuid"))]
|
||||
pub fn current() -> Self {
|
||||
getuid()
|
||||
}
|
||||
|
||||
/// Returns effective Uid of calling process. This is practically a more Rusty alias for `geteuid`.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("geteuid")))]
|
||||
#[doc(alias("geteuid"))]
|
||||
pub fn effective() -> Self {
|
||||
geteuid()
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ impl Gid {
|
|||
}
|
||||
|
||||
/// Returns Gid of calling process. This is practically a more Rusty alias for `getgid`.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("getgid")))]
|
||||
#[doc(alias("getgid"))]
|
||||
pub fn current() -> Self {
|
||||
getgid()
|
||||
}
|
||||
|
||||
/// Returns effective Gid of calling process. This is practically a more Rusty alias for `getegid`.
|
||||
#[cfg_attr(has_doc_alias, doc(alias("getegid")))]
|
||||
#[doc(alias("getegid"))]
|
||||
pub fn effective() -> Self {
|
||||
getegid()
|
||||
}
|
||||
|
@ -188,13 +188,13 @@ impl Pid {
|
|||
}
|
||||
|
||||
/// Returns PID of calling process
|
||||
#[cfg_attr(has_doc_alias, doc(alias("getpid")))]
|
||||
#[doc(alias("getpid"))]
|
||||
pub fn this() -> Self {
|
||||
getpid()
|
||||
}
|
||||
|
||||
/// Returns PID of parent of calling process
|
||||
#[cfg_attr(has_doc_alias, doc(alias("getppid")))]
|
||||
#[doc(alias("getppid"))]
|
||||
pub fn parent() -> Self {
|
||||
getppid()
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ feature! {
|
|||
/// Create a copy of the specified file descriptor (see
|
||||
/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)).
|
||||
///
|
||||
/// The new file descriptor will be have a new index but refer to the same
|
||||
/// The new file descriptor will have a new index but refer to the same
|
||||
/// resource as the old file descriptor and the old and new file descriptors may
|
||||
/// be used interchangeably. The new and old file descriptor share the same
|
||||
/// underlying resource, offset, and file status flags. The actual index used
|
||||
|
@ -1354,6 +1354,17 @@ pub fn sync() {
|
|||
unsafe { libc::sync() };
|
||||
}
|
||||
|
||||
/// Commit filesystem caches containing file referred to by the open file
|
||||
/// descriptor `fd` to disk
|
||||
///
|
||||
/// See also [syncfs(2)](https://man7.org/linux/man-pages/man2/sync.2.html)
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn syncfs(fd: RawFd) -> Result<()> {
|
||||
let res = unsafe { libc::syncfs(fd) };
|
||||
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
||||
/// Synchronize changes to a file
|
||||
///
|
||||
/// See also [fsync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html)
|
||||
|
@ -2910,9 +2921,8 @@ pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
|
|||
/// # References
|
||||
///
|
||||
/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html)
|
||||
// illumos: faccessat(2) appears to be supported, but the libc crate does not provide a binding.
|
||||
// redox: does not appear to support the *at family of syscalls.
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "redox")))]
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
pub fn faccessat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: AccessFlags, flags: AtFlags) -> Result<()> {
|
||||
let res = path.with_nix_path(|cstr| {
|
||||
unsafe {
|
||||
|
@ -2921,6 +2931,27 @@ pub fn faccessat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Acce
|
|||
})?;
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
|
||||
/// Checks the file named by `path` for accessibility according to the flags given
|
||||
/// by `mode` using effective UID, effective GID and supplementary group lists.
|
||||
///
|
||||
/// # References
|
||||
///
|
||||
/// * [FreeBSD man page](https://www.freebsd.org/cgi/man.cgi?query=eaccess&sektion=2&n=1)
|
||||
/// * [Linux man page](https://man7.org/linux/man-pages/man3/euidaccess.3.html)
|
||||
#[cfg(any(
|
||||
all(target_os = "linux", not(target_env = "uclibc")),
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"
|
||||
))]
|
||||
pub fn eaccess<P: ?Sized + NixPath>(path: &P, mode: AccessFlags) -> Result<()> {
|
||||
let res = path.with_nix_path(|cstr| {
|
||||
unsafe {
|
||||
libc::eaccess(cstr.as_ptr(), mode.bits)
|
||||
}
|
||||
})?;
|
||||
Errno::result(res).map(drop)
|
||||
}
|
||||
}
|
||||
|
||||
feature! {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::{
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
io::{Read, Seek, Write},
|
||||
ops::Deref,
|
||||
os::unix::io::AsRawFd,
|
||||
pin::Pin,
|
||||
|
@ -371,7 +371,7 @@ mod aio_write {
|
|||
assert_eq!(err, Ok(()));
|
||||
assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len());
|
||||
|
||||
f.seek(SeekFrom::Start(0)).unwrap();
|
||||
f.rewind().unwrap();
|
||||
let len = f.read_to_end(&mut rbuf).unwrap();
|
||||
assert_eq!(len, EXPECT.len());
|
||||
assert_eq!(rbuf, EXPECT);
|
||||
|
@ -402,7 +402,7 @@ mod aio_write {
|
|||
assert_eq!(err, Ok(()));
|
||||
assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len());
|
||||
|
||||
f.seek(SeekFrom::Start(0)).unwrap();
|
||||
f.rewind().unwrap();
|
||||
let len = f.read_to_end(&mut rbuf).unwrap();
|
||||
assert_eq!(len, EXPECT.len());
|
||||
assert_eq!(rbuf, EXPECT);
|
||||
|
@ -487,7 +487,7 @@ mod aio_writev {
|
|||
assert_eq!(err, Ok(()));
|
||||
assert_eq!(aiow.as_mut().aio_return().unwrap(), wlen);
|
||||
|
||||
f.seek(SeekFrom::Start(0)).unwrap();
|
||||
f.rewind().unwrap();
|
||||
let len = f.read_to_end(&mut rbuf).unwrap();
|
||||
assert_eq!(len, EXPECT.len());
|
||||
assert_eq!(rbuf, EXPECT);
|
||||
|
@ -537,7 +537,7 @@ fn sigev_signal() {
|
|||
}
|
||||
|
||||
assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
|
||||
f.seek(SeekFrom::Start(0)).unwrap();
|
||||
f.rewind().unwrap();
|
||||
let len = f.read_to_end(&mut rbuf).unwrap();
|
||||
assert_eq!(len, EXPECT.len());
|
||||
assert_eq!(rbuf, EXPECT);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
#[test]
|
||||
fn test_mmap_anonymous() {
|
||||
unsafe {
|
||||
let ptr = mmap(
|
||||
std::ptr::null_mut(),
|
||||
1,
|
||||
None,
|
||||
NonZeroUsize::new(1).unwrap(),
|
||||
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
|
||||
MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
|
||||
-1,
|
||||
|
@ -25,10 +26,12 @@ fn test_mremap_grow() {
|
|||
use nix::sys::mman::{mremap, MRemapFlags};
|
||||
|
||||
const ONE_K: size_t = 1024;
|
||||
let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
|
||||
|
||||
let slice: &mut [u8] = unsafe {
|
||||
let mem = mmap(
|
||||
std::ptr::null_mut(),
|
||||
ONE_K,
|
||||
None,
|
||||
one_k_non_zero,
|
||||
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
|
||||
MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
|
||||
-1,
|
||||
|
@ -79,12 +82,14 @@ fn test_mremap_grow() {
|
|||
fn test_mremap_shrink() {
|
||||
use nix::libc::{c_void, size_t};
|
||||
use nix::sys::mman::{mremap, MRemapFlags};
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
const ONE_K: size_t = 1024;
|
||||
let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
|
||||
let slice: &mut [u8] = unsafe {
|
||||
let mem = mmap(
|
||||
std::ptr::null_mut(),
|
||||
10 * ONE_K,
|
||||
None,
|
||||
ten_one_k,
|
||||
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
|
||||
MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
|
||||
-1,
|
||||
|
@ -100,7 +105,7 @@ fn test_mremap_shrink() {
|
|||
let slice: &mut [u8] = unsafe {
|
||||
let mem = mremap(
|
||||
slice.as_mut_ptr() as *mut c_void,
|
||||
10 * ONE_K,
|
||||
ten_one_k.into(),
|
||||
ONE_K,
|
||||
MRemapFlags::empty(),
|
||||
None,
|
||||
|
|
|
@ -223,7 +223,7 @@ pub fn test_addr_equality_abstract() {
|
|||
}
|
||||
|
||||
// Test getting/setting abstract addresses (without unix socket creation)
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
pub fn test_abstract_uds_addr() {
|
||||
let empty = String::new();
|
||||
|
@ -244,6 +244,22 @@ pub fn test_abstract_uds_addr() {
|
|||
assert_eq!(unsafe { (*addr.as_ptr()).sun_path[0] }, 0);
|
||||
}
|
||||
|
||||
// Test getting an unnamed address (without unix socket creation)
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
pub fn test_unnamed_uds_addr() {
|
||||
use crate::nix::sys::socket::SockaddrLike;
|
||||
|
||||
let addr = UnixAddr::new_unnamed();
|
||||
|
||||
assert!(addr.is_unnamed());
|
||||
assert_eq!(addr.len(), 2);
|
||||
assert!(addr.path().is_none());
|
||||
assert_eq!(addr.path_len(), 0);
|
||||
|
||||
assert!(addr.as_abstract().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_getsockname() {
|
||||
use nix::sys::socket::bind;
|
||||
|
@ -501,31 +517,31 @@ mod recvfrom {
|
|||
rsock,
|
||||
ssock,
|
||||
move |s, m, flags| {
|
||||
let iov = [IoSlice::new(m)];
|
||||
let mut msgs = vec![SendMmsgData {
|
||||
iov: &iov,
|
||||
cmsgs: &[],
|
||||
addr: Some(sock_addr),
|
||||
_lt: Default::default(),
|
||||
}];
|
||||
|
||||
let batch_size = 15;
|
||||
let mut iovs = Vec::with_capacity(1 + batch_size);
|
||||
let mut addrs = Vec::with_capacity(1 + batch_size);
|
||||
let mut data = MultiHeaders::preallocate(1 + batch_size, None);
|
||||
let iov = IoSlice::new(m);
|
||||
// first chunk:
|
||||
iovs.push([iov]);
|
||||
addrs.push(Some(sock_addr));
|
||||
|
||||
for _ in 0..batch_size {
|
||||
msgs.push(SendMmsgData {
|
||||
iov: &iov,
|
||||
cmsgs: &[],
|
||||
addr: Some(sock_addr2),
|
||||
_lt: Default::default(),
|
||||
});
|
||||
iovs.push([iov]);
|
||||
addrs.push(Some(sock_addr2));
|
||||
}
|
||||
sendmmsg(s, msgs.iter(), flags).map(move |sent_bytes| {
|
||||
assert!(!sent_bytes.is_empty());
|
||||
for sent in &sent_bytes {
|
||||
assert_eq!(*sent, m.len());
|
||||
}
|
||||
sent_bytes.len()
|
||||
})
|
||||
|
||||
let res = sendmmsg(s, &mut data, &iovs, addrs, [], flags)?;
|
||||
let mut sent_messages = 0;
|
||||
let mut sent_bytes = 0;
|
||||
for item in res {
|
||||
sent_messages += 1;
|
||||
sent_bytes += item.bytes;
|
||||
}
|
||||
//
|
||||
assert_eq!(sent_messages, iovs.len());
|
||||
assert_eq!(sent_bytes, sent_messages * m.len());
|
||||
Ok(sent_messages)
|
||||
},
|
||||
|_, _| {},
|
||||
);
|
||||
|
@ -577,21 +593,19 @@ mod recvfrom {
|
|||
|
||||
// Buffers to receive exactly `NUM_MESSAGES_SENT` messages
|
||||
let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT];
|
||||
let iovs: Vec<_> = receive_buffers
|
||||
.iter_mut()
|
||||
.map(|buf| [IoSliceMut::new(&mut buf[..])])
|
||||
.collect();
|
||||
msgs.extend(
|
||||
receive_buffers
|
||||
.iter_mut()
|
||||
.map(|buf| [IoSliceMut::new(&mut buf[..])]),
|
||||
);
|
||||
|
||||
for iov in &iovs {
|
||||
msgs.push_back(RecvMmsgData {
|
||||
iov,
|
||||
cmsg_buffer: None,
|
||||
})
|
||||
}
|
||||
let mut data =
|
||||
MultiHeaders::<SockaddrIn>::preallocate(msgs.len(), None);
|
||||
|
||||
let res: Vec<RecvMsg<SockaddrIn>> =
|
||||
recvmmsg(rsock, &mut msgs, MsgFlags::empty(), None)
|
||||
.expect("recvmmsg");
|
||||
recvmmsg(rsock, &mut data, msgs.iter(), MsgFlags::empty(), None)
|
||||
.expect("recvmmsg")
|
||||
.collect();
|
||||
assert_eq!(res.len(), DATA.len());
|
||||
|
||||
for RecvMsg { address, bytes, .. } in res.into_iter() {
|
||||
|
@ -655,21 +669,26 @@ mod recvfrom {
|
|||
// will return when there are fewer than requested messages in the
|
||||
// kernel buffers when using `MSG_DONTWAIT`.
|
||||
let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2];
|
||||
let iovs: Vec<_> = receive_buffers
|
||||
.iter_mut()
|
||||
.map(|buf| [IoSliceMut::new(&mut buf[..])])
|
||||
.collect();
|
||||
msgs.extend(
|
||||
receive_buffers
|
||||
.iter_mut()
|
||||
.map(|buf| [IoSliceMut::new(&mut buf[..])]),
|
||||
);
|
||||
|
||||
for iov in &iovs {
|
||||
msgs.push_back(RecvMmsgData {
|
||||
iov,
|
||||
cmsg_buffer: None,
|
||||
})
|
||||
}
|
||||
let mut data = MultiHeaders::<SockaddrIn>::preallocate(
|
||||
NUM_MESSAGES_SENT + 2,
|
||||
None,
|
||||
);
|
||||
|
||||
let res: Vec<RecvMsg<SockaddrIn>> =
|
||||
recvmmsg(rsock, &mut msgs, MsgFlags::MSG_DONTWAIT, None)
|
||||
.expect("recvmmsg");
|
||||
let res: Vec<RecvMsg<SockaddrIn>> = recvmmsg(
|
||||
rsock,
|
||||
&mut data,
|
||||
msgs.iter(),
|
||||
MsgFlags::MSG_DONTWAIT,
|
||||
None,
|
||||
)
|
||||
.expect("recvmmsg")
|
||||
.collect();
|
||||
assert_eq!(res.len(), NUM_MESSAGES_SENT);
|
||||
|
||||
for RecvMsg { address, bytes, .. } in res.into_iter() {
|
||||
|
@ -1481,7 +1500,7 @@ fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
|
|||
|
||||
// Test creating and using named unix domain sockets
|
||||
#[test]
|
||||
pub fn test_unixdomain() {
|
||||
pub fn test_named_unixdomain() {
|
||||
use nix::sys::socket::{accept, bind, connect, listen, socket, UnixAddr};
|
||||
use nix::sys::socket::{SockFlag, SockType};
|
||||
use nix::unistd::{close, read, write};
|
||||
|
@ -1524,6 +1543,59 @@ pub fn test_unixdomain() {
|
|||
assert_eq!(&buf[..], b"hello");
|
||||
}
|
||||
|
||||
// Test using unnamed unix domain addresses
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
pub fn test_unnamed_unixdomain() {
|
||||
use nix::sys::socket::{getsockname, socketpair};
|
||||
use nix::sys::socket::{SockFlag, SockType};
|
||||
use nix::unistd::close;
|
||||
|
||||
let (fd_1, fd_2) = socketpair(
|
||||
AddressFamily::Unix,
|
||||
SockType::Stream,
|
||||
None,
|
||||
SockFlag::empty(),
|
||||
)
|
||||
.expect("socketpair failed");
|
||||
|
||||
let addr_1: UnixAddr = getsockname(fd_1).expect("getsockname failed");
|
||||
assert!(addr_1.is_unnamed());
|
||||
|
||||
close(fd_1).unwrap();
|
||||
close(fd_2).unwrap();
|
||||
}
|
||||
|
||||
// Test creating and using unnamed unix domain addresses for autobinding sockets
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[test]
|
||||
pub fn test_unnamed_unixdomain_autobind() {
|
||||
use nix::sys::socket::{bind, getsockname, socket};
|
||||
use nix::sys::socket::{SockFlag, SockType};
|
||||
use nix::unistd::close;
|
||||
|
||||
let fd = socket(
|
||||
AddressFamily::Unix,
|
||||
SockType::Stream,
|
||||
SockFlag::empty(),
|
||||
None,
|
||||
)
|
||||
.expect("socket failed");
|
||||
|
||||
// unix(7): "If a bind(2) call specifies addrlen as `sizeof(sa_family_t)`, or [...], then the
|
||||
// socket is autobound to an abstract address"
|
||||
bind(fd, &UnixAddr::new_unnamed()).expect("bind failed");
|
||||
|
||||
let addr: UnixAddr = getsockname(fd).expect("getsockname failed");
|
||||
let addr = addr.as_abstract().unwrap();
|
||||
|
||||
// changed from 8 to 5 bytes in Linux 2.3.15, and rust's minimum supported Linux version is 3.2
|
||||
// (as of 2022-11)
|
||||
assert_eq!(addr.len(), 5);
|
||||
|
||||
close(fd).unwrap();
|
||||
}
|
||||
|
||||
// Test creating and using named system control sockets
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
#[test]
|
||||
|
@ -2205,14 +2277,13 @@ fn test_recvmmsg_timestampns() {
|
|||
assert_eq!(message.len(), l);
|
||||
// Receive the message
|
||||
let mut buffer = vec![0u8; message.len()];
|
||||
let mut cmsgspace = nix::cmsg_space!(TimeSpec);
|
||||
let iov = [IoSliceMut::new(&mut buffer)];
|
||||
let mut data = vec![RecvMmsgData {
|
||||
iov,
|
||||
cmsg_buffer: Some(&mut cmsgspace),
|
||||
}];
|
||||
let cmsgspace = nix::cmsg_space!(TimeSpec);
|
||||
let iov = vec![[IoSliceMut::new(&mut buffer)]];
|
||||
let mut data = MultiHeaders::preallocate(1, Some(cmsgspace));
|
||||
let r: Vec<RecvMsg<()>> =
|
||||
recvmmsg(in_socket, &mut data, flags, None).unwrap();
|
||||
recvmmsg(in_socket, &mut data, iov.iter(), flags, None)
|
||||
.unwrap()
|
||||
.collect();
|
||||
let rtime = match r[0].cmsgs().next() {
|
||||
Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
|
||||
Some(_) => panic!("Unexpected control message"),
|
||||
|
|
|
@ -263,6 +263,33 @@ fn test_so_tcp_keepalive() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
#[cfg_attr(qemu, ignore)]
|
||||
fn test_get_mtu() {
|
||||
use nix::sys::socket::{bind, connect, SockaddrIn};
|
||||
use std::net::SocketAddrV4;
|
||||
use std::str::FromStr;
|
||||
|
||||
let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap();
|
||||
let std_sb = SocketAddrV4::from_str("127.0.0.1:4002").unwrap();
|
||||
|
||||
let usock = socket(
|
||||
AddressFamily::Inet,
|
||||
SockType::Datagram,
|
||||
SockFlag::empty(),
|
||||
SockProtocol::Udp,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Bind and initiate connection
|
||||
bind(usock, &SockaddrIn::from(std_sa)).unwrap();
|
||||
connect(usock, &SockaddrIn::from(std_sb)).unwrap();
|
||||
|
||||
// Loopback connections have 2^16 - the maximum - MTU
|
||||
assert_eq!(getsockopt(usock, sockopt::IpMtu), Ok(u16::MAX as i32))
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
|
||||
fn test_ttl_opts() {
|
||||
|
@ -354,3 +381,51 @@ fn test_v6dontfrag_opts() {
|
|||
"unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_so_priority() {
|
||||
let fd = socket(
|
||||
AddressFamily::Inet,
|
||||
SockType::Stream,
|
||||
SockFlag::empty(),
|
||||
SockProtocol::Tcp,
|
||||
)
|
||||
.unwrap();
|
||||
let priority = 3;
|
||||
setsockopt(fd, sockopt::Priority, &priority).unwrap();
|
||||
assert_eq!(getsockopt(fd, sockopt::Priority).unwrap(), priority);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_ip_tos() {
|
||||
let fd = socket(
|
||||
AddressFamily::Inet,
|
||||
SockType::Stream,
|
||||
SockFlag::empty(),
|
||||
SockProtocol::Tcp,
|
||||
)
|
||||
.unwrap();
|
||||
let tos = 0x80; // CS4
|
||||
setsockopt(fd, sockopt::IpTos, &tos).unwrap();
|
||||
assert_eq!(getsockopt(fd, sockopt::IpTos).unwrap(), tos);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
// Disable the test under emulation because it fails in Cirrus-CI. Lack
|
||||
// of QEMU support is suspected.
|
||||
#[cfg_attr(qemu, ignore)]
|
||||
fn test_ipv6_tclass() {
|
||||
let fd = socket(
|
||||
AddressFamily::Inet6,
|
||||
SockType::Stream,
|
||||
SockFlag::empty(),
|
||||
SockProtocol::Tcp,
|
||||
)
|
||||
.unwrap();
|
||||
let class = 0x80; // CS4
|
||||
setsockopt(fd, sockopt::Ipv6TClass, &class).unwrap();
|
||||
assert_eq!(getsockopt(fd, sockopt::Ipv6TClass).unwrap(), class);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ mod test_resource;
|
|||
#[cfg(any(
|
||||
target_os = "android",
|
||||
target_os = "dragonfly",
|
||||
all(target_os = "freebsd", fbsd14),
|
||||
target_os = "linux"
|
||||
))]
|
||||
mod test_sched;
|
||||
|
|
|
@ -231,7 +231,7 @@ fn test_readlink() {
|
|||
mod linux_android {
|
||||
use libc::loff_t;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{IoSlice, SeekFrom};
|
||||
use std::io::IoSlice;
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
use nix::fcntl::*;
|
||||
|
@ -272,7 +272,7 @@ mod linux_android {
|
|||
.unwrap();
|
||||
|
||||
let mut res: String = String::new();
|
||||
tmp2.seek(SeekFrom::Start(0)).unwrap();
|
||||
tmp2.rewind().unwrap();
|
||||
tmp2.read_to_string(&mut res).unwrap();
|
||||
|
||||
assert_eq!(res, String::from("bar"));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
|
||||
use nix::sched::{sched_getaffinity, sched_getcpu, sched_setaffinity, CpuSet};
|
||||
use nix::unistd::Pid;
|
||||
|
||||
#[test]
|
||||
|
@ -30,6 +30,10 @@ fn test_sched_affinity() {
|
|||
)
|
||||
}
|
||||
|
||||
// Now check that we're also currently running on the CPU in question.
|
||||
let cur_cpu = sched_getcpu().unwrap();
|
||||
assert_eq!(cur_cpu, last_valid_cpu);
|
||||
|
||||
// Finally, reset the initial CPU set
|
||||
sched_setaffinity(Pid::from_raw(0), &initial_affinity).unwrap();
|
||||
}
|
||||
|
|
|
@ -1310,7 +1310,7 @@ fn test_getpeereid_invalid_fd() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "redox")))]
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
fn test_faccessat_none_not_existing() {
|
||||
use nix::fcntl::AtFlags;
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
|
@ -1324,7 +1324,7 @@ fn test_faccessat_none_not_existing() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "redox")))]
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
fn test_faccessat_not_existing() {
|
||||
use nix::fcntl::AtFlags;
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
|
@ -1344,7 +1344,7 @@ fn test_faccessat_not_existing() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "redox")))]
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
fn test_faccessat_none_file_exists() {
|
||||
use nix::fcntl::AtFlags;
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
|
@ -1360,7 +1360,7 @@ fn test_faccessat_none_file_exists() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(any(target_os = "illumos", target_os = "redox")))]
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
fn test_faccessat_file_exists() {
|
||||
use nix::fcntl::AtFlags;
|
||||
let tempdir = tempfile::tempdir().unwrap();
|
||||
|
@ -1376,3 +1376,32 @@ fn test_faccessat_file_exists() {
|
|||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(
|
||||
all(target_os = "linux", not(target_env = "uclibc")),
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"
|
||||
))]
|
||||
fn test_eaccess_not_existing() {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let dir = tempdir.path().join("does_not_exist.txt");
|
||||
assert_eq!(
|
||||
eaccess(&dir, AccessFlags::F_OK).err().unwrap(),
|
||||
Errno::ENOENT
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(
|
||||
all(target_os = "linux", not(target_env = "uclibc")),
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"
|
||||
))]
|
||||
fn test_eaccess_file_exists() {
|
||||
let tempdir = tempdir().unwrap();
|
||||
let path = tempdir.path().join("does_exist.txt");
|
||||
let _file = File::create(path.clone()).unwrap();
|
||||
eaccess(&path, AccessFlags::R_OK | AccessFlags::W_OK)
|
||||
.expect("assertion failed");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче