summaryrefslogtreecommitdiffstats
path: root/vendor/signal-hook
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/signal-hook')
-rw-r--r--vendor/signal-hook/.cargo-checksum.json1
-rw-r--r--vendor/signal-hook/CHANGELOG.md256
-rw-r--r--vendor/signal-hook/Cargo.lock260
-rw-r--r--vendor/signal-hook/Cargo.toml66
-rw-r--r--vendor/signal-hook/LICENSE-APACHE201
-rw-r--r--vendor/signal-hook/LICENSE-MIT25
-rw-r--r--vendor/signal-hook/README.md70
-rw-r--r--vendor/signal-hook/build.rs9
-rwxr-xr-xvendor/signal-hook/ci-check.sh31
-rw-r--r--vendor/signal-hook/examples/print.rs27
-rw-r--r--vendor/signal-hook/rustfmt.toml0
-rw-r--r--vendor/signal-hook/src/flag.rs283
-rw-r--r--vendor/signal-hook/src/iterator/backend.rs494
-rw-r--r--vendor/signal-hook/src/iterator/exfiltrator/mod.rs152
-rw-r--r--vendor/signal-hook/src/iterator/exfiltrator/origin.rs66
-rw-r--r--vendor/signal-hook/src/iterator/exfiltrator/raw.rs95
-rw-r--r--vendor/signal-hook/src/iterator/mod.rs323
-rw-r--r--vendor/signal-hook/src/lib.rs414
-rw-r--r--vendor/signal-hook/src/low_level/channel.rs235
-rw-r--r--vendor/signal-hook/src/low_level/extract.c55
-rw-r--r--vendor/signal-hook/src/low_level/mod.rs59
-rw-r--r--vendor/signal-hook/src/low_level/pipe.rs265
-rw-r--r--vendor/signal-hook/src/low_level/siginfo.rs261
-rw-r--r--vendor/signal-hook/src/low_level/signal_details.rs255
-rw-r--r--vendor/signal-hook/tests/default.rs25
-rw-r--r--vendor/signal-hook/tests/iterator.rs260
-rw-r--r--vendor/signal-hook/tests/shutdown.rs81
27 files changed, 4269 insertions, 0 deletions
diff --git a/vendor/signal-hook/.cargo-checksum.json b/vendor/signal-hook/.cargo-checksum.json
new file mode 100644
index 000000000..9c6dd5450
--- /dev/null
+++ b/vendor/signal-hook/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"20a9b9bd056e5fbb980b7c5a7fc706dd32309743eeff23c5d4228ac10fca5b7b","Cargo.lock":"284dcdbc909099e591c59d059e66aa435d463c232f5fd0759b9732780d27fd8f","Cargo.toml":"41ccc6b0e364bc0da0a42496fa079037edad3f3bdb711a944f3332db89a9e18d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"503558bfefe66ca15e4e3f7955b3cb0ec87fd52f29bf24b336af7bd00e946d5c","README.md":"be97b822f26b642165c4fac3ed6a515f2c522f30c12a2011aa3b5cab1eb988d0","build.rs":"3a95a69d2921f1c28922a141a671e23a061f358b6d831350043003e13ef96463","ci-check.sh":"65f6e254cca1adf4579998fa393521cef8bc5bfbfb79b9fb430e1814a5a7c091","examples/print.rs":"ff4e0aeaf2533e7b48edec866cd6b65021a1e588e22d9a443a631d750daa36a0","rustfmt.toml":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","src/flag.rs":"c240f03b5895a24803192a720ac3280c43d83867ca414e0622f53f90d287d07f","src/iterator/backend.rs":"98096e6fa7c3187c81acf8bf68b4aef013019a993dcdcde37b235bdfaf3c1561","src/iterator/exfiltrator/mod.rs":"c5476b32f00094e7556350c79bff7cec88e890750a42b613a5bf00e33234311f","src/iterator/exfiltrator/origin.rs":"ada8f6289c9b31d523f3cc9e02d533a3f348cfad6f5fc59ab929f851816ed156","src/iterator/exfiltrator/raw.rs":"22085d408ed660d6a2cb744f2c1bd321dbe261dfcc8858c41ad3ff9d367609c9","src/iterator/mod.rs":"d0c5e02df18ab578f98d4fa8b3c0d6c1f74a9c76033468216cb1704c946eb5f2","src/lib.rs":"968a13e57ba4c5a05f6a73aab83a6f4fae72d79a235129e09700946141c6c238","src/low_level/channel.rs":"7561da67226f0c668adc06d398d5a6f0f84a67b90092067e14359e9ee05cdac1","src/low_level/extract.c":"7583e69e6d0e57893dc6813ec6a519a83c86f9d1e4129812eacaca630dcf1c9d","src/low_level/mod.rs":"91b2a8995a7dcb71cf50bc5ead532e5ee706c77b7af99dbf6fc55c4a1516f03f","src/low_level/pipe.rs":"544d780577ba802af32abd7a075a3702f36b644d16baf3c2708ccec373b01c61","src/low_level/siginfo.rs":"3a416031a654add7b39a2a6c0328e6c60dbf33ca972a45ef11eaf198615a0aaf","src/low_level/signal_details.rs":"93d68af97fa45435e0236e96412eeea60ac2715eac0aa0648f27837537a722f1","tests/default.rs":"2e6e400990d31a5968f6909278e9cf20b75ba7f1a92b8485122ac790a2e94a44","tests/iterator.rs":"1533f9722c047a221a6e8903d179cace76c395fff54df010e42fbcaabeca7bc9","tests/shutdown.rs":"3ca8dbf94eead616bd47968f029a91c6bdffc9fb44be3f004d6e8fe2ac46db00"},"package":"732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"} \ No newline at end of file
diff --git a/vendor/signal-hook/CHANGELOG.md b/vendor/signal-hook/CHANGELOG.md
new file mode 100644
index 000000000..7277e7631
--- /dev/null
+++ b/vendor/signal-hook/CHANGELOG.md
@@ -0,0 +1,256 @@
+# 0.3.15
+# signal-hook-registry-1.4.1
+
+* AIX support (experimental/not guaranteed to work).
+
+# 0.3.14
+
+* Added the SIGINFO signal (where available).
+
+# signal-hook-mio-0.2.3
+
+* Support for mio 0.8
+
+# signal-hook-async-std-0.2.2
+# signal-hook-tokio-0.3.1
+
+* Fix support for SignalsInfo with non-default info extractors.
+
+# 0.3.13
+
+* Add haiku support.
+
+# 0.3.12
+
+* Fix accidentally broken windows build.
+
+# 0.3.11
+
+* Provide fallback sigaddset, sigemptyset on certain androids, as they are
+ missing them.
+
+# 0.3.10
+
+* Doc link fixes.
+
+# 0.3.9
+
+* Deliver SIGCHLD even on stop/continue.
+
+# 0.3.8
+
+* Fix docs.rs build.
+
+# 0.3.7
+
+* Unmask a signal in default emulation if it is termination.
+
+# mio-0.2.2
+
+* The same fix, but for the 0.6 support 😇.
+
+# mio-0.2.1
+
+* Fix example: handle ErrorKind::Interrupted inside poll. It's very likely to
+ happen, when we are waiting for signals there.
+
+# 0.3.6
+
+* Fix the labels on docs.rs :-|.
+
+# 0.3.5
+
+* Doc: include the features & these little labels inside docs.
+
+# signal-hook-async-std-0.2.1
+
+* Dependency updates ‒ no longer depends on the whole async-std, but only on
+ some smaller dependencies of it (`async-io`, `futures-lite`). This might make
+ it work even outside of async-std context.
+
+# signal-hook-tokio-0.3.0
+
+* Support for tokio 1.0.
+
+# 0.3.4
+
+* Fix feature dependencies (`iterator` depends on `channel`).
+
+# 0.3.3
+
+* `low_level::emulate_default_handler` to emulate whatever default handler would
+ do.
+* `low_level::signal_name` to look up human readable name.
+* The `Origin`'s debug output now contains the human readable name of the
+ signal.
+
+# 0.3.2
+
+* Allow extracting Origin from the raw `siginfo_t` structure by hand, without
+ needing an iterator.
+* Folding the signal-hook-sys inline (but still compiling C code only
+ conditionally).
+* `WithRawSiginfo` extractor (to get hands on the raw `siginfo_t`).
+* Bugfix: Don't leak on WithOrigin destruction.
+
+# 0.3.1
+
+* Use caret dependencies where appropriate (to allow upgrades on
+ signal-hook-registry).
+
+# async-std-0.2.0
+
+* No longer depends on `futures`.
+
+# 0.3.0
+
+* The `cleanup` module is gone, it was not a good API. Replaced by conditional
+ termination in `flag`.
+* Some abstractions/patterns are moved to `low_level` submodule, as they are
+ considered building blocks, not for direct use (`register`, `pipe`,
+ `channel`).
+* The signal constants are moved to a submodule (`consts`), together with few
+ more constants, to not clutter the root.
+* The forever iterator no longer consumes.
+
+# registry-1.3.0
+
+* The `unregister_signal` in is deprecated, without a replacement.
+
+# 0.2.2
+
+* Extractor for the origin of a signal (PID, UID, what caused it).
+* Fixing some doc links on re-exports.
+
+# 0.2.1
+
+* Allow turning the iterator module off (the `iterator` feature, part of default
+ features). This would allow compiling the crate on 1.31.0.
+
+# 0.2.0
+
+* Bump minimal rustc version to 1.36.0 (signal-hook-registry still builds with
+ 1.26.0).
+* (Breaking) Support for exfiltrators ‒ ability to return more than just the
+ signal number from the iterator and streams. Nothing more is implemented yet,
+ but the place to put it is reserved in the API.
+* (Breaking) `pipe::register_raw` now takes ownership and tries to use send
+ first, falls back to `O_NONBLOCK` and `write` on failure.
+* (Breaking) All async support is pulled out into separate crates, to decouple
+ from the async runtime release cycles on the main `signal-hook` crate.
+* Inner parts of the `Iterator` are now exposed in
+ `signal_hook::iterator::backend`, to support the async crates.
+
+# registry-1.2.2
+
+* Drop dependency on arc-swap (only very small subset used and arc-swap would
+ like to drop that part anyway).
+
+# registry-1.2.1
+
+* Abort instead of panicking if the OS gives us NULL as siginfo (which is
+ illegal). Panicking would be UB.
+
+# 0.1.16
+
+* Fix possible blocking in signal handler registered by `Signals`.
+
+# 0.1.15
+
+* Make `Signals` work in edge-triggered mode in mio too, by always draining
+ everything from the socket. Needed, because mio 0.7 doesn't have
+ level-triggered any more.
+
+# 0.1.14
+
+* `mio-0_7-support` feature for use with mio 0.7.0+.
+* Bump minimal rustc version to 1.31.0 (signal-hook-registry can still build
+ with 1.26.0).
+
+# 0.1.13
+
+* Some doc clarifications.
+
+# 0.1.12
+
+* `cleanup` module to register resetting signals to default.
+
+# registry-1.2.0
+
+* `unregister_signal`, to remove all hooks of one signal.
+
+# 0.1.11
+
+* Docs improvements.
+* Fix registering pipes as well as sockets into the pipe module (#27).
+
+# registry-1.1.1
+
+* Update deps.
+
+# registry-1.1.0
+
+* Adding Windows support (thanks to @qnighy).
+
+# 0.1.10
+
+* Fix busy loop in Iterator::forever when the mio-support feature is enabled
+ (#16).
+
+# registry-1.0.1
+
+* Include the registry files in the crates.io tarball.
+
+# 0.1.9
+# registry-1.0.0
+
+* Split into backend signal-hook-registry and the frontend. The backend is much
+ less likely to have breaking changes so it contains the things that can be in
+ the application just once.
+
+# 0.1.8
+
+* The `Signals` iterator can now be closed (from another instance or thread),
+ which can be used to shut down the thread handling signals from the main
+ thread.
+
+# 0.1.7
+
+* The `Signals` iterator allows adding signals after creation.
+* Fixed a bug where `Signals` registrations could be unregirestered too soon if
+ the `Signals` was cloned previously.
+
+# 0.1.6
+
+* The internally used ArcSwap thing doesn't block other ArcSwaps now (has
+ independent generation lock).
+
+# 0.1.5
+
+* Re-exported signal constants, so users no longer need libc.
+
+# 0.1.4
+
+* Compilation fix for android-aarch64
+
+# 0.1.3
+
+* Tokio support.
+* Mio support.
+* Dependency updates.
+
+# 0.1.2
+
+* Dependency updates.
+
+# 0.1.1
+
+* Get rid of `catch_unwind` inside the signal handler.
+* Link to the nix crate.
+
+# 0.1.0
+
+* Initial basic implementation.
+* Flag helpers.
+* Pipe helpers.
+* High-level iterator helper.
diff --git a/vendor/signal-hook/Cargo.lock b/vendor/signal-hook/Cargo.lock
new file mode 100644
index 000000000..d969becf3
--- /dev/null
+++ b/vendor/signal-hook/Cargo.lock
@@ -0,0 +1,260 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "cc"
+version = "1.0.73"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+
+[[package]]
+name = "lock_api"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "serial_test"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d19dbfb999a147cedbfe82f042eb9555f5b0fa4ef95ee4570b74349103d9c9f4"
+dependencies = [
+ "lazy_static",
+ "log",
+ "parking_lot",
+ "serial_test_derive",
+]
+
+[[package]]
+name = "serial_test_derive"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb9e2050b2be1d681f8f1c1a528bcfe4e00afa2d8995f713974f5333288659f2"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn",
+]
+
+[[package]]
+name = "signal-hook"
+version = "0.3.15"
+dependencies = [
+ "cc",
+ "libc",
+ "serial_test",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
+
+[[package]]
+name = "syn"
+version = "1.0.96"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
diff --git a/vendor/signal-hook/Cargo.toml b/vendor/signal-hook/Cargo.toml
new file mode 100644
index 000000000..45e3e13f6
--- /dev/null
+++ b/vendor/signal-hook/Cargo.toml
@@ -0,0 +1,66 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "signal-hook"
+version = "0.3.15"
+authors = [
+ "Michal 'vorner' Vaner <vorner@vorner.cz>",
+ "Thomas Himmelstoss <thimm@posteo.de>",
+]
+description = "Unix signal handling"
+documentation = "https://docs.rs/signal-hook"
+readme = "README.md"
+keywords = [
+ "signal",
+ "unix",
+ "daemon",
+]
+license = "Apache-2.0/MIT"
+repository = "https://github.com/vorner/signal-hook"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[dependencies.libc]
+version = "^0.2"
+
+[dependencies.signal-hook-registry]
+version = "^1.4"
+
+[dev-dependencies.serial_test]
+version = "^0.7"
+
+[build-dependencies.cc]
+version = "^1"
+optional = true
+
+[features]
+channel = []
+default = [
+ "channel",
+ "iterator",
+]
+extended-siginfo = [
+ "channel",
+ "iterator",
+ "extended-siginfo-raw",
+]
+extended-siginfo-raw = ["cc"]
+iterator = ["channel"]
+
+[badges.maintenance]
+status = "actively-developed"
diff --git a/vendor/signal-hook/LICENSE-APACHE b/vendor/signal-hook/LICENSE-APACHE
new file mode 100644
index 000000000..16fe87b06
--- /dev/null
+++ b/vendor/signal-hook/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/signal-hook/LICENSE-MIT b/vendor/signal-hook/LICENSE-MIT
new file mode 100644
index 000000000..ebe0bc91e
--- /dev/null
+++ b/vendor/signal-hook/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2017 tokio-jsonrpc developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/vendor/signal-hook/README.md b/vendor/signal-hook/README.md
new file mode 100644
index 000000000..71a3d2701
--- /dev/null
+++ b/vendor/signal-hook/README.md
@@ -0,0 +1,70 @@
+# Signal-hook
+
+[![Actions Status](https://github.com/vorner/signal-hook/workflows/test/badge.svg)](https://github.com/vorner/signal-hook/actions)
+[![codecov](https://codecov.io/gh/vorner/signal-hook/branch/master/graph/badge.svg?token=3KA3R2D9fV)](https://codecov.io/gh/vorner/signal-hook)
+[![docs](https://docs.rs/signal-hook/badge.svg)](https://docs.rs/signal-hook)
+
+Library for safe and correct Unix signal handling in Rust.
+
+Unix signals are inherently hard to handle correctly, for several reasons:
+
+* They are a global resource. If a library wants to set its own signal handlers,
+ it risks disturbing some other library. It is possible to chain the previous
+ signal handler, but then it is impossible to remove the old signal handlers
+ from the chains in any practical manner.
+* They can be called from whatever thread, requiring synchronization. Also, as
+ they can interrupt a thread at any time, making most handling race-prone.
+* According to the POSIX standard, the set of functions one may call inside a
+ signal handler is limited to very few of them. To highlight, mutexes (or other
+ locking mechanisms) and memory allocation and deallocation are *not* allowed.
+
+This library aims to solve some of the problems. It provides a global registry
+of actions performed on arrival of signals. It is possible to register multiple
+actions for the same signal and it is possible to remove the actions later on.
+If there was a previous signal handler when the first action for a signal is
+registered, it is chained (but the original one can't be removed).
+
+Besides the basic registration of an arbitrary action, several helper actions
+are provided to cover the needs of the most common use cases, available from
+safe Rust.
+
+For further details, see the [documentation](https://docs.rs/signal-hook).
+
+## Example
+
+(This likely does a lot more than you need in each individual application, it's
+more of a show-case of what everything is possible, not of what you need to do
+each time).
+
+```rust
+use std::io::Error;
+use std::sync::Arc;
+use std::sync::atomic::{AtomicBool, Ordering};
+
+fn main() -> Result<(), Error> {
+ let term = Arc::new(AtomicBool::new(false));
+ signal_hook::flag::register(signal_hook::consts::SIGTERM, Arc::clone(&term))?;
+ while !term.load(Ordering::Relaxed) {
+ // Do some time-limited stuff here
+ // (if this could block forever, then there's no guarantee the signal will have any
+ // effect).
+ }
+ Ok(())
+}
+```
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally
+submitted for inclusion in the work by you, as defined in the Apache-2.0
+license, shall be dual licensed as above, without any additional terms
+or conditions.
diff --git a/vendor/signal-hook/build.rs b/vendor/signal-hook/build.rs
new file mode 100644
index 000000000..82545f1ec
--- /dev/null
+++ b/vendor/signal-hook/build.rs
@@ -0,0 +1,9 @@
+#[cfg(feature = "extended-siginfo-raw")]
+fn main() {
+ cc::Build::new()
+ .file("src/low_level/extract.c")
+ .compile("extract");
+}
+
+#[cfg(not(feature = "extended-siginfo-raw"))]
+fn main() {}
diff --git a/vendor/signal-hook/ci-check.sh b/vendor/signal-hook/ci-check.sh
new file mode 100755
index 000000000..05879b651
--- /dev/null
+++ b/vendor/signal-hook/ci-check.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# We try to support some older versions of rustc. However, the support is
+# tiered a bit. Our dev-dependencies do *not* guarantee that old minimal
+# version. So we don't do tests on the older ones. Also, the
+# signal-hook-registry supports older rustc than we signal-hook.
+
+set -ex
+
+rm -f Cargo.lock
+cargo build --all --exclude signal-hook-async-std --exclude signal-hook-tokio
+
+if [ "$RUST_VERSION" = 1.36.0 ] ; then
+ exit
+fi
+
+if [ "$OS" = "windows-latest" ] || [ "$RUST_VERSION" = 1.40.0 ]; then
+ # The async support crates rely on the iterator module
+ # which isn't available for windows. So exclude them
+ # from the build.
+
+ # Also, some dependencies of the runtimes don't like 1.40.
+ EXCLUDE_FROM_BUILD="--exclude signal-hook-mio --exclude signal-hook-tokio --exclude signal-hook-async-std"
+else
+ EXCLUDE_FROM_BUILD=""
+fi
+
+export RUSTFLAGS="-D warnings"
+
+cargo test --all --all-features $EXCLUDE_FROM_BUILD
+cargo test --all $EXCLUDE_FROM_BUILD
diff --git a/vendor/signal-hook/examples/print.rs b/vendor/signal-hook/examples/print.rs
new file mode 100644
index 000000000..4007f9171
--- /dev/null
+++ b/vendor/signal-hook/examples/print.rs
@@ -0,0 +1,27 @@
+use libc::c_int;
+use signal_hook::consts::signal::*;
+use signal_hook::low_level;
+
+use std::io::Error;
+
+#[cfg(feature = "extended-siginfo")]
+type Signals =
+ signal_hook::iterator::SignalsInfo<signal_hook::iterator::exfiltrator::origin::WithOrigin>;
+
+#[cfg(not(feature = "extended-siginfo"))]
+use signal_hook::iterator::Signals;
+
+fn main() -> Result<(), Error> {
+ const SIGNALS: &[c_int] = &[
+ SIGTERM, SIGQUIT, SIGINT, SIGTSTP, SIGWINCH, SIGHUP, SIGCHLD, SIGCONT,
+ ];
+ let mut sigs = Signals::new(SIGNALS)?;
+ for signal in &mut sigs {
+ eprintln!("Received signal {:?}", signal);
+ #[cfg(feature = "extended-siginfo")]
+ let signal = signal.signal;
+ // After printing it, do whatever the signal was supposed to do in the first place
+ low_level::emulate_default_handler(signal)?;
+ }
+ Ok(())
+}
diff --git a/vendor/signal-hook/rustfmt.toml b/vendor/signal-hook/rustfmt.toml
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/signal-hook/rustfmt.toml
diff --git a/vendor/signal-hook/src/flag.rs b/vendor/signal-hook/src/flag.rs
new file mode 100644
index 000000000..8573fcd7f
--- /dev/null
+++ b/vendor/signal-hook/src/flag.rs
@@ -0,0 +1,283 @@
+//! Module for actions setting flags.
+//!
+//! This contains helper functions to set flags whenever a signal happens. The flags are atomic
+//! bools or numbers and the library manipulates them with the `SeqCst` ordering, in case someone
+//! cares about relative order to some *other* atomic variables. If you don't care about the
+//! relative order, you are free to use `Ordering::Relaxed` when reading and resetting the flags.
+//!
+//! # When to use
+//!
+//! The flags in this module allow for polling if a signal arrived since the previous poll. The do
+//! not allow blocking until something arrives.
+//!
+//! Therefore, the natural way to use them is in applications that have some kind of iterative work
+//! with both some upper and lower time limit on one iteration. If one iteration could block for
+//! arbitrary time, the handling of the signal would be postponed for a long time. If the iteration
+//! didn't block at all, the checking for the signal would turn into a busy-loop.
+//!
+//! If what you need is blocking until a signal comes, you might find better tools in the
+//! [`pipe`][crate::low_level::pipe] and [`iterator`][crate::iterator] modules.
+//!
+//! # Examples
+//!
+//! Doing something until terminated. This also knows by which signal it was terminated. In case
+//! multiple termination signals arrive before it is handled, it recognizes the last one.
+//!
+//! ```rust
+//! use std::io::Error;
+//! use std::sync::Arc;
+//! use std::sync::atomic::{AtomicUsize, Ordering};
+//!
+//! use signal_hook::consts::signal::*;
+//! use signal_hook::flag as signal_flag;
+//!
+//! fn main() -> Result<(), Error> {
+//! let term = Arc::new(AtomicUsize::new(0));
+//! const SIGTERM_U: usize = SIGTERM as usize;
+//! const SIGINT_U: usize = SIGINT as usize;
+//! # #[cfg(not(windows))]
+//! const SIGQUIT_U: usize = SIGQUIT as usize;
+//! signal_flag::register_usize(SIGTERM, Arc::clone(&term), SIGTERM_U)?;
+//! signal_flag::register_usize(SIGINT, Arc::clone(&term), SIGINT_U)?;
+//! # #[cfg(not(windows))]
+//! signal_flag::register_usize(SIGQUIT, Arc::clone(&term), SIGQUIT_U)?;
+//!
+//! # // Hack to terminate the example when run as a doc-test.
+//! # term.store(SIGTERM_U, Ordering::Relaxed);
+//! loop {
+//! match term.load(Ordering::Relaxed) {
+//! 0 => {
+//! // Do some useful stuff here
+//! }
+//! SIGTERM_U => {
+//! eprintln!("Terminating on the TERM signal");
+//! break;
+//! }
+//! SIGINT_U => {
+//! eprintln!("Terminating on the INT signal");
+//! break;
+//! }
+//! # #[cfg(not(windows))]
+//! SIGQUIT_U => {
+//! eprintln!("Terminating on the QUIT signal");
+//! break;
+//! }
+//! _ => unreachable!(),
+//! }
+//! }
+//!
+//! Ok(())
+//! }
+//! ```
+//!
+//! Sending a signal to self and seeing it arrived (not of a practical usage on itself):
+//!
+//! ```rust
+//! use std::io::Error;
+//! use std::sync::Arc;
+//! use std::sync::atomic::{AtomicBool, Ordering};
+//! use std::thread;
+//! use std::time::Duration;
+//!
+//! use signal_hook::consts::signal::*;
+//! use signal_hook::low_level::raise;
+//!
+//! fn main() -> Result<(), Error> {
+//! let got = Arc::new(AtomicBool::new(false));
+//! # #[cfg(not(windows))]
+//! signal_hook::flag::register(SIGUSR1, Arc::clone(&got))?;
+//! # #[cfg(windows)]
+//! # signal_hook::flag::register(SIGTERM, Arc::clone(&got))?;
+//! # #[cfg(not(windows))]
+//! raise(SIGUSR1).unwrap();
+//! # #[cfg(windows)]
+//! # raise(SIGTERM).unwrap();
+//! // A sleep here, because it could run the signal handler in another thread and we may not
+//! // see the flag right away. This is still a hack and not guaranteed to work, it is just an
+//! // example!
+//! thread::sleep(Duration::from_secs(1));
+//! assert!(got.load(Ordering::Relaxed));
+//! Ok(())
+//! }
+//! ```
+//!
+//! Reloading a configuration on `SIGHUP` (which is a common behaviour of many UNIX daemons,
+//! together with reopening the log file).
+//!
+//! ```rust
+//! use std::io::Error;
+//! use std::sync::Arc;
+//! use std::sync::atomic::{AtomicBool, Ordering};
+//!
+//! use signal_hook::consts::signal::*;
+//! use signal_hook::flag as signal_flag;
+//!
+//! fn main() -> Result<(), Error> {
+//! // We start with true, to load the configuration in the very first iteration too.
+//! let reload = Arc::new(AtomicBool::new(true));
+//! let term = Arc::new(AtomicBool::new(false));
+//! # #[cfg(not(windows))]
+//! signal_flag::register(SIGHUP, Arc::clone(&reload))?;
+//! signal_flag::register(SIGINT, Arc::clone(&term))?;
+//! signal_flag::register(SIGTERM, Arc::clone(&term))?;
+//! # #[cfg(not(windows))]
+//! signal_flag::register(SIGQUIT, Arc::clone(&term))?;
+//! while !term.load(Ordering::Relaxed) {
+//! // Using swap here, not load, to reset it back to false once it is reloaded.
+//! if reload.swap(false, Ordering::Relaxed) {
+//! // Reload the config here
+//! #
+//! # // Hiden hack to make the example terminate when run as doc-test. Not part of the
+//! # // real code.
+//! # term.store(true, Ordering::Relaxed);
+//! }
+//! // Serve one request
+//! }
+//! Ok(())
+//! }
+//! ```
+
+use std::io::Error;
+use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
+use std::sync::Arc;
+
+use libc::{c_int, EINVAL};
+
+use crate::{low_level, SigId};
+
+/// Registers an action to set the flag to `true` whenever the given signal arrives.
+///
+/// # Panics
+///
+/// If the signal is one of the forbidden.
+pub fn register(signal: c_int, flag: Arc<AtomicBool>) -> Result<SigId, Error> {
+ // We use SeqCst for two reasons:
+ // * Signals should not come very often, so the performance does not really matter.
+ // * We promise the order of actions, but setting different atomics with Relaxed or similar
+ // would not guarantee the effective order.
+ unsafe { low_level::register(signal, move || flag.store(true, Ordering::SeqCst)) }
+}
+
+/// Registers an action to set the flag to the given value whenever the signal arrives.
+pub fn register_usize(signal: c_int, flag: Arc<AtomicUsize>, value: usize) -> Result<SigId, Error> {
+ unsafe { low_level::register(signal, move || flag.store(value, Ordering::SeqCst)) }
+}
+
+/// Terminate the application on a signal if the given condition is true.
+///
+/// This can be used for different use cases. One of them (with the condition being always true) is
+/// just unconditionally terminate on the given signal.
+///
+/// Another is being able to turn on and off the behaviour by the shared flag.
+///
+/// The last one is handling double CTRL+C ‒ if the user presses CTRL+C, we would like to start a
+/// graceful shutdown. But if anything ever gets stuck in the shutdown, second CTRL+C (or other
+/// such termination signal) should terminate the application without further delay.
+///
+/// To do that, one can combine this with [`register`]. On the first run, the flag is `false` and
+/// this doesn't terminate. But then the flag is set to true during the first run and „arms“ the
+/// shutdown on the second run. Note that it matters in which order the actions are registered (the
+/// shutdown must go first). And yes, this also allows asking the user „Do you want to terminate“
+/// and disarming the abrupt shutdown if the user answers „No“.
+///
+/// # Panics
+///
+/// If the signal is one of the forbidden.
+pub fn register_conditional_shutdown(
+ signal: c_int,
+ status: c_int,
+ condition: Arc<AtomicBool>,
+) -> Result<SigId, Error> {
+ let action = move || {
+ if condition.load(Ordering::SeqCst) {
+ low_level::exit(status);
+ }
+ };
+ unsafe { low_level::register(signal, action) }
+}
+
+/// Conditionally runs an emulation of the default action on the given signal.
+///
+/// If the provided condition is true at the time of invoking the signal handler, the equivalent of
+/// the default action of the given signal is run. It is a bit similar to
+/// [`register_conditional_shutdown`], except that it doesn't terminate for non-termination
+/// signals, it runs their default handler.
+///
+/// # Panics
+///
+/// If the signal is one of the forbidden
+///
+/// # Errors
+///
+/// Similarly to the [`emulate_default_handler`][low_level::emulate_default_handler] function, this
+/// one looks the signal up in a table. If it is unknown, an error is returned.
+///
+/// Additionally to that, any errors that can be caused by a registration of a handler can happen
+/// too.
+pub fn register_conditional_default(
+ signal: c_int,
+ condition: Arc<AtomicBool>,
+) -> Result<SigId, Error> {
+ // Verify we know about this particular signal.
+ low_level::signal_name(signal).ok_or_else(|| Error::from_raw_os_error(EINVAL))?;
+ let action = move || {
+ if condition.load(Ordering::SeqCst) {
+ let _ = low_level::emulate_default_handler(signal);
+ }
+ };
+ unsafe { low_level::register(signal, action) }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::sync::atomic;
+ use std::time::{Duration, Instant};
+
+ use super::*;
+ use crate::consts::signal::*;
+
+ fn self_signal() {
+ #[cfg(not(windows))]
+ const SIG: c_int = SIGUSR1;
+ #[cfg(windows)]
+ const SIG: c_int = SIGTERM;
+ crate::low_level::raise(SIG).unwrap();
+ }
+
+ fn wait_flag(flag: &AtomicBool) -> bool {
+ let start = Instant::now();
+ while !flag.load(Ordering::Relaxed) {
+ // Replaced by hint::spin_loop, but we want to support older compiler
+ #[allow(deprecated)]
+ atomic::spin_loop_hint();
+ if Instant::now() - start > Duration::from_secs(1) {
+ // We reached a timeout and nothing happened yet.
+ // In theory, using timeouts for thread-synchronization tests is wrong, but a
+ // second should be enough in practice.
+ return false;
+ }
+ }
+ true
+ }
+
+ #[test]
+ fn register_unregister() {
+ // When we register the action, it is active.
+ let flag = Arc::new(AtomicBool::new(false));
+ #[cfg(not(windows))]
+ let signal = register(SIGUSR1, Arc::clone(&flag)).unwrap();
+ #[cfg(windows)]
+ let signal = register(crate::SIGTERM, Arc::clone(&flag)).unwrap();
+ self_signal();
+ assert!(wait_flag(&flag));
+ // But stops working after it is unregistered.
+ assert!(crate::low_level::unregister(signal));
+ flag.store(false, Ordering::Relaxed);
+ self_signal();
+ assert!(!wait_flag(&flag));
+ // And the unregistration actually dropped its copy of the Arc
+ assert_eq!(1, Arc::strong_count(&flag));
+ }
+
+ // The shutdown is tested in tests/shutdown.rs
+}
diff --git a/vendor/signal-hook/src/iterator/backend.rs b/vendor/signal-hook/src/iterator/backend.rs
new file mode 100644
index 000000000..2ed4bf93a
--- /dev/null
+++ b/vendor/signal-hook/src/iterator/backend.rs
@@ -0,0 +1,494 @@
+//! A backend module for implementing the iterator like
+//! [`iterator`][crate::iterator] module and the asynchronous
+//! adapter crates.
+//!
+//! This module contains generic types which abstract over the concrete
+//! IO type for the self-pipe. The motivation for having this abstraction
+//! are the adapter crates for different asynchronous runtimes. The runtimes
+//! provide their own wrappers for [`std::os::unix::net::UnixStream`]
+//! which should be used as the internal self pipe. But large parts of the
+//! remaining functionality doesn't depend directly onto the IO type and can
+//! be reused.
+//!
+//! See also the [`SignalDelivery::with_pipe`] method for more information
+//! about requirements the IO types have to fulfill.
+//!
+//! As a regular user you shouldn't need to use the types in this module.
+//! Use the [`Signals`][crate::iterator::Signals] struct or one of the types
+//! contained in the adapter libraries instead.
+
+use std::borrow::{Borrow, BorrowMut};
+use std::fmt::{Debug, Formatter, Result as FmtResult};
+use std::io::Error;
+use std::mem::MaybeUninit;
+use std::os::unix::io::AsRawFd;
+use std::ptr;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::{Arc, Mutex};
+
+use libc::{self, c_int};
+
+use super::exfiltrator::Exfiltrator;
+use crate::low_level::pipe::{self, WakeMethod};
+use crate::SigId;
+
+/// Maximal signal number we support.
+const MAX_SIGNUM: usize = 128;
+
+trait SelfPipeWrite: Debug + Send + Sync {
+ fn wake_readers(&self);
+}
+
+impl<W: AsRawFd + Debug + Send + Sync> SelfPipeWrite for W {
+ fn wake_readers(&self) {
+ pipe::wake(self.as_raw_fd(), WakeMethod::Send);
+ }
+}
+
+#[derive(Debug)]
+struct DeliveryState {
+ closed: AtomicBool,
+ registered_signal_ids: Mutex<Vec<Option<SigId>>>,
+}
+
+impl DeliveryState {
+ fn new() -> Self {
+ let ids = (0..MAX_SIGNUM).map(|_| None).collect();
+ Self {
+ closed: AtomicBool::new(false),
+ registered_signal_ids: Mutex::new(ids),
+ }
+ }
+}
+
+impl Drop for DeliveryState {
+ fn drop(&mut self) {
+ let lock = self.registered_signal_ids.lock().unwrap();
+ for id in lock.iter().filter_map(|s| *s) {
+ crate::low_level::unregister(id);
+ }
+ }
+}
+
+struct PendingSignals<E: Exfiltrator> {
+ exfiltrator: E,
+ slots: [E::Storage; MAX_SIGNUM],
+}
+
+impl<E: Exfiltrator> PendingSignals<E> {
+ fn new(exfiltrator: E) -> Self {
+ // Unfortunately, Default is not implemented for long arrays :-(
+ //
+ // Note that if the default impl panics, the already existing instances are leaked.
+ let mut slots = MaybeUninit::<[E::Storage; MAX_SIGNUM]>::uninit();
+ for i in 0..MAX_SIGNUM {
+ unsafe {
+ let slot: *mut E::Storage = slots.as_mut_ptr() as *mut _;
+ let slot = slot.add(i);
+ ptr::write(slot, E::Storage::default());
+ }
+ }
+
+ Self {
+ exfiltrator,
+ slots: unsafe { slots.assume_init() },
+ }
+ }
+}
+
+/// An internal trait to hide adding new signals into a Handle behind a dynamic dispatch.
+trait AddSignal: Debug + Send + Sync {
+ fn add_signal(
+ self: Arc<Self>,
+ write: Arc<dyn SelfPipeWrite>,
+ signal: c_int,
+ ) -> Result<SigId, Error>;
+}
+
+// Implemented manually because 1.36.0 doesn't yet support Debug for [X; BIG_NUMBER].
+impl<E: Exfiltrator> Debug for PendingSignals<E> {
+ fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
+ fmt.debug_struct("PendingSignals")
+ .field("exfiltrator", &self.exfiltrator)
+ // While the array does not, the slice does implement Debug
+ .field("slots", &&self.slots[..])
+ .finish()
+ }
+}
+
+impl<E: Exfiltrator> AddSignal for PendingSignals<E> {
+ fn add_signal(
+ self: Arc<Self>,
+ write: Arc<dyn SelfPipeWrite>,
+ signal: c_int,
+ ) -> Result<SigId, Error> {
+ assert!(signal >= 0);
+ assert!(
+ (signal as usize) < MAX_SIGNUM,
+ "Signal number {} too large. If your OS really supports such signal, file a bug",
+ signal,
+ );
+ assert!(
+ self.exfiltrator.supports_signal(signal),
+ "Signal {} not supported by exfiltrator {:?}",
+ signal,
+ self.exfiltrator,
+ );
+ self.exfiltrator.init(&self.slots[signal as usize], signal);
+
+ let action = move |act: &_| {
+ let slot = &self.slots[signal as usize];
+ let ex = &self.exfiltrator;
+ ex.store(slot, signal, act);
+ write.wake_readers();
+ };
+ let id = unsafe { signal_hook_registry::register_sigaction(signal, action) }?;
+ Ok(id)
+ }
+}
+
+/// A struct to control an instance of an associated type
+/// (like for example [`Signals`][super::Signals]).
+///
+/// It allows to register more signal handlers and to shutdown the signal
+/// delivery. You can [`clone`][Handle::clone] this type which isn't a
+/// very expensive operation. The cloned instances can be shared between
+/// multiple threads.
+#[derive(Debug, Clone)]
+pub struct Handle {
+ pending: Arc<dyn AddSignal>,
+ write: Arc<dyn SelfPipeWrite>,
+ delivery_state: Arc<DeliveryState>,
+}
+
+impl Handle {
+ fn new<W>(write: W, pending: Arc<dyn AddSignal>) -> Self
+ where
+ W: 'static + SelfPipeWrite,
+ {
+ Self {
+ pending,
+ write: Arc::new(write),
+ delivery_state: Arc::new(DeliveryState::new()),
+ }
+ }
+
+ /// Registers another signal to the set watched by the associated instance.
+ ///
+ /// # Notes
+ ///
+ /// * This is safe to call concurrently from whatever thread.
+ /// * This is *not* safe to call from within a signal handler.
+ /// * If the signal number was already registered previously, this is a no-op.
+ /// * If this errors, the original set of signals is left intact.
+ ///
+ /// # Panics
+ ///
+ /// * If the given signal is [forbidden][crate::FORBIDDEN].
+ /// * If the signal number is negative or larger than internal limit. The limit should be
+ /// larger than any supported signal the OS supports.
+ /// * If the relevant [`Exfiltrator`] does not support this particular signal. The default
+ /// [`SignalOnly`] one supports all signals.
+ pub fn add_signal(&self, signal: c_int) -> Result<(), Error> {
+ let mut lock = self.delivery_state.registered_signal_ids.lock().unwrap();
+ // Already registered, ignoring
+ if lock[signal as usize].is_some() {
+ return Ok(());
+ }
+
+ let id = Arc::clone(&self.pending).add_signal(Arc::clone(&self.write), signal)?;
+
+ lock[signal as usize] = Some(id);
+
+ Ok(())
+ }
+
+ /// Closes the associated instance.
+ ///
+ /// This is meant to signalize termination of the signal delivery process.
+ /// After calling close:
+ ///
+ /// * [`is_closed`][Handle::is_closed] will return true.
+ /// * All currently blocking operations of associated instances
+ /// are interrupted and terminate.
+ /// * Any further operations will not block.
+ /// * Further signals may or may not be returned from the iterators. However, if any are
+ /// returned, these are real signals that happened.
+ ///
+ /// The goal is to be able to shut down any background thread that handles only the signals.
+ pub fn close(&self) {
+ self.delivery_state.closed.store(true, Ordering::SeqCst);
+ self.write.wake_readers();
+ }
+
+ /// Is it closed?
+ ///
+ /// See [`close`][Handle::close].
+ pub fn is_closed(&self) -> bool {
+ self.delivery_state.closed.load(Ordering::SeqCst)
+ }
+}
+
+/// A struct for delivering received signals to the main program flow.
+/// The self-pipe IO type is generic. See the
+/// [`with_pipe`][SignalDelivery::with_pipe] method for requirements
+/// for the IO type.
+#[derive(Debug)]
+pub struct SignalDelivery<R, E: Exfiltrator> {
+ read: R,
+ handle: Handle,
+ pending: Arc<PendingSignals<E>>,
+}
+
+impl<R, E: Exfiltrator> SignalDelivery<R, E>
+where
+ R: 'static + AsRawFd + Send + Sync,
+{
+ /// Creates the `SignalDelivery` structure.
+ ///
+ /// The read and write arguments must be the ends of a suitable pipe type. These are used
+ /// for communication between the signal handler and main program flow.
+ ///
+ /// Registers all the signals listed. The same restrictions (panics, errors) apply as with
+ /// [`add_signal`][Handle::add_signal].
+ ///
+ /// # Requirements for the pipe type
+ ///
+ /// * Must support [`send`](https://man7.org/linux/man-pages/man2/send.2.html) for
+ /// asynchronously writing bytes to the write end
+ /// * Must support [`recv`](https://man7.org/linux/man-pages/man2/recv.2.html) for
+ /// reading bytes from the read end
+ ///
+ /// So UnixStream is a good choice for this.
+ pub fn with_pipe<I, S, W>(read: R, write: W, exfiltrator: E, signals: I) -> Result<Self, Error>
+ where
+ I: IntoIterator<Item = S>,
+ S: Borrow<c_int>,
+ W: 'static + AsRawFd + Debug + Send + Sync,
+ {
+ let pending = Arc::new(PendingSignals::new(exfiltrator));
+ let pending_add_signal = Arc::clone(&pending);
+ let handle = Handle::new(write, pending_add_signal);
+ let me = Self {
+ read,
+ handle,
+ pending,
+ };
+ for sig in signals {
+ me.handle.add_signal(*sig.borrow())?;
+ }
+ Ok(me)
+ }
+
+ /// Get a reference to the read end of the self pipe
+ ///
+ /// You may use this method to register the underlying file descriptor
+ /// with an eventing system (e. g. epoll) to get notified if there are
+ /// bytes in the pipe. If the event system reports the file descriptor
+ /// ready for reading you can then call [`pending`][SignalDelivery::pending]
+ /// to get the arrived signals.
+ pub fn get_read(&self) -> &R {
+ &self.read
+ }
+
+ /// Get a mutable reference to the read end of the self pipe
+ ///
+ /// See the [`get_read`][SignalDelivery::get_read] method for some additional
+ /// information.
+ pub fn get_read_mut(&mut self) -> &mut R {
+ &mut self.read
+ }
+
+ /// Drains all data from the internal self-pipe. This method will never block.
+ fn flush(&mut self) {
+ const SIZE: usize = 1024;
+ let mut buff = [0u8; SIZE];
+
+ unsafe {
+ // Draining the data in the self pipe. We ignore all errors on purpose. This
+ // should not be something like closed file descriptor. It could EAGAIN, but
+ // that's OK in case we say MSG_DONTWAIT. If it's EINTR, then it's OK too,
+ // it'll only create a spurious wakeup.
+ #[cfg(target_os = "aix")]
+ let nowait_flag = libc::MSG_NONBLOCK;
+ #[cfg(not(target_os = "aix"))]
+ let nowait_flag = libc::MSG_DONTWAIT;
+ while libc::recv(
+ self.read.as_raw_fd(),
+ buff.as_mut_ptr() as *mut libc::c_void,
+ SIZE,
+ nowait_flag,
+ ) > 0
+ {}
+ }
+ }
+
+ /// Returns an iterator of already received signals.
+ ///
+ /// This returns an iterator over all the signal numbers of the signals received since last
+ /// time they were read (out of the set registered by this `SignalDelivery` instance). Note
+ /// that they are returned in arbitrary order and a signal number is returned only once even
+ /// if it was received multiple times.
+ ///
+ /// This method returns immediately (does not block) and may produce an empty iterator if
+ /// there are no signals ready.
+ pub fn pending(&mut self) -> Pending<E> {
+ self.flush();
+ Pending::new(Arc::clone(&self.pending))
+ }
+
+ /// Checks the reading end of the self pipe for available signals.
+ ///
+ /// If there are no signals available or this instance was already closed it returns
+ /// [`Option::None`]. If there are some signals it returns a [`Pending`]
+ /// instance wrapped inside a [`Option::Some`]. However, due to implementation details,
+ /// this still can produce an empty iterator.
+ ///
+ /// This method doesn't check the reading end by itself but uses the passed in callback.
+ /// This method blocks if and only if the callback blocks trying to read some bytes.
+ pub fn poll_pending<F>(&mut self, has_signals: &mut F) -> Result<Option<Pending<E>>, Error>
+ where
+ F: FnMut(&mut R) -> Result<bool, Error>,
+ {
+ if self.handle.is_closed() {
+ return Ok(None);
+ }
+
+ match has_signals(self.get_read_mut()) {
+ Ok(false) => Ok(None),
+ Ok(true) => Ok(Some(self.pending())),
+ Err(err) => Err(err),
+ }
+ }
+
+ /// Get a [`Handle`] for this `SignalDelivery` instance.
+ ///
+ /// This can be used to add further signals or close the whole
+ /// signal delivery mechanism.
+ pub fn handle(&self) -> Handle {
+ self.handle.clone()
+ }
+}
+
+/// The iterator of one batch of signals.
+///
+/// This is returned by the [`pending`][SignalDelivery::pending] method.
+#[derive(Debug)]
+pub struct Pending<E: Exfiltrator> {
+ pending: Arc<PendingSignals<E>>,
+ position: usize,
+}
+
+impl<E: Exfiltrator> Pending<E> {
+ fn new(pending: Arc<PendingSignals<E>>) -> Self {
+ Self {
+ pending,
+ position: 0,
+ }
+ }
+}
+
+impl<E: Exfiltrator> Iterator for Pending<E> {
+ type Item = E::Output;
+
+ fn next(&mut self) -> Option<E::Output> {
+ while self.position < self.pending.slots.len() {
+ let sig = self.position;
+ let slot = &self.pending.slots[sig];
+ let result = self.pending.exfiltrator.load(slot, sig as c_int);
+ if result.is_some() {
+ return result;
+ } else {
+ self.position += 1;
+ }
+ }
+
+ None
+ }
+}
+
+/// Possible results of the [`poll_signal`][SignalIterator::poll_signal] function.
+pub enum PollResult<O> {
+ /// A signal arrived
+ Signal(O),
+ /// There are no signals yet but there may arrive some in the future
+ Pending,
+ /// The iterator was closed. There won't be any signals reported from now on.
+ Closed,
+ /// An error happened during polling for arrived signals.
+ Err(Error),
+}
+
+/// An infinite iterator of received signals.
+pub struct SignalIterator<SD, E: Exfiltrator> {
+ signals: SD,
+ iter: Pending<E>,
+}
+
+impl<SD, E: Exfiltrator> SignalIterator<SD, E> {
+ /// Create a new infinite iterator for signals registered with the passed
+ /// in [`SignalDelivery`] instance.
+ pub fn new<R>(mut signals: SD) -> Self
+ where
+ SD: BorrowMut<SignalDelivery<R, E>>,
+ R: 'static + AsRawFd + Send + Sync,
+ {
+ let iter = signals.borrow_mut().pending();
+ Self { signals, iter }
+ }
+
+ /// Return a signal if there is one or tell the caller that there is none at the moment.
+ ///
+ /// You have to pass in a callback which checks the underlying reading end of the pipe if
+ /// there may be any pending signals. This callback may or may not block. If the callback
+ /// returns [`true`] this method will try to fetch the next signal and return it as a
+ /// [`PollResult::Signal`]. If the callback returns [`false`] the method will return
+ /// [`PollResult::Pending`] and assume it will be called again at a later point in time.
+ /// The callback may be called any number of times by this function.
+ ///
+ /// If the iterator was closed by the [`close`][Handle::close] method of the associtated
+ /// [`Handle`] this method will return [`PollResult::Closed`].
+ pub fn poll_signal<R, F>(&mut self, has_signals: &mut F) -> PollResult<E::Output>
+ where
+ SD: BorrowMut<SignalDelivery<R, E>>,
+ R: 'static + AsRawFd + Send + Sync,
+ F: FnMut(&mut R) -> Result<bool, Error>,
+ {
+ // The loop is necessary because it is possible that a signal was already consumed
+ // by a previous pending iterator due to the asynchronous nature of signals and
+ // always moving to the end of the iterator before calling has_more.
+ while !self.signals.borrow_mut().handle.is_closed() {
+ if let Some(result) = self.iter.next() {
+ return PollResult::Signal(result);
+ }
+
+ match self.signals.borrow_mut().poll_pending(has_signals) {
+ Ok(Some(pending)) => self.iter = pending,
+ Ok(None) => return PollResult::Pending,
+ Err(err) => return PollResult::Err(err),
+ }
+ }
+
+ PollResult::Closed
+ }
+
+ /// Get a shareable [`Handle`] for this instance.
+ ///
+ /// This can be used to add further signals or terminate the whole
+ /// signal iteration using the [`close`][Handle::close] method.
+ pub fn handle<R>(&self) -> Handle
+ where
+ SD: Borrow<SignalDelivery<R, E>>,
+ R: 'static + AsRawFd + Send + Sync,
+ {
+ self.signals.borrow().handle()
+ }
+}
+
+/// A signal iterator which consumes a [`SignalDelivery`] instance and takes
+/// ownership of it.
+pub type OwningSignalIterator<R, E> = SignalIterator<SignalDelivery<R, E>, E>;
+
+/// A signal iterator which takes a mutable reference to a [`SignalDelivery`]
+/// instance.
+pub type RefSignalIterator<'a, R, E> = SignalIterator<&'a mut SignalDelivery<R, E>, E>;
diff --git a/vendor/signal-hook/src/iterator/exfiltrator/mod.rs b/vendor/signal-hook/src/iterator/exfiltrator/mod.rs
new file mode 100644
index 000000000..0b7cd0e34
--- /dev/null
+++ b/vendor/signal-hook/src/iterator/exfiltrator/mod.rs
@@ -0,0 +1,152 @@
+//! An abstraction over exfiltrating information out of signal handlers.
+//!
+//! The [`Exfiltrator`] trait provides a way to abstract the information extracted from a signal
+//! handler and the way it is extracted out of it.
+//!
+//! The implementations can be used to parametrize the
+//! [`SignalsInfo`][crate::iterator::SignalsInfo] to specify what results are returned.
+//!
+//! # Sealed
+//!
+//! Currently, the trait is sealed and all methods hidden. This is likely temporary, until some
+//! experience with them is gained.
+
+#[cfg(feature = "extended-siginfo")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extended-siginfo")))]
+pub mod origin;
+pub mod raw;
+
+#[cfg(feature = "extended-siginfo")]
+pub use origin::WithOrigin;
+pub use raw::WithRawSiginfo;
+
+use std::sync::atomic::{AtomicBool, Ordering};
+
+use libc::{c_int, siginfo_t};
+
+mod sealed {
+ use std::fmt::Debug;
+
+ use libc::{c_int, siginfo_t};
+
+ /// The actual implementation of the [`Exfiltrator`][super::Exfiltrator].
+ ///
+ /// For now, this is hidden from the public API, but the intention is to move it to a public
+ /// place so users can implement it eventually, once we verify that it works well.
+ ///
+ /// # Safety
+ ///
+ /// The trait is unsafe as the [`Exfiltrator::store`] is called inside the signal handler and
+ /// must be async-signal-safe. Implementing this correctly may be difficult, therefore care
+ /// needs to be taken. One method known to work is encoding the data into an atomic variable.
+ /// Other, less limiting approaches, will be eventually explored.
+ pub unsafe trait Exfiltrator: Debug + Send + Sync + 'static {
+ /// One slot for storing the data.
+ ///
+ /// Each signal will get its one slot of this type, independent of other signals. It can
+ /// store the information in there inside the signal handler and will be loaded from it in
+ /// load.
+ ///
+ /// Each slot is initialized to the [`Default`] value. It is expected this value represents
+ /// „no signal delivered“ state.
+ type Storage: Debug + Default + Send + Sync + 'static;
+
+ /// The type returned to the user.
+ type Output;
+
+ /// If the given signal is supported by this specific exfiltrator.
+ ///
+ /// Not all information is available to all signals, therefore not all exfiltrators must
+ /// support all signals. If `false` is returned, the user is prevented for registering such
+ /// signal number with the given exfiltrator.
+ fn supports_signal(&self, sig: c_int) -> bool;
+
+ /// Puts the signal information inside the slot.
+ ///
+ /// It needs to somehow store the relevant information and the fact that a signal happened.
+ ///
+ /// # Warning
+ ///
+ /// This will be called inside the signal handler. It needs to be async-signal-safe. In
+ /// particular, very small amount of operations are allowed in there. This namely does
+ /// *not* include any locking nor allocation.
+ ///
+ /// It is also possible that multiple store methods are called concurrently; it is up to
+ /// the implementor to deal with that.
+ fn store(&self, slot: &Self::Storage, signal: c_int, info: &siginfo_t);
+
+ /// Loads the signal information from the given slot.
+ ///
+ /// The method shall check if the signal happened (it may be possible to be called without
+ /// the signal previously being delivered; it is up to the implementer to recognize it). It
+ /// is assumed the [`Default`] value is recognized as no signal delivered.
+ ///
+ /// If it was delivered, the method shall extract the relevant information *and reset the
+ /// slot* to the no signal delivered state.
+ ///
+ /// It shall return `Some(value)` if the signal was successfully received and `None` in
+ /// case no signal was delivered.
+ ///
+ /// No blocking shall happen inside this method. It may be called concurrently with
+ /// [`store`][Exfiltrator::store] (due to how signals work, concurrently even inside the
+ /// same thread ‒ a `store` may „interrupt“ a call to `load`). It is up to the implementer
+ /// to deal with that.
+ fn load(&self, slot: &Self::Storage, signal: c_int) -> Option<Self::Output>;
+
+ /// Initialize the given slot for the given signal before the first use.
+ ///
+ /// This is called before the first use of the given slot (and it is annotated with the
+ /// corresponding signal). The default does nothing, this is just an opportunity to
+ /// allocate data lazily (this is called outside of the signal handler, so it doesn't have
+ /// to be async-signal-safe). It will be called at most once for each slot.
+ ///
+ /// Note that you can rely on this being called for correctness, but not for safety (this
+ /// crate calls it before the first use, but a user abusing the trait might not and in such
+ /// case it is OK to eg. lose signals, but not segfault).
+ fn init(&self, slot: &Self::Storage, signal: c_int) {
+ // Suppress unused variable warning without putting the underscores into public
+ // signature.
+ let _ = slot;
+ let _ = signal;
+ }
+ }
+}
+
+/// A trait describing what and how is extracted from signal handlers.
+///
+/// By choosing a specific implementor as the type parameter for
+/// [`SignalsInfo`][crate::iterator::SignalsInfo], one can pick how much and what information is
+/// returned from the iterator.
+pub trait Exfiltrator: sealed::Exfiltrator {}
+
+impl<E: sealed::Exfiltrator> Exfiltrator for E {}
+
+/// An [`Exfiltrator`] providing just the signal numbers.
+///
+/// This is the basic exfiltrator for most needs. For that reason, there's the
+/// [`crate::iterator::Signals`] type alias, to simplify the type names for usual needs.
+#[derive(Clone, Copy, Debug, Default)]
+pub struct SignalOnly;
+
+unsafe impl sealed::Exfiltrator for SignalOnly {
+ type Storage = AtomicBool;
+ fn supports_signal(&self, _: c_int) -> bool {
+ true
+ }
+ type Output = c_int;
+
+ fn store(&self, slot: &Self::Storage, _: c_int, _: &siginfo_t) {
+ slot.store(true, Ordering::SeqCst);
+ }
+
+ fn load(&self, slot: &Self::Storage, signal: c_int) -> Option<Self::Output> {
+ if slot
+ .compare_exchange(true, false, Ordering::SeqCst, Ordering::Relaxed)
+ .is_ok()
+ {
+ Some(signal)
+ } else {
+ None
+ }
+ }
+}
diff --git a/vendor/signal-hook/src/iterator/exfiltrator/origin.rs b/vendor/signal-hook/src/iterator/exfiltrator/origin.rs
new file mode 100644
index 000000000..c3e2f15d2
--- /dev/null
+++ b/vendor/signal-hook/src/iterator/exfiltrator/origin.rs
@@ -0,0 +1,66 @@
+//! An exfiltrator providing the process that caused the signal.
+//!
+//! The [`WithOrigin`] is an [`Exfiltrator`][crate::iterator::exfiltrator::Exfiltrator] that
+//! provides the information about sending process in addition to the signal number, through the
+//! [`Origin`] type.
+//!
+//! See the [`WithOrigin`] example.
+
+use libc::{c_int, siginfo_t};
+
+pub use super::raw::Slot;
+use super::sealed::Exfiltrator;
+use super::WithRawSiginfo;
+pub use crate::low_level::siginfo::{Origin, Process};
+
+/// The [`Exfiltrator`][crate::iterator::exfiltrator::Exfiltrator] that produces [`Origin`] of
+/// signals.
+///
+/// # Examples
+///
+/// ```rust
+/// # use signal_hook::consts::SIGUSR1;
+/// # use signal_hook::iterator::SignalsInfo;
+/// # use signal_hook::iterator::exfiltrator::WithOrigin;
+/// #
+/// # fn main() -> Result<(), std::io::Error> {
+/// // Subscribe to SIGUSR1, with information about the process.
+/// let mut signals = SignalsInfo::<WithOrigin>::new(&[SIGUSR1])?;
+///
+/// // Send a signal to ourselves.
+/// let my_pid = unsafe { libc::getpid() };
+/// unsafe { libc::kill(my_pid, SIGUSR1) };
+///
+/// // Grab the signal and look into the details.
+/// let received = signals.wait().next().unwrap();
+///
+/// assert_eq!(SIGUSR1, received.signal);
+/// assert_eq!(my_pid, received.process.unwrap().pid);
+/// # Ok(()) }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct WithOrigin(WithRawSiginfo);
+
+// Safety: We need to be async-signal-safe. We delegate to other Exfiltrator, which already is and
+// call a function that promises to be (Origin::extract)
+unsafe impl Exfiltrator for WithOrigin {
+ type Storage = Slot;
+ type Output = Origin;
+ fn supports_signal(&self, signal: c_int) -> bool {
+ self.0.supports_signal(signal)
+ }
+
+ fn store(&self, slot: &Slot, signal: c_int, info: &siginfo_t) {
+ self.0.store(slot, signal, info)
+ }
+
+ fn load(&self, slot: &Self::Storage, signal: c_int) -> Option<Origin> {
+ self.0
+ .load(slot, signal)
+ .map(|info| unsafe { Origin::extract(&info) })
+ }
+
+ fn init(&self, slot: &Self::Storage, signal: c_int) {
+ self.0.init(slot, signal)
+ }
+}
diff --git a/vendor/signal-hook/src/iterator/exfiltrator/raw.rs b/vendor/signal-hook/src/iterator/exfiltrator/raw.rs
new file mode 100644
index 000000000..93c1ace6a
--- /dev/null
+++ b/vendor/signal-hook/src/iterator/exfiltrator/raw.rs
@@ -0,0 +1,95 @@
+//! An exfiltrator providing the raw [`siginfo_t`].
+
+// Note on unsafety in this module:
+// * Implementing an unsafe trait, that one needs to ensure at least store is async-signal-safe.
+// That's done by delegating to the Channel (and reading an atomic pointer, but that one is
+// primitive op).
+// * A bit of juggling with atomic and raw pointers. In effect, that is just late lazy
+// initialization, the Slot is in line with Option would be, except that it is set atomically
+// during the init. Lifetime is ensured by not dropping until the Drop of the whole slot and that
+// is checked by taking `&mut self`.
+
+use std::sync::atomic::{AtomicPtr, Ordering};
+
+use libc::{c_int, siginfo_t};
+
+use super::sealed::Exfiltrator;
+use crate::low_level::channel::Channel;
+
+#[doc(hidden)]
+#[derive(Default, Debug)]
+pub struct Slot(AtomicPtr<Channel<siginfo_t>>);
+
+impl Drop for Slot {
+ fn drop(&mut self) {
+ let ptr = self.0.load(Ordering::Acquire);
+ if !ptr.is_null() {
+ drop(unsafe { Box::from_raw(ptr) });
+ }
+ }
+}
+
+/// The [`Exfiltrator`][crate::iterator::exfiltrator::Exfiltrator] that produces the raw
+/// [`libc::siginfo_t`]. Note that it might look differently on different OSes and its API is a
+/// little bit more limited than its C counterpart.
+///
+/// You might prefer the [`WithOrigin`][super::WithOrigin] if you simply need information about the
+/// origin of the signal.
+///
+/// # Examples
+///
+/// ```rust
+/// # use signal_hook::consts::SIGUSR1;
+/// # use signal_hook::iterator::SignalsInfo;
+/// # use signal_hook::iterator::exfiltrator::WithRawSiginfo;
+/// #
+/// # fn main() -> Result<(), std::io::Error> {
+/// // Subscribe to SIGUSR1, with information about the process.
+/// let mut signals = SignalsInfo::<WithRawSiginfo>::new(&[SIGUSR1])?;
+///
+/// // Send ourselves a signal.
+/// signal_hook::low_level::raise(SIGUSR1)?;
+///
+/// // Grab the signal and look into the details.
+/// let received = signals.wait().next().unwrap();
+///
+/// // Not much else is useful in a cross-platform way :-(
+/// assert_eq!(SIGUSR1, received.si_signo);
+/// # Ok(()) }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct WithRawSiginfo;
+
+unsafe impl Exfiltrator for WithRawSiginfo {
+ type Storage = Slot;
+ type Output = siginfo_t;
+
+ fn supports_signal(&self, _: c_int) -> bool {
+ true
+ }
+
+ fn store(&self, slot: &Slot, _: c_int, info: &siginfo_t) {
+ let info = *info;
+ // Condition just not to crash if someone forgot to call init.
+ //
+ // Lifetime is from init to our own drop, and drop needs &mut self.
+ if let Some(slot) = unsafe { slot.0.load(Ordering::Acquire).as_ref() } {
+ slot.send(info);
+ }
+ }
+
+ fn load(&self, slot: &Slot, _: libc::c_int) -> Option<siginfo_t> {
+ let slot = unsafe { slot.0.load(Ordering::Acquire).as_ref() };
+ // Condition just not to crash if someone forgot to call init.
+ slot.and_then(|s| s.recv())
+ }
+
+ fn init(&self, slot: &Self::Storage, _: c_int) {
+ let new = Box::default();
+ let old = slot.0.swap(Box::into_raw(new), Ordering::Release);
+ // We leak the pointer on purpose here. This is invalid state anyway and must not happen,
+ // but if it still does, we can't drop that while some other thread might still be having
+ // the raw pointer.
+ assert!(old.is_null(), "Init called multiple times");
+ }
+}
diff --git a/vendor/signal-hook/src/iterator/mod.rs b/vendor/signal-hook/src/iterator/mod.rs
new file mode 100644
index 000000000..b4bfec4e6
--- /dev/null
+++ b/vendor/signal-hook/src/iterator/mod.rs
@@ -0,0 +1,323 @@
+//! An iterator over incoming signals.
+//!
+//! This provides a higher abstraction over the signals, providing
+//! the [`SignalsInfo`] structure which is able to iterate over the
+//! incoming signals. The structure is parametrized by an
+//! [`Exfiltrator`][self::exfiltrator::Exfiltrator], which specifies what information is returned
+//! for each delivered signal. Note that some exfiltrators are behind a feature flag.
+//!
+//! The [`Signals`] is a type alias for the common case when it is enough to get the signal number.
+//!
+//! This module (and everything in it) is turned by the `iterator` feature. It is **on** by
+//! default, the possibility to turn off is mostly possible for very special purposes (compiling on
+//! `<rustc-1.36`, minimizing the amount of code compiled, …). In a sense, this is the highest
+//! level abstraction of the crate and the API expected to be used by most of the people.
+//!
+//! # Examples
+//!
+//! ```rust
+//! extern crate libc;
+//! extern crate signal_hook;
+//!
+//! use std::io::Error;
+//!
+//! use signal_hook::consts::signal::*;
+//! use signal_hook::iterator::Signals;
+//!
+//! fn main() -> Result<(), Error> {
+//! let mut signals = Signals::new(&[
+//! SIGHUP,
+//! SIGTERM,
+//! SIGINT,
+//! SIGQUIT,
+//! # SIGUSR1,
+//! ])?;
+//! # // A trick to terminate the example when run as doc-test. Not part of the real code.
+//! # signal_hook::low_level::raise(SIGUSR1).unwrap();
+//! 'outer: loop {
+//! // Pick up signals that arrived since last time
+//! for signal in signals.pending() {
+//! match signal as libc::c_int {
+//! SIGHUP => {
+//! // Reload configuration
+//! // Reopen the log file
+//! }
+//! SIGTERM | SIGINT | SIGQUIT => {
+//! break 'outer;
+//! },
+//! # SIGUSR1 => return Ok(()),
+//! _ => unreachable!(),
+//! }
+//! }
+//! // Do some bit of work ‒ something with upper limit on waiting, so we don't block
+//! // forever with a SIGTERM already waiting.
+//! }
+//! println!("Terminating. Bye bye");
+//! Ok(())
+//! }
+//! ```
+
+pub mod backend;
+pub mod exfiltrator;
+
+use std::borrow::Borrow;
+use std::fmt::{Debug, Formatter, Result as FmtResult};
+use std::io::{Error, ErrorKind, Read};
+use std::os::unix::net::UnixStream;
+
+use libc::{self, c_int};
+
+pub use self::backend::{Handle, Pending};
+use self::backend::{PollResult, RefSignalIterator, SignalDelivery};
+use self::exfiltrator::{Exfiltrator, SignalOnly};
+
+/// The main structure of the module, representing interest in some signals.
+///
+/// Unlike the helpers in other modules, this registers the signals when created and unregisters
+/// them on drop. It provides the pending signals during its lifetime, either in batches or as an
+/// infinite iterator.
+///
+/// Most users will want to use it through the [`Signals`] type alias for simplicity.
+///
+/// # Multiple threads
+///
+/// Instances of this struct can be [sent][std::marker::Send] to other threads. In a multithreaded
+/// application this can be used to dedicate a separate thread for signal handling. In this case
+/// you should get a [`Handle`] using the [`handle`][Signals::handle] method before sending the
+/// `Signals` instance to a background thread. With the handle you will be able to shut down the
+/// background thread later, or to operatively add more signals.
+///
+/// The controller handle can be shared between as many threads as you like using its
+/// [`clone`][Handle::clone] method.
+///
+/// # Exfiltrators
+///
+/// The [`SignalOnly]` provides only the signal number. There are further exfiltrators available in
+/// the [`exfiltrator`] module. Note that some of them are behind feature flags that need to be
+/// enabled.
+///
+/// # Examples
+///
+/// ```rust
+/// # extern crate signal_hook;
+/// #
+/// # use std::io::Error;
+/// # use std::thread;
+/// use signal_hook::consts::signal::*;
+/// use signal_hook::iterator::Signals;
+///
+/// #
+/// # fn main() -> Result<(), Error> {
+/// let mut signals = Signals::new(&[SIGUSR1, SIGUSR2])?;
+/// let handle = signals.handle();
+/// let thread = thread::spawn(move || {
+/// for signal in &mut signals {
+/// match signal {
+/// SIGUSR1 => {},
+/// SIGUSR2 => {},
+/// _ => unreachable!(),
+/// }
+/// }
+/// });
+///
+/// // Some time later...
+/// handle.close();
+/// thread.join().unwrap();
+/// # Ok(())
+/// # }
+/// ```
+pub struct SignalsInfo<E: Exfiltrator = SignalOnly>(SignalDelivery<UnixStream, E>);
+
+impl<E: Exfiltrator> SignalsInfo<E> {
+ /// Creates the `Signals` structure.
+ ///
+ /// This registers all the signals listed. The same restrictions (panics, errors) apply as
+ /// for the [`Handle::add_signal`] method.
+ pub fn new<I, S>(signals: I) -> Result<Self, Error>
+ where
+ I: IntoIterator<Item = S>,
+ S: Borrow<c_int>,
+ E: Default,
+ {
+ Self::with_exfiltrator(signals, E::default())
+ }
+
+ /// An advanced constructor with explicit [`Exfiltrator`].
+ pub fn with_exfiltrator<I, S>(signals: I, exfiltrator: E) -> Result<Self, Error>
+ where
+ I: IntoIterator<Item = S>,
+ S: Borrow<c_int>,
+ {
+ let (read, write) = UnixStream::pair()?;
+ Ok(SignalsInfo(SignalDelivery::with_pipe(
+ read,
+ write,
+ exfiltrator,
+ signals,
+ )?))
+ }
+
+ /// Registers another signal to the set watched by this [`Signals`] instance.
+ ///
+ /// The same restrictions (panics, errors) apply as for the [`Handle::add_signal`]
+ /// method.
+ pub fn add_signal(&self, signal: c_int) -> Result<(), Error> {
+ self.handle().add_signal(signal)
+ }
+
+ /// Returns an iterator of already received signals.
+ ///
+ /// This returns an iterator over all the signal numbers of the signals received since last
+ /// time they were read (out of the set registered by this `Signals` instance). Note that they
+ /// are returned in arbitrary order and a signal instance may returned only once even if it was
+ /// received multiple times.
+ ///
+ /// This method returns immediately (does not block) and may produce an empty iterator if there
+ /// are no signals ready.
+ pub fn pending(&mut self) -> Pending<E> {
+ self.0.pending()
+ }
+
+ /// Block until the stream contains some bytes.
+ ///
+ /// Returns true if it was possible to read a byte and false otherwise.
+ fn has_signals(read: &mut UnixStream) -> Result<bool, Error> {
+ loop {
+ match read.read(&mut [0u8]) {
+ Ok(num_read) => break Ok(num_read > 0),
+ // If we get an EINTR error it is fine to retry reading from the stream.
+ // Otherwise we should pass on the error to the caller.
+ Err(error) => {
+ if error.kind() != ErrorKind::Interrupted {
+ break Err(error);
+ }
+ }
+ }
+ }
+ }
+
+ /// Waits for some signals to be available and returns an iterator.
+ ///
+ /// This is similar to [`pending`][SignalsInfo::pending]. If there are no signals available, it
+ /// tries to wait for some to arrive. However, due to implementation details, this still can
+ /// produce an empty iterator.
+ ///
+ /// This can block for arbitrary long time. If the [`Handle::close`] method is used in
+ /// another thread this method will return immediately.
+ ///
+ /// Note that the blocking is done in this method, not in the iterator.
+ pub fn wait(&mut self) -> Pending<E> {
+ match self.0.poll_pending(&mut Self::has_signals) {
+ Ok(Some(pending)) => pending,
+ // Because of the blocking has_signals method the poll_pending method
+ // only returns None if the instance is closed. But we want to return
+ // a possibly empty pending object anyway.
+ Ok(None) => self.pending(),
+ // Users can't manipulate the internal file descriptors and the way we use them
+ // shouldn't produce any errors. So it is OK to panic.
+ Err(error) => panic!("Unexpected error: {}", error),
+ }
+ }
+
+ /// Is it closed?
+ ///
+ /// See [`close`][Handle::close].
+ pub fn is_closed(&self) -> bool {
+ self.handle().is_closed()
+ }
+
+ /// Get an infinite iterator over arriving signals.
+ ///
+ /// The iterator's `next()` blocks as necessary to wait for signals to arrive. This is adequate
+ /// if you want to designate a thread solely to handling signals. If multiple signals come at
+ /// the same time (between two values produced by the iterator), they will be returned in
+ /// arbitrary order. Multiple instances of the same signal may be collated.
+ ///
+ /// This is also the iterator returned by `IntoIterator` implementation on `&mut Signals`.
+ ///
+ /// This iterator terminates only if explicitly [closed][Handle::close].
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # extern crate libc;
+ /// # extern crate signal_hook;
+ /// #
+ /// # use std::io::Error;
+ /// # use std::thread;
+ /// #
+ /// use signal_hook::consts::signal::*;
+ /// use signal_hook::iterator::Signals;
+ ///
+ /// # fn main() -> Result<(), Error> {
+ /// let mut signals = Signals::new(&[SIGUSR1, SIGUSR2])?;
+ /// let handle = signals.handle();
+ /// thread::spawn(move || {
+ /// for signal in signals.forever() {
+ /// match signal {
+ /// SIGUSR1 => {},
+ /// SIGUSR2 => {},
+ /// _ => unreachable!(),
+ /// }
+ /// }
+ /// });
+ /// handle.close();
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn forever(&mut self) -> Forever<E> {
+ Forever(RefSignalIterator::new(&mut self.0))
+ }
+
+ /// Get a shareable handle to a [`Handle`] for this instance.
+ ///
+ /// This can be used to add further signals or close the [`Signals`] instance.
+ pub fn handle(&self) -> Handle {
+ self.0.handle()
+ }
+}
+
+impl<E> Debug for SignalsInfo<E>
+where
+ E: Debug + Exfiltrator,
+ E::Storage: Debug,
+{
+ fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
+ fmt.debug_tuple("Signals").field(&self.0).finish()
+ }
+}
+
+impl<'a, E: Exfiltrator> IntoIterator for &'a mut SignalsInfo<E> {
+ type Item = E::Output;
+ type IntoIter = Forever<'a, E>;
+ fn into_iter(self) -> Self::IntoIter {
+ self.forever()
+ }
+}
+
+/// An infinit iterator of arriving signals.
+pub struct Forever<'a, E: Exfiltrator>(RefSignalIterator<'a, UnixStream, E>);
+
+impl<'a, E: Exfiltrator> Iterator for Forever<'a, E> {
+ type Item = E::Output;
+
+ fn next(&mut self) -> Option<E::Output> {
+ match self.0.poll_signal(&mut SignalsInfo::<E>::has_signals) {
+ PollResult::Signal(result) => Some(result),
+ PollResult::Closed => None,
+ PollResult::Pending => unreachable!(
+ "Because of the blocking has_signals method the \
+ poll_signal method never returns Poll::Pending but blocks until a signal arrived"
+ ),
+ // Users can't manipulate the internal file descriptors and the way we use them
+ // shouldn't produce any errors. So it is OK to panic.
+ PollResult::Err(error) => panic!("Unexpected error: {}", error),
+ }
+ }
+}
+
+/// A type alias for an iterator returning just the signal numbers.
+///
+/// This is the simplified version for most of the use cases. For advanced usages, the
+/// [`SignalsInfo`] with explicit [`Exfiltrator`] type can be used.
+pub type Signals = SignalsInfo<SignalOnly>;
diff --git a/vendor/signal-hook/src/lib.rs b/vendor/signal-hook/src/lib.rs
new file mode 100644
index 000000000..d750e15c2
--- /dev/null
+++ b/vendor/signal-hook/src/lib.rs
@@ -0,0 +1,414 @@
+#![doc(
+ test(attr(deny(warnings))),
+ test(attr(allow(bare_trait_objects, unknown_lints)))
+)]
+#![warn(missing_docs)]
+// Don't fail on links to things not enabled in features
+#![allow(
+ unknown_lints,
+ renamed_and_removed_lints,
+ intra_doc_link_resolution_failure,
+ broken_intra_doc_links
+)]
+// These little nifty labels saying that something needs a feature to be enabled
+#![cfg_attr(docsrs, feature(doc_cfg))]
+//! Library for easier and safe Unix signal handling
+//!
+//! Unix signals are inherently hard to handle correctly, for several reasons:
+//!
+//! * They are a global resource. If a library wants to set its own signal handlers, it risks
+//! disrupting some other library. It is possible to chain the previous signal handler, but then
+//! it is impossible to remove the old signal handlers from the chains in any practical manner.
+//! * They can be called from whatever thread, requiring synchronization. Also, as they can
+//! interrupt a thread at any time, making most handling race-prone.
+//! * According to the POSIX standard, the set of functions one may call inside a signal handler is
+//! limited to very few of them. To highlight, mutexes (or other locking mechanisms) and memory
+//! allocation and deallocation is *not* allowed.
+//!
+//! # The goal of the library
+//!
+//! The aim is to subscriptions to signals a „structured“ resource, in a similar way memory
+//! allocation is ‒ parts of the program can independently subscribe and it's the same part of the
+//! program that can give them up, independently of what the other parts do. Therefore, it is
+//! possible to register multiple actions to the same signal.
+//!
+//! Another goal is to shield applications away from differences between platforms. Various Unix
+//! systems have little quirks and differences that need to be worked around and that's not
+//! something every application should be dealing with. We even try to provide some support for
+//! Windows, but we lack the expertise in that area, so that one is not complete and is a bit rough
+//! (if you know how it works there and are willing to either contribute the code or consult,
+//! please get in touch).
+//!
+//! Furthermore, it provides implementation of certain common signal-handling patterns, usable from
+//! safe Rust, without the application author needing to learn about *all* the traps.
+//!
+//! Note that despite everything, there are still some quirks around signal handling that are not
+//! possible to paper over and need to be considered. Also, there are some signal use cases that
+//! are inherently unsafe and they are not covered by this crate.
+//!
+//! # Anatomy of the crate
+//!
+//! The crate is split into several modules.
+//!
+//! The easiest way to handle signals is using the [`Signals`][crate::iterator::Signals] iterator
+//! thing. It can register for a set of signals and produce them one by one, in a blocking manner.
+//! You can reserve a thread for handling them as they come. If you want something asynchronous,
+//! there are adaptor crates for the most common asynchronous runtimes. The module also contains
+//! ways to build iterators that produce a bit more information that just the signal number.
+//!
+//! The [`flag`] module contains routines to set a flag based on incoming signals and to do
+//! certain actions inside the signal handlers based on the flags (the flags can also be
+//! manipulated by the rest of the application). This allows building things like checking if a
+//! signal happened on each loop iteration or making sure application shuts down on the second
+//! CTRL+C if it got stuck in graceful shutdown requested by the first.
+//!
+//! The [`consts`] module contains some constants, most importantly the signal numbers themselves
+//! (these are just re-exports from [`libc`] and if your OS has some extra ones, you can use them
+//! too, this is just for convenience).
+//!
+//! And last, there is the [`low_level`] module. It contains routines to directly register and
+//! unregister arbitrary actions. Some of the patters in the above modules return a [`SigId`],
+//! which can be used with the [`low_level::unregister`] to remove the action. There are also some
+//! other utilities that are more suited to build other abstractions with than to use directly.
+//!
+//! Certain parts of the library can be enabled or disabled with use flags:
+//!
+//! * `channel`: The [low_level::channel] module (on by default).
+//! * `iterator`: The [iterator] module (on by default).
+//! * `extended-sig-info`: Support for providing more information in the iterators or from the
+//! async adaptor crates. This is off by default.
+//!
+//! # Limitations
+//!
+//! * OS limitations still apply. Certain signals are not possible to override or subscribe to ‒
+//! `SIGKILL` or `SIGSTOP`.
+//! * Overriding some others is probably a very stupid idea (or very unusual needs) ‒ handling eg.
+//! `SIGSEGV` is not something done lightly. For that reason, the crate will panic in case
+//! registering of these is attempted (see [`FORBIDDEN`][crate::consts::FORBIDDEN]. If you still
+//! need to do so, you can find such APIs in the `signal-hook-registry` backend crate, but
+//! additional care must be taken.
+//! * Interaction with other signal-handling libraries is limited. If signal-hook finds an existing
+//! handler present, it chain-calls it from the signal it installs and assumes other libraries
+//! would do the same, but that's everything that can be done to make it work with libraries not
+//! based on [`signal-hook-registry`](https://lib.rs/signal-hook-registry)
+//! (the backend of this crate).
+//! * The above chaining contains a race condition in multi-threaded programs, where the previous
+//! handler might not get called if it is received during the registration process. This is
+//! handled (at least on non-windows platforms) on the same thread where the registration
+//! happens, therefore it is advised to register at least one action for each signal of interest
+//! early, before any additional threads are started. Registering any additional (or removing and
+//! registering again) action on the same signal is without the race condition.
+//! * Once at least one action is registered for a signal, the default action is replaced (this is
+//! how signals work in the OS). Even if all actions of that signal are removed, `signal-hook`
+//! does not restore the default handler (such behaviour would be at times inconsistent with
+//! making the actions independent and there's no reasonable way to do so in a race-free way in a
+//! multi-threaded program while also dealing with signal handlers registered with other
+//! libraries). It is, however, possible to *emulate* the default handler (see the
+//! [`emulate_default_handler`][low_level::emulate_default_handler]) ‒ there are only 4
+//! default handlers:
+//! - Ignore. This is easy to emulate.
+//! - Abort. Depending on if you call it from within a signal handler of from outside, the
+//! [`low_level::abort`] or [`std::process::abort`] can be used.
+//! - Terminate. This can be done with `exit` ([`low_level::exit`] or [`std::process::exit`]).
+//! - Stop. It is possible to [`raise`][low_level::raise] the [`SIGSTOP`][consts::SIGSTOP] signal.
+//! That one can't be replaced and always stops the application.
+//! * Many of the patterns here can collate multiple instances of the same signal into fewer
+//! instances, if the application doesn't consume them fast enough. This is consistent with what
+//! the kernel does if the application doesn't keep up with them (at least for non-realtime
+//! signals, see below), so it is something one needs to deal with anyway.
+//! * (By design) the library mostly _postpones_ or helps the user postpone acting on the signals
+//! until later. This, in combination with the above collating inside the library may make it
+//! unsuitable for realtime signals. These usually want to be handled directly inside the signal
+//! handler ‒ which still can be done with [signal_hook_registry::register], but using unsafe and
+//! due care. Patterns for working safely with realtime signals are not unwanted in the library,
+//! but nobody contributed them yet.
+//!
+//! # Signal masks
+//!
+//! As the library uses `sigaction` under the hood, signal masking works as expected (eg. with
+//! `pthread_sigmask`). This means, signals will *not* be delivered if the signal is masked in all
+//! program's threads.
+//!
+//! By the way, if you do want to modify the signal mask (or do other Unix-specific magic), the
+//! [nix](https://lib.rs/crates/nix) crate offers safe interface to many low-level functions,
+//! including
+//! [`pthread_sigmask`](https://docs.rs/nix/0.11.0/nix/sys/signal/fn.pthread_sigmask.html).
+//!
+//! # Portability
+//!
+//! It should work on any POSIX.1-2001 system, which are all the major big OSes with the notable
+//! exception of Windows.
+//!
+//! Non-standard signals are also supported. Pass the signal value directly from `libc` or use
+//! the numeric value directly.
+//!
+//! ```rust
+//! use std::sync::Arc;
+//! use std::sync::atomic::{AtomicBool};
+//! let term = Arc::new(AtomicBool::new(false));
+//! let _ = signal_hook::flag::register(libc::SIGINT, Arc::clone(&term));
+//! ```
+//!
+//! This crate includes a limited support for Windows, based on `signal`/`raise` in the CRT.
+//! There are differences in both API and behavior:
+//!
+//! - Many parts of the library are not available there.
+//! - We have only a few signals: `SIGABRT`, `SIGABRT_COMPAT`, `SIGBREAK`,
+//! `SIGFPE`, `SIGILL`, `SIGINT`, `SIGSEGV` and `SIGTERM`.
+//! - Due to lack of signal blocking, there's a race condition.
+//! After the call to `signal`, there's a moment where we miss a signal.
+//! That means when you register a handler, there may be a signal which invokes
+//! neither the default handler or the handler you register.
+//! - Handlers registered by `signal` in Windows are cleared on first signal.
+//! To match behavior in other platforms, we re-register the handler each time the handler is
+//! called, but there's a moment where we miss a handler.
+//! That means when you receive two signals in a row, there may be a signal which invokes
+//! the default handler, nevertheless you certainly have registered the handler.
+//!
+//! Moreover, signals won't work as you expected. `SIGTERM` isn't actually used and
+//! not all `Ctrl-C`s are turned into `SIGINT`.
+//!
+//! Patches to improve Windows support in this library are welcome.
+//!
+//! # Features
+//!
+//! There are several feature flags that control how much is available as part of the crate, some
+//! enabled by default.
+//!
+//! * `channel`: (enabled by default) The [Channel][crate::low_level::channel] synchronization
+//! primitive for exporting data out of signal handlers.
+//! * `iterator`: (enabled by default) An [Signals iterator][crate::iterator::Signals] that
+//! provides a convenient interface for receiving signals in rust-friendly way.
+//! * `extended-siginfo` adds support for providing extra information as part of the iterator
+//! interface.
+//!
+//! # Examples
+//!
+//! ## Using a flag to terminate a loop-based application
+//!
+//! ```rust
+//! use std::io::Error;
+//! use std::sync::Arc;
+//! use std::sync::atomic::{AtomicBool, Ordering};
+//!
+//! fn main() -> Result<(), Error> {
+//! let term = Arc::new(AtomicBool::new(false));
+//! signal_hook::flag::register(signal_hook::consts::SIGTERM, Arc::clone(&term))?;
+//! while !term.load(Ordering::Relaxed) {
+//! // Do some time-limited stuff here
+//! // (if this could block forever, then there's no guarantee the signal will have any
+//! // effect).
+//! #
+//! # // Hack to terminate the example, not part of the real code.
+//! # term.store(true, Ordering::Relaxed);
+//! }
+//! Ok(())
+//! }
+//! ```
+//!
+//! ## A complex signal handling with a background thread
+//!
+//! This also handles the double CTRL+C situation (eg. the second CTRL+C kills) and resetting the
+//! terminal on `SIGTSTP` (CTRL+Z, curses-based applications should do something like this).
+//!
+//! ```rust
+//! # #[cfg(feature = "extended-siginfo")] pub mod test {
+//! use std::io::Error;
+//! use std::sync::Arc;
+//! use std::sync::atomic::AtomicBool;
+//!
+//! use signal_hook::consts::signal::*;
+//! use signal_hook::consts::TERM_SIGNALS;
+//! use signal_hook::flag;
+//! // A friend of the Signals iterator, but can be customized by what we want yielded about each
+//! // signal.
+//! use signal_hook::iterator::SignalsInfo;
+//! use signal_hook::iterator::exfiltrator::WithOrigin;
+//! use signal_hook::low_level;
+//!
+//! # struct App;
+//! # impl App {
+//! # fn run_background() -> Self { Self }
+//! # fn wait_for_stop(self) {}
+//! # fn restore_term(&self) {}
+//! # fn claim_term(&self) {}
+//! # fn resize_term(&self) {}
+//! # fn reload_config(&self) {}
+//! # fn print_stats(&self) {}
+//! # }
+//! # pub
+//! fn main() -> Result<(), Error> {
+//! // Make sure double CTRL+C and similar kills
+//! let term_now = Arc::new(AtomicBool::new(false));
+//! for sig in TERM_SIGNALS {
+//! // When terminated by a second term signal, exit with exit code 1.
+//! // This will do nothing the first time (because term_now is false).
+//! flag::register_conditional_shutdown(*sig, 1, Arc::clone(&term_now))?;
+//! // But this will "arm" the above for the second time, by setting it to true.
+//! // The order of registering these is important, if you put this one first, it will
+//! // first arm and then terminate ‒ all in the first round.
+//! flag::register(*sig, Arc::clone(&term_now))?;
+//! }
+//!
+//! // Subscribe to all these signals with information about where they come from. We use the
+//! // extra info only for logging in this example (it is not available on all the OSes or at
+//! // all the occasions anyway, it may return `Unknown`).
+//! let mut sigs = vec![
+//! // Some terminal handling
+//! SIGTSTP, SIGCONT, SIGWINCH,
+//! // Reload of configuration for daemons ‒ um, is this example for a TUI app or a daemon
+//! // O:-)? You choose...
+//! SIGHUP,
+//! // Application-specific action, to print some statistics.
+//! SIGUSR1,
+//! ];
+//! sigs.extend(TERM_SIGNALS);
+//! let mut signals = SignalsInfo::<WithOrigin>::new(&sigs)?;
+//! # low_level::raise(SIGTERM)?; // Trick to terminate the example
+//!
+//! // This is the actual application that'll start in its own thread. We'll control it from
+//! // this thread based on the signals, but it keeps running.
+//! // This is called after all the signals got registered, to avoid the short race condition
+//! // in the first registration of each signal in multi-threaded programs.
+//! let app = App::run_background();
+//!
+//! // Consume all the incoming signals. This happens in "normal" Rust thread, not in the
+//! // signal handlers. This means that we are allowed to do whatever we like in here, without
+//! // restrictions, but it also means the kernel believes the signal already got delivered, we
+//! // handle them in delayed manner. This is in contrast with eg the above
+//! // `register_conditional_shutdown` where the shutdown happens *inside* the handler.
+//! let mut has_terminal = true;
+//! for info in &mut signals {
+//! // Will print info about signal + where it comes from.
+//! eprintln!("Received a signal {:?}", info);
+//! match info.signal {
+//! SIGTSTP => {
+//! // Restore the terminal to non-TUI mode
+//! if has_terminal {
+//! app.restore_term();
+//! has_terminal = false;
+//! // And actually stop ourselves.
+//! low_level::emulate_default_handler(SIGTSTP)?;
+//! }
+//! }
+//! SIGCONT => {
+//! if !has_terminal {
+//! app.claim_term();
+//! has_terminal = true;
+//! }
+//! }
+//! SIGWINCH => app.resize_term(),
+//! SIGHUP => app.reload_config(),
+//! SIGUSR1 => app.print_stats(),
+//! term_sig => { // These are all the ones left
+//! eprintln!("Terminating");
+//! assert!(TERM_SIGNALS.contains(&term_sig));
+//! break;
+//! }
+//! }
+//! }
+//!
+//! // If during this another termination signal comes, the trick at the top would kick in and
+//! // terminate early. But if it doesn't, the application shuts down gracefully.
+//! app.wait_for_stop();
+//!
+//! Ok(())
+//! }
+//! # }
+//! # fn main() {
+//! # #[cfg(feature = "extended-siginfo")] test::main().unwrap();
+//! # }
+//! ```
+//!
+//! # Asynchronous runtime support
+//!
+//! If you are looking for integration with an asynchronous runtime take a look at one of the
+//! following adapter crates:
+//!
+//! * [`signal-hook-async-std`](https://docs.rs/signal-hook-async-std) for async-std support
+//! * [`signal-hook-mio`](https://docs.rs/signal-hook-mio) for MIO support
+//! * [`signal-hook-tokio`](https://docs.rs/signal-hook-tokio) for Tokio support
+//!
+//! Feel free to open a pull requests if you want to add support for runtimes not mentioned above.
+//!
+//! # Porting from previous versions
+//!
+//! There were some noisy changes when going from 0.2 version to the 0.3 version. In particular:
+//!
+//! * A lot of things moved around to make the structure of the crate a bit more understandable.
+//! Most of the time it should be possible to just search the documentation for the name that
+//! can't be resolved to discover the new location.
+//! - The signal constants (`SIGTERM`, for example) are in [`consts`] submodule (individual
+//! imports) and in the [`consts::signal`] (for wildcard import of all of them).
+//! - Some APIs that are considered more of a low-level building blocks than for casual day to
+//! day use are now in the [`low_level`] submodule.
+//! * The previous version contained the `cleanup` module that allowed for removal of the actions
+//! in rather destructive way (nuking actions of arbitrary other parts of the program). This is
+//! completely gone in this version. The use case of shutting down the application on second
+//! CTRL+C is now supported by a pattern described in the [`flag`] submodule. For other similar
+//! needs, refer above for emulating default handlers.
+
+pub mod flag;
+#[cfg(all(not(windows), feature = "iterator"))]
+#[cfg_attr(docsrs, doc(cfg(all(not(windows), feature = "iterator"))))]
+pub mod iterator;
+pub mod low_level;
+
+/// The low-level constants.
+///
+/// Like the signal numbers.
+pub mod consts {
+
+ use libc::c_int;
+
+ /// The signal constants.
+ ///
+ /// Can be mass-imported by `use signal_hook::consts::signal::*`, without polluting the
+ /// namespace with other names. Also available in the [`consts`][crate::consts] directly (but
+ /// with more constants around).
+ pub mod signal {
+ #[cfg(not(windows))]
+ pub use libc::{
+ SIGABRT, SIGALRM, SIGBUS, SIGCHLD, SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGKILL,
+ SIGPIPE, SIGPROF, SIGQUIT, SIGSEGV, SIGSTOP, SIGSYS, SIGTERM, SIGTRAP, SIGTSTP,
+ SIGTTIN, SIGTTOU, SIGURG, SIGUSR1, SIGUSR2, SIGVTALRM, SIGWINCH, SIGXCPU, SIGXFSZ,
+ };
+
+ #[cfg(not(any(windows, target_os = "haiku")))]
+ pub use libc::SIGIO;
+
+ #[cfg(any(
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "macos"
+ ))]
+ pub use libc::SIGINFO;
+
+ #[cfg(windows)]
+ pub use libc::{SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM};
+
+ // NOTE: they perhaps deserve backport to libc.
+ #[cfg(windows)]
+ /// Same as `SIGABRT`, but the number is compatible to other platforms.
+ pub const SIGABRT_COMPAT: libc::c_int = 6;
+ #[cfg(windows)]
+ /// Ctrl-Break is pressed for Windows Console processes.
+ pub const SIGBREAK: libc::c_int = 21;
+ }
+
+ pub use self::signal::*;
+
+ pub use signal_hook_registry::FORBIDDEN;
+
+ /// Various signals commonly requesting shutdown of an application.
+ #[cfg(not(windows))]
+ pub const TERM_SIGNALS: &[c_int] = &[SIGTERM, SIGQUIT, SIGINT];
+
+ /// Various signals commonly requesting shutdown of an application.
+ #[cfg(windows)]
+ pub const TERM_SIGNALS: &[c_int] = &[SIGTERM, SIGINT];
+}
+
+pub use signal_hook_registry::SigId;
diff --git a/vendor/signal-hook/src/low_level/channel.rs b/vendor/signal-hook/src/low_level/channel.rs
new file mode 100644
index 000000000..cc46c836f
--- /dev/null
+++ b/vendor/signal-hook/src/low_level/channel.rs
@@ -0,0 +1,235 @@
+//! A restricted channel to pass data from signal handler.
+//!
+//! When trying to communicate data from signal handler to the outside world, one can use an atomic
+//! variable (as it doesn't lock, so it can be made async-signal-safe). But this won't work for
+//! larger data.
+//!
+//! This module provides a channel that can be used for that purpose. It is used by certain
+//! [exfiltrators][crate::iterator::exfiltrator], but can be used as building block for custom
+//! actions. In general, this is not a ready-made end-user API.
+//!
+//! # How does it work
+//!
+//! Each channel has a fixed number of slots and two queues (one for empty slots, one for full
+//! slots). A signal handler takes a slot out of the empty one, fills it and passes it into the
+//! full one. Outside of signal handler, it can take the value out of the full queue and return the
+//! slot to the empty queue.
+//!
+//! The queues are implemented as bit-encoded indexes of the slots in the storage. The bits are
+//! stored in an atomic variable.
+//!
+//! Note that the algorithm allows for a slot to be in neither queue (when it is being emptied or
+//! filled).
+//!
+//! # Fallible allocation of a slot
+//!
+//! It is apparent that allocation of a new slot can fail (there's nothing in the empty slot). In
+//! such case, there's no way to send the new value out of the handler (there's no way to safely
+//! wait for a slot to appear, because the handler can be blocking the thread that is responsible
+//! for emptying them). But that's considered acceptable ‒ even the kernel collates the same kinds
+//! of signals together if they are not consumed by application fast enough and there are no free
+//! slots exactly because some are being filled, emptied or are full ‒ in particular, the whole
+//! system will yield a signal.
+//!
+//! This assumes that separate signals don't share the same buffer and that there's only one reader
+//! (using multiple readers is still safe, but it is possible that all slots would be inside the
+//! readers, but already empty, so the above argument would not hold).
+
+// TODO: Other sizes? Does anyone need more than 5 slots?
+
+use std::cell::UnsafeCell;
+use std::sync::atomic::{AtomicU16, Ordering};
+
+const SLOTS: usize = 5;
+const BITS: u16 = 3;
+const MASK: u16 = 0b111;
+
+fn get(n: u16, idx: u16) -> u16 {
+ (n >> (BITS * idx)) & MASK
+}
+
+fn set(n: u16, idx: u16, v: u16) -> u16 {
+ let v = v << (BITS * idx);
+ let mask = MASK << (BITS * idx);
+ (n & !mask) | v
+}
+
+fn enqueue(q: &AtomicU16, val: u16) {
+ let mut current = q.load(Ordering::Relaxed);
+ loop {
+ let empty = (0..SLOTS as u16)
+ .find(|i| get(current, *i) == 0)
+ .expect("No empty slot available");
+ let modified = set(current, empty, val);
+ match q.compare_exchange_weak(current, modified, Ordering::Release, Ordering::Relaxed) {
+ Ok(_) => break,
+ Err(changed) => current = changed, // And retry with the changed value
+ }
+ }
+}
+
+fn dequeue(q: &AtomicU16) -> Option<u16> {
+ let mut current = q.load(Ordering::Relaxed);
+ loop {
+ let val = current & MASK;
+ // It's completely empty
+ if val == 0 {
+ break None;
+ }
+ let modified = current >> BITS;
+ match q.compare_exchange_weak(current, modified, Ordering::Acquire, Ordering::Relaxed) {
+ Ok(_) => break Some(val),
+ Err(changed) => current = changed,
+ }
+ }
+}
+
+/// A restricted async-signal-safe channel
+///
+/// This is a bit like the usual channel used for inter-thread communication, but with several
+/// restrictions:
+///
+/// * There's a limited number of slots (currently 5).
+/// * There's no way to wait for a place in it or for a value. If value is not available, `None` is
+/// returned. If there's no space for a value, the value is silently dropped.
+///
+/// In exchange for that, all the operations on that channel are async-signal-safe. That means it
+/// is possible to use it to communicate between a signal handler and the rest of the world with it
+/// (specifically, it's designed to send information from the handler to the rest of the
+/// application). The throwing out of values when full is in line with collating of the same type
+/// in kernel (you should not use the same channel for multiple different signals).
+///
+/// Technically, this is a MPMC queue which preserves order, but it is expected to be used in MPSC
+/// mode mostly (in theory, multiple threads can be executing a signal handler for the same signal
+/// at the same time). The channel is not responsible for wakeups.
+///
+/// While the channel is async-signal-safe, you still need to make sure *creating* of the values is
+/// too (it should not contain anything that allocates, for example ‒ so no `String`s inside, etc).
+///
+/// The code was *not* tuned for performance (signals are not expected to happen often).
+pub struct Channel<T> {
+ storage: [UnsafeCell<Option<T>>; SLOTS],
+ empty: AtomicU16,
+ full: AtomicU16,
+}
+
+impl<T> Channel<T> {
+ /// Creates a new channel with nothing in it.
+ pub fn new() -> Self {
+ let storage = Default::default();
+ let me = Self {
+ storage,
+ empty: AtomicU16::new(0),
+ full: AtomicU16::new(0),
+ };
+
+ for i in 1..SLOTS + 1 {
+ enqueue(&me.empty, i as u16);
+ }
+
+ me
+ }
+
+ /// Inserts a value into the channel.
+ ///
+ /// If the value doesn't fit, it is silently dropped. Never blocks.
+ pub fn send(&self, val: T) {
+ if let Some(empty_idx) = dequeue(&self.empty) {
+ unsafe { *self.storage[empty_idx as usize - 1].get() = Some(val) };
+ enqueue(&self.full, empty_idx);
+ }
+ }
+
+ /// Takes a value from the channel.
+ ///
+ /// Or returns `None` if the channel is empty. Never blocks.
+ pub fn recv(&self) -> Option<T> {
+ dequeue(&self.full).map(|idx| {
+ let result = unsafe { &mut *self.storage[idx as usize - 1].get() }
+ .take()
+ .expect("Full slot with nothing in it");
+ enqueue(&self.empty, idx);
+ result
+ })
+ }
+}
+
+impl<T> Default for Channel<T> {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+unsafe impl<T: Send> Send for Channel<T> {}
+
+// Yes, really Send -> Sync. Having a reference to Channel allows Sending Ts, but not having refs
+// on them.
+unsafe impl<T: Send> Sync for Channel<T> {}
+
+#[cfg(test)]
+mod tests {
+ use std::sync::Arc;
+ use std::thread;
+
+ use super::*;
+
+ #[test]
+ fn new_empty() {
+ let channel = Channel::<usize>::new();
+ assert!(channel.recv().is_none());
+ assert!(channel.recv().is_none());
+ }
+
+ #[test]
+ fn pass_value() {
+ let channel = Channel::new();
+ channel.send(42);
+ assert_eq!(42, channel.recv().unwrap());
+ assert!(channel.recv().is_none());
+ }
+
+ #[test]
+ fn multiple() {
+ let channel = Channel::new();
+ for i in 0..1000 {
+ channel.send(i);
+ assert_eq!(i, channel.recv().unwrap());
+ assert!(channel.recv().is_none());
+ }
+ }
+
+ #[test]
+ fn overflow() {
+ let channel = Channel::new();
+ for i in 0..10 {
+ channel.send(i);
+ }
+ for i in 0..5 {
+ assert_eq!(i, channel.recv().unwrap());
+ }
+ assert!(channel.recv().is_none());
+ }
+
+ #[test]
+ fn multi_thread() {
+ let channel = Arc::new(Channel::<usize>::new());
+
+ let sender = thread::spawn({
+ let channel = Arc::clone(&channel);
+ move || {
+ for i in 0..4 {
+ channel.send(i);
+ }
+ }
+ });
+
+ let mut results = Vec::new();
+ while results.len() < 4 {
+ results.extend(channel.recv());
+ }
+
+ assert_eq!(vec![0, 1, 2, 3], results);
+
+ sender.join().unwrap();
+ }
+}
diff --git a/vendor/signal-hook/src/low_level/extract.c b/vendor/signal-hook/src/low_level/extract.c
new file mode 100644
index 000000000..5f226158b
--- /dev/null
+++ b/vendor/signal-hook/src/low_level/extract.c
@@ -0,0 +1,55 @@
+/*
+ * Low-level extraction code to overcome rust's libc not having the best access
+ * to siginfo_t details.
+ */
+#include <stdbool.h>
+#include <signal.h>
+#include <stdint.h>
+
+struct Const {
+ int native;
+ // The signal this applies to, or -1 if it applies to anything.
+ int signal;
+ uint8_t translated;
+};
+
+// Warning: must be in sync with the rust source code
+struct Const consts[] = {
+#ifdef SI_KERNEL
+ { SI_KERNEL, -1, 1 },
+#endif
+ { SI_USER, -1, 2 },
+#ifdef SI_TKILL
+ { SI_TKILL, -1, 3 },
+#endif
+ { SI_QUEUE, -1, 4 },
+ { SI_MESGQ, -1, 5 },
+ { CLD_EXITED, SIGCHLD, 6 },
+ { CLD_KILLED, SIGCHLD, 7 },
+ { CLD_DUMPED, SIGCHLD, 8 },
+ { CLD_TRAPPED, SIGCHLD, 9 },
+ { CLD_STOPPED, SIGCHLD, 10 },
+ { CLD_CONTINUED, SIGCHLD, 11 },
+};
+
+uint8_t sighook_signal_cause(const siginfo_t *info) {
+ const size_t const_len = sizeof consts / sizeof *consts;
+ size_t i;
+ for (i = 0; i < const_len; i ++) {
+ if (
+ consts[i].native == info->si_code &&
+ (consts[i].signal == -1 || consts[i].signal == info->si_signo)
+ ) {
+ return consts[i].translated;
+ }
+ }
+ return 0; // The "Unknown" variant
+}
+
+pid_t sighook_signal_pid(const siginfo_t *info) {
+ return info->si_pid;
+}
+
+uid_t sighook_signal_uid(const siginfo_t *info) {
+ return info->si_uid;
+}
diff --git a/vendor/signal-hook/src/low_level/mod.rs b/vendor/signal-hook/src/low_level/mod.rs
new file mode 100644
index 000000000..bf99fac78
--- /dev/null
+++ b/vendor/signal-hook/src/low_level/mod.rs
@@ -0,0 +1,59 @@
+//! Some low level utilities
+//!
+//! More often to build other abstractions than used directly.
+
+use std::io::Error;
+
+use libc::c_int;
+
+#[cfg(feature = "channel")]
+#[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
+pub mod channel;
+#[cfg(not(windows))]
+#[cfg_attr(docsrs, doc(cfg(not(windows))))]
+pub mod pipe;
+#[cfg(feature = "extended-siginfo-raw")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extended-siginfo-raw")))]
+pub mod siginfo;
+mod signal_details;
+
+pub use signal_hook_registry::{register, unregister};
+
+pub use self::signal_details::{emulate_default_handler, signal_name};
+
+/// The usual raise, just the safe wrapper around it.
+///
+/// This is async-signal-safe.
+pub fn raise(sig: c_int) -> Result<(), Error> {
+ let result = unsafe { libc::raise(sig) };
+ if result == -1 {
+ Err(Error::last_os_error())
+ } else {
+ Ok(())
+ }
+}
+
+/// A bare libc abort.
+///
+/// Unlike the [std::process::abort], this one is guaranteed to contain no additions or wrappers
+/// and therefore is async-signal-safe. You can use this to terminate the application from within a
+/// signal handler.
+pub fn abort() -> ! {
+ unsafe {
+ libc::abort();
+ }
+}
+
+/// A bare libc exit.
+///
+/// Unlike the [std::process::exit], this one is guaranteed to contain no additions or wrappers and
+/// therefore is async-signal-safe. You can use this to terminate the application from within a
+/// signal handler.
+///
+/// Also, see [`register_conditional_shutdown`][crate::flag::register_conditional_shutdown].
+pub fn exit(status: c_int) -> ! {
+ unsafe {
+ // Yes, the one with underscore. That one doesn't call the at-exit hooks.
+ libc::_exit(status);
+ }
+}
diff --git a/vendor/signal-hook/src/low_level/pipe.rs b/vendor/signal-hook/src/low_level/pipe.rs
new file mode 100644
index 000000000..3cd218743
--- /dev/null
+++ b/vendor/signal-hook/src/low_level/pipe.rs
@@ -0,0 +1,265 @@
+//! Module with the self-pipe pattern.
+//!
+//! One of the common patterns around signals is to have a pipe with both ends in the same program.
+//! Whenever there's a signal, the signal handler writes one byte of garbage data to the write end,
+//! unless the pipe's already full. The application then can handle the read end.
+//!
+//! This has two advantages. First, the real signal action moves outside of the signal handler
+//! where there are a lot less restrictions. Second, it fits nicely in all kinds of asynchronous
+//! loops and has less chance of race conditions.
+//!
+//! This module offers premade functions for the write end (and doesn't insist that it must be a
+//! pipe ‒ anything that can be written to is fine ‒ sockets too, therefore `UnixStream::pair` is a
+//! good candidate).
+//!
+//! If you want to integrate with some asynchronous library, plugging streams from `mio-uds` or
+//! `tokio-uds` libraries should work.
+//!
+//! If it looks too low-level for your needs, the [`iterator`][crate::iterator] module contains some
+//! higher-lever interface that also uses a self-pipe pattern under the hood.
+//!
+//! # Correct order of handling
+//!
+//! A care needs to be taken to avoid race conditions, especially when handling the same signal in
+//! a loop. Specifically, another signal might come when the action for the previous signal is
+//! being taken. The correct order is first to clear the content of the pipe (read some/all data
+//! from it) and then take the action. This way a spurious wakeup can happen (the pipe could wake
+//! up even when no signal came after the signal was taken, because ‒ it arrived between cleaning
+//! the pipe and taking the action). Note that some OS primitives (eg. `select`) suffer from
+//! spurious wakeups themselves (they can claim a FD is readable when it is not true) and blocking
+//! `read` might return prematurely (with eg. `EINTR`).
+//!
+//! The reverse order of first taking the action and then clearing the pipe might lose signals,
+//! which is usually worse.
+//!
+//! This is not a problem with blocking on reading from the pipe (because both the blocking and
+//! cleaning is the same action), but in case of asynchronous handling it matters.
+//!
+//! If you want to combine setting some flags with a self-pipe pattern, the flag needs to be set
+//! first, then the pipe written. On the read end, first the pipe needs to be cleaned, then the
+//! flag and then the action taken. This is what the [`SignalsInfo`][crate::iterator::SignalsInfo]
+//! structure does internally.
+//!
+//! # Write collating
+//!
+//! While unlikely if handled correctly, it is possible the write end is full when a signal comes.
+//! In such case the signal handler simply does nothing. If the write end is full, the read end is
+//! readable and therefore will wake up. On the other hand, blocking in the signal handler would
+//! definitely be a bad idea.
+//!
+//! However, this also means the number of bytes read from the end might be lower than the number
+//! of signals that arrived. This should not generally be a problem, since the OS already collates
+//! signals of the same kind together.
+//!
+//! # Examples
+//!
+//! This example waits for at last one `SIGUSR1` signal to come before continuing (and
+//! terminating). It sends the signal to itself, so it correctly terminates.
+//!
+//! ```rust
+//! use std::io::{Error, Read};
+//! use std::os::unix::net::UnixStream;
+//!
+//! use signal_hook::consts::SIGUSR1;
+//! use signal_hook::low_level::{pipe, raise};
+//!
+//! fn main() -> Result<(), Error> {
+//! let (mut read, write) = UnixStream::pair()?;
+//! pipe::register(SIGUSR1, write)?;
+//! // This will write into the pipe write end through the signal handler
+//! raise(SIGUSR1).unwrap();
+//! let mut buff = [0];
+//! read.read_exact(&mut buff)?;
+//! println!("Happily terminating");
+//! Ok(())
+//! }
+
+use std::io::{Error, ErrorKind};
+use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
+
+use libc::{self, c_int};
+
+use crate::SigId;
+
+#[cfg(target_os = "aix")]
+const MSG_NOWAIT: i32 = libc::MSG_NONBLOCK;
+#[cfg(not(target_os = "aix"))]
+const MSG_NOWAIT: i32 = libc::MSG_DONTWAIT;
+
+#[derive(Copy, Clone)]
+pub(crate) enum WakeMethod {
+ Send,
+ Write,
+}
+
+struct WakeFd {
+ fd: RawFd,
+ method: WakeMethod,
+}
+
+impl WakeFd {
+ /// Sets close on exec and nonblock on the inner file descriptor.
+ fn set_flags(&self) -> Result<(), Error> {
+ unsafe {
+ let flags = libc::fcntl(self.as_raw_fd(), libc::F_GETFL, 0);
+ if flags == -1 {
+ return Err(Error::last_os_error());
+ }
+ let flags = flags | libc::O_NONBLOCK | libc::O_CLOEXEC;
+ if libc::fcntl(self.as_raw_fd(), libc::F_SETFL, flags) == -1 {
+ return Err(Error::last_os_error());
+ }
+ }
+ Ok(())
+ }
+ fn wake(&self) {
+ wake(self.fd, self.method);
+ }
+}
+
+impl AsRawFd for WakeFd {
+ fn as_raw_fd(&self) -> RawFd {
+ self.fd
+ }
+}
+
+impl Drop for WakeFd {
+ fn drop(&mut self) {
+ unsafe {
+ libc::close(self.fd);
+ }
+ }
+}
+
+pub(crate) fn wake(pipe: RawFd, method: WakeMethod) {
+ unsafe {
+ // This writes some data into the pipe.
+ //
+ // There are two tricks:
+ // * First, the crazy cast. The first part turns reference into pointer. The second part
+ // turns pointer to u8 into a pointer to void, which is what write requires.
+ // * Second, we ignore errors, on purpose. We don't have any means to handling them. The
+ // two conceivable errors are EBADFD, if someone passes a non-existent file descriptor or
+ // if it is closed. The second is EAGAIN, in which case the pipe is full ‒ there were
+ // many signals, but the reader didn't have time to read the data yet. It'll still get
+ // woken up, so not fitting another letter in it is fine.
+ let data = b"X" as *const _ as *const _;
+ match method {
+ WakeMethod::Write => libc::write(pipe, data, 1),
+ WakeMethod::Send => libc::send(pipe, data, 1, MSG_NOWAIT),
+ };
+ }
+}
+
+/// Registers a write to a self-pipe whenever there's the signal.
+///
+/// In this case, the pipe is taken as the `RawFd`. It'll be closed on deregistration. Effectively,
+/// the function takes ownership of the file descriptor. This includes feeling free to set arbitrary
+/// flags on it, including file status flags (that are shared across file descriptors created by
+/// `dup`).
+///
+/// Note that passing the wrong file descriptor won't cause UB, but can still lead to severe bugs ‒
+/// like data corruptions in files. Prefer using [`register`] if possible.
+///
+/// Also, it is perfectly legal for multiple writes to be collated together (if not consumed) and
+/// to generate spurious wakeups (but will not generate spurious *bytes* in the pipe).
+///
+/// # Internal details
+///
+/// Internally, it *currently* does following. Note that this is *not* part of the stability
+/// guarantees and may change if necessary.
+///
+/// * If the file descriptor can be used with [`send`][libc::send], it'll be used together with
+/// [`MSG_DONTWAIT`][libc::MSG_DONTWAIT]. This is tested by sending `0` bytes of data (depending
+/// on the socket type, this might wake the read end with an empty message).
+/// * If it is not possible, the [`O_NONBLOCK`][libc::O_NONBLOCK] will be set on the file
+/// descriptor and [`write`][libc::write] will be used instead.
+pub fn register_raw(signal: c_int, pipe: RawFd) -> Result<SigId, Error> {
+ let res = unsafe { libc::send(pipe, &[] as *const _, 0, MSG_NOWAIT) };
+ let fd = match (res, Error::last_os_error().kind()) {
+ (0, _) | (-1, ErrorKind::WouldBlock) => WakeFd {
+ fd: pipe,
+ method: WakeMethod::Send,
+ },
+ _ => {
+ let fd = WakeFd {
+ fd: pipe,
+ method: WakeMethod::Write,
+ };
+ fd.set_flags()?;
+ fd
+ }
+ };
+ let action = move || fd.wake();
+ unsafe { super::register(signal, action) }
+}
+
+/// Registers a write to a self-pipe whenever there's the signal.
+///
+/// The ownership of pipe is taken and will be closed whenever the created action is unregistered.
+///
+/// Note that if you want to register the same pipe for multiple signals, there's `try_clone`
+/// method on many unix socket primitives.
+///
+/// See [`register_raw`] for further details.
+pub fn register<P>(signal: c_int, pipe: P) -> Result<SigId, Error>
+where
+ P: IntoRawFd + 'static,
+{
+ register_raw(signal, pipe.into_raw_fd())
+}
+
+#[cfg(test)]
+mod tests {
+ use std::io::Read;
+ use std::os::unix::net::{UnixDatagram, UnixStream};
+
+ use super::*;
+
+ // Note: multiple tests share the SIGUSR1 signal. This is fine, we only need to know the signal
+ // arrives. It's OK to arrive multiple times, from multiple tests.
+ fn wakeup() {
+ crate::low_level::raise(libc::SIGUSR1).unwrap();
+ }
+
+ #[test]
+ fn register_with_socket() -> Result<(), Error> {
+ let (mut read, write) = UnixStream::pair()?;
+ register(libc::SIGUSR1, write)?;
+ wakeup();
+ let mut buff = [0; 1];
+ read.read_exact(&mut buff)?;
+ assert_eq!(b"X", &buff);
+ Ok(())
+ }
+
+ #[test]
+ #[cfg(not(target_os = "haiku"))]
+ fn register_dgram_socket() -> Result<(), Error> {
+ let (read, write) = UnixDatagram::pair()?;
+ register(libc::SIGUSR1, write)?;
+ wakeup();
+ let mut buff = [0; 1];
+ // The attempt to detect if it is socket can generate an empty message. Therefore, do a few
+ // retries.
+ for _ in 0..3 {
+ let len = read.recv(&mut buff)?;
+ if len == 1 && &buff == b"X" {
+ return Ok(());
+ }
+ }
+ panic!("Haven't received the right data");
+ }
+
+ #[test]
+ fn register_with_pipe() -> Result<(), Error> {
+ let mut fds = [0; 2];
+ unsafe { assert_eq!(0, libc::pipe(fds.as_mut_ptr())) };
+ register_raw(libc::SIGUSR1, fds[1])?;
+ wakeup();
+ let mut buff = [0; 1];
+ unsafe { assert_eq!(1, libc::read(fds[0], buff.as_mut_ptr() as *mut _, 1)) }
+ assert_eq!(b"X", &buff);
+ Ok(())
+ }
+}
diff --git a/vendor/signal-hook/src/low_level/siginfo.rs b/vendor/signal-hook/src/low_level/siginfo.rs
new file mode 100644
index 000000000..9114d7f79
--- /dev/null
+++ b/vendor/signal-hook/src/low_level/siginfo.rs
@@ -0,0 +1,261 @@
+//! Extracting more information from the C [`siginfo_t`] structure.
+//!
+//! See [`Origin`].
+
+use std::fmt::{Debug, Formatter, Result as FmtResult};
+
+use libc::{c_int, pid_t, siginfo_t, uid_t};
+
+use crate::low_level;
+
+// Careful: make sure the signature and the constants match the C source
+extern "C" {
+ fn sighook_signal_cause(info: &siginfo_t) -> ICause;
+ fn sighook_signal_pid(info: &siginfo_t) -> pid_t;
+ fn sighook_signal_uid(info: &siginfo_t) -> uid_t;
+}
+
+// Warning: must be in sync with the C code
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[non_exhaustive]
+#[repr(u8)]
+// For some reason, the fact it comes from the C makes rustc emit warning that *some* of these are
+// not constructed. No idea why only some of them.
+#[allow(dead_code)]
+enum ICause {
+ Unknown = 0,
+ Kernel = 1,
+ User = 2,
+ TKill = 3,
+ Queue = 4,
+ MesgQ = 5,
+ Exited = 6,
+ Killed = 7,
+ Dumped = 8,
+ Trapped = 9,
+ Stopped = 10,
+ Continued = 11,
+}
+
+impl ICause {
+ // The MacOs doesn't use the SI_* constants and leaves si_code at 0. But it doesn't use an
+ // union, it has a good-behaved struct with fields and therefore we *can* read the values,
+ // even though they'd contain nonsense (zeroes). We wipe that out later.
+ #[cfg(target_os = "macos")]
+ fn has_process(self) -> bool {
+ true
+ }
+
+ #[cfg(not(target_os = "macos"))]
+ fn has_process(self) -> bool {
+ use ICause::*;
+ match self {
+ Unknown | Kernel => false,
+ User | TKill | Queue | MesgQ | Exited | Killed | Dumped | Trapped | Stopped
+ | Continued => true,
+ }
+ }
+}
+
+/// Information about process, as presented in the signal metadata.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[non_exhaustive]
+pub struct Process {
+ /// The process ID.
+ pub pid: pid_t,
+
+ /// The user owning the process.
+ pub uid: uid_t,
+}
+
+impl Process {
+ /**
+ * Extract the process information.
+ *
+ * # Safety
+ *
+ * The `info` must have a `si_code` corresponding to some situation that has the `si_pid`
+ * and `si_uid` filled in.
+ */
+ unsafe fn extract(info: &siginfo_t) -> Self {
+ Self {
+ pid: sighook_signal_pid(info),
+ uid: sighook_signal_uid(info),
+ }
+ }
+}
+
+/// The means by which a signal was sent by other process.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[non_exhaustive]
+pub enum Sent {
+ /// The `kill` call.
+ User,
+
+ /// The `tkill` call.
+ ///
+ /// This is likely linux specific.
+ TKill,
+
+ /// `sigqueue`.
+ Queue,
+
+ /// `mq_notify`.
+ MesgQ,
+}
+
+/// A child changed its state.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[non_exhaustive]
+pub enum Chld {
+ /// The child exited normally.
+ Exited,
+
+ /// It got killed by a signal.
+ Killed,
+
+ /// It got killed by a signal and dumped core.
+ Dumped,
+
+ /// The child was trapped by a `SIGTRAP` signal.
+ Trapped,
+
+ /// The child got stopped.
+ Stopped,
+
+ /// The child continued (after being stopped).
+ Continued,
+}
+
+/// What caused a signal.
+///
+/// This is a best-effort (and possibly incomplete) representation of the C `siginfo_t::si_code`.
+/// It may differ between OSes and may be extended in future versions.
+///
+/// Note that this doesn't contain all the „fault“ signals (`SIGILL`, `SIGSEGV` and similar).
+/// There's no reasonable way to use the exfiltrators with them, since the handler either needs to
+/// terminate the process or somehow recover from the situation. Things based on exfiltrators do
+/// neither, which would cause an UB and therefore these values just don't make sense.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[non_exhaustive]
+pub enum Cause {
+ /// The cause is unknown.
+ ///
+ /// Some systems don't fill this in. Some systems have values we don't understand. Some signals
+ /// don't have specific reasons to come to being.
+ Unknown,
+
+ /// Sent by the kernel.
+ ///
+ /// This probably exists only on Linux.
+ Kernel,
+
+ /// The signal was sent by other process.
+ Sent(Sent),
+
+ /// A `SIGCHLD`, caused by a child process changing state.
+ Chld(Chld),
+}
+
+impl From<ICause> for Cause {
+ fn from(c: ICause) -> Cause {
+ match c {
+ ICause::Kernel => Cause::Kernel,
+ ICause::User => Cause::Sent(Sent::User),
+ ICause::TKill => Cause::Sent(Sent::TKill),
+ ICause::Queue => Cause::Sent(Sent::Queue),
+ ICause::MesgQ => Cause::Sent(Sent::MesgQ),
+ ICause::Exited => Cause::Chld(Chld::Exited),
+ ICause::Killed => Cause::Chld(Chld::Killed),
+ ICause::Dumped => Cause::Chld(Chld::Dumped),
+ ICause::Trapped => Cause::Chld(Chld::Trapped),
+ ICause::Stopped => Cause::Chld(Chld::Stopped),
+ ICause::Continued => Cause::Chld(Chld::Continued),
+ // Unknown and possibly others if the underlying lib is updated
+ _ => Cause::Unknown,
+ }
+ }
+}
+
+/// Information about a signal and its origin.
+///
+/// This is produced by the [`WithOrigin`] exfiltrator (or can be [extracted][Origin::extract] from
+/// `siginfo_t` by hand).
+#[derive(Clone, Eq, PartialEq)]
+#[non_exhaustive]
+pub struct Origin {
+ /// The signal that happened.
+ pub signal: c_int,
+
+ /// Information about the process that caused the signal.
+ ///
+ /// Note that not all signals are caused by a specific process or have the information
+ /// available („fault“ signals like `SIGBUS` don't have, any signal may be sent by the kernel
+ /// instead of a specific process).
+ ///
+ /// This is filled in whenever available. For most signals, this is the process that sent the
+ /// signal (by `kill` or similar), for `SIGCHLD` it is the child that caused the signal.
+ pub process: Option<Process>,
+
+ /// How the signal happened.
+ ///
+ /// This is a best-effort value. In particular, some systems may have causes not known to this
+ /// library. Some other systems (MacOS) does not fill the value in so there's no way to know.
+ /// In all these cases, this will contain [`Cause::Unknown`].
+ ///
+ /// Some values are platform specific and not available on other systems.
+ ///
+ /// Future versions may enrich the enum by further values.
+ pub cause: Cause,
+}
+
+impl Debug for Origin {
+ fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
+ fn named_signal(sig: c_int) -> String {
+ low_level::signal_name(sig)
+ .map(|n| format!("{} ({})", n, sig))
+ .unwrap_or_else(|| sig.to_string())
+ }
+ fmt.debug_struct("Origin")
+ .field("signal", &named_signal(self.signal))
+ .field("process", &self.process)
+ .field("cause", &self.cause)
+ .finish()
+ }
+}
+
+impl Origin {
+ /// Extracts the Origin from a raw `siginfo_t` structure.
+ ///
+ /// This function is async-signal-safe, can be called inside a signal handler.
+ ///
+ /// # Safety
+ ///
+ /// On systems where the structure is backed by an union on the C side, this requires the
+ /// `si_code` and `si_signo` fields must be set properly according to what fields are
+ /// available.
+ ///
+ /// The value passed by kernel satisfies this, care must be taken only when constructed
+ /// manually.
+ pub unsafe fn extract(info: &siginfo_t) -> Self {
+ let cause = sighook_signal_cause(info);
+ let process = if cause.has_process() {
+ let process = Process::extract(info);
+ // On macos we don't have the si_code to go by, but we can go by the values being
+ // empty there.
+ if cfg!(target_os = "macos") && process.pid == 0 && process.uid == 0 {
+ None
+ } else {
+ Some(process)
+ }
+ } else {
+ None
+ };
+ let signal = info.si_signo;
+ Origin {
+ cause: cause.into(),
+ signal,
+ process,
+ }
+ }
+}
diff --git a/vendor/signal-hook/src/low_level/signal_details.rs b/vendor/signal-hook/src/low_level/signal_details.rs
new file mode 100644
index 000000000..303f4e422
--- /dev/null
+++ b/vendor/signal-hook/src/low_level/signal_details.rs
@@ -0,0 +1,255 @@
+//! Providing auxiliary information for signals.
+
+use std::io::Error;
+use std::mem;
+use std::ptr;
+
+use libc::{c_int, EINVAL};
+#[cfg(not(windows))]
+use libc::{sigset_t, SIG_UNBLOCK};
+
+use crate::consts::signal::*;
+use crate::low_level;
+
+#[derive(Clone, Copy, Debug)]
+enum DefaultKind {
+ Ignore,
+ #[cfg(not(windows))]
+ Stop,
+ Term,
+}
+
+struct Details {
+ signal: c_int,
+ name: &'static str,
+ default_kind: DefaultKind,
+}
+
+macro_rules! s {
+ ($name: expr, $kind: ident) => {
+ Details {
+ signal: $name,
+ name: stringify!($name),
+ default_kind: DefaultKind::$kind,
+ }
+ };
+}
+
+#[cfg(not(windows))]
+const DETAILS: &[Details] = &[
+ s!(SIGABRT, Term),
+ s!(SIGALRM, Term),
+ s!(SIGBUS, Term),
+ s!(SIGCHLD, Ignore),
+ // Technically, continue the process... but this is not done *by* the process.
+ s!(SIGCONT, Ignore),
+ s!(SIGFPE, Term),
+ s!(SIGHUP, Term),
+ s!(SIGILL, Term),
+ s!(SIGINT, Term),
+ #[cfg(any(
+ target_os = "freebsd",
+ target_os = "dragonfly",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "macos"
+ ))]
+ s!(SIGINFO, Ignore),
+ #[cfg(not(target_os = "haiku"))]
+ s!(SIGIO, Ignore),
+ // Can't override anyway, but...
+ s!(SIGKILL, Term),
+ s!(SIGPIPE, Term),
+ s!(SIGPROF, Term),
+ s!(SIGQUIT, Term),
+ s!(SIGSEGV, Term),
+ // Can't override anyway, but...
+ s!(SIGSTOP, Stop),
+ s!(SIGSYS, Term),
+ s!(SIGTERM, Term),
+ s!(SIGTRAP, Term),
+ s!(SIGTSTP, Stop),
+ s!(SIGTTIN, Stop),
+ s!(SIGTTOU, Stop),
+ s!(SIGURG, Ignore),
+ s!(SIGUSR1, Term),
+ s!(SIGUSR2, Term),
+ s!(SIGVTALRM, Term),
+ s!(SIGWINCH, Ignore),
+ s!(SIGXCPU, Term),
+ s!(SIGXFSZ, Term),
+];
+
+#[cfg(windows)]
+const DETAILS: &[Details] = &[
+ s!(SIGABRT, Term),
+ s!(SIGFPE, Term),
+ s!(SIGILL, Term),
+ s!(SIGINT, Term),
+ s!(SIGSEGV, Term),
+ s!(SIGTERM, Term),
+];
+
+/// Provides a human-readable name of a signal.
+///
+/// Note that the name does not have to be known (in case it is some less common, or non-standard
+/// signal).
+///
+/// # Examples
+///
+/// ```
+/// # use signal_hook::low_level::signal_name;
+/// assert_eq!("SIGKILL", signal_name(9).unwrap());
+/// assert!(signal_name(142).is_none());
+/// ```
+pub fn signal_name(signal: c_int) -> Option<&'static str> {
+ DETAILS.iter().find(|d| d.signal == signal).map(|d| d.name)
+}
+
+#[cfg(not(windows))]
+fn restore_default(signal: c_int) -> Result<(), Error> {
+ unsafe {
+ // A C structure, supposed to be memset to 0 before use.
+ let mut action: libc::sigaction = mem::zeroed();
+ #[cfg(target_os = "aix")]
+ {
+ action.sa_union.__su_sigaction = mem::transmute::<
+ usize,
+ extern "C" fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void),
+ >(libc::SIG_DFL);
+ }
+ #[cfg(not(target_os = "aix"))]
+ { action.sa_sigaction = libc::SIG_DFL as _; }
+ if libc::sigaction(signal, &action, ptr::null_mut()) == 0 {
+ Ok(())
+ } else {
+ Err(Error::last_os_error())
+ }
+ }
+}
+
+#[cfg(windows)]
+fn restore_default(signal: c_int) -> Result<(), Error> {
+ unsafe {
+ // SIG_DFL = 0, but not in libc :-(
+ if libc::signal(signal, 0) == 0 {
+ Ok(())
+ } else {
+ Err(Error::last_os_error())
+ }
+ }
+}
+
+/// Emulates the behaviour of a default handler for the provided signal.
+///
+/// This function does its best to provide the same action as the default handler would do, without
+/// disrupting the rest of the handling of such signal in the application. It is also
+/// async-signal-safe.
+///
+/// This function necessarily looks up the appropriate action in a table. That means it is possible
+/// your system has a signal that is not known to this function. In such case an error is returned
+/// (equivalent of `EINVAL`).
+///
+/// See also the [`register_conditional_default`][crate::flag::register_conditional_default].
+///
+/// # Warning
+///
+/// There's a short race condition in case of signals that terminate (either with or without a core
+/// dump). The emulation first resets the signal handler back to default (as the application is
+/// going to end, it's not a problem) and invokes it. But if some other thread installs a signal
+/// handler in the meantime (without assistance from `signal-hook`), it can happen this will be
+/// invoked by the re-raised signal.
+///
+/// This function will still terminate the application (there's a fallback on `abort`), the risk is
+/// invoking the newly installed signal handler. Note that manipulating the low-level signals is
+/// always racy in a multi-threaded program, therefore the described situation is already
+/// discouraged.
+///
+/// If you are uneasy about such race condition, the recommendation is to run relevant termination
+/// routine manually ([`exit`][super::exit] or [`abort`][super::abort]); they always do what they
+/// say, but slightly differ in externally observable behaviour from termination by a signal (the
+/// exit code will specify that the application exited, not that it terminated with a signal in the
+/// first case, and `abort` terminates on `SIGABRT`, so the detected termination signal may be
+/// different).
+pub fn emulate_default_handler(signal: c_int) -> Result<(), Error> {
+ #[cfg(not(windows))]
+ {
+ if signal == SIGSTOP || signal == SIGKILL {
+ return low_level::raise(signal);
+ }
+ }
+ let kind = DETAILS
+ .iter()
+ .find(|d| d.signal == signal)
+ .map(|d| d.default_kind)
+ .ok_or_else(|| Error::from_raw_os_error(EINVAL))?;
+ match kind {
+ DefaultKind::Ignore => Ok(()),
+ #[cfg(not(windows))]
+ DefaultKind::Stop => low_level::raise(SIGSTOP),
+ DefaultKind::Term => {
+ if let Ok(()) = restore_default(signal) {
+ #[cfg(not(windows))]
+ unsafe {
+ #[allow(deprecated)]
+ let mut newsigs: sigset_t = mem::zeroed();
+
+ // Some android versions don't have the sigemptyset and sigaddset.
+ // Unfortunately, we don't have an access to the android _version_. We just
+ // know that 64bit versions are all OK, so this is a best-effort guess.
+ //
+ // For the affected/guessed versions, we provide our own implementation. We
+ // hope it to be correct (it's inspired by a libc implementation and we assume
+ // the kernel uses the same format ‒ it's unlikely to be different both because
+ // of compatibility and because there's really nothing to invent about a
+ // bitarray).
+ //
+ // We use the proper way for other systems.
+ #[cfg(all(target_os = "android", target_pointer_width = "32"))]
+ unsafe fn prepare_sigset(set: *mut sigset_t, mut signal: c_int) {
+ signal -= 1;
+ let set_raw: *mut libc::c_ulong = set.cast();
+ let size = mem::size_of::<libc::c_ulong>();
+ assert_eq!(set_raw as usize % mem::align_of::<libc::c_ulong>(), 0);
+ let pos = signal as usize / size;
+ assert!(pos < mem::size_of::<sigset_t>() / size);
+ let bit = 1 << (signal as usize % size);
+ set_raw.add(pos).write(bit);
+ }
+
+ #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
+ unsafe fn prepare_sigset(set: *mut sigset_t, signal: c_int) {
+ libc::sigemptyset(set);
+ libc::sigaddset(set, signal);
+ }
+
+ prepare_sigset(&mut newsigs, signal);
+ // Ignore the result, if it doesn't work, we try anyway
+ // Also, sigprocmask is unspecified, but available on more systems. And we want
+ // to just enable _something_. And if it doesn't work, we'll terminate
+ // anyway... It's not UB, so we are good.
+ libc::sigprocmask(SIG_UNBLOCK, &newsigs, ptr::null_mut());
+ }
+ let _ = low_level::raise(signal);
+ }
+ // Fallback if anything failed or someone managed to put some other action in in
+ // between.
+ unsafe { libc::abort() }
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn existing() {
+ assert_eq!("SIGTERM", signal_name(SIGTERM).unwrap());
+ }
+
+ #[test]
+ fn unknown() {
+ assert!(signal_name(128).is_none());
+ }
+}
diff --git a/vendor/signal-hook/tests/default.rs b/vendor/signal-hook/tests/default.rs
new file mode 100644
index 000000000..bccf55891
--- /dev/null
+++ b/vendor/signal-hook/tests/default.rs
@@ -0,0 +1,25 @@
+//! Check the hack of SIG_DFL for windows.
+//!
+//! Libc doesn't export SIG_DFL on windows. It seems to be 0 on all platforms, though, but just to
+//! make sure, we observe it is so. We try to read the previous signal on startup and it must be
+//! the default.
+
+extern crate libc;
+
+use libc::{sighandler_t, signal, SIGTERM};
+
+const SIG_DFL: sighandler_t = 0;
+
+#[test]
+fn sig_dfl() {
+ unsafe {
+ let prev = signal(SIGTERM, SIG_DFL);
+ assert_eq!(SIG_DFL, prev);
+ }
+}
+
+#[cfg(not(windows))]
+#[test]
+fn sig_dfl_static() {
+ assert_eq!(::libc::SIG_DFL, SIG_DFL);
+}
diff --git a/vendor/signal-hook/tests/iterator.rs b/vendor/signal-hook/tests/iterator.rs
new file mode 100644
index 000000000..90e0598fe
--- /dev/null
+++ b/vendor/signal-hook/tests/iterator.rs
@@ -0,0 +1,260 @@
+#![cfg(not(windows))]
+
+extern crate signal_hook;
+
+use std::collections::HashSet;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::mpsc::{self, RecvTimeoutError};
+use std::sync::Arc;
+use std::thread::{self, JoinHandle};
+use std::time::Duration;
+
+use signal_hook::consts::{SIGUSR1, SIGUSR2};
+use signal_hook::iterator::{Handle, Signals};
+use signal_hook::low_level::raise;
+
+use serial_test::serial;
+
+fn send_sigusr1() {
+ raise(SIGUSR1).unwrap();
+}
+
+fn send_sigusr2() {
+ raise(SIGUSR2).unwrap();
+}
+
+fn setup_without_any_signals() -> (Signals, Handle) {
+ let signals = Signals::new(&[]).unwrap();
+ let controller = signals.handle();
+ (signals, controller)
+}
+
+fn setup_for_sigusr2() -> (Signals, Handle) {
+ let signals = Signals::new(&[SIGUSR2]).unwrap();
+ let controller = signals.handle();
+ (signals, controller)
+}
+
+macro_rules! assert_signals {
+ ($actual:expr, $($expected:expr),+ $(,)?) => {
+ let actual = $actual.collect::<HashSet<libc::c_int>>();
+ let expected = vec!($($expected),+).into_iter().collect::<HashSet<libc::c_int>>();
+ assert_eq!(actual, expected);
+ };
+}
+
+macro_rules! assert_no_signals {
+ ($signals:expr) => {
+ assert_eq!($signals.next(), None);
+ };
+}
+
+#[test]
+#[serial]
+fn forever_terminates_when_closed() {
+ let (mut signals, controller) = setup_for_sigusr2();
+
+ // Detect early terminations.
+ let stopped = Arc::new(AtomicBool::new(false));
+
+ let stopped_bg = Arc::clone(&stopped);
+ let thread = thread::spawn(move || {
+ // Eat all the signals there are (might come from a concurrent test, in theory).
+ // Would wait forever, but it should be terminated by the close below.
+ for _sig in &mut signals {}
+
+ stopped_bg.store(true, Ordering::SeqCst);
+ });
+
+ // Wait a bit to see if the thread terminates by itself.
+ thread::sleep(Duration::from_millis(100));
+ assert!(!stopped.load(Ordering::SeqCst));
+
+ controller.close();
+
+ thread.join().unwrap();
+}
+
+// A reproducer for #16: if we had the mio-support enabled (which is enabled also by the
+// tokio-support feature), blocking no longer works. The .wait() would return immediately (an empty
+// iterator, possibly), .forever() would do a busy loop.
+// flag)
+#[test]
+#[serial]
+fn signals_block_wait() {
+ let mut signals = Signals::new(&[SIGUSR2]).unwrap();
+ let (s, r) = mpsc::channel();
+ let finish = Arc::new(AtomicBool::new(false));
+ let thread_id = thread::spawn({
+ let finish = Arc::clone(&finish);
+ move || {
+ // Technically, it may spuriously return early. But it shouldn't be doing it too much,
+ // so we just try to wait multiple times ‒ if they *all* return right away, it is
+ // broken.
+ for _ in 0..10 {
+ for _ in signals.wait() {
+ if finish.load(Ordering::SeqCst) {
+ // Asked to terminate at the end of the thread. Do so (but without
+ // signalling the receipt).
+ return;
+ } else {
+ panic!("Someone really did send us SIGUSR2, which breaks the test");
+ }
+ }
+ }
+ let _ = s.send(());
+ }
+ });
+
+ // A RAII guard to make sure we shut down the thread even if the test fails.
+ struct ThreadGuard {
+ thread: Option<JoinHandle<()>>,
+ finish: Arc<AtomicBool>,
+ }
+
+ impl ThreadGuard {
+ fn shutdown(&mut self) {
+ // Tell it to shut down
+ self.finish.store(true, Ordering::SeqCst);
+ // Wake it up
+ send_sigusr2();
+ // Wait for it to actually terminate.
+ if let Some(thread) = self.thread.take() {
+ thread.join().unwrap(); // Propagate panics
+ }
+ }
+ }
+
+ impl Drop for ThreadGuard {
+ fn drop(&mut self) {
+ self.shutdown(); // OK if done twice, won't have the thread any more.
+ }
+ }
+
+ let mut bg_thread = ThreadGuard {
+ thread: Some(thread_id),
+ finish,
+ };
+
+ let err = r
+ .recv_timeout(Duration::from_millis(100))
+ .expect_err("Wait didn't wait properly");
+ assert_eq!(err, RecvTimeoutError::Timeout);
+
+ bg_thread.shutdown();
+}
+
+#[test]
+#[serial]
+fn pending_doesnt_block() {
+ let (mut signals, _) = setup_for_sigusr2();
+
+ let mut recieved_signals = signals.pending();
+
+ assert_no_signals!(recieved_signals);
+}
+
+#[test]
+#[serial]
+fn wait_returns_recieved_signals() {
+ let (mut signals, _) = setup_for_sigusr2();
+ send_sigusr2();
+
+ let recieved_signals = signals.wait();
+
+ assert_signals!(recieved_signals, SIGUSR2);
+}
+
+#[test]
+#[serial]
+fn forever_returns_recieved_signals() {
+ let (mut signals, _) = setup_for_sigusr2();
+ send_sigusr2();
+
+ let signal = signals.forever().take(1);
+
+ assert_signals!(signal, SIGUSR2);
+}
+
+#[test]
+#[serial]
+fn wait_doesnt_block_when_closed() {
+ let (mut signals, controller) = setup_for_sigusr2();
+ controller.close();
+
+ let mut recieved_signals = signals.wait();
+
+ assert_no_signals!(recieved_signals);
+}
+
+#[test]
+#[serial]
+fn wait_unblocks_when_closed() {
+ let (mut signals, controller) = setup_without_any_signals();
+
+ let thread = thread::spawn(move || {
+ signals.wait();
+ });
+
+ controller.close();
+
+ thread.join().unwrap();
+}
+
+#[test]
+#[serial]
+fn forever_doesnt_block_when_closed() {
+ let (mut signals, controller) = setup_for_sigusr2();
+ controller.close();
+
+ let mut signal = signals.forever();
+
+ assert_no_signals!(signal);
+}
+
+#[test]
+#[serial]
+fn add_signal_after_creation() {
+ let (mut signals, _) = setup_without_any_signals();
+ signals.add_signal(SIGUSR1).unwrap();
+
+ send_sigusr1();
+
+ assert_signals!(signals.pending(), SIGUSR1);
+}
+
+#[test]
+#[serial]
+fn delayed_signal_consumed() {
+ let (mut signals, _) = setup_for_sigusr2();
+ signals.add_signal(SIGUSR1).unwrap();
+
+ send_sigusr1();
+ let mut recieved_signals = signals.wait();
+ send_sigusr2();
+
+ assert_signals!(recieved_signals, SIGUSR1, SIGUSR2);
+
+ // The pipe still contains the byte from the second
+ // signal and so wait won't block but won't return
+ // a signal.
+ recieved_signals = signals.wait();
+ assert_no_signals!(recieved_signals);
+}
+
+#[test]
+#[serial]
+fn is_closed_initially_returns_false() {
+ let (_, controller) = setup_for_sigusr2();
+
+ assert!(!controller.is_closed());
+}
+
+#[test]
+#[serial]
+fn is_closed_returns_true_when_closed() {
+ let (_, controller) = setup_for_sigusr2();
+ controller.close();
+
+ assert!(controller.is_closed());
+}
diff --git a/vendor/signal-hook/tests/shutdown.rs b/vendor/signal-hook/tests/shutdown.rs
new file mode 100644
index 000000000..381fab729
--- /dev/null
+++ b/vendor/signal-hook/tests/shutdown.rs
@@ -0,0 +1,81 @@
+//! Tests for the shutdown.
+//!
+//! The tests work like this:
+//!
+//! * The register an alarm, to fail if anything takes too long (which is very much possible here).
+//! * A fork is done, with the child registering a signal with a NOP and cleanup operation (one or
+//! the other).
+//! * The child puts some kind of infinite loop or sleep inside itself, so it never actually
+//! terminates on the first, but would terminate after the signal.
+
+#![cfg(not(windows))] // Forks don't work on Windows, but windows has the same implementation.
+
+use std::io::Error;
+use std::ptr;
+use std::sync::atomic::AtomicBool;
+use std::sync::Arc;
+use std::thread;
+use std::time::Duration;
+
+use signal_hook::consts::signal::*;
+use signal_hook::flag;
+use signal_hook::low_level;
+
+fn do_test<C: FnOnce()>(child: C) {
+ unsafe {
+ libc::alarm(10); // Time out the test after 10 seconds and get it killed.
+ match libc::fork() {
+ -1 => panic!("Fork failed: {}", Error::last_os_error()),
+ 0 => {
+ child();
+ loop {
+ thread::sleep(Duration::from_secs(1));
+ }
+ }
+ pid => {
+ // Give the child some time to register signals and stuff
+ // We could actually signal that the child is ready by it eg. closing STDOUT, but
+ // this is just a test so we don't really bother.
+ thread::sleep(Duration::from_millis(250));
+ libc::kill(pid, libc::SIGTERM);
+ // Wait a small bit to make sure the signal got delivered.
+ thread::sleep(Duration::from_millis(50));
+ // The child is still running, because the first signal got "handled" by being
+ // ignored.
+ let terminated = libc::waitpid(pid, ptr::null_mut(), libc::WNOHANG);
+ assert_eq!(0, terminated, "Process {} terminated prematurely", pid);
+ // But it terminates on the second attempt (we do block on wait here).
+ libc::kill(pid, libc::SIGTERM);
+ let terminated = libc::waitpid(pid, ptr::null_mut(), 0);
+ assert_eq!(pid, terminated);
+ }
+ }
+ }
+}
+
+/// Use automatic cleanup inside the signal handler to get rid of old signals, the aggressive way.
+#[test]
+fn cleanup_inside_signal() {
+ fn hook() {
+ // Make sure we have some signal handler, not the default.
+ unsafe { low_level::register(SIGTERM, || ()).unwrap() };
+ let shutdown_cond = Arc::new(AtomicBool::new(false));
+ // „disarmed“ shutdown
+ flag::register_conditional_shutdown(SIGTERM, 0, Arc::clone(&shutdown_cond)).unwrap();
+ // But arm at the first SIGTERM
+ flag::register(SIGTERM, shutdown_cond).unwrap();
+ }
+ do_test(hook);
+}
+
+/// Manually remove the signal handler just after receiving the signal but before going into an
+/// infinite loop.
+#[test]
+fn cleanup_after_signal() {
+ fn hook() {
+ let mut signals = signal_hook::iterator::Signals::new(&[libc::SIGTERM]).unwrap();
+ assert_eq!(Some(SIGTERM), signals.into_iter().next());
+ flag::register_conditional_shutdown(SIGTERM, 0, Arc::new(AtomicBool::new(true))).unwrap();
+ }
+ do_test(hook);
+}