summaryrefslogtreecommitdiffstats
path: root/vendor/nix
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/nix')
-rw-r--r--vendor/nix/.cargo-checksum.json1
-rw-r--r--vendor/nix/CHANGELOG.md1585
-rw-r--r--vendor/nix/Cargo.toml185
-rw-r--r--vendor/nix/LICENSE21
-rw-r--r--vendor/nix/README.md105
-rw-r--r--vendor/nix/src/dir.rs276
-rw-r--r--vendor/nix/src/env.rs64
-rw-r--r--vendor/nix/src/errno.rs3133
-rw-r--r--vendor/nix/src/fcntl.rs882
-rw-r--r--vendor/nix/src/features.rs126
-rw-r--r--vendor/nix/src/ifaddrs.rs213
-rw-r--r--vendor/nix/src/kmod.rs128
-rw-r--r--vendor/nix/src/lib.rs333
-rw-r--r--vendor/nix/src/macros.rs328
-rw-r--r--vendor/nix/src/mount/bsd.rs453
-rw-r--r--vendor/nix/src/mount/linux.rs115
-rw-r--r--vendor/nix/src/mount/mod.rs26
-rw-r--r--vendor/nix/src/mqueue.rs276
-rw-r--r--vendor/nix/src/net/if_.rs469
-rw-r--r--vendor/nix/src/net/mod.rs4
-rw-r--r--vendor/nix/src/poll.rs197
-rw-r--r--vendor/nix/src/pty.rs371
-rw-r--r--vendor/nix/src/sched.rs324
-rw-r--r--vendor/nix/src/sys/aio.rs1241
-rw-r--r--vendor/nix/src/sys/epoll.rs128
-rw-r--r--vendor/nix/src/sys/event.rs374
-rw-r--r--vendor/nix/src/sys/eventfd.rs17
-rw-r--r--vendor/nix/src/sys/inotify.rs248
-rw-r--r--vendor/nix/src/sys/ioctl/bsd.rs129
-rw-r--r--vendor/nix/src/sys/ioctl/linux.rs172
-rw-r--r--vendor/nix/src/sys/ioctl/mod.rs786
-rw-r--r--vendor/nix/src/sys/memfd.rs64
-rw-r--r--vendor/nix/src/sys/mman.rs599
-rw-r--r--vendor/nix/src/sys/mod.rs228
-rw-r--r--vendor/nix/src/sys/personality.rs93
-rw-r--r--vendor/nix/src/sys/pthread.rs43
-rw-r--r--vendor/nix/src/sys/ptrace/bsd.rs195
-rw-r--r--vendor/nix/src/sys/ptrace/linux.rs558
-rw-r--r--vendor/nix/src/sys/ptrace/mod.rs25
-rw-r--r--vendor/nix/src/sys/quota.rs338
-rw-r--r--vendor/nix/src/sys/reboot.rs48
-rw-r--r--vendor/nix/src/sys/resource.rs443
-rw-r--r--vendor/nix/src/sys/select.rs455
-rw-r--r--vendor/nix/src/sys/sendfile.rs277
-rw-r--r--vendor/nix/src/sys/signal.rs1348
-rw-r--r--vendor/nix/src/sys/signalfd.rs175
-rw-r--r--vendor/nix/src/sys/socket/addr.rs3247
-rw-r--r--vendor/nix/src/sys/socket/mod.rs2487
-rw-r--r--vendor/nix/src/sys/socket/sockopt.rs1422
-rw-r--r--vendor/nix/src/sys/stat.rs480
-rw-r--r--vendor/nix/src/sys/statfs.rs853
-rw-r--r--vendor/nix/src/sys/statvfs.rs173
-rw-r--r--vendor/nix/src/sys/sysinfo.rs83
-rw-r--r--vendor/nix/src/sys/termios.rs1227
-rw-r--r--vendor/nix/src/sys/time.rs811
-rw-r--r--vendor/nix/src/sys/timer.rs187
-rw-r--r--vendor/nix/src/sys/timerfd.rs214
-rw-r--r--vendor/nix/src/sys/uio.rs291
-rw-r--r--vendor/nix/src/sys/utsname.rs85
-rw-r--r--vendor/nix/src/sys/wait.rs388
-rw-r--r--vendor/nix/src/time.rs283
-rw-r--r--vendor/nix/src/ucontext.rs47
-rw-r--r--vendor/nix/src/unistd.rs3383
-rw-r--r--vendor/nix/test/common/mod.rs149
-rw-r--r--vendor/nix/test/sys/mod.rs60
-rw-r--r--vendor/nix/test/sys/test_aio.rs626
-rw-r--r--vendor/nix/test/sys/test_aio_drop.rs35
-rw-r--r--vendor/nix/test/sys/test_epoll.rs24
-rw-r--r--vendor/nix/test/sys/test_inotify.rs65
-rw-r--r--vendor/nix/test/sys/test_ioctl.rs376
-rw-r--r--vendor/nix/test/sys/test_mman.rs122
-rw-r--r--vendor/nix/test/sys/test_pthread.rs22
-rw-r--r--vendor/nix/test/sys/test_ptrace.rs275
-rw-r--r--vendor/nix/test/sys/test_select.rs81
-rw-r--r--vendor/nix/test/sys/test_signal.rs147
-rw-r--r--vendor/nix/test/sys/test_signalfd.rs27
-rw-r--r--vendor/nix/test/sys/test_socket.rs2628
-rw-r--r--vendor/nix/test/sys/test_sockopt.rs431
-rw-r--r--vendor/nix/test/sys/test_stat.rs29
-rw-r--r--vendor/nix/test/sys/test_sysinfo.rs20
-rw-r--r--vendor/nix/test/sys/test_termios.rs136
-rw-r--r--vendor/nix/test/sys/test_timerfd.rs69
-rw-r--r--vendor/nix/test/sys/test_uio.rs270
-rw-r--r--vendor/nix/test/sys/test_wait.rs257
-rw-r--r--vendor/nix/test/test.rs124
-rw-r--r--vendor/nix/test/test_clearenv.rs9
-rw-r--r--vendor/nix/test/test_dir.rs65
-rw-r--r--vendor/nix/test/test_fcntl.rs565
-rw-r--r--vendor/nix/test/test_kmod/hello_mod/Makefile7
-rw-r--r--vendor/nix/test/test_kmod/mod.rs188
-rw-r--r--vendor/nix/test/test_mount.rs271
-rw-r--r--vendor/nix/test/test_mq.rs190
-rw-r--r--vendor/nix/test/test_net.rs19
-rw-r--r--vendor/nix/test/test_nix_path.rs1
-rw-r--r--vendor/nix/test/test_nmount.rs49
-rw-r--r--vendor/nix/test/test_poll.rs84
-rw-r--r--vendor/nix/test/test_pty.rs313
-rw-r--r--vendor/nix/test/test_ptymaster_drop.rs20
-rw-r--r--vendor/nix/test/test_resource.rs34
-rw-r--r--vendor/nix/test/test_sched.rs39
-rw-r--r--vendor/nix/test/test_sendfile.rs208
-rw-r--r--vendor/nix/test/test_stat.rs421
-rw-r--r--vendor/nix/test/test_time.rs59
-rw-r--r--vendor/nix/test/test_timer.rs102
-rw-r--r--vendor/nix/test/test_unistd.rs1407
105 files changed, 0 insertions, 43284 deletions
diff --git a/vendor/nix/.cargo-checksum.json b/vendor/nix/.cargo-checksum.json
deleted file mode 100644
index f4c932b88..000000000
--- a/vendor/nix/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"8ee4e556e53d1b39400a48675d3ecff0bf27e419accab7ca3be76ab934289548","Cargo.toml":"2e6eff9170182f107188b8bc9802efd044ef47178afc7f138950ecff1c1ceb96","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"1ed9a0e26ae6e575b3262ae734dd02889455593b761ee62403ea5a64104f3c9c","src/dir.rs":"0280a2dc480bd913f24ed84fbe26569fa2e8eefa660e5ad7c21e05fc34c14d16","src/env.rs":"028bc5e20139ebba418a655a2978a53335dc7680bf1de43d2c8333dd72cfa5c4","src/errno.rs":"e55d075858e349d9afea9ce0480f7fb7ba4dccccf0694fd7b3280b918836203c","src/fcntl.rs":"ea8f43d8fec0b6c3b7d903333e4c1ce85611684a4afd561c55cfe4b61a979e94","src/features.rs":"5b4a0831e5f4b79a6f0e42ed052fd66c875da18959750be51e41fb59ac19feed","src/ifaddrs.rs":"377865eb48040d28c392a1aec0221320108e3392ea285d23405ae2cfa5c54b20","src/kmod.rs":"c818ced08d55ae36fdf82fa914ba856b688e37234d574d3faa37128211d512fb","src/lib.rs":"a62fac2ba7111157c5b64251f67f8a189f04bd587d5c80703454a596ea7ae5d9","src/macros.rs":"e23d7d8be22ef0bf9febaaf2739585453103607c0139bd3995a324e4a16d011e","src/mount/bsd.rs":"4cf35606a63d7ca41caac3b38f01e2b70c63e71978c0529f19fc79182629dbe0","src/mount/linux.rs":"6e5d61788dedf1ca4416c6c6a3a9c6c747f9352c26d863f4a1d4142e288584d6","src/mount/mod.rs":"ba9f60eb831224ab73bdd87e00e15d13b9ce9efb70b18bf8f3fe60406d522b3e","src/mqueue.rs":"ed0a189036b2437b5f7f7f1312fa545540b06ca72171b451d8bce42cc3627534","src/net/if_.rs":"b32a8a1f952de60d95e549779a5c673fd72aa665e86bfdfc8ec6badf3016b9b1","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"2fc1d144fb40db51811c6357b520ab7993529702d8f0d8060c903118ff4f7259","src/pty.rs":"27b4f76c23acf02542674017067fee74cdcac907338458700a1aa4d6f6a62e27","src/sched.rs":"403aa5ebed81910263d42a94717612b737550bf053227b7d90f1c8949188d919","src/sys/aio.rs":"ae091de8540c97da374a39e7d154c1b3ce50f41e6fc20a45c6b06eb838e74366","src/sys/epoll.rs":"28e22debf474d1b047e8044a00b354c25dab2fa125960f9f2f14cc34289fd5c9","src/sys/event.rs":"dbd8e84bccb813839295b0a336485783ef19548d2317931f0ceb5ee62f839a40","src/sys/eventfd.rs":"c8db8f5874726fdad289ad5e2603a7d71a1ae5a899dcde3a35d3edff8b498b7e","src/sys/inotify.rs":"5b4da774313afa9c28c3f92f9d07dce9bf4c8d044fd6a16f19480e79a19e808b","src/sys/ioctl/bsd.rs":"bbd02e30b0a78c1cb22777d9b00cfcbba9c68505cffc06118ac68474cf6fea39","src/sys/ioctl/linux.rs":"028181834d119b834bf399f2b8a6176cc57e75144693f28f32059d087d8c8018","src/sys/ioctl/mod.rs":"89b20579476b2e0254e0ecb1b41830cccd7027a22cbdb816a9d4ec3924842ac1","src/sys/memfd.rs":"f58d7fbe67c4b994832d72f5fbd59c136c8f1ae88ea8b0bc1c099db2d847ee6c","src/sys/mman.rs":"17df1bc34ba92bdd6bad1e11e4ef139998117f6c468c8f560421858f3cc899a5","src/sys/mod.rs":"baabf649f758ad4acce849ec1795dd4e4f9c6539e677bad5fa777300a4871dcb","src/sys/personality.rs":"aa89760c023bfec3fca5d8636f9eac9d337f5547933793ce6df7a0de97ae6ee1","src/sys/pthread.rs":"258cdf7ff0b61a4afa6d228109e4cb4fb88d859bb8dfe6c959d95130fb010906","src/sys/ptrace/bsd.rs":"4c590d8f023ff52f396f8b6f2150c08e5c9486d3088d9c173db33a70d616b800","src/sys/ptrace/linux.rs":"c82db3fb18aa97755f9ccb440a957cd46d664968a94045830c5d74d2d53bc19f","src/sys/ptrace/mod.rs":"e9e5d970097f5eafffba900959d4fdbf233bff9ed7f599fc9896bb44d86a57a4","src/sys/quota.rs":"02e698a25f0986fb43aa88689f3d3d8b9edc6ae48496ad02f7214fccaa493e00","src/sys/reboot.rs":"eacdf57694a6629fb05787e16450446102a62818274495f2ad4e445807d09221","src/sys/resource.rs":"d498d0c00fd30e35e1269a8902cb812014d813f63ec95364f8f59f1912ba5657","src/sys/select.rs":"65c39b129d3cc85b8ca026ff26dcf80c5639824f43715881c3c1bbb6bf0c8a60","src/sys/sendfile.rs":"7a62099f9771fecff49b9c11210341e3c1a4acf22f8dfb96d395e29421648676","src/sys/signal.rs":"c3e13a2edea54d190a4b051f62efc97953c00b5051a9fda0e39e3bc732a31939","src/sys/signalfd.rs":"583524434fd37143be3db37fa6f6cbd339f7946416f05b58a95e246947e5cc9d","src/sys/socket/addr.rs":"84df895052f59ec84774b189ffb285d2a37a9703af6c8310ae5040cca1a2583e","src/sys/socket/mod.rs":"6deb55438cad3606385303f036b0efd842dfd759fba93611911f5a4f2613c9dc","src/sys/socket/sockopt.rs":"ed1f920364bfe88bbe6eaeeefb27a63bfcdd7d67604aca2f03e22f2b502df55a","src/sys/stat.rs":"337dea8d55d6177dc85b3235b40b8a3e81af7f4a6e2806a0b2f730bec5424350","src/sys/statfs.rs":"17103659a85279bac046c69cb3b22bf2c11c2492cffb0edfa4c3b233d161a2f2","src/sys/statvfs.rs":"f81e3900ef90d62e7eceaf1b6ff8dcfd965466714c033eb4717687f692171f48","src/sys/sysinfo.rs":"b4519b1ca091c9dbe94d2a6fd6304944bf3df5626973d2c6884022559706f0d9","src/sys/termios.rs":"7923f9846a8122096b6b1cd240d3618b876ce500a751ac434954d172e2e85745","src/sys/time.rs":"9026033b60a5ccc95b70424aef043c8c748722e2ea8c7c86366ecd4585b651a0","src/sys/timer.rs":"8c10f0e7cfac857ad00460be30bc68b957909cc9296e70718d3b5d4a0babafde","src/sys/timerfd.rs":"ef7c48aefdcfac13316eeddbef5da04cf12e9f574b8d9f43402c02b6b8db86b3","src/sys/uio.rs":"e1d59ccbee9d46c65d3aa8c36aa3a3222539beea0d20163a8b707d08fca14e09","src/sys/utsname.rs":"0cdda0cc111caaa0e4ebe2d4588bdc825d878e5bcb7a9136073b15f87a20e11f","src/sys/wait.rs":"cc70d2d9b880ff6c48577a479c209af6127067bc013a90ee22538e4dfad7d2b4","src/time.rs":"d4e0872361a57810837f5bd790cbca3a2b9db1ac4694a3c52d1564ad3532d3be","src/ucontext.rs":"b8f2e04757a9c2bc38c3b1e259d3a013da8a730fe9bfbe5487637395681b43d3","src/unistd.rs":"e19be456124731c5b93aef92ed72a7c4c9092e28db0649814ba3fcc1f0d620fa","test/common/mod.rs":"1d7e28e3635754664cd056f3a1079232ff5c118df619e1d0551a9972eb0b3cd6","test/sys/mod.rs":"87b2891d83067ff21f72b8ff7fde3019dc45b6877282ac278b6da151de45c7a7","test/sys/test_aio.rs":"4dac9f716f852f1f438f78d6e64bf041e6fd316bf15dcb27afffaf0894bdefa6","test/sys/test_aio_drop.rs":"614070155fa16a979b7341d001639c5ce24a1d6f632c3abce45a5a6d49c4039b","test/sys/test_epoll.rs":"ffe95e36c79e37426ef8e8ca3b137b7f35ea0333ce666a20a4b7878db17680e9","test/sys/test_inotify.rs":"a141b9a995892547b51ceeb6761a70a6b86d37e8f38d13ea2c497b81b4b0f49f","test/sys/test_ioctl.rs":"00ccc5afb665e533a0a4b6d6a6be438bcaea19fce335390feef4e91d17b3036c","test/sys/test_mman.rs":"2b4161964c9204b74659028b0f89a88f4e3bcc9886137a3039737cd91d2698cb","test/sys/test_pthread.rs":"ace36a2f5587f1874854281b4fd84e4e4d892a1e3c5cc38ced57975739522ad6","test/sys/test_ptrace.rs":"0385eebc8b1b8c72f655b745769decd9143ad83018198375982da0896310456b","test/sys/test_select.rs":"54cea1c34ad28d5770a613c1c3cbc3b1064b22037ec2b9d3fcd422d3be9e60a7","test/sys/test_signal.rs":"acc9941227bd3e2afad323613c2b8c83902ed0486d3745fd72704f395924f1e4","test/sys/test_signalfd.rs":"0e1060143e2612c490bc3d0168d0bbb042ef55e3f1d91d2578b9e42e4310a14d","test/sys/test_socket.rs":"d2df1001f9a0b2dac0b88051a67c3868bb216e72e4da4eecd11c4448b9fa4b40","test/sys/test_sockopt.rs":"4465f22f718442f3f7b502e052dad02b93cebfa3b71fa55ff4f25fb02534acab","test/sys/test_stat.rs":"6630a28217fd708bb84cd4f7e7101836b74f2420f9888923fdab664ccc331c1d","test/sys/test_sysinfo.rs":"ffd49bc96375914a2c4a4a59730cae8072f85771e2c4a80d3403df38d967e272","test/sys/test_termios.rs":"e5bcef10c84bd7583d600d5601835bcb3cfc88781cb283ab0185bbef5faf4327","test/sys/test_timerfd.rs":"cfed3abf58118611d08f6985251a7739cff67108e11214222a1d2394a3a026ce","test/sys/test_uio.rs":"32656bd0a5699e4d019aa928edf104637937179782914a82d50d37226e84c421","test/sys/test_wait.rs":"6fd59fffeeb09ff620c359baefd062ba777598982b6cb001ccc07b6bc7605493","test/test.rs":"11f40b0718ddd1a150cb9e703d56d0b2a9462306505a2245ddf273a2011f48b5","test/test_clearenv.rs":"45ca548035b3c20ec87314715feaba2be973709a635d85b8cde46fd1d9f1ecd4","test/test_dir.rs":"ae3c11c58cb06da6557aa2a839c6653c54cd7724283fffe9df5a5d3feabdd89a","test/test_fcntl.rs":"71dcb87f7b04d78fc62937ba46cb7f0f1f2dbb330b63a996ea2e8ec9056b98a9","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"b4ae25841c2f06f32de9f1acd8230eeccd7095721302ebe78ad454e4e4f9c783","test/test_mount.rs":"6dd242b6e23c9c39e1a75612bbea62573898818ab374c3c032c2cdb97033554d","test/test_mq.rs":"136071f24131aac0e65d5f29ac18e3806641dfae1164813f5570c0e3a6f70553","test/test_net.rs":"f2912327ebb2a3d37e6cff02a5ac3106cf889cc5c74404db4ef0034059ba26f1","test/test_nix_path.rs":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","test/test_nmount.rs":"d6c112547bb80968170b5497cda4b6cbf69dabec6f51d494bd52298995ceff18","test/test_poll.rs":"3e0b8f0397ba080785c61a3bfc3d637bc87f324bc4e52b5f1bf3ca0d32dbc9fe","test/test_pty.rs":"b26238a0783746cb31880e11eebc1913149be999ce75fbc2d6677bdd1e2731b2","test/test_ptymaster_drop.rs":"ae63c815f5028ddc67d194e86559483018ab1816316bdb917f40cee9364fd8a5","test/test_resource.rs":"40aef790ab745cec31a4b333d2ca406b462aa9bdf4a6d3756371e498b8d51e9a","test/test_sched.rs":"c4579bd376fab8816e63b07fa9ace31dc08e63ebb7c855a2c450698090d1d1e8","test/test_sendfile.rs":"bb41b4f3621b518e397d3a5b5ad3c5dcef3fe506afe516eab7572fbab92b77e3","test/test_stat.rs":"c407ca47a5258750076d041afad2f6add4c3563be36628bde1c5b314f5d0765d","test/test_time.rs":"f7a21b1e279e60e84909d5dadda97ded66d3326b131fe317badf9af0a1b50335","test/test_timer.rs":"3ae20d364f075d2811f3ff94eda9886682cc21d8807656007d2464fe36d1e361","test/test_unistd.rs":"20a00be4fbe26302ea5fe50ce25b99265dc763db138663d6aa1d7ac729a1d292"},"package":"bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"} \ No newline at end of file
diff --git a/vendor/nix/CHANGELOG.md b/vendor/nix/CHANGELOG.md
deleted file mode 100644
index 283cb86a3..000000000
--- a/vendor/nix/CHANGELOG.md
+++ /dev/null
@@ -1,1585 +0,0 @@
-# Change Log
-
-All notable changes to this project will be documented in this file.
-This project adheres to [Semantic Versioning](https://semver.org/).
-
-## [0.26.2] - 2023-01-18
-### Fixed
-- Fix `SockaddrIn6` bug that was swapping flowinfo and scope_id byte ordering.
- ([#1964](https://github.com/nix-rust/nix/pull/1964))
-
-## [0.26.1] - 2022-11-29
-### Fixed
-- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`.
- ([#1821](https://github.com/nix-rust/nix/pull/1821))
-
-## [0.26.0] - 2022-11-29
-### Added
-
-- Added `SockaddrStorage::{as_unix_addr, as_unix_addr_mut}`
- ([#1871](https://github.com/nix-rust/nix/pull/1871))
-- Added `MntFlags` and `unmount` on all of the BSDs.
-- Added `any()` and `all()` to `poll::PollFd`.
- ([#1877](https://github.com/nix-rust/nix/pull/1877))
-- Add `MntFlags` and `unmount` on all of the BSDs.
- ([#1849](https://github.com/nix-rust/nix/pull/1849))
-- Added a `Statfs::flags` method.
- ([#1849](https://github.com/nix-rust/nix/pull/1849))
-- Added `NSFS_MAGIC` FsType on Linux and Android.
- ([#1829](https://github.com/nix-rust/nix/pull/1829))
-- Added `sched_getcpu` on platforms that support it.
- ([#1825](https://github.com/nix-rust/nix/pull/1825))
-- Added `sched_getaffinity` and `sched_setaffinity` on FreeBSD.
- ([#1804](https://github.com/nix-rust/nix/pull/1804))
-- Added `line_discipline` field to `Termios` on Linux, Android and Haiku
- ([#1805](https://github.com/nix-rust/nix/pull/1805))
-- Expose the memfd module on FreeBSD (memfd was added in FreeBSD 13)
- ([#1808](https://github.com/nix-rust/nix/pull/1808))
-- Added `domainname` field of `UtsName` on Android and Linux
- ([#1817](https://github.com/nix-rust/nix/pull/1817))
-- Re-export `RLIM_INFINITY` from `libc`
- ([#1831](https://github.com/nix-rust/nix/pull/1831))
-- Added `syncfs(2)` on Linux
- ([#1833](https://github.com/nix-rust/nix/pull/1833))
-- Added `faccessat(2)` on illumos
- ([#1841](https://github.com/nix-rust/nix/pull/1841))
-- Added `eaccess()` on FreeBSD, DragonFly and Linux (glibc and musl).
- ([#1842](https://github.com/nix-rust/nix/pull/1842))
-- Added `IP_TOS` `SO_PRIORITY` and `IPV6_TCLASS` sockopts for Linux
- ([#1853](https://github.com/nix-rust/nix/pull/1853))
-- Added `new_unnamed` and `is_unnamed` for `UnixAddr` on Linux and Android.
- ([#1857](https://github.com/nix-rust/nix/pull/1857))
-- Added `SockProtocol::Raw` for raw sockets
- ([#1848](https://github.com/nix-rust/nix/pull/1848))
-- added `IP_MTU` (`IpMtu`) `IPPROTO_IP` sockopt on Linux and Android.
- ([#1865](https://github.com/nix-rust/nix/pull/1865))
-
-### Changed
-
-- The MSRV is now 1.56.1
- ([#1792](https://github.com/nix-rust/nix/pull/1792))
-- The `addr` argument of `sys::mman::mmap` is now of type `Option<NonZeroUsize>`.
- ([#1870](https://github.com/nix-rust/nix/pull/1870))
-- The `length` argument of `sys::mman::mmap` is now of type `NonZeroUsize`.
- ([#1873](https://github.com/nix-rust/nix/pull/1873))
-
-### Fixed
-
-- Fixed using `SockaddrStorage` to store a Unix-domain socket address on Linux.
- ([#1871](https://github.com/nix-rust/nix/pull/1871))
-- Fix microsecond calculation for `TimeSpec`.
- ([#1801](https://github.com/nix-rust/nix/pull/1801))
-- Fix `User::from_name` and `Group::from_name` panicking
- when given a name containing a nul.
- ([#1815](https://github.com/nix-rust/nix/pull/1815))
-- Fix `User::from_uid` and `User::from_name` crash on Android platform.
- ([#1824](https://github.com/nix-rust/nix/pull/1824))
-- Workaround XNU bug causing netmasks returned by `getifaddrs` to misbehave.
- ([#1788](https://github.com/nix-rust/nix/pull/1788))
-
-### Removed
-
-- Removed deprecated error constants and conversions.
- ([#1860](https://github.com/nix-rust/nix/pull/1860))
-
-## [0.25.0] - 2022-08-13
-### Added
-
-- Added `faccessat`
- ([#1780](https://github.com/nix-rust/nix/pull/1780))
-- Added `memfd` on Android.
- (#[1773](https://github.com/nix-rust/nix/pull/1773))
-- Added `ETH_P_ALL` to `SockProtocol` enum
- (#[1768](https://github.com/nix-rust/nix/pull/1768))
-- Added four non-standard Linux `SysconfVar` variants
- (#[1761](https://github.com/nix-rust/nix/pull/1761))
-- Added const constructors for `TimeSpec` and `TimeVal`
- (#[1760](https://github.com/nix-rust/nix/pull/1760))
-- Added `chflags`.
- (#[1758](https://github.com/nix-rust/nix/pull/1758))
-- Added `aio_writev` and `aio_readv`.
- (#[1713](https://github.com/nix-rust/nix/pull/1713))
-- impl `From<uid_t>` for `Uid` and `From<gid_t>` for `Gid`
- (#[1727](https://github.com/nix-rust/nix/pull/1727))
-- impl `From<SockaddrIn>` for `std::net::SocketAddrV4` and
- impl `From<SockaddrIn6>` for `std::net::SocketAddrV6`.
- (#[1711](https://github.com/nix-rust/nix/pull/1711))
-- Added support for the `x86_64-unknown-haiku` target.
- (#[1703](https://github.com/nix-rust/nix/pull/1703))
-- Added `ptrace::read_user` and `ptrace::write_user` for Linux.
- (#[1697](https://github.com/nix-rust/nix/pull/1697))
-- Added `getrusage` and helper types `UsageWho` and `Usage`
- (#[1747](https://github.com/nix-rust/nix/pull/1747))
-- Added the `DontRoute` SockOpt
- (#[1752](https://github.com/nix-rust/nix/pull/1752))
-- Added `signal::SigSet::from_sigset_t_unchecked()`.
- (#[1741](https://github.com/nix-rust/nix/pull/1741))
-- Added the `Ipv4OrigDstAddr` sockopt and control message.
- (#[1772](https://github.com/nix-rust/nix/pull/1772))
-- Added the `Ipv6OrigDstAddr` sockopt and control message.
- (#[1772](https://github.com/nix-rust/nix/pull/1772))
-- Added the `Ipv4SendSrcAddr` control message.
- (#[1776](https://github.com/nix-rust/nix/pull/1776))
-
-### Changed
-
-- Reimplemented sendmmsg/recvmmsg to avoid allocations and with better API
- (#[1744](https://github.com/nix-rust/nix/pull/1744))
-
-- Rewrote the aio module. The new module:
- * Does more type checking at compile time rather than runtime.
- * Gives the caller control over whether and when to `Box` an aio operation.
- * Changes the type of the `priority` arguments to `i32`.
- * Changes the return type of `aio_return` to `usize`.
- (#[1713](https://github.com/nix-rust/nix/pull/1713))
-- `nix::poll::ppoll`: `sigmask` parameter is now optional.
- (#[1739](https://github.com/nix-rust/nix/pull/1739))
-- Changed `gethostname` to return an owned `OsString`.
- (#[1745](https://github.com/nix-rust/nix/pull/1745))
-- `signal:SigSet` is now marked as `repr(transparent)`.
- (#[1741](https://github.com/nix-rust/nix/pull/1741))
-
-### Removed
-
-- Removed support for resubmitting partially complete `lio_listio` operations.
- It was too complicated, and didn't fit Nix's theme of zero-cost abstractions.
- Instead, it can be reimplemented downstream.
- (#[1713](https://github.com/nix-rust/nix/pull/1713))
-
-## [0.24.2] - 2022-07-17
-### Fixed
-
-- Fixed buffer overflow in `nix::sys::socket::recvfrom`.
- (#[1763](https://github.com/nix-rust/nix/pull/1763))
-- Enabled `SockaddrStorage::{as_link_addr, as_link_addr_mut}` for Linux-like
- operating systems.
- (#[1729](https://github.com/nix-rust/nix/pull/1729))
-- Fixed `SockaddrLike::from_raw` implementations for `VsockAddr` and
- `SysControlAddr`.
- (#[1736](https://github.com/nix-rust/nix/pull/1736))
-
-## [0.24.1] - 2022-04-22
-### Fixed
-
-- Fixed `UnixAddr::size` on Linux-based OSes.
- (#[1702](https://github.com/nix-rust/nix/pull/1702))
-
-## [0.24.0] - 2022-04-21
-### Added
-
-- Added fine-grained features flags. Most Nix functionality can now be
- conditionally enabled. By default, all features are enabled.
- (#[1611](https://github.com/nix-rust/nix/pull/1611))
-- Added statfs FS type magic constants for `target_os = "android"`
- and synced constants with libc v0.2.121.
- (#[1690](https://github.com/nix-rust/nix/pull/1690))
-- Added `fexecve` on DragonFly.
- (#[1577](https://github.com/nix-rust/nix/pull/1577))
-- `sys::uio::IoVec` is now `Send` and `Sync`
- (#[1582](https://github.com/nix-rust/nix/pull/1582))
-- Added `EPOLLEXCLUSIVE` on Android.
- (#[1567](https://github.com/nix-rust/nix/pull/1567))
-- Added `fdatasync` for FreeBSD, Fuchsia, NetBSD, and OpenBSD.
- (#[1581](https://github.com/nix-rust/nix/pull/1581))
-- Added `sched_setaffinity` and `sched_getaffinity` on DragonFly.
- (#[1537](https://github.com/nix-rust/nix/pull/1537))
-- Added `posix_fallocate` on DragonFly.
- (#[1621](https://github.com/nix-rust/nix/pull/1621))
-- Added `SO_TIMESTAMPING` support
- (#[1547](https://github.com/nix-rust/nix/pull/1547))
-- Added getter methods to `MqAttr` struct
- (#[1619](https://github.com/nix-rust/nix/pull/1619))
-- Added the `TxTime` sockopt and control message.
- (#[1564](https://github.com/nix-rust/nix/pull/1564))
-- Added POSIX per-process timer support
- (#[1622](https://github.com/nix-rust/nix/pull/1622))
-- Added `sendfile` on DragonFly.
- (#[1615](https://github.com/nix-rust/nix/pull/1615))
-- Added `UMOUNT_NOFOLLOW`, `FUSE_SUPER_MAGIC` on Linux.
- (#[1634](https://github.com/nix-rust/nix/pull/1634))
-- Added `getresuid`, `setresuid`, `getresgid`, and `setresgid` on DragonFly, FreeBSD, and OpenBSD.
- (#[1628](https://github.com/nix-rust/nix/pull/1628))
-- Added `MAP_FIXED_NOREPLACE` on Linux.
- (#[1636](https://github.com/nix-rust/nix/pull/1636))
-- Added `fspacectl` on FreeBSD
- (#[1640](https://github.com/nix-rust/nix/pull/1640))
-- Added `accept4` on DragonFly, Emscripten, Fuchsia, Illumos, and NetBSD.
- (#[1654](https://github.com/nix-rust/nix/pull/1654))
-- Added `AsRawFd` implementation on `OwningIter`.
- (#[1563](https://github.com/nix-rust/nix/pull/1563))
-- Added `process_vm_readv` and `process_vm_writev` on Android.
- (#[1557](https://github.com/nix-rust/nix/pull/1557))
-- Added `nix::uncontext` module on s390x.
- (#[1662](https://github.com/nix-rust/nix/pull/1662))
-- Implemented `Extend`, `FromIterator`, and `IntoIterator` for `SigSet` and
- added `SigSet::iter` and `SigSetIter`.
- (#[1553](https://github.com/nix-rust/nix/pull/1553))
-- Added `ENOTRECOVERABLE` and `EOWNERDEAD` error codes on DragonFly.
- (#[1665](https://github.com/nix-rust/nix/pull/1665))
-- Implemented `Read` and `Write` for `&PtyMaster`
- (#[1664](https://github.com/nix-rust/nix/pull/1664))
-- Added `MSG_NOSIGNAL` for Android, Dragonfly, FreeBSD, Fuchsia, Haiku, Illumos, Linux, NetBSD, OpenBSD and Solaris.
- (#[1670](https://github.com/nix-rust/nix/pull/1670))
-- Added `waitid`.
- (#[1584](https://github.com/nix-rust/nix/pull/1584))
-- Added `Ipv6DontFrag` for android, iOS, linux and macOS.
-- Added `IpDontFrag` for iOS, macOS.
- (#[1692](https://github.com/nix-rust/nix/pull/1692))
-
-### Changed
-
-- `mqueue` functions now operate on a distinct type, `nix::mqueue::MqdT`.
- Accessors take this type by reference, not by value.
- (#[1639](https://github.com/nix-rust/nix/pull/1639))
-- Removed `SigSet::extend` in favor of `<SigSet as Extend<Signal>>::extend`.
- Because of this change, you now need `use std::iter::Extend` to call `extend`
- on a `SigSet`.
- (#[1553](https://github.com/nix-rust/nix/pull/1553))
-- Removed the the `PATH_MAX` restriction from APIs accepting paths. Paths
- will now be allocated on the heap if they are too long. In addition, large
- instruction count improvements (~30x) were made to path handling.
- (#[1656](https://github.com/nix-rust/nix/pull/1656))
-- Changed `getrlimit` and `setrlimit` to use `rlim_t` directly
- instead of `Option<rlim_t>`.
- (#[1668](https://github.com/nix-rust/nix/pull/1668))
-- Deprecated `InetAddr` and `SockAddr` in favor of `SockaddrIn`, `SockaddrIn6`,
- and `SockaddrStorage`.
- (#[1684](https://github.com/nix-rust/nix/pull/1684))
-- Deprecated `IpAddr`, `Ipv4Addr`, and `Ipv6Addr` in favor of their equivalents
- from the standard library.
- (#[1685](https://github.com/nix-rust/nix/pull/1685))
-- `uname` now returns a `Result<UtsName>` instead of just a `UtsName` and
- ignoring failures from libc. And getters on the `UtsName` struct now return
- an `&OsStr` instead of `&str`.
- (#[1672](https://github.com/nix-rust/nix/pull/1672))
-- Replaced `IoVec` with `IoSlice` and `IoSliceMut`, and replaced `IoVec::from_slice` with
- `IoSlice::new`. (#[1643](https://github.com/nix-rust/nix/pull/1643))
-
-### Fixed
-
-- `InetAddr::from_std` now sets the `sin_len`/`sin6_len` fields on the BSDs.
- (#[1642](https://github.com/nix-rust/nix/pull/1642))
-- Fixed a panic in `LinkAddr::addr`. That function now returns an `Option`.
- (#[1675](https://github.com/nix-rust/nix/pull/1675))
- (#[1677](https://github.com/nix-rust/nix/pull/1677))
-
-### Removed
-
-- Removed public access to the inner fields of `NetlinkAddr`, `AlgAddr`,
- `SysControlAddr`, `LinkAddr`, and `VsockAddr`.
- (#[1614](https://github.com/nix-rust/nix/pull/1614))
-- Removed `EventFlag::EV_SYSFLAG`.
- (#[1635](https://github.com/nix-rust/nix/pull/1635))
-
-## [0.23.1] - 2021-12-16
-
-### Changed
-
-- Relaxed the bitflags requirement from 1.3.1 to 1.1. This partially reverts
- #1492. From now on, the MSRV is not guaranteed to work with all versions of
- all dependencies, just with some version of all dependencies.
- (#[1607](https://github.com/nix-rust/nix/pull/1607))
-
-### Fixed
-
-- Fixed soundness issues in `FdSet::insert`, `FdSet::remove`, and
- `FdSet::contains` involving file descriptors outside of the range
- `0..FD_SETSIZE`.
- (#[1575](https://github.com/nix-rust/nix/pull/1575))
-
-## [0.23.0] - 2021-09-28
-### Added
-
-- Added the `LocalPeerCred` sockopt.
- (#[1482](https://github.com/nix-rust/nix/pull/1482))
-- Added `TimeSpec::from_duration` and `TimeSpec::from_timespec`
- (#[1465](https://github.com/nix-rust/nix/pull/1465))
-- Added `IPV6_V6ONLY` sockopt.
- (#[1470](https://github.com/nix-rust/nix/pull/1470))
-- Added `impl From<User> for libc::passwd` trait implementation to convert a `User`
- into a `libc::passwd`. Consumes the `User` struct to give ownership over
- the member pointers.
- (#[1471](https://github.com/nix-rust/nix/pull/1471))
-- Added `pthread_kill`.
- (#[1472](https://github.com/nix-rust/nix/pull/1472))
-- Added `mknodat`.
- (#[1473](https://github.com/nix-rust/nix/pull/1473))
-- Added `setrlimit` and `getrlimit`.
- (#[1302](https://github.com/nix-rust/nix/pull/1302))
-- Added `ptrace::interrupt` method for platforms that support `PTRACE_INTERRUPT`
- (#[1422](https://github.com/nix-rust/nix/pull/1422))
-- Added `IP6T_SO_ORIGINAL_DST` sockopt.
- (#[1490](https://github.com/nix-rust/nix/pull/1490))
-- Added the `PTRACE_EVENT_STOP` variant to the `sys::ptrace::Event` enum
- (#[1335](https://github.com/nix-rust/nix/pull/1335))
-- Exposed `SockAddr::from_raw_sockaddr`
- (#[1447](https://github.com/nix-rust/nix/pull/1447))
-- Added `TcpRepair`
- (#[1503](https://github.com/nix-rust/nix/pull/1503))
-- Enabled `pwritev` and `preadv` for more operating systems.
- (#[1511](https://github.com/nix-rust/nix/pull/1511))
-- Added support for `TCP_MAXSEG` TCP Maximum Segment Size socket options
- (#[1292](https://github.com/nix-rust/nix/pull/1292))
-- Added `Ipv4RecvErr` and `Ipv6RecvErr` sockopts and associated control messages.
- (#[1514](https://github.com/nix-rust/nix/pull/1514))
-- Added `AsRawFd` implementation on `PollFd`.
- (#[1516](https://github.com/nix-rust/nix/pull/1516))
-- Added `Ipv4Ttl` and `Ipv6Ttl` sockopts.
- (#[1515](https://github.com/nix-rust/nix/pull/1515))
-- Added `MAP_EXCL`, `MAP_ALIGNED_SUPER`, and `MAP_CONCEAL` mmap flags, and
- exposed `MAP_ANONYMOUS` for all operating systems.
- (#[1522](https://github.com/nix-rust/nix/pull/1522))
- (#[1525](https://github.com/nix-rust/nix/pull/1525))
- (#[1531](https://github.com/nix-rust/nix/pull/1531))
- (#[1534](https://github.com/nix-rust/nix/pull/1534))
-- Added read/write accessors for 'events' on `PollFd`.
- (#[1517](https://github.com/nix-rust/nix/pull/1517))
-
-### Changed
-
-- `FdSet::{contains, highest, fds}` no longer require a mutable reference.
- (#[1464](https://github.com/nix-rust/nix/pull/1464))
-- `User::gecos` and corresponding `libc::passwd::pw_gecos` are supported on
- 64-bit Android, change conditional compilation to include the field in
- 64-bit Android builds
- (#[1471](https://github.com/nix-rust/nix/pull/1471))
-- `eventfd`s are supported on Android, change conditional compilation to
- include `sys::eventfd::eventfd` and `sys::eventfd::EfdFlags`for Android
- builds.
- (#[1481](https://github.com/nix-rust/nix/pull/1481))
-- Most enums that come from C, for example `Errno`, are now marked as
- `#[non_exhaustive]`.
- (#[1474](https://github.com/nix-rust/nix/pull/1474))
-- Many more functions, mostly contructors, are now `const`.
- (#[1476](https://github.com/nix-rust/nix/pull/1476))
- (#[1492](https://github.com/nix-rust/nix/pull/1492))
-- `sys::event::KEvent::filter` now returns a `Result` instead of being
- infalliable. The only cases where it will now return an error are cases
- where it previously would've had undefined behavior.
- (#[1484](https://github.com/nix-rust/nix/pull/1484))
-- Minimum supported Rust version is now 1.46.0.
- ([#1492](https://github.com/nix-rust/nix/pull/1492))
-- Rework `UnixAddr` to encapsulate internals better in order to fix soundness
- issues. No longer allows creating a `UnixAddr` from a raw `sockaddr_un`.
- ([#1496](https://github.com/nix-rust/nix/pull/1496))
-- Raised bitflags to 1.3.0 and the MSRV to 1.46.0.
- ([#1492](https://github.com/nix-rust/nix/pull/1492))
-
-### Fixed
-
-- `posix_fadvise` now returns errors in the conventional way, rather than as a
- non-zero value in `Ok()`.
- (#[1538](https://github.com/nix-rust/nix/pull/1538))
-- Added more errno definitions for better backwards compatibility with
- Nix 0.21.0.
- (#[1467](https://github.com/nix-rust/nix/pull/1467))
-- Fixed potential undefined behavior in `Signal::try_from` on some platforms.
- (#[1484](https://github.com/nix-rust/nix/pull/1484))
-- Fixed buffer overflow in `unistd::getgrouplist`.
- (#[1545](https://github.com/nix-rust/nix/pull/1545))
-
-
-### Removed
-
-- Removed a couple of termios constants on redox that were never actually
- supported.
- (#[1483](https://github.com/nix-rust/nix/pull/1483))
-- Removed `nix::sys::signal::NSIG`. It was of dubious utility, and not correct
- for all platforms.
- (#[1484](https://github.com/nix-rust/nix/pull/1484))
-- Removed support for 32-bit Apple targets, since they've been dropped by both
- Rustc and Xcode.
- (#[1492](https://github.com/nix-rust/nix/pull/1492))
-- Deprecated `SockAddr/InetAddr::to_str` in favor of `ToString::to_string`
- (#[1495](https://github.com/nix-rust/nix/pull/1495))
-- Removed `SigevNotify` on OpenBSD and Redox.
- (#[1511](https://github.com/nix-rust/nix/pull/1511))
-
-## [0.22.3] - 22 January 2022
-### Changed
-- Relaxed the bitflags requirement from 1.3.1 to 1.1. This partially reverts
- #1492. From now on, the MSRV is not guaranteed to work with all versions of
- all dependencies, just with some version of all dependencies.
- (#[1607](https://github.com/nix-rust/nix/pull/1607))
-
-## [0.22.2] - 28 September 2021
-### Fixed
-- Fixed buffer overflow in `unistd::getgrouplist`.
- (#[1545](https://github.com/nix-rust/nix/pull/1545))
-- Added more errno definitions for better backwards compatibility with
- Nix 0.21.0.
- (#[1467](https://github.com/nix-rust/nix/pull/1467))
-
-## [0.22.1] - 13 August 2021
-### Fixed
-- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
-
-### Removed
-- Removed a couple of termios constants on redox that were never actually
- supported.
- (#[1483](https://github.com/nix-rust/nix/pull/1483))
-
-## [0.22.0] - 9 July 2021
-### Added
-- Added `if_nameindex` (#[1445](https://github.com/nix-rust/nix/pull/1445))
-- Added `nmount` for FreeBSD.
- (#[1453](https://github.com/nix-rust/nix/pull/1453))
-- Added `IpFreebind` socket option (sockopt) on Linux, Fuchsia and Android.
- (#[1456](https://github.com/nix-rust/nix/pull/1456))
-- Added `TcpUserTimeout` socket option (sockopt) on Linux and Fuchsia.
- (#[1457](https://github.com/nix-rust/nix/pull/1457))
-- Added `renameat2` for Linux
- (#[1458](https://github.com/nix-rust/nix/pull/1458))
-- Added `RxqOvfl` support on Linux, Fuchsia and Android.
- (#[1455](https://github.com/nix-rust/nix/pull/1455))
-
-### Changed
-- `ptsname_r` now returns a lossily-converted string in the event of bad UTF,
- just like `ptsname`.
- ([#1446](https://github.com/nix-rust/nix/pull/1446))
-- Nix's error type is now a simple wrapper around the platform's Errno. This
- means it is now `Into<std::io::Error>`. It's also `Clone`, `Copy`, `Eq`, and
- has a small fixed size. It also requires less typing. For example, the old
- enum variant `nix::Error::Sys(nix::errno::Errno::EINVAL)` is now simply
- `nix::Error::EINVAL`.
- ([#1446](https://github.com/nix-rust/nix/pull/1446))
-
-## [0.21.2] - 29 September 2021
-### Fixed
-- Fixed buffer overflow in `unistd::getgrouplist`.
- (#[1545](https://github.com/nix-rust/nix/pull/1545))
-
-## [0.21.1] - 13 August 2021
-### Fixed
-- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
-
-### Removed
-- Removed a couple of termios constants on redox that were never actually
- supported.
- (#[1483](https://github.com/nix-rust/nix/pull/1483))
-
-## [0.21.0] - 31 May 2021
-### Added
-- Added `getresuid` and `getresgid`
- (#[1430](https://github.com/nix-rust/nix/pull/1430))
-- Added TIMESTAMPNS support for linux
- (#[1402](https://github.com/nix-rust/nix/pull/1402))
-- Added `sendfile64` (#[1439](https://github.com/nix-rust/nix/pull/1439))
-- Added `MS_LAZYTIME` to `MsFlags`
- (#[1437](https://github.com/nix-rust/nix/pull/1437))
-
-### Changed
-- Made `forkpty` unsafe, like `fork`
- (#[1390](https://github.com/nix-rust/nix/pull/1390))
-- Made `Uid`, `Gid` and `Pid` methods `from_raw` and `as_raw` a `const fn`
- (#[1429](https://github.com/nix-rust/nix/pull/1429))
-- Made `Uid::is_root` a `const fn`
- (#[1429](https://github.com/nix-rust/nix/pull/1429))
-- `AioCb` is now always pinned. Once a `libc::aiocb` gets sent to the kernel,
- its address in memory must not change. Nix now enforces that by using
- `std::pin`. Most users won't need to change anything, except when using
- `aio_suspend`. See that method's documentation for the new usage.
- (#[1440](https://github.com/nix-rust/nix/pull/1440))
-- `LioCb` is now constructed using a distinct `LioCbBuilder` struct. This
- avoids a soundness issue with the old `LioCb`. Usage is similar but
- construction now uses the builder pattern. See the documentation for
- details.
- (#[1440](https://github.com/nix-rust/nix/pull/1440))
-- Minimum supported Rust version is now 1.41.0.
- ([#1440](https://github.com/nix-rust/nix/pull/1440))
-- Errno aliases are now associated consts on `Errno`, instead of consts in the
- `errno` module.
- (#[1452](https://github.com/nix-rust/nix/pull/1452))
-
-### Fixed
-- Allow `sockaddr_ll` size, as reported by the Linux kernel, to be smaller then it's definition
- (#[1395](https://github.com/nix-rust/nix/pull/1395))
-- Fix spurious errors using `sendmmsg` with multiple cmsgs
- (#[1414](https://github.com/nix-rust/nix/pull/1414))
-- Added `Errno::EOPNOTSUPP` to FreeBSD, where it was missing.
- (#[1452](https://github.com/nix-rust/nix/pull/1452))
-
-### Removed
-
-- Removed `sys::socket::accept4` from Android arm because libc removed it in
- version 0.2.87.
- ([#1399](https://github.com/nix-rust/nix/pull/1399))
-- `AioCb::from_boxed_slice` and `AioCb::from_boxed_mut_slice` have been
- removed. They were useful with earlier versions of Rust, but should no
- longer be needed now that async/await are available. `AioCb`s now work
- exclusively with borrowed buffers, not owned ones.
- (#[1440](https://github.com/nix-rust/nix/pull/1440))
-- Removed some Errno values from platforms where they aren't actually defined.
- (#[1452](https://github.com/nix-rust/nix/pull/1452))
-
-## [0.20.2] - 28 September 2021
-### Fixed
-- Fixed buffer overflow in `unistd::getgrouplist`.
- (#[1545](https://github.com/nix-rust/nix/pull/1545))
-
-## [0.20.1] - 13 August 2021
-### Fixed
-- Locked bitflags to < 1.3.0 to fix the build with rust < 1.46.0.
-
-### Removed
-- Removed a couple of termios constants on redox that were never actually
- supported.
- (#[1483](https://github.com/nix-rust/nix/pull/1483))
-
-## [0.20.0] - 20 February 2021
-### Added
-
-- Added a `passwd` field to `Group` (#[1338](https://github.com/nix-rust/nix/pull/1338))
-- Added `mremap` (#[1306](https://github.com/nix-rust/nix/pull/1306))
-- Added `personality` (#[1331](https://github.com/nix-rust/nix/pull/1331))
-- Added limited Fuchsia support (#[1285](https://github.com/nix-rust/nix/pull/1285))
-- Added `getpeereid` (#[1342](https://github.com/nix-rust/nix/pull/1342))
-- Implemented `IntoIterator` for `Dir`
- (#[1333](https://github.com/nix-rust/nix/pull/1333)).
-
-### Changed
-
-- Minimum supported Rust version is now 1.40.0.
- ([#1356](https://github.com/nix-rust/nix/pull/1356))
-- i686-apple-darwin has been demoted to Tier 2 support, because it's deprecated
- by Xcode.
- (#[1350](https://github.com/nix-rust/nix/pull/1350))
-- Fixed calling `recvfrom` on an `AddrFamily::Packet` socket
- (#[1344](https://github.com/nix-rust/nix/pull/1344))
-
-### Fixed
-- `TimerFd` now closes the underlying fd on drop.
- ([#1381](https://github.com/nix-rust/nix/pull/1381))
-- Define `*_MAGIC` filesystem constants on Linux s390x
- (#[1372](https://github.com/nix-rust/nix/pull/1372))
-- mqueue, sysinfo, timespec, statfs, test_ptrace_syscall() on x32
- (#[1366](https://github.com/nix-rust/nix/pull/1366))
-
-### Removed
-
-- `Dir`, `SignalFd`, and `PtyMaster` are no longer `Clone`.
- (#[1382](https://github.com/nix-rust/nix/pull/1382))
-- Removed `SockLevel`, which hasn't been used for a few years
- (#[1362](https://github.com/nix-rust/nix/pull/1362))
-- Removed both `Copy` and `Clone` from `TimerFd`.
- ([#1381](https://github.com/nix-rust/nix/pull/1381))
-
-## [0.19.1] - 28 November 2020
-### Fixed
-- Fixed bugs in `recvmmsg`.
- (#[1341](https://github.com/nix-rust/nix/pull/1341))
-
-## [0.19.0] - 6 October 2020
-### Added
-- Added Netlink protocol families to the `SockProtocol` enum
- (#[1289](https://github.com/nix-rust/nix/pull/1289))
-- Added `clock_gettime`, `clock_settime`, `clock_getres`,
- `clock_getcpuclockid` functions and `ClockId` struct.
- (#[1281](https://github.com/nix-rust/nix/pull/1281))
-- Added wrapper functions for `PTRACE_SYSEMU` and `PTRACE_SYSEMU_SINGLESTEP`.
- (#[1300](https://github.com/nix-rust/nix/pull/1300))
-- Add support for Vsock on Android rather than just Linux.
- (#[1301](https://github.com/nix-rust/nix/pull/1301))
-- Added `TCP_KEEPCNT` and `TCP_KEEPINTVL` TCP keepalive options.
- (#[1283](https://github.com/nix-rust/nix/pull/1283))
-### Changed
-- Expose `SeekData` and `SeekHole` on all Linux targets
- (#[1284](https://github.com/nix-rust/nix/pull/1284))
-- Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s).
- (#[1278](https://github.com/nix-rust/nix/pull/1278))
-- Made `unistd::fork` an unsafe funtion, bringing it in line with [libstd's decision](https://github.com/rust-lang/rust/pull/58059).
- (#[1293](https://github.com/nix-rust/nix/pull/1293))
-
-## [0.18.0] - 26 July 2020
-### Added
-- Added `fchown(2)` wrapper.
- (#[1257](https://github.com/nix-rust/nix/pull/1257))
-- Added support on linux systems for `MAP_HUGE_`_`SIZE`_ family of flags.
- (#[1211](https://github.com/nix-rust/nix/pull/1211))
-- Added support for `F_OFD_*` `fcntl` commands on Linux and Android.
- (#[1195](https://github.com/nix-rust/nix/pull/1195))
-- Added `env::clearenv()`: calls `libc::clearenv` on platforms
- where it's available, and clears the environment of all variables
- via `std::env::vars` and `std::env::remove_var` on others.
- (#[1185](https://github.com/nix-rust/nix/pull/1185))
-- `FsType` inner value made public.
- (#[1187](https://github.com/nix-rust/nix/pull/1187))
-- Added `unistd::setfsuid` and `unistd::setfsgid` to set the user or group
- identity for filesystem checks per-thread.
- (#[1163](https://github.com/nix-rust/nix/pull/1163))
-- Derived `Ord`, `PartialOrd` for `unistd::Pid` (#[1189](https://github.com/nix-rust/nix/pull/1189))
-- Added `select::FdSet::fds` method to iterate over file descriptors in a set.
- ([#1207](https://github.com/nix-rust/nix/pull/1207))
-- Added support for UDP generic segmentation offload (GSO) and generic
- receive offload (GRO) ([#1209](https://github.com/nix-rust/nix/pull/1209))
-- Added support for `sendmmsg` and `recvmmsg` calls
- (#[1208](https://github.com/nix-rust/nix/pull/1208))
-- Added support for `SCM_CREDS` messages (`UnixCredentials`) on FreeBSD/DragonFly
- (#[1216](https://github.com/nix-rust/nix/pull/1216))
-- Added `BindToDevice` socket option (sockopt) on Linux
- (#[1233](https://github.com/nix-rust/nix/pull/1233))
-- Added `EventFilter` bitflags for `EV_DISPATCH` and `EV_RECEIPT` on OpenBSD.
- (#[1252](https://github.com/nix-rust/nix/pull/1252))
-- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage`.
- (#[1222](https://github.com/nix-rust/nix/pull/1222))
-- `CpuSet` and `UnixCredentials` now implement `Default`.
- (#[1244](https://github.com/nix-rust/nix/pull/1244))
-- Added `unistd::ttyname`
- (#[1259](https://github.com/nix-rust/nix/pull/1259))
-- Added support for `Ipv4PacketInfo` and `Ipv6PacketInfo` to `ControlMessage` for iOS and Android.
- (#[1265](https://github.com/nix-rust/nix/pull/1265))
-- Added support for `TimerFd`.
- (#[1261](https://github.com/nix-rust/nix/pull/1261))
-
-### Changed
-- Changed `fallocate` return type from `c_int` to `()` (#[1201](https://github.com/nix-rust/nix/pull/1201))
-- Enabled `sys::ptrace::setregs` and `sys::ptrace::getregs` on x86_64-unknown-linux-musl target
- (#[1198](https://github.com/nix-rust/nix/pull/1198))
-- On Linux, `ptrace::write` is now an `unsafe` function. Caveat programmer.
- (#[1245](https://github.com/nix-rust/nix/pull/1245))
-- `execv`, `execve`, `execvp` and `execveat` in `::nix::unistd` and `reboot` in
- `::nix::sys::reboot` now return `Result<Infallible>` instead of `Result<Void>` (#[1239](https://github.com/nix-rust/nix/pull/1239))
-- `sys::socket::sockaddr_storage_to_addr` is no longer `unsafe`. So is
- `offset_of!`.
-- `sys::socket::sockaddr_storage_to_addr`, `offset_of!`, and `Errno::clear` are
- no longer `unsafe`.
-- `SockAddr::as_ffi_pair`,`sys::socket::sockaddr_storage_to_addr`, `offset_of!`,
- and `Errno::clear` are no longer `unsafe`.
- (#[1244](https://github.com/nix-rust/nix/pull/1244))
-- Several `Inotify` methods now take `self` by value instead of by reference
- (#[1244](https://github.com/nix-rust/nix/pull/1244))
-- `nix::poll::ppoll`: `timeout` parameter is now optional, None is equivalent for infinite timeout.
-
-### Fixed
-
-- Fixed `getsockopt`. The old code produced UB which triggers a panic with
- Rust 1.44.0.
- (#[1214](https://github.com/nix-rust/nix/pull/1214))
-
-- Fixed a bug in nix::unistd that would result in an infinite loop
- when a group or user lookup required a buffer larger than
- 16KB. (#[1198](https://github.com/nix-rust/nix/pull/1198))
-- Fixed unaligned casting of `cmsg_data` to `af_alg_iv` (#[1206](https://github.com/nix-rust/nix/pull/1206))
-- Fixed `readlink`/`readlinkat` when reading symlinks longer than `PATH_MAX` (#[1231](https://github.com/nix-rust/nix/pull/1231))
-- `PollFd`, `EpollEvent`, `IpMembershipRequest`, `Ipv6MembershipRequest`,
- `TimeVal`, and `IoVec` are now `repr(transparent)`. This is required for
- correctness's sake across all architectures and compilers, though now bugs
- have been reported so far.
- (#[1243](https://github.com/nix-rust/nix/pull/1243))
-- Fixed unaligned pointer read in `Inotify::read_events`.
- (#[1244](https://github.com/nix-rust/nix/pull/1244))
-
-### Removed
-
-- Removed `sys::socket::addr::from_libc_sockaddr` from the public API.
- (#[1215](https://github.com/nix-rust/nix/pull/1215))
-- Removed `sys::termios::{get_libc_termios, get_libc_termios_mut, update_wrapper`
- from the public API. These were previously hidden in the docs but still usable
- by downstream.
- (#[1235](https://github.com/nix-rust/nix/pull/1235))
-
-- Nix no longer implements `NixPath` for `Option<P> where P: NixPath`. Most
- Nix functions that accept `NixPath` arguments can't do anything useful with
- `None`. The exceptions (`mount` and `quotactl_sync`) already take explicitly
- optional arguments.
- (#[1242](https://github.com/nix-rust/nix/pull/1242))
-
-- Removed `unistd::daemon` and `unistd::pipe2` on OSX and ios
- (#[1255](https://github.com/nix-rust/nix/pull/1255))
-
-- Removed `sys::event::FilterFlag::NOTE_EXIT_REPARENTED` and
- `sys::event::FilterFlag::NOTE_REAP` on OSX and ios.
- (#[1255](https://github.com/nix-rust/nix/pull/1255))
-
-- Removed `sys::ptrace::ptrace` on Android and Linux.
- (#[1255](https://github.com/nix-rust/nix/pull/1255))
-
-- Dropped support for powerpc64-unknown-linux-gnu
- (#[1266](https://github.com/nix-rust/nix/pull/1268))
-
-## [0.17.0] - 3 February 2020
-### Added
-- Add `CLK_TCK` to `SysconfVar`
- (#[1177](https://github.com/nix-rust/nix/pull/1177))
-### Removed
-- Removed deprecated Error::description from error types
- (#[1175](https://github.com/nix-rust/nix/pull/1175))
-
-## [0.16.1] - 23 December 2019
-### Fixed
-
-- Fixed the build for OpenBSD
- (#[1168](https://github.com/nix-rust/nix/pull/1168))
-
-## [0.16.0] - 1 December 2019
-### Added
-- Added `ptrace::seize()`: similar to `attach()` on Linux
- but with better-defined semantics.
- (#[1154](https://github.com/nix-rust/nix/pull/1154))
-
-- Added `Signal::as_str()`: returns signal name as `&'static str`
- (#[1138](https://github.com/nix-rust/nix/pull/1138))
-
-- Added `posix_fallocate`.
- ([#1105](https://github.com/nix-rust/nix/pull/1105))
-
-- Implemented `Default` for `FdSet`
- ([#1107](https://github.com/nix-rust/nix/pull/1107))
-
-- Added `NixPath::is_empty`.
- ([#1107](https://github.com/nix-rust/nix/pull/1107))
-
-- Added `mkfifoat`
- ([#1133](https://github.com/nix-rust/nix/pull/1133))
-
-- Added `User::from_uid`, `User::from_name`, `User::from_gid` and
- `Group::from_name`,
- ([#1139](https://github.com/nix-rust/nix/pull/1139))
-
-- Added `linkat`
- ([#1101](https://github.com/nix-rust/nix/pull/1101))
-
-- Added `sched_getaffinity`.
- ([#1148](https://github.com/nix-rust/nix/pull/1148))
-
-- Added optional `Signal` argument to `ptrace::{detach, syscall}` for signal
- injection. ([#1083](https://github.com/nix-rust/nix/pull/1083))
-
-### Changed
-- `sys::termios::BaudRate` now implements `TryFrom<speed_t>` instead of
- `From<speed_t>`. The old `From` implementation would panic on failure.
- ([#1159](https://github.com/nix-rust/nix/pull/1159))
-
-- `sys::socket::ControlMessage::ScmCredentials` and
- `sys::socket::ControlMessageOwned::ScmCredentials` now wrap `UnixCredentials`
- rather than `libc::ucred`.
- ([#1160](https://github.com/nix-rust/nix/pull/1160))
-
-- `sys::socket::recvmsg` now takes a plain `Vec` instead of a `CmsgBuffer`
- implementor. If you were already using `cmsg_space!`, then you needn't worry.
- ([#1156](https://github.com/nix-rust/nix/pull/1156))
-
-- `sys::socket::recvfrom` now returns
- `Result<(usize, Option<SockAddr>)>` instead of `Result<(usize, SockAddr)>`.
- ([#1145](https://github.com/nix-rust/nix/pull/1145))
-
-- `Signal::from_c_int` has been replaced by `Signal::try_from`
- ([#1113](https://github.com/nix-rust/nix/pull/1113))
-
-- Changed `readlink` and `readlinkat` to return `OsString`
- ([#1109](https://github.com/nix-rust/nix/pull/1109))
-
- ```rust
- # use nix::fcntl::{readlink, readlinkat};
- // the buffer argument of `readlink` and `readlinkat` has been removed,
- // and the return value is now an owned type (`OsString`).
- // Existing code can be updated by removing the buffer argument
- // and removing any clone or similar operation on the output
-
- // old code `readlink(&path, &mut buf)` can be replaced with the following
- let _: OsString = readlink(&path);
-
- // old code `readlinkat(dirfd, &path, &mut buf)` can be replaced with the following
- let _: OsString = readlinkat(dirfd, &path);
- ```
-
-- Minimum supported Rust version is now 1.36.0.
- ([#1108](https://github.com/nix-rust/nix/pull/1108))
-
-- `Ipv4Addr::octets`, `Ipv4Addr::to_std`, `Error::as_errno`,
- `ForkResult::is_child`, `ForkResult::is_parent`, `Gid::as_raw`,
- `Uid::is_root`, `Uid::as_raw`, `Pid::as_raw`, and `PollFd::revents` now take
- `self` by value.
- ([#1107](https://github.com/nix-rust/nix/pull/1107))
-
-- Type `&CString` for parameters of `exec(v|ve|vp|vpe|veat)` are changed to `&CStr`.
- ([#1121](https://github.com/nix-rust/nix/pull/1121))
-
-### Fixed
-- Fix length of abstract socket addresses
- ([#1120](https://github.com/nix-rust/nix/pull/1120))
-
-- Fix initialization of msghdr in recvmsg/sendmsg when built with musl
- ([#1136](https://github.com/nix-rust/nix/pull/1136))
-
-### Removed
-- Remove the deprecated `CmsgSpace`.
- ([#1156](https://github.com/nix-rust/nix/pull/1156))
-
-## [0.15.0] - 10 August 2019
-### Added
-- Added `MSG_WAITALL` to `MsgFlags` in `sys::socket`.
- ([#1079](https://github.com/nix-rust/nix/pull/1079))
-- Implemented `Clone`, `Copy`, `Debug`, `Eq`, `Hash`, and `PartialEq` for most
- types that support them. ([#1035](https://github.com/nix-rust/nix/pull/1035))
-- Added `copy_file_range` wrapper
- ([#1069](https://github.com/nix-rust/nix/pull/1069))
-- Add `mkdirat`.
- ([#1084](https://github.com/nix-rust/nix/pull/1084))
-- Add `posix_fadvise`.
- ([#1089](https://github.com/nix-rust/nix/pull/1089))
-- Added `AF_VSOCK` to `AddressFamily`.
- ([#1091](https://github.com/nix-rust/nix/pull/1091))
-- Add `unlinkat`
- ([#1058](https://github.com/nix-rust/nix/pull/1058))
-- Add `renameat`.
- ([#1097](https://github.com/nix-rust/nix/pull/1097))
-
-### Changed
-- Support for `ifaddrs` now present when building for Android.
- ([#1077](https://github.com/nix-rust/nix/pull/1077))
-- Minimum supported Rust version is now 1.31.0
- ([#1035](https://github.com/nix-rust/nix/pull/1035))
- ([#1095](https://github.com/nix-rust/nix/pull/1095))
-- Now functions `statfs()` and `fstatfs()` return result with `Statfs` wrapper
- ([#928](https://github.com/nix-rust/nix/pull/928))
-
-### Fixed
-- Enabled `sched_yield` for all nix hosts.
- ([#1090](https://github.com/nix-rust/nix/pull/1090))
-
-## [0.14.1] - 2019-06-06
-### Added
-- Macros exported by `nix` may now be imported via `use` on the Rust 2018
- edition without importing helper macros on Linux targets.
- ([#1066](https://github.com/nix-rust/nix/pull/1066))
-
- For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported
- without importing the `convert_ioctl_res!` macro.
-
- ```rust
- use nix::ioctl_read_bad;
-
- ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
- ```
-
-### Changed
-- Changed some public types from reexports of libc types like `uint32_t` to the
- native equivalents like `u32.`
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-
-### Fixed
-- Fix the build on Android and Linux/mips with recent versions of libc.
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-
-## [0.14.0] - 2019-05-21
-### Added
-- Add IP_RECVIF & IP_RECVDSTADDR. Enable IP_PKTINFO and IP6_PKTINFO on netbsd/openbsd.
- ([#1002](https://github.com/nix-rust/nix/pull/1002))
-- Added `inotify_init1`, `inotify_add_watch` and `inotify_rm_watch` wrappers for
- Android and Linux. ([#1016](https://github.com/nix-rust/nix/pull/1016))
-- Add `ALG_SET_IV`, `ALG_SET_OP` and `ALG_SET_AEAD_ASSOCLEN` control messages and `AF_ALG`
- socket types on Linux and Android ([#1031](https://github.com/nix-rust/nix/pull/1031))
-- Add killpg
- ([#1034](https://github.com/nix-rust/nix/pull/1034))
-- Added ENOTSUP errno support for Linux and Android.
- ([#969](https://github.com/nix-rust/nix/pull/969))
-- Add several errno constants from OpenBSD 6.2
- ([#1036](https://github.com/nix-rust/nix/pull/1036))
-- Added `from_std` and `to_std` methods for `sys::socket::IpAddr`
- ([#1043](https://github.com/nix-rust/nix/pull/1043))
-- Added `nix::unistd:seteuid` and `nix::unistd::setegid` for those platforms that do
- not support `setresuid` nor `setresgid` respectively.
- ([#1044](https://github.com/nix-rust/nix/pull/1044))
-- Added a `access` wrapper
- ([#1045](https://github.com/nix-rust/nix/pull/1045))
-- Add `forkpty`
- ([#1042](https://github.com/nix-rust/nix/pull/1042))
-- Add `sched_yield`
- ([#1050](https://github.com/nix-rust/nix/pull/1050))
-
-### Changed
-- `PollFd` event flags renamed to `PollFlags` ([#1024](https://github.com/nix-rust/nix/pull/1024/))
-- `recvmsg` now returns an Iterator over `ControlMessageOwned` objects rather
- than `ControlMessage` objects. This is sadly not backwards-compatible. Fix
- code like this:
- ```rust
- if let ControlMessage::ScmRights(&fds) = cmsg {
- ```
-
- By replacing it with code like this:
- ```rust
- if let ControlMessageOwned::ScmRights(fds) = cmsg {
- ```
- ([#1020](https://github.com/nix-rust/nix/pull/1020))
-- Replaced `CmsgSpace` with the `cmsg_space` macro.
- ([#1020](https://github.com/nix-rust/nix/pull/1020))
-
-### Fixed
-- Fixed multiple bugs when using `sendmsg` and `recvmsg` with ancillary control messages
- ([#1020](https://github.com/nix-rust/nix/pull/1020))
-- Macros exported by `nix` may now be imported via `use` on the Rust 2018
- edition without importing helper macros for BSD targets.
- ([#1041](https://github.com/nix-rust/nix/pull/1041))
-
- For example, in Rust 2018, the `ioctl_read_bad!` macro can now be imported
- without importing the `convert_ioctl_res!` macro.
-
- ```rust
- use nix::ioctl_read_bad;
-
- ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
- ```
-
-### Removed
-- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
- and iOS.
- ([#1033](https://github.com/nix-rust/nix/pull/1033))
-- `PTRACE_GETREGS`, `PTRACE_SETREGS`, `PTRACE_GETFPREGS`, and
- `PTRACE_SETFPREGS` have been removed from some platforms where they never
- should've been defined in the first place.
- ([#1055](https://github.com/nix-rust/nix/pull/1055))
-
-## [0.13.1] - 2019-06-10
-### Changed
-- Changed some public types from reexports of libc types like `uint32_t` to the
- native equivalents like `u32.`
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-
-### Fixed
-- Fix the build on Android and Linux/mips with recent versions of libc.
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc
- ([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973))
-
-### Removed
-- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
- and iOS.
- ([#1033](https://github.com/nix-rust/nix/pull/1033))
-
-## [0.13.0] - 2019-01-15
-### Added
-- Added PKTINFO(V4) & V6PKTINFO cmsg support - Android/FreeBSD/iOS/Linux/MacOS.
- ([#990](https://github.com/nix-rust/nix/pull/990))
-- Added support of CString type in `setsockopt`.
- ([#972](https://github.com/nix-rust/nix/pull/972))
-- Added option `TCP_CONGESTION` in `setsockopt`.
- ([#972](https://github.com/nix-rust/nix/pull/972))
-- Added `symlinkat` wrapper.
- ([#997](https://github.com/nix-rust/nix/pull/997))
-- Added `ptrace::{getregs, setregs}`.
- ([#1010](https://github.com/nix-rust/nix/pull/1010))
-- Added `nix::sys::signal::signal`.
- ([#817](https://github.com/nix-rust/nix/pull/817))
-- Added an `mprotect` wrapper.
- ([#991](https://github.com/nix-rust/nix/pull/991))
-
-### Fixed
-- `lutimes` never worked on OpenBSD as it is not implemented on OpenBSD. It has
- been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
-- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
- either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
-
-## [0.12.1] 2019-06-08
-### Changed
-- Changed some public types from reexports of libc types like `uint32_t` to the
- native equivalents like `u32.`
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-
-### Fixed
-- Fix the build on Android and Linux/mips with recent versions of libc.
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc
- ([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973))
-
-### Removed
-- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
- either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
-- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
- and iOS.
- ([#1033](https://github.com/nix-rust/nix/pull/1033))
-
-## [0.12.0] 2018-11-28
-
-### Added
-- Added `FromStr` and `Display` impls for `nix::sys::Signal`
- ([#884](https://github.com/nix-rust/nix/pull/884))
-- Added a `sync` wrapper.
- ([#961](https://github.com/nix-rust/nix/pull/961))
-- Added a `sysinfo` wrapper.
- ([#922](https://github.com/nix-rust/nix/pull/922))
-- Support the `SO_PEERCRED` socket option and the `UnixCredentials` type on all Linux and Android targets.
- ([#921](https://github.com/nix-rust/nix/pull/921))
-- Added support for `SCM_CREDENTIALS`, allowing to send process credentials over Unix sockets.
- ([#923](https://github.com/nix-rust/nix/pull/923))
-- Added a `dir` module for reading directories (wraps `fdopendir`, `readdir`, and `rewinddir`).
- ([#916](https://github.com/nix-rust/nix/pull/916))
-- Added `kmod` module that allows loading and unloading kernel modules on Linux.
- ([#930](https://github.com/nix-rust/nix/pull/930))
-- Added `futimens` and `utimesat` wrappers ([#944](https://github.com/nix-rust/nix/pull/944)),
- an `lutimes` wrapper ([#967](https://github.com/nix-rust/nix/pull/967)),
- and a `utimes` wrapper ([#946](https://github.com/nix-rust/nix/pull/946)).
-- Added `AF_UNSPEC` wrapper to `AddressFamily` ([#948](https://github.com/nix-rust/nix/pull/948))
-- Added the `mode_t` public alias within `sys::stat`.
- ([#954](https://github.com/nix-rust/nix/pull/954))
-- Added a `truncate` wrapper.
- ([#956](https://github.com/nix-rust/nix/pull/956))
-- Added a `fchownat` wrapper.
- ([#955](https://github.com/nix-rust/nix/pull/955))
-- Added support for `ptrace` on BSD operating systems ([#949](https://github.com/nix-rust/nix/pull/949))
-- Added `ptrace` functions for reads and writes to tracee memory and ptrace kill
- ([#949](https://github.com/nix-rust/nix/pull/949)) ([#958](https://github.com/nix-rust/nix/pull/958))
-- Added a `acct` wrapper module for enabling and disabling process accounting
- ([#952](https://github.com/nix-rust/nix/pull/952))
-- Added the `time_t` and `suseconds_t` public aliases within `sys::time`.
- ([#968](https://github.com/nix-rust/nix/pull/968))
-- Added `unistd::execvpe` for Haiku, Linux and OpenBSD
- ([#975](https://github.com/nix-rust/nix/pull/975))
-- Added `Error::as_errno`.
- ([#977](https://github.com/nix-rust/nix/pull/977))
-
-### Changed
-- Increased required Rust version to 1.24.1
- ([#900](https://github.com/nix-rust/nix/pull/900))
- ([#966](https://github.com/nix-rust/nix/pull/966))
-
-### Fixed
-- Made `preadv` take immutable slice of IoVec.
- ([#914](https://github.com/nix-rust/nix/pull/914))
-- Fixed passing multiple file descriptors over Unix Sockets.
- ([#918](https://github.com/nix-rust/nix/pull/918))
-
-## [0.11.1] 2019-06-06
-### Changed
-- Changed some public types from reexports of libc types like `uint32_t` to the
- native equivalents like `u32.`
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-
-### Fixed
-- Fix the build on Android and Linux/mips with recent versions of libc.
- ([#1072](https://github.com/nix-rust/nix/pull/1072/commits))
-- Fixed build on Linux/arm and Linux/s390x with the latest Rust libc
- ([52102cb](https://github.com/nix-rust/nix/commit/52102cb76398c4dfb9ea141b98c5b01a2e050973))
-
-### Removed
-- `fexecve` never worked on NetBSD or on OpenBSD as it is not implemented on
- either OS. It has been removed. ([#1000](https://github.com/nix-rust/nix/pull/1000))
-- `Daemon`, `NOTE_REAP`, and `NOTE_EXIT_REPARENTED` are now deprecated on OSX
- and iOS.
- ([#1033](https://github.com/nix-rust/nix/pull/1033))
-
-## [0.11.0] 2018-06-01
-
-### Added
-- Added `sendfile` on FreeBSD and Darwin.
- ([#901](https://github.com/nix-rust/nix/pull/901))
-- Added `pselect`
- ([#894](https://github.com/nix-rust/nix/pull/894))
-- Exposed `preadv` and `pwritev` on the BSDs.
- ([#883](https://github.com/nix-rust/nix/pull/883))
-- Added `mlockall` and `munlockall`
- ([#876](https://github.com/nix-rust/nix/pull/876))
-- Added `SO_MARK` on Linux.
- ([#873](https://github.com/nix-rust/nix/pull/873))
-- Added safe support for nearly any buffer type in the `sys::aio` module.
- ([#872](https://github.com/nix-rust/nix/pull/872))
-- Added `sys::aio::LioCb` as a wrapper for `libc::lio_listio`.
- ([#872](https://github.com/nix-rust/nix/pull/872))
-- Added `unistd::getsid`
- ([#850](https://github.com/nix-rust/nix/pull/850))
-- Added `alarm`. ([#830](https://github.com/nix-rust/nix/pull/830))
-- Added interface flags `IFF_NO_PI, IFF_TUN, IFF_TAP` on linux-like systems.
- ([#853](https://github.com/nix-rust/nix/pull/853))
-- Added `statvfs` module to all MacOS and Linux architectures.
- ([#832](https://github.com/nix-rust/nix/pull/832))
-- Added `EVFILT_EMPTY`, `EVFILT_PROCDESC`, and `EVFILT_SENDFILE` on FreeBSD.
- ([#825](https://github.com/nix-rust/nix/pull/825))
-- Exposed `termios::cfmakesane` on FreeBSD.
- ([#825](https://github.com/nix-rust/nix/pull/825))
-- Exposed `MSG_CMSG_CLOEXEC` on *BSD.
- ([#825](https://github.com/nix-rust/nix/pull/825))
-- Added `fchmod`, `fchmodat`.
- ([#857](https://github.com/nix-rust/nix/pull/857))
-- Added `request_code_write_int!` on FreeBSD/DragonFlyBSD
- ([#833](https://github.com/nix-rust/nix/pull/833))
-
-### Changed
-- `Display` and `Debug` for `SysControlAddr` now includes all fields.
- ([#837](https://github.com/nix-rust/nix/pull/837))
-- `ioctl!` has been replaced with a family of `ioctl_*!` macros.
- ([#833](https://github.com/nix-rust/nix/pull/833))
-- `io!`, `ior!`, `iow!`, and `iorw!` has been renamed to `request_code_none!`, `request_code_read!`,
- `request_code_write!`, and `request_code_readwrite!` respectively. These have also now been exposed
- in the documentation.
- ([#833](https://github.com/nix-rust/nix/pull/833))
-- Enabled more `ptrace::Request` definitions for uncommon Linux platforms
- ([#892](https://github.com/nix-rust/nix/pull/892))
-- Emulation of `FD_CLOEXEC` and `O_NONBLOCK` was removed from `socket()`, `accept4()`, and
- `socketpair()`.
- ([#907](https://github.com/nix-rust/nix/pull/907))
-
-### Fixed
-- Fixed possible panics when using `SigAction::flags` on Linux
- ([#869](https://github.com/nix-rust/nix/pull/869))
-- Properly exposed 460800 and 921600 baud rates on NetBSD
- ([#837](https://github.com/nix-rust/nix/pull/837))
-- Fixed `ioctl_write_int!` on FreeBSD/DragonFlyBSD
- ([#833](https://github.com/nix-rust/nix/pull/833))
-- `ioctl_write_int!` now properly supports passing a `c_ulong` as the parameter on Linux non-musl targets
- ([#833](https://github.com/nix-rust/nix/pull/833))
-
-### Removed
-- Removed explicit support for the `bytes` crate from the `sys::aio` module.
- See `sys::aio::AioCb::from_boxed_slice` examples for alternatives.
- ([#872](https://github.com/nix-rust/nix/pull/872))
-- Removed `sys::aio::lio_listio`. Use `sys::aio::LioCb::listio` instead.
- ([#872](https://github.com/nix-rust/nix/pull/872))
-- Removed emulated `accept4()` from macos, ios, and netbsd targets
- ([#907](https://github.com/nix-rust/nix/pull/907))
-- Removed `IFF_NOTRAILERS` on OpenBSD, as it has been removed in OpenBSD 6.3
- ([#893](https://github.com/nix-rust/nix/pull/893))
-
-## [0.10.0] 2018-01-26
-
-### Added
-- Added specialized wrapper: `sys::ptrace::step`
- ([#852](https://github.com/nix-rust/nix/pull/852))
-- Added `AioCb::from_ptr` and `AioCb::from_mut_ptr`
- ([#820](https://github.com/nix-rust/nix/pull/820))
-- Added specialized wrappers: `sys::ptrace::{traceme, syscall, cont, attach}`. Using the matching routines
- with `sys::ptrace::ptrace` is now deprecated.
-- Added `nix::poll` module for all platforms
- ([#672](https://github.com/nix-rust/nix/pull/672))
-- Added `nix::ppoll` function for FreeBSD and DragonFly
- ([#672](https://github.com/nix-rust/nix/pull/672))
-- Added protocol families in `AddressFamily` enum.
- ([#647](https://github.com/nix-rust/nix/pull/647))
-- Added the `pid()` method to `WaitStatus` for extracting the PID.
- ([#722](https://github.com/nix-rust/nix/pull/722))
-- Added `nix::unistd:fexecve`.
- ([#727](https://github.com/nix-rust/nix/pull/727))
-- Expose `uname()` on all platforms.
- ([#739](https://github.com/nix-rust/nix/pull/739))
-- Expose `signalfd` module on Android as well.
- ([#739](https://github.com/nix-rust/nix/pull/739))
-- Added `nix::sys::ptrace::detach`.
- ([#749](https://github.com/nix-rust/nix/pull/749))
-- Added timestamp socket control message variant:
- `nix::sys::socket::ControlMessage::ScmTimestamp`
- ([#663](https://github.com/nix-rust/nix/pull/663))
-- Added socket option variant that enables the timestamp socket
- control message: `nix::sys::socket::sockopt::ReceiveTimestamp`
- ([#663](https://github.com/nix-rust/nix/pull/663))
-- Added more accessor methods for `AioCb`
- ([#773](https://github.com/nix-rust/nix/pull/773))
-- Add `nix::sys::fallocate`
- ([#768](https:://github.com/nix-rust/nix/pull/768))
-- Added `nix::unistd::mkfifo`.
- ([#602](https://github.com/nix-rust/nix/pull/774))
-- Added `ptrace::Options::PTRACE_O_EXITKILL` on Linux and Android.
- ([#771](https://github.com/nix-rust/nix/pull/771))
-- Added `nix::sys::uio::{process_vm_readv, process_vm_writev}` on Linux
- ([#568](https://github.com/nix-rust/nix/pull/568))
-- Added `nix::unistd::{getgroups, setgroups, getgrouplist, initgroups}`. ([#733](https://github.com/nix-rust/nix/pull/733))
-- Added `nix::sys::socket::UnixAddr::as_abstract` on Linux and Android.
- ([#785](https://github.com/nix-rust/nix/pull/785))
-- Added `nix::unistd::execveat` on Linux and Android.
- ([#800](https://github.com/nix-rust/nix/pull/800))
-- Added the `from_raw()` method to `WaitStatus` for converting raw status values
- to `WaitStatus` independent of syscalls.
- ([#741](https://github.com/nix-rust/nix/pull/741))
-- Added more standard trait implementations for various types.
- ([#814](https://github.com/nix-rust/nix/pull/814))
-- Added `sigprocmask` to the signal module.
- ([#826](https://github.com/nix-rust/nix/pull/826))
-- Added `nix::sys::socket::LinkAddr` on Linux and all bsdlike system.
- ([#813](https://github.com/nix-rust/nix/pull/813))
-- Add socket options for `IP_TRANSPARENT` / `BIND_ANY`.
- ([#835](https://github.com/nix-rust/nix/pull/835))
-
-### Changed
-- Exposed the `mqueue` module for all supported operating systems.
- ([#834](https://github.com/nix-rust/nix/pull/834))
-- Use native `pipe2` on all BSD targets. Users should notice no difference.
- ([#777](https://github.com/nix-rust/nix/pull/777))
-- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
-- Marked `sys::ptrace::ptrace` as `unsafe`.
-- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument
- has changed type from `c_int` to `SockProtocol`.
- It accepts a `None` value for default protocol that was specified with zero using `c_int`.
- ([#647](https://github.com/nix-rust/nix/pull/647))
-- Made `select` easier to use, adding the ability to automatically calculate the `nfds` parameter using the new
- `FdSet::highest` ([#701](https://github.com/nix-rust/nix/pull/701))
-- Exposed `unistd::setresuid` and `unistd::setresgid` on FreeBSD and OpenBSD
- ([#721](https://github.com/nix-rust/nix/pull/721))
-- Refactored the `statvfs` module removing extraneous API functions and the
- `statvfs::vfs` module. Additionally `(f)statvfs()` now return the struct
- directly. And the returned `Statvfs` struct now exposes its data through
- accessor methods. ([#729](https://github.com/nix-rust/nix/pull/729))
-- The `addr` argument to `madvise` and `msync` is now `*mut` to better match the
- libc API. ([#731](https://github.com/nix-rust/nix/pull/731))
-- `shm_open` and `shm_unlink` are no longer exposed on Android targets, where
- they are not officially supported. ([#731](https://github.com/nix-rust/nix/pull/731))
-- `MapFlags`, `MmapAdvise`, and `MsFlags` expose some more variants and only
- officially-supported variants are provided for each target.
- ([#731](https://github.com/nix-rust/nix/pull/731))
-- Marked `pty::ptsname` function as `unsafe`
- ([#744](https://github.com/nix-rust/nix/pull/744))
-- Moved constants ptrace request, event and options to enums and updated ptrace functions and argument types accordingly.
- ([#749](https://github.com/nix-rust/nix/pull/749))
-- `AioCb::Drop` will now panic if the `AioCb` is still in-progress ([#715](https://github.com/nix-rust/nix/pull/715))
-- Restricted `nix::sys::socket::UnixAddr::new_abstract` to Linux and Android only.
- ([#785](https://github.com/nix-rust/nix/pull/785))
-- The `ucred` struct has been removed in favor of a `UserCredentials` struct that
- contains only getters for its fields.
- ([#814](https://github.com/nix-rust/nix/pull/814))
-- Both `ip_mreq` and `ipv6_mreq` have been replaced with `IpMembershipRequest` and
- `Ipv6MembershipRequest`.
- ([#814](https://github.com/nix-rust/nix/pull/814))
-- Removed return type from `pause`.
- ([#829](https://github.com/nix-rust/nix/pull/829))
-- Changed the termios APIs to allow for using a `u32` instead of the `BaudRate`
- enum on BSD platforms to support arbitrary baud rates. See the module docs for
- `nix::sys::termios` for more details.
- ([#843](https://github.com/nix-rust/nix/pull/843))
-
-### Fixed
-- Fix compilation and tests for OpenBSD targets
- ([#688](https://github.com/nix-rust/nix/pull/688))
-- Fixed error handling in `AioCb::fsync`, `AioCb::read`, and `AioCb::write`.
- It is no longer an error to drop an `AioCb` that failed to enqueue in the OS.
- ([#715](https://github.com/nix-rust/nix/pull/715))
-- Fix potential memory corruption on non-Linux platforms when using
- `sendmsg`/`recvmsg`, caused by mismatched `msghdr` definition.
- ([#648](https://github.com/nix-rust/nix/pull/648))
-
-### Removed
-- `AioCb::from_boxed_slice` has been removed. It was never actually safe. Use
- `from_bytes` or `from_bytes_mut` instead.
- ([#820](https://github.com/nix-rust/nix/pull/820))
-- The syscall module has been removed. This only exposed enough functionality for
- `memfd_create()` and `pivot_root()`, which are still exposed as separate functions.
- ([#747](https://github.com/nix-rust/nix/pull/747))
-- The `Errno` variants are no longer reexported from the `errno` module. `Errno` itself is no longer reexported from the
- crate root and instead must be accessed using the `errno` module. ([#696](https://github.com/nix-rust/nix/pull/696))
-- Removed `MS_VERBOSE`, `MS_NOSEC`, and `MS_BORN` from `MsFlags`. These
- are internal kernel flags and should never have been exposed.
- ([#814](https://github.com/nix-rust/nix/pull/814))
-
-
-## [0.9.0] 2017-07-23
-
-### Added
-- Added `sysconf`, `pathconf`, and `fpathconf`
- ([#630](https://github.com/nix-rust/nix/pull/630)
-- Added `sys::signal::SigAction::{ flags, mask, handler}`
- ([#611](https://github.com/nix-rust/nix/pull/609)
-- Added `nix::sys::pthread::pthread_self`
- ([#591](https://github.com/nix-rust/nix/pull/591)
-- Added `AioCb::from_boxed_slice`
- ([#582](https://github.com/nix-rust/nix/pull/582)
-- Added `nix::unistd::{openat, fstatat, readlink, readlinkat}`
- ([#551](https://github.com/nix-rust/nix/pull/551))
-- Added `nix::pty::{grantpt, posix_openpt, ptsname/ptsname_r, unlockpt}`
- ([#556](https://github.com/nix-rust/nix/pull/556)
-- Added `nix::ptr::openpty`
- ([#456](https://github.com/nix-rust/nix/pull/456))
-- Added `nix::ptrace::{ptrace_get_data, ptrace_getsiginfo, ptrace_setsiginfo
- and nix::Error::UnsupportedOperation}`
- ([#614](https://github.com/nix-rust/nix/pull/614))
-- Added `cfmakeraw`, `cfsetspeed`, and `tcgetsid`. ([#527](https://github.com/nix-rust/nix/pull/527))
-- Added "bad none", "bad write_ptr", "bad write_int", and "bad readwrite" variants to the `ioctl!`
- macro. ([#670](https://github.com/nix-rust/nix/pull/670))
-- On Linux and Android, added support for receiving `PTRACE_O_TRACESYSGOOD`
- events from `wait` and `waitpid` using `WaitStatus::PtraceSyscall`
- ([#566](https://github.com/nix-rust/nix/pull/566)).
-
-### Changed
-- The `ioctl!` macro and its variants now allow the generated functions to have
- doccomments. ([#661](https://github.com/nix-rust/nix/pull/661))
-- Changed `ioctl!(write ...)` into `ioctl!(write_ptr ...)` and `ioctl!(write_int ..)` variants
- to more clearly separate those use cases. ([#670](https://github.com/nix-rust/nix/pull/670))
-- Marked `sys::mman::{ mmap, munmap, madvise, munlock, msync }` as unsafe.
- ([#559](https://github.com/nix-rust/nix/pull/559))
-- Minimum supported Rust version is now 1.13.
-- Removed `revents` argument from `PollFd::new()` as it's an output argument and
- will be overwritten regardless of value.
- ([#542](https://github.com/nix-rust/nix/pull/542))
-- Changed type signature of `sys::select::FdSet::contains` to make `self`
- immutable ([#564](https://github.com/nix-rust/nix/pull/564))
-- Introduced wrapper types for `gid_t`, `pid_t`, and `uid_t` as `Gid`, `Pid`, and `Uid`
- respectively. Various functions have been changed to use these new types as
- arguments. ([#629](https://github.com/nix-rust/nix/pull/629))
-- Fixed compilation on all Android and iOS targets ([#527](https://github.com/nix-rust/nix/pull/527))
- and promoted them to Tier 2 support.
-- `nix::sys::statfs::{statfs,fstatfs}` uses statfs definition from `libc::statfs` instead of own linux specific type `nix::sys::Statfs`.
- Also file system type constants like `nix::sys::statfs::ADFS_SUPER_MAGIC` were removed in favor of the libc equivalent.
- ([#561](https://github.com/nix-rust/nix/pull/561))
-- Revised the termios API including additional tests and documentation and exposed it on iOS. ([#527](https://github.com/nix-rust/nix/pull/527))
-- `eventfd`, `signalfd`, and `pwritev`/`preadv` functionality is now included by default for all
- supported platforms. ([#681](https://github.com/nix-rust/nix/pull/561))
-- The `ioctl!` macro's plain variants has been replaced with "bad read" to be consistent with
- other variants. The generated functions also have more strict types for their arguments. The
- "*_buf" variants also now calculate total array size and take slice references for improved type
- safety. The documentation has also been dramatically improved.
- ([#670](https://github.com/nix-rust/nix/pull/670))
-
-### Removed
-- Removed `io::Error` from `nix::Error` and the conversion from `nix::Error` to `Errno`
- ([#614](https://github.com/nix-rust/nix/pull/614))
-- All feature flags have been removed in favor of conditional compilation on supported platforms.
- `execvpe` is no longer supported, but this was already broken and will be added back in the next
- release. ([#681](https://github.com/nix-rust/nix/pull/561))
-- Removed `ioc_*` functions and many helper constants and macros within the `ioctl` module. These
- should always have been private and only the `ioctl!` should be used in public code.
- ([#670](https://github.com/nix-rust/nix/pull/670))
-
-### Fixed
-- Fixed multiple issues compiling under different archetectures and OSes.
- Now compiles on Linux/MIPS ([#538](https://github.com/nix-rust/nix/pull/538)),
- `Linux/PPC` ([#553](https://github.com/nix-rust/nix/pull/553)),
- `MacOS/x86_64,i686` ([#553](https://github.com/nix-rust/nix/pull/553)),
- `NetBSD/x64_64` ([#538](https://github.com/nix-rust/nix/pull/538)),
- `FreeBSD/x86_64,i686` ([#536](https://github.com/nix-rust/nix/pull/536)), and
- `Android` ([#631](https://github.com/nix-rust/nix/pull/631)).
-- `bind` and `errno_location` now work correctly on `Android`
- ([#631](https://github.com/nix-rust/nix/pull/631))
-- Added `nix::ptrace` on all Linux-kernel-based platforms
- [#624](https://github.com/nix-rust/nix/pull/624). Previously it was
- only available on x86, x86-64, and ARM, and also not on Android.
-- Fixed `sys::socket::sendmsg` with zero entry `cmsgs` parameter.
- ([#623](https://github.com/nix-rust/nix/pull/623))
-- Multiple constants related to the termios API have now been properly defined for
- all supported platforms. ([#527](https://github.com/nix-rust/nix/pull/527))
-- `ioctl!` macro now supports working with non-int datatypes and properly supports all platforms.
- ([#670](https://github.com/nix-rust/nix/pull/670))
-
-## [0.8.1] 2017-04-16
-
-### Fixed
-- Fixed build on FreeBSD. (Cherry-picked
- [a859ee3c](https://github.com/nix-rust/nix/commit/a859ee3c9396dfdb118fcc2c8ecc697e2d303467))
-
-## [0.8.0] 2017-03-02
-
-### Added
-- Added `::nix::sys::termios::BaudRate` enum to provide portable baudrate
- values. ([#518](https://github.com/nix-rust/nix/pull/518))
-- Added a new `WaitStatus::PtraceEvent` to support ptrace events on Linux
- and Android ([#438](https://github.com/nix-rust/nix/pull/438))
-- Added support for POSIX AIO
- ([#483](https://github.com/nix-rust/nix/pull/483))
- ([#506](https://github.com/nix-rust/nix/pull/506))
-- Added support for XNU system control sockets
- ([#478](https://github.com/nix-rust/nix/pull/478))
-- Added support for `ioctl` calls on BSD platforms
- ([#478](https://github.com/nix-rust/nix/pull/478))
-- Added struct `TimeSpec`
- ([#475](https://github.com/nix-rust/nix/pull/475))
- ([#483](https://github.com/nix-rust/nix/pull/483))
-- Added complete definitions for all kqueue-related constants on all supported
- OSes
- ([#415](https://github.com/nix-rust/nix/pull/415))
-- Added function `epoll_create1` and bitflags `EpollCreateFlags` in
- `::nix::sys::epoll` in order to support `::libc::epoll_create1`.
- ([#410](https://github.com/nix-rust/nix/pull/410))
-- Added `setresuid` and `setresgid` for Linux in `::nix::unistd`
- ([#448](https://github.com/nix-rust/nix/pull/448))
-- Added `getpgid` in `::nix::unistd`
- ([#433](https://github.com/nix-rust/nix/pull/433))
-- Added `tcgetpgrp` and `tcsetpgrp` in `::nix::unistd`
- ([#451](https://github.com/nix-rust/nix/pull/451))
-- Added `CLONE_NEWCGROUP` in `::nix::sched`
- ([#457](https://github.com/nix-rust/nix/pull/457))
-- Added `getpgrp` in `::nix::unistd`
- ([#491](https://github.com/nix-rust/nix/pull/491))
-- Added `fchdir` in `::nix::unistd`
- ([#497](https://github.com/nix-rust/nix/pull/497))
-- Added `major` and `minor` in `::nix::sys::stat` for decomposing `dev_t`
- ([#508](https://github.com/nix-rust/nix/pull/508))
-- Fixed the style of many bitflags and use `libc` in more places.
- ([#503](https://github.com/nix-rust/nix/pull/503))
-- Added `ppoll` in `::nix::poll`
- ([#520](https://github.com/nix-rust/nix/pull/520))
-- Added support for getting and setting pipe size with fcntl(2) on Linux
- ([#540](https://github.com/nix-rust/nix/pull/540))
-
-### Changed
-- `::nix::sys::termios::{cfgetispeed, cfsetispeed, cfgetospeed, cfsetospeed}`
- switched to use `BaudRate` enum from `speed_t`.
- ([#518](https://github.com/nix-rust/nix/pull/518))
-- `epoll_ctl` now could accept None as argument `event`
- when op is `EpollOp::EpollCtlDel`.
- ([#480](https://github.com/nix-rust/nix/pull/480))
-- Removed the `bad` keyword from the `ioctl!` macro
- ([#478](https://github.com/nix-rust/nix/pull/478))
-- Changed `TimeVal` into an opaque Newtype
- ([#475](https://github.com/nix-rust/nix/pull/475))
-- `kill`'s signature, defined in `::nix::sys::signal`, changed, so that the
- signal parameter has type `T: Into<Option<Signal>>`. `None` as an argument
- for that parameter will result in a 0 passed to libc's `kill`, while a
- `Some`-argument will result in the previous behavior for the contained
- `Signal`.
- ([#445](https://github.com/nix-rust/nix/pull/445))
-- The minimum supported version of rustc is now 1.7.0.
- ([#444](https://github.com/nix-rust/nix/pull/444))
-- Changed `KEvent` to an opaque structure that may only be modified by its
- constructor and the `ev_set` method.
- ([#415](https://github.com/nix-rust/nix/pull/415))
- ([#442](https://github.com/nix-rust/nix/pull/442))
- ([#463](https://github.com/nix-rust/nix/pull/463))
-- `pipe2` now calls `libc::pipe2` where available. Previously it was emulated
- using `pipe`, which meant that setting `O_CLOEXEC` was not atomic.
- ([#427](https://github.com/nix-rust/nix/pull/427))
-- Renamed `EpollEventKind` to `EpollFlags` in `::nix::sys::epoll` in order for
- it to conform with our conventions.
- ([#410](https://github.com/nix-rust/nix/pull/410))
-- `EpollEvent` in `::nix::sys::epoll` is now an opaque proxy for
- `::libc::epoll_event`. The formerly public field `events` is now be read-only
- accessible with the new method `events()` of `EpollEvent`. Instances of
- `EpollEvent` can be constructed using the new method `new()` of EpollEvent.
- ([#410](https://github.com/nix-rust/nix/pull/410))
-- `SigFlags` in `::nix::sys::signal` has be renamed to `SigmaskHow` and its type
- has changed from `bitflags` to `enum` in order to conform to our conventions.
- ([#460](https://github.com/nix-rust/nix/pull/460))
-- `sethostname` now takes a `&str` instead of a `&[u8]` as this provides an API
- that makes more sense in normal, correct usage of the API.
-- `gethostname` previously did not expose the actual length of the hostname
- written from the underlying system call at all. This has been updated to
- return a `&CStr` within the provided buffer that is always properly
- NUL-terminated (this is not guaranteed by the call with all platforms/libc
- implementations).
-- Exposed all fcntl(2) operations at the module level, so they can be
- imported direclty instead of via `FcntlArg` enum.
- ([#541](https://github.com/nix-rust/nix/pull/541))
-
-### Fixed
-- Fixed multiple issues with Unix domain sockets on non-Linux OSes
- ([#474](https://github.com/nix-rust/nix/pull/415))
-- Fixed using kqueue with `EVFILT_USER` on FreeBSD
- ([#415](https://github.com/nix-rust/nix/pull/415))
-- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg
- functions on that same OS.
- ([#397](https://github.com/nix-rust/nix/pull/397))
-- Fixed an off-by-one bug in `UnixAddr::new_abstract` in `::nix::sys::socket`.
- ([#429](https://github.com/nix-rust/nix/pull/429))
-- Fixed clone passing a potentially unaligned stack.
- ([#490](https://github.com/nix-rust/nix/pull/490))
-- Fixed mkdev not creating a `dev_t` the same way as libc.
- ([#508](https://github.com/nix-rust/nix/pull/508))
-
-## [0.7.0] 2016-09-09
-
-### Added
-- Added `lseek` and `lseek64` in `::nix::unistd`
- ([#377](https://github.com/nix-rust/nix/pull/377))
-- Added `mkdir` and `getcwd` in `::nix::unistd`
- ([#416](https://github.com/nix-rust/nix/pull/416))
-- Added accessors `sigmask_mut` and `sigmask` to `UContext` in
- `::nix::ucontext`.
- ([#370](https://github.com/nix-rust/nix/pull/370))
-- Added `WUNTRACED` to `WaitPidFlag` in `::nix::sys::wait` for non-_linux_
- targets.
- ([#379](https://github.com/nix-rust/nix/pull/379))
-- Added new module `::nix::sys::reboot` with enumeration `RebootMode` and
- functions `reboot` and `set_cad_enabled`. Currently for _linux_ only.
- ([#386](https://github.com/nix-rust/nix/pull/386))
-- `FdSet` in `::nix::sys::select` now also implements `Clone`.
- ([#405](https://github.com/nix-rust/nix/pull/405))
-- Added `F_FULLFSYNC` to `FcntlArg` in `::nix::fcntl` for _apple_ targets.
- ([#407](https://github.com/nix-rust/nix/pull/407))
-- Added `CpuSet::unset` in `::nix::sched`.
- ([#402](https://github.com/nix-rust/nix/pull/402))
-- Added constructor method `new()` to `PollFd` in `::nix::poll`, in order to
- allow creation of objects, after removing public access to members.
- ([#399](https://github.com/nix-rust/nix/pull/399))
-- Added method `revents()` to `PollFd` in `::nix::poll`, in order to provide
- read access to formerly public member `revents`.
- ([#399](https://github.com/nix-rust/nix/pull/399))
-- Added `MSG_CMSG_CLOEXEC` to `MsgFlags` in `::nix::sys::socket` for _linux_ only.
- ([#422](https://github.com/nix-rust/nix/pull/422))
-
-### Changed
-- Replaced the reexported integer constants for signals by the enumeration
- `Signal` in `::nix::sys::signal`.
- ([#362](https://github.com/nix-rust/nix/pull/362))
-- Renamed `EventFdFlag` to `EfdFlags` in `::nix::sys::eventfd`.
- ([#383](https://github.com/nix-rust/nix/pull/383))
-- Changed the result types of `CpuSet::is_set` and `CpuSet::set` in
- `::nix::sched` to `Result<bool>` and `Result<()>`, respectively. They now
- return `EINVAL`, if an invalid argument for the `field` parameter is passed.
- ([#402](https://github.com/nix-rust/nix/pull/402))
-- `MqAttr` in `::nix::mqueue` is now an opaque proxy for `::libc::mq_attr`,
- which has the same structure as the old `MqAttr`. The field `mq_flags` of
- `::libc::mq_attr` is readable using the new method `flags()` of `MqAttr`.
- `MqAttr` also no longer implements `Debug`.
- ([#392](https://github.com/nix-rust/nix/pull/392))
-- The parameter `msq_prio` of `mq_receive` with type `u32` in `::nix::mqueue`
- was replaced by a parameter named `msg_prio` with type `&mut u32`, so that
- the message priority can be obtained by the caller.
- ([#392](https://github.com/nix-rust/nix/pull/392))
-- The type alias `MQd` in `::nix::queue` was replaced by the type alias
- `libc::mqd_t`, both of which are aliases for the same type.
- ([#392](https://github.com/nix-rust/nix/pull/392))
-
-### Removed
-- Type alias `SigNum` from `::nix::sys::signal`.
- ([#362](https://github.com/nix-rust/nix/pull/362))
-- Type alias `CpuMask` from `::nix::shed`.
- ([#402](https://github.com/nix-rust/nix/pull/402))
-- Removed public fields from `PollFd` in `::nix::poll`. (See also added method
- `revents()`.
- ([#399](https://github.com/nix-rust/nix/pull/399))
-
-### Fixed
-- Fixed the build problem for NetBSD (Note, that we currently do not support
- it, so it might already be broken again).
- ([#389](https://github.com/nix-rust/nix/pull/389))
-- Fixed the build on FreeBSD, and fixed the getsockopt, sendmsg, and recvmsg
- functions on that same OS.
- ([#397](https://github.com/nix-rust/nix/pull/397))
-
-## [0.6.0] 2016-06-10
-
-### Added
-- Added `gettid` in `::nix::unistd` for _linux_ and _android_.
- ([#293](https://github.com/nix-rust/nix/pull/293))
-- Some _mips_ support in `::nix::sched` and `::nix::sys::syscall`.
- ([#301](https://github.com/nix-rust/nix/pull/301))
-- Added `SIGNALFD_SIGINFO_SIZE` in `::nix::sys::signalfd`.
- ([#309](https://github.com/nix-rust/nix/pull/309))
-- Added new module `::nix::ucontext` with struct `UContext`. Currently for
- _linux_ only.
- ([#311](https://github.com/nix-rust/nix/pull/311))
-- Added `EPOLLEXCLUSIVE` to `EpollEventKind` in `::nix::sys::epoll`.
- ([#330](https://github.com/nix-rust/nix/pull/330))
-- Added `pause` to `::nix::unistd`.
- ([#336](https://github.com/nix-rust/nix/pull/336))
-- Added `sleep` to `::nix::unistd`.
- ([#351](https://github.com/nix-rust/nix/pull/351))
-- Added `S_IFDIR`, `S_IFLNK`, `S_IFMT` to `SFlag` in `::nix::sys::stat`.
- ([#359](https://github.com/nix-rust/nix/pull/359))
-- Added `clear` and `extend` functions to `SigSet`'s implementation in
- `::nix::sys::signal`.
- ([#347](https://github.com/nix-rust/nix/pull/347))
-- `sockaddr_storage_to_addr` in `::nix::sys::socket` now supports `sockaddr_nl`
- on _linux_ and _android_.
- ([#366](https://github.com/nix-rust/nix/pull/366))
-- Added support for `SO_ORIGINAL_DST` in `::nix::sys::socket` on _linux_.
- ([#367](https://github.com/nix-rust/nix/pull/367))
-- Added `SIGINFO` in `::nix::sys::signal` for the _macos_ target as well as
- `SIGPWR` and `SIGSTKFLT` in `::nix::sys::signal` for non-_macos_ targets.
- ([#361](https://github.com/nix-rust/nix/pull/361))
-
-### Changed
-- Changed the structure `IoVec` in `::nix::sys::uio`.
- ([#304](https://github.com/nix-rust/nix/pull/304))
-- Replaced `CREATE_NEW_FD` by `SIGNALFD_NEW` in `::nix::sys::signalfd`.
- ([#309](https://github.com/nix-rust/nix/pull/309))
-- Renamed `SaFlag` to `SaFlags` and `SigFlag` to `SigFlags` in
- `::nix::sys::signal`.
- ([#314](https://github.com/nix-rust/nix/pull/314))
-- Renamed `Fork` to `ForkResult` and changed its fields in `::nix::unistd`.
- ([#332](https://github.com/nix-rust/nix/pull/332))
-- Added the `signal` parameter to `clone`'s signature in `::nix::sched`.
- ([#344](https://github.com/nix-rust/nix/pull/344))
-- `execv`, `execve`, and `execvp` now return `Result<Void>` instead of
- `Result<()>` in `::nix::unistd`.
- ([#357](https://github.com/nix-rust/nix/pull/357))
-
-### Fixed
-- Improved the conversion from `std::net::SocketAddr` to `InetAddr` in
- `::nix::sys::socket::addr`.
- ([#335](https://github.com/nix-rust/nix/pull/335))
-
-## [0.5.0] 2016-03-01
diff --git a/vendor/nix/Cargo.toml b/vendor/nix/Cargo.toml
deleted file mode 100644
index 0afc445c2..000000000
--- a/vendor/nix/Cargo.toml
+++ /dev/null
@@ -1,185 +0,0 @@
-# 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"
-rust-version = "1.56"
-name = "nix"
-version = "0.26.2"
-authors = ["The nix-rust Project Developers"]
-include = [
- "src/**/*",
- "test/**/*",
- "LICENSE",
- "README.md",
- "CHANGELOG.md",
-]
-description = "Rust friendly bindings to *nix APIs"
-readme = "README.md"
-categories = ["os::unix-apis"]
-license = "MIT"
-repository = "https://github.com/nix-rust/nix"
-
-[package.metadata.docs.rs]
-rustdoc-args = [
- "--cfg",
- "docsrs",
-]
-targets = [
- "x86_64-unknown-linux-gnu",
- "aarch64-linux-android",
- "x86_64-apple-darwin",
- "aarch64-apple-ios",
- "x86_64-unknown-freebsd",
- "x86_64-unknown-openbsd",
- "x86_64-unknown-netbsd",
- "x86_64-unknown-dragonfly",
- "x86_64-fuchsia",
- "x86_64-unknown-redox",
- "x86_64-unknown-illumos",
-]
-
-[[test]]
-name = "test"
-path = "test/test.rs"
-
-[[test]]
-name = "test-aio-drop"
-path = "test/sys/test_aio_drop.rs"
-
-[[test]]
-name = "test-clearenv"
-path = "test/test_clearenv.rs"
-
-[[test]]
-name = "test-mount"
-path = "test/test_mount.rs"
-harness = false
-
-[[test]]
-name = "test-ptymaster-drop"
-path = "test/test_ptymaster_drop.rs"
-
-[dependencies.bitflags]
-version = "1.1"
-
-[dependencies.cfg-if]
-version = "1.0"
-
-[dependencies.libc]
-version = "0.2.137"
-features = ["extra_traits"]
-
-[dependencies.pin-utils]
-version = "0.1.0"
-optional = true
-
-[dependencies.static_assertions]
-version = "1"
-
-[dev-dependencies.assert-impl]
-version = "0.1"
-
-[dev-dependencies.lazy_static]
-version = "1.4"
-
-[dev-dependencies.parking_lot]
-version = "0.12"
-
-[dev-dependencies.rand]
-version = "0.8"
-
-[dev-dependencies.semver]
-version = "1.0.7"
-
-[dev-dependencies.tempfile]
-version = "3.3.0"
-
-[features]
-acct = []
-aio = ["pin-utils"]
-default = [
- "acct",
- "aio",
- "dir",
- "env",
- "event",
- "feature",
- "fs",
- "hostname",
- "inotify",
- "ioctl",
- "kmod",
- "mman",
- "mount",
- "mqueue",
- "net",
- "personality",
- "poll",
- "process",
- "pthread",
- "ptrace",
- "quota",
- "reboot",
- "resource",
- "sched",
- "signal",
- "socket",
- "term",
- "time",
- "ucontext",
- "uio",
- "user",
- "zerocopy",
-]
-dir = ["fs"]
-env = []
-event = []
-feature = []
-fs = []
-hostname = []
-inotify = []
-ioctl = []
-kmod = []
-mman = []
-mount = ["uio"]
-mqueue = ["fs"]
-net = ["socket"]
-personality = []
-poll = []
-process = []
-pthread = []
-ptrace = ["process"]
-quota = []
-reboot = []
-resource = []
-sched = ["process"]
-signal = ["process"]
-socket = ["memoffset"]
-term = []
-time = []
-ucontext = ["signal"]
-uio = []
-user = ["feature"]
-zerocopy = [
- "fs",
- "uio",
-]
-
-[target."cfg(any(target_os = \"android\", target_os = \"linux\"))".dev-dependencies.caps]
-version = "0.5.3"
-
-[target."cfg(not(target_os = \"redox\"))".dependencies.memoffset]
-version = "0.7"
-optional = true
-
-[target."cfg(target_os = \"freebsd\")".dev-dependencies.sysctl]
-version = "0.4"
diff --git a/vendor/nix/LICENSE b/vendor/nix/LICENSE
deleted file mode 100644
index aff9096fd..000000000
--- a/vendor/nix/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Carl Lerche + nix-rust Authors
-
-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/nix/README.md b/vendor/nix/README.md
deleted file mode 100644
index 2c42b905f..000000000
--- a/vendor/nix/README.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Rust bindings to *nix APIs
-
-[![Cirrus Build Status](https://api.cirrus-ci.com/github/nix-rust/nix.svg)](https://cirrus-ci.com/github/nix-rust/nix)
-[![crates.io](https://img.shields.io/crates/v/nix.svg)](https://crates.io/crates/nix)
-
-[Documentation (Releases)](https://docs.rs/nix/)
-
-Nix seeks to provide friendly bindings to various *nix platform APIs (Linux, Darwin,
-...). The goal is to not provide a 100% unified interface, but to unify
-what can be while still providing platform specific APIs.
-
-For many system APIs, Nix provides a safe alternative to the unsafe APIs
-exposed by the [libc crate](https://github.com/rust-lang/libc). This is done by
-wrapping the libc functionality with types/abstractions that enforce legal/safe
-usage.
-
-
-As an example of what Nix provides, examine the differences between what is
-exposed by libc and nix for the
-[gethostname](https://man7.org/linux/man-pages/man2/gethostname.2.html) system
-call:
-
-```rust,ignore
-// libc api (unsafe, requires handling return code/errno)
-pub unsafe extern fn gethostname(name: *mut c_char, len: size_t) -> c_int;
-
-// nix api (returns a nix::Result<OsString>)
-pub fn gethostname() -> Result<OsString>;
-```
-
-## Supported Platforms
-
-nix target support consists of two tiers. While nix attempts to support all
-platforms supported by [libc](https://github.com/rust-lang/libc), only some
-platforms are actively supported due to either technical or manpower
-limitations. Support for platforms is split into three tiers:
-
- * Tier 1 - Builds and tests for this target are run in CI. Failures of either
- block the inclusion of new code.
- * Tier 2 - Builds for this target are run in CI. Failures during the build
- blocks the inclusion of new code. Tests may be run, but failures
- in tests don't block the inclusion of new code.
- * Tier 3 - Builds for this target are run in CI. Failures during the build
- *do not* block the inclusion of new code. Testing may be run, but
- failures in tests don't block the inclusion of new code.
-
-The following targets are supported by `nix`:
-
-Tier 1:
- * aarch64-apple-darwin
- * aarch64-unknown-linux-gnu
- * arm-unknown-linux-gnueabi
- * armv7-unknown-linux-gnueabihf
- * i686-unknown-freebsd
- * i686-unknown-linux-gnu
- * i686-unknown-linux-musl
- * mips-unknown-linux-gnu
- * mips64-unknown-linux-gnuabi64
- * mips64el-unknown-linux-gnuabi64
- * mipsel-unknown-linux-gnu
- * powerpc64le-unknown-linux-gnu
- * x86_64-unknown-freebsd
- * x86_64-unknown-linux-gnu
- * x86_64-unknown-linux-musl
-
-Tier 2:
- * aarch64-apple-ios
- * aarch64-linux-android
- * arm-linux-androideabi
- * arm-unknown-linux-musleabi
- * armv7-linux-androideabi
- * i686-linux-android
- * powerpc-unknown-linux-gnu
- * s390x-unknown-linux-gnu
- * x86_64-apple-ios
- * x86_64-linux-android
- * x86_64-apple-darwin
- * x86_64-unknown-illumos
- * x86_64-unknown-netbsd
-
-Tier 3:
- * armv7-unknown-linux-uclibceabihf
- * x86_64-fuchsia
- * x86_64-unknown-dragonfly
- * x86_64-unknown-haiku
- * x86_64-unknown-linux-gnux32
- * x86_64-unknown-openbsd
- * x86_64-unknown-redox
-
-## Minimum Supported Rust Version (MSRV)
-
-nix is supported on Rust 1.56.1 and higher. Its MSRV will not be
-changed in the future without bumping the major or minor version.
-
-## Contributing
-
-Contributions are very welcome. Please See [CONTRIBUTING](CONTRIBUTING.md) for
-additional details.
-
-Feel free to join us in [the nix-rust/nix](https://gitter.im/nix-rust/nix) channel on Gitter to
-discuss `nix` development.
-
-## License
-
-Nix is licensed under the MIT license. See [LICENSE](LICENSE) for more details.
diff --git a/vendor/nix/src/dir.rs b/vendor/nix/src/dir.rs
deleted file mode 100644
index 5ce503644..000000000
--- a/vendor/nix/src/dir.rs
+++ /dev/null
@@ -1,276 +0,0 @@
-//! List directory contents
-
-use crate::errno::Errno;
-use crate::fcntl::{self, OFlag};
-use crate::sys;
-use crate::{Error, NixPath, Result};
-use cfg_if::cfg_if;
-use std::ffi;
-use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
-use std::ptr;
-
-#[cfg(target_os = "linux")]
-use libc::{dirent64 as dirent, readdir64_r as readdir_r};
-
-#[cfg(not(target_os = "linux"))]
-use libc::{dirent, readdir_r};
-
-/// An open directory.
-///
-/// This is a lower-level interface than `std::fs::ReadDir`. Notable differences:
-/// * can be opened from a file descriptor (as returned by `openat`, perhaps before knowing
-/// if the path represents a file or directory).
-/// * implements `AsRawFd`, so it can be passed to `fstat`, `openat`, etc.
-/// The file descriptor continues to be owned by the `Dir`, so callers must not keep a `RawFd`
-/// after the `Dir` is dropped.
-/// * can be iterated through multiple times without closing and reopening the file
-/// descriptor. Each iteration rewinds when finished.
-/// * returns entries for `.` (current directory) and `..` (parent directory).
-/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
-/// does).
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct Dir(ptr::NonNull<libc::DIR>);
-
-impl Dir {
- /// Opens the given path as with `fcntl::open`.
- pub fn open<P: ?Sized + NixPath>(
- path: &P,
- oflag: OFlag,
- mode: sys::stat::Mode,
- ) -> Result<Self> {
- let fd = fcntl::open(path, oflag, mode)?;
- Dir::from_fd(fd)
- }
-
- /// Opens the given path as with `fcntl::openat`.
- pub fn openat<P: ?Sized + NixPath>(
- dirfd: RawFd,
- path: &P,
- oflag: OFlag,
- mode: sys::stat::Mode,
- ) -> Result<Self> {
- let fd = fcntl::openat(dirfd, path, oflag, mode)?;
- Dir::from_fd(fd)
- }
-
- /// Converts from a descriptor-based object, closing the descriptor on success or failure.
- #[inline]
- pub fn from<F: IntoRawFd>(fd: F) -> Result<Self> {
- Dir::from_fd(fd.into_raw_fd())
- }
-
- /// Converts from a file descriptor, closing it on success or failure.
- #[doc(alias("fdopendir"))]
- pub fn from_fd(fd: RawFd) -> Result<Self> {
- let d = ptr::NonNull::new(unsafe { libc::fdopendir(fd) }).ok_or_else(
- || {
- let e = Error::last();
- unsafe { libc::close(fd) };
- e
- },
- )?;
- Ok(Dir(d))
- }
-
- /// Returns an iterator of `Result<Entry>` which rewinds when finished.
- pub fn iter(&mut self) -> Iter {
- Iter(self)
- }
-}
-
-// `Dir` is not `Sync`. With the current implementation, it could be, but according to
-// https://www.gnu.org/software/libc/manual/html_node/Reading_002fClosing-Directory.html,
-// future versions of POSIX are likely to obsolete `readdir_r` and specify that it's unsafe to
-// call `readdir` simultaneously from multiple threads.
-//
-// `Dir` is safe to pass from one thread to another, as it's not reference-counted.
-unsafe impl Send for Dir {}
-
-impl AsRawFd for Dir {
- fn as_raw_fd(&self) -> RawFd {
- unsafe { libc::dirfd(self.0.as_ptr()) }
- }
-}
-
-impl Drop for Dir {
- fn drop(&mut self) {
- let e = Errno::result(unsafe { libc::closedir(self.0.as_ptr()) });
- if !std::thread::panicking() && e == Err(Errno::EBADF) {
- panic!("Closing an invalid file descriptor!");
- };
- }
-}
-
-fn next(dir: &mut Dir) -> Option<Result<Entry>> {
- unsafe {
- // Note: POSIX specifies that portable applications should dynamically allocate a
- // buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
- // for the NUL byte. It doesn't look like the std library does this; it just uses
- // fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
- // Probably fine here too then.
- let mut ent = std::mem::MaybeUninit::<dirent>::uninit();
- let mut result = ptr::null_mut();
- if let Err(e) = Errno::result(readdir_r(
- dir.0.as_ptr(),
- ent.as_mut_ptr(),
- &mut result,
- )) {
- return Some(Err(e));
- }
- if result.is_null() {
- return None;
- }
- assert_eq!(result, ent.as_mut_ptr());
- Some(Ok(Entry(ent.assume_init())))
- }
-}
-
-/// Return type of [`Dir::iter`].
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct Iter<'d>(&'d mut Dir);
-
-impl<'d> Iterator for Iter<'d> {
- type Item = Result<Entry>;
-
- fn next(&mut self) -> Option<Self::Item> {
- next(self.0)
- }
-}
-
-impl<'d> Drop for Iter<'d> {
- fn drop(&mut self) {
- unsafe { libc::rewinddir((self.0).0.as_ptr()) }
- }
-}
-
-/// The return type of [Dir::into_iter]
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct OwningIter(Dir);
-
-impl Iterator for OwningIter {
- type Item = Result<Entry>;
-
- fn next(&mut self) -> Option<Self::Item> {
- next(&mut self.0)
- }
-}
-
-/// The file descriptor continues to be owned by the `OwningIter`,
-/// so callers must not keep a `RawFd` after the `OwningIter` is dropped.
-impl AsRawFd for OwningIter {
- fn as_raw_fd(&self) -> RawFd {
- self.0.as_raw_fd()
- }
-}
-
-impl IntoIterator for Dir {
- type Item = Result<Entry>;
- type IntoIter = OwningIter;
-
- /// Creates a owning iterator, that is, one that takes ownership of the
- /// `Dir`. The `Dir` cannot be used after calling this. This can be useful
- /// when you have a function that both creates a `Dir` instance and returns
- /// an `Iterator`.
- ///
- /// Example:
- ///
- /// ```
- /// use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode};
- /// use std::{iter::Iterator, string::String};
- ///
- /// fn ls_upper(dirname: &str) -> impl Iterator<Item=String> {
- /// let d = Dir::open(dirname, OFlag::O_DIRECTORY, Mode::S_IXUSR).unwrap();
- /// d.into_iter().map(|x| x.unwrap().file_name().as_ref().to_string_lossy().to_ascii_uppercase())
- /// }
- /// ```
- fn into_iter(self) -> Self::IntoIter {
- OwningIter(self)
- }
-}
-
-/// A directory entry, similar to `std::fs::DirEntry`.
-///
-/// Note that unlike the std version, this may represent the `.` or `..` entries.
-#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
-#[repr(transparent)]
-pub struct Entry(dirent);
-
-/// Type of file referenced by a directory entry
-#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
-pub enum Type {
- /// FIFO (Named pipe)
- Fifo,
- /// Character device
- CharacterDevice,
- /// Directory
- Directory,
- /// Block device
- BlockDevice,
- /// Regular file
- File,
- /// Symbolic link
- Symlink,
- /// Unix-domain socket
- Socket,
-}
-
-impl Entry {
- /// Returns the inode number (`d_ino`) of the underlying `dirent`.
- #[allow(clippy::useless_conversion)] // Not useless on all OSes
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- pub fn ino(&self) -> u64 {
- cfg_if! {
- if #[cfg(any(target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "ios",
- target_os = "l4re",
- target_os = "linux",
- target_os = "macos",
- target_os = "solaris"))] {
- self.0.d_ino as u64
- } else {
- u64::from(self.0.d_fileno)
- }
- }
- }
-
- /// Returns the bare file name of this directory entry without any other leading path component.
- pub fn file_name(&self) -> &ffi::CStr {
- unsafe { ::std::ffi::CStr::from_ptr(self.0.d_name.as_ptr()) }
- }
-
- /// Returns the type of this directory entry, if known.
- ///
- /// See platform `readdir(3)` or `dirent(5)` manpage for when the file type is known;
- /// notably, some Linux filesystems don't implement this. The caller should use `stat` or
- /// `fstat` if this returns `None`.
- pub fn file_type(&self) -> Option<Type> {
- #[cfg(not(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
- )))]
- match self.0.d_type {
- libc::DT_FIFO => Some(Type::Fifo),
- libc::DT_CHR => Some(Type::CharacterDevice),
- libc::DT_DIR => Some(Type::Directory),
- libc::DT_BLK => Some(Type::BlockDevice),
- libc::DT_REG => Some(Type::File),
- libc::DT_LNK => Some(Type::Symlink),
- libc::DT_SOCK => Some(Type::Socket),
- /* libc::DT_UNKNOWN | */ _ => None,
- }
-
- // illumos, Solaris, and Haiku systems do not have the d_type member at all:
- #[cfg(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
- ))]
- None
- }
-}
diff --git a/vendor/nix/src/env.rs b/vendor/nix/src/env.rs
deleted file mode 100644
index 95177a1d2..000000000
--- a/vendor/nix/src/env.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-//! Environment variables
-use cfg_if::cfg_if;
-use std::fmt;
-
-/// Indicates that [`clearenv`] failed for some unknown reason
-#[derive(Clone, Copy, Debug)]
-pub struct ClearEnvError;
-
-impl fmt::Display for ClearEnvError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "clearenv failed")
- }
-}
-
-impl std::error::Error for ClearEnvError {}
-
-/// Clear the environment of all name-value pairs.
-///
-/// On platforms where libc provides `clearenv()`, it will be used. libc's
-/// `clearenv()` is documented to return an error code but not set errno; if the
-/// return value indicates a failure, this function will return
-/// [`ClearEnvError`].
-///
-/// On platforms where libc does not provide `clearenv()`, a fallback
-/// implementation will be used that iterates over all environment variables and
-/// removes them one-by-one.
-///
-/// # Safety
-///
-/// This function is not threadsafe and can cause undefined behavior in
-/// combination with `std::env` or other program components that access the
-/// environment. See, for example, the discussion on `std::env::remove_var`; this
-/// function is a case of an "inherently unsafe non-threadsafe API" dealing with
-/// the environment.
-///
-/// The caller must ensure no other threads access the process environment while
-/// this function executes and that no raw pointers to an element of libc's
-/// `environ` is currently held. The latter is not an issue if the only other
-/// environment access in the program is via `std::env`, but the requirement on
-/// thread safety must still be upheld.
-pub unsafe fn clearenv() -> std::result::Result<(), ClearEnvError> {
- cfg_if! {
- if #[cfg(any(target_os = "fuchsia",
- target_os = "wasi",
- target_env = "uclibc",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten"))] {
- let ret = libc::clearenv();
- } else {
- use std::env;
- for (name, _) in env::vars_os() {
- env::remove_var(name);
- }
- let ret = 0;
- }
- }
-
- if ret == 0 {
- Ok(())
- } else {
- Err(ClearEnvError)
- }
-}
diff --git a/vendor/nix/src/errno.rs b/vendor/nix/src/errno.rs
deleted file mode 100644
index d8ad28de8..000000000
--- a/vendor/nix/src/errno.rs
+++ /dev/null
@@ -1,3133 +0,0 @@
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{c_int, c_void};
-use std::convert::TryFrom;
-use std::{error, fmt, io};
-
-pub use self::consts::*;
-
-cfg_if! {
- if #[cfg(any(target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))] {
- unsafe fn errno_location() -> *mut c_int {
- libc::__error()
- }
- } else if #[cfg(any(target_os = "android",
- target_os = "netbsd",
- target_os = "openbsd"))] {
- unsafe fn errno_location() -> *mut c_int {
- libc::__errno()
- }
- } else if #[cfg(any(target_os = "linux",
- target_os = "redox",
- target_os = "dragonfly",
- target_os = "fuchsia"))] {
- unsafe fn errno_location() -> *mut c_int {
- libc::__errno_location()
- }
- } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
- unsafe fn errno_location() -> *mut c_int {
- libc::___errno()
- }
- } else if #[cfg(any(target_os = "haiku",))] {
- unsafe fn errno_location() -> *mut c_int {
- libc::_errnop()
- }
- }
-}
-
-/// Sets the platform-specific errno to no-error
-fn clear() {
- // Safe because errno is a thread-local variable
- unsafe {
- *errno_location() = 0;
- }
-}
-
-/// Returns the platform-specific value of errno
-pub fn errno() -> i32 {
- unsafe { *errno_location() }
-}
-
-impl Errno {
- pub fn last() -> Self {
- last()
- }
-
- pub fn desc(self) -> &'static str {
- desc(self)
- }
-
- pub const fn from_i32(err: i32) -> Errno {
- from_i32(err)
- }
-
- pub fn clear() {
- clear()
- }
-
- /// Returns `Ok(value)` if it does not contain the sentinel value. This
- /// should not be used when `-1` is not the errno sentinel value.
- #[inline]
- pub fn result<S: ErrnoSentinel + PartialEq<S>>(value: S) -> Result<S> {
- if value == S::sentinel() {
- Err(Self::last())
- } else {
- Ok(value)
- }
- }
-}
-
-/// The sentinel value indicates that a function failed and more detailed
-/// information about the error can be found in `errno`
-pub trait ErrnoSentinel: Sized {
- fn sentinel() -> Self;
-}
-
-impl ErrnoSentinel for isize {
- fn sentinel() -> Self {
- -1
- }
-}
-
-impl ErrnoSentinel for i32 {
- fn sentinel() -> Self {
- -1
- }
-}
-
-impl ErrnoSentinel for i64 {
- fn sentinel() -> Self {
- -1
- }
-}
-
-impl ErrnoSentinel for *mut c_void {
- fn sentinel() -> Self {
- -1isize as *mut c_void
- }
-}
-
-impl ErrnoSentinel for libc::sighandler_t {
- fn sentinel() -> Self {
- libc::SIG_ERR
- }
-}
-
-impl error::Error for Errno {}
-
-impl fmt::Display for Errno {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}: {}", self, self.desc())
- }
-}
-
-impl From<Errno> for io::Error {
- fn from(err: Errno) -> Self {
- io::Error::from_raw_os_error(err as i32)
- }
-}
-
-impl TryFrom<io::Error> for Errno {
- type Error = io::Error;
-
- fn try_from(ioerror: io::Error) -> std::result::Result<Self, io::Error> {
- ioerror.raw_os_error().map(Errno::from_i32).ok_or(ioerror)
- }
-}
-
-fn last() -> Errno {
- Errno::from_i32(errno())
-}
-
-fn desc(errno: Errno) -> &'static str {
- use self::Errno::*;
- match errno {
- UnknownErrno => "Unknown errno",
- EPERM => "Operation not permitted",
- ENOENT => "No such file or directory",
- ESRCH => "No such process",
- EINTR => "Interrupted system call",
- EIO => "I/O error",
- ENXIO => "No such device or address",
- E2BIG => "Argument list too long",
- ENOEXEC => "Exec format error",
- EBADF => "Bad file number",
- ECHILD => "No child processes",
- EAGAIN => "Try again",
- ENOMEM => "Out of memory",
- EACCES => "Permission denied",
- EFAULT => "Bad address",
- #[cfg(not(target_os = "haiku"))]
- ENOTBLK => "Block device required",
- EBUSY => "Device or resource busy",
- EEXIST => "File exists",
- EXDEV => "Cross-device link",
- ENODEV => "No such device",
- ENOTDIR => "Not a directory",
- EISDIR => "Is a directory",
- EINVAL => "Invalid argument",
- ENFILE => "File table overflow",
- EMFILE => "Too many open files",
- ENOTTY => "Not a typewriter",
- ETXTBSY => "Text file busy",
- EFBIG => "File too large",
- ENOSPC => "No space left on device",
- ESPIPE => "Illegal seek",
- EROFS => "Read-only file system",
- EMLINK => "Too many links",
- EPIPE => "Broken pipe",
- EDOM => "Math argument out of domain of func",
- ERANGE => "Math result not representable",
- EDEADLK => "Resource deadlock would occur",
- ENAMETOOLONG => "File name too long",
- ENOLCK => "No record locks available",
- ENOSYS => "Function not implemented",
- ENOTEMPTY => "Directory not empty",
- ELOOP => "Too many symbolic links encountered",
- ENOMSG => "No message of desired type",
- EIDRM => "Identifier removed",
- EINPROGRESS => "Operation now in progress",
- EALREADY => "Operation already in progress",
- ENOTSOCK => "Socket operation on non-socket",
- EDESTADDRREQ => "Destination address required",
- EMSGSIZE => "Message too long",
- EPROTOTYPE => "Protocol wrong type for socket",
- ENOPROTOOPT => "Protocol not available",
- EPROTONOSUPPORT => "Protocol not supported",
- #[cfg(not(target_os = "haiku"))]
- ESOCKTNOSUPPORT => "Socket type not supported",
- #[cfg(not(target_os = "haiku"))]
- EPFNOSUPPORT => "Protocol family not supported",
- #[cfg(not(target_os = "haiku"))]
- EAFNOSUPPORT => "Address family not supported by protocol",
- EADDRINUSE => "Address already in use",
- EADDRNOTAVAIL => "Cannot assign requested address",
- ENETDOWN => "Network is down",
- ENETUNREACH => "Network is unreachable",
- ENETRESET => "Network dropped connection because of reset",
- ECONNABORTED => "Software caused connection abort",
- ECONNRESET => "Connection reset by peer",
- ENOBUFS => "No buffer space available",
- EISCONN => "Transport endpoint is already connected",
- ENOTCONN => "Transport endpoint is not connected",
- ESHUTDOWN => "Cannot send after transport endpoint shutdown",
- #[cfg(not(target_os = "haiku"))]
- ETOOMANYREFS => "Too many references: cannot splice",
- ETIMEDOUT => "Connection timed out",
- ECONNREFUSED => "Connection refused",
- EHOSTDOWN => "Host is down",
- EHOSTUNREACH => "No route to host",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ECHRNG => "Channel number out of range",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EL2NSYNC => "Level 2 not synchronized",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EL3HLT => "Level 3 halted",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EL3RST => "Level 3 reset",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ELNRNG => "Link number out of range",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EUNATCH => "Protocol driver not attached",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOCSI => "No CSI structure available",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EL2HLT => "Level 2 halted",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EBADE => "Invalid exchange",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EBADR => "Invalid request descriptor",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EXFULL => "Exchange full",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOANO => "No anode",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EBADRQC => "Invalid request code",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EBADSLT => "Invalid slot",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EBFONT => "Bad font file format",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOSTR => "Device not a stream",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENODATA => "No data available",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ETIME => "Timer expired",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOSR => "Out of streams resources",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENONET => "Machine is not on the network",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOPKG => "Package not installed",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EREMOTE => "Object is remote",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOLINK => "Link has been severed",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EADV => "Advertise error",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ESRMNT => "Srmount error",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ECOMM => "Communication error on send",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EPROTO => "Protocol error",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EMULTIHOP => "Multihop attempted",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EDOTDOT => "RFS specific error",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EBADMSG => "Not a data message",
-
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- EBADMSG => "Trying to read unreadable message",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku"
- ))]
- EOVERFLOW => "Value too large for defined data type",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ENOTUNIQ => "Name not unique on network",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EBADFD => "File descriptor in bad state",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EREMCHG => "Remote address changed",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ELIBACC => "Can not access a needed shared library",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ELIBBAD => "Accessing a corrupted shared library",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ELIBSCN => ".lib section in a.out corrupted",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ELIBMAX => "Attempting to link in too many shared libraries",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ELIBEXEC => "Cannot exec a shared library directly",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia",
- target_os = "openbsd"
- ))]
- EILSEQ => "Illegal byte sequence",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ERESTART => "Interrupted system call should be restarted",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- ESTRPIPE => "Streams pipe error",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia"
- ))]
- EUSERS => "Too many users",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- EOPNOTSUPP => "Operation not supported on transport endpoint",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- ESTALE => "Stale file handle",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EUCLEAN => "Structure needs cleaning",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- ENOTNAM => "Not a XENIX named type file",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- ENAVAIL => "No XENIX semaphores available",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EISNAM => "Is a named type file",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EREMOTEIO => "Remote I/O error",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EDQUOT => "Quota exceeded",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "openbsd",
- target_os = "dragonfly"
- ))]
- ENOMEDIUM => "No medium found",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "openbsd"
- ))]
- EMEDIUMTYPE => "Wrong medium type",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "fuchsia",
- target_os = "haiku"
- ))]
- ECANCELED => "Operation canceled",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- ENOKEY => "Required key not available",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EKEYEXPIRED => "Key has expired",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EKEYREVOKED => "Key has been revoked",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EKEYREJECTED => "Key was rejected by service",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- EOWNERDEAD => "Owner died",
-
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- EOWNERDEAD => "Process died with lock",
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia"
- ))]
- ENOTRECOVERABLE => "State not recoverable",
-
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- ENOTRECOVERABLE => "Lock is not recoverable",
-
- #[cfg(any(
- all(target_os = "linux", not(target_arch = "mips")),
- target_os = "fuchsia"
- ))]
- ERFKILL => "Operation not possible due to RF-kill",
-
- #[cfg(any(
- all(target_os = "linux", not(target_arch = "mips")),
- target_os = "fuchsia"
- ))]
- EHWPOISON => "Memory page has hardware error",
-
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- EDOOFUS => "Programming error",
-
- #[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "redox"
- ))]
- EMULTIHOP => "Multihop attempted",
-
- #[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "redox"
- ))]
- ENOLINK => "Link has been severed",
-
- #[cfg(target_os = "freebsd")]
- ENOTCAPABLE => "Capabilities insufficient",
-
- #[cfg(target_os = "freebsd")]
- ECAPMODE => "Not permitted in capability mode",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- ENEEDAUTH => "Need authenticator",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox",
- target_os = "illumos",
- target_os = "solaris"
- ))]
- EOVERFLOW => "Value too large to be stored in data type",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "redox",
- target_os = "haiku"
- ))]
- EILSEQ => "Illegal byte sequence",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "haiku"
- ))]
- ENOATTR => "Attribute not found",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox",
- target_os = "haiku"
- ))]
- EBADMSG => "Bad message",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox",
- target_os = "haiku"
- ))]
- EPROTO => "Protocol error",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd"
- ))]
- ENOTRECOVERABLE => "State not recoverable",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd"
- ))]
- EOWNERDEAD => "Previous owner died",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
- ))]
- ENOTSUP => "Operation not supported",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EPROCLIM => "Too many processes",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- EUSERS => "Too many users",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
- ))]
- EDQUOT => "Disc quota exceeded",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox",
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
- ))]
- ESTALE => "Stale NFS file handle",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- EREMOTE => "Too many levels of remote in path",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EBADRPC => "RPC struct is bad",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- ERPCMISMATCH => "RPC version wrong",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EPROGUNAVAIL => "RPC prog. not avail",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EPROGMISMATCH => "Program version wrong",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EPROCUNAVAIL => "Bad procedure for program",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EFTYPE => "Inappropriate file type or format",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd"
- ))]
- EAUTH => "Authentication error",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- ECANCELED => "Operation canceled",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EPWROFF => "Device power is off",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EDEVERR => "Device error, e.g. paper out",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADEXEC => "Bad executable",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADARCH => "Bad CPU type in executable",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ESHLIBVERS => "Shared library version mismatch",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EBADMACHO => "Malformed Macho file",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "haiku"
- ))]
- EMULTIHOP => "Reserved",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- ENODATA => "No message available on STREAM",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "haiku"
- ))]
- ENOLINK => "Reserved",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- ENOSR => "No STREAM resources",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- ENOSTR => "Not a STREAM",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "netbsd",
- target_os = "redox"
- ))]
- ETIME => "STREAM ioctl timeout",
-
- #[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "illumos",
- target_os = "solaris"
- ))]
- EOPNOTSUPP => "Operation not supported on socket",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- ENOPOLICY => "No such policy registered",
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EQFULL => "Interface output queue is full",
-
- #[cfg(target_os = "openbsd")]
- EOPNOTSUPP => "Operation not supported",
-
- #[cfg(target_os = "openbsd")]
- EIPSEC => "IPsec processing failure",
-
- #[cfg(target_os = "dragonfly")]
- EASYNC => "Async",
-
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- EDEADLOCK => "Resource deadlock would occur",
-
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- ELOCKUNMAPPED => "Locked lock was unmapped",
-
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- ENOTACTIVE => "Facility is not active",
- }
-}
-
-#[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EAGAIN = libc::EAGAIN,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EDEADLK = libc::EDEADLK,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- ENOTEMPTY = libc::ENOTEMPTY,
- ELOOP = libc::ELOOP,
- ENOMSG = libc::ENOMSG,
- EIDRM = libc::EIDRM,
- ECHRNG = libc::ECHRNG,
- EL2NSYNC = libc::EL2NSYNC,
- EL3HLT = libc::EL3HLT,
- EL3RST = libc::EL3RST,
- ELNRNG = libc::ELNRNG,
- EUNATCH = libc::EUNATCH,
- ENOCSI = libc::ENOCSI,
- EL2HLT = libc::EL2HLT,
- EBADE = libc::EBADE,
- EBADR = libc::EBADR,
- EXFULL = libc::EXFULL,
- ENOANO = libc::ENOANO,
- EBADRQC = libc::EBADRQC,
- EBADSLT = libc::EBADSLT,
- EBFONT = libc::EBFONT,
- ENOSTR = libc::ENOSTR,
- ENODATA = libc::ENODATA,
- ETIME = libc::ETIME,
- ENOSR = libc::ENOSR,
- ENONET = libc::ENONET,
- ENOPKG = libc::ENOPKG,
- EREMOTE = libc::EREMOTE,
- ENOLINK = libc::ENOLINK,
- EADV = libc::EADV,
- ESRMNT = libc::ESRMNT,
- ECOMM = libc::ECOMM,
- EPROTO = libc::EPROTO,
- EMULTIHOP = libc::EMULTIHOP,
- EDOTDOT = libc::EDOTDOT,
- EBADMSG = libc::EBADMSG,
- EOVERFLOW = libc::EOVERFLOW,
- ENOTUNIQ = libc::ENOTUNIQ,
- EBADFD = libc::EBADFD,
- EREMCHG = libc::EREMCHG,
- ELIBACC = libc::ELIBACC,
- ELIBBAD = libc::ELIBBAD,
- ELIBSCN = libc::ELIBSCN,
- ELIBMAX = libc::ELIBMAX,
- ELIBEXEC = libc::ELIBEXEC,
- EILSEQ = libc::EILSEQ,
- ERESTART = libc::ERESTART,
- ESTRPIPE = libc::ESTRPIPE,
- EUSERS = libc::EUSERS,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- EOPNOTSUPP = libc::EOPNOTSUPP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- EALREADY = libc::EALREADY,
- EINPROGRESS = libc::EINPROGRESS,
- ESTALE = libc::ESTALE,
- EUCLEAN = libc::EUCLEAN,
- ENOTNAM = libc::ENOTNAM,
- ENAVAIL = libc::ENAVAIL,
- EISNAM = libc::EISNAM,
- EREMOTEIO = libc::EREMOTEIO,
- EDQUOT = libc::EDQUOT,
- ENOMEDIUM = libc::ENOMEDIUM,
- EMEDIUMTYPE = libc::EMEDIUMTYPE,
- ECANCELED = libc::ECANCELED,
- ENOKEY = libc::ENOKEY,
- EKEYEXPIRED = libc::EKEYEXPIRED,
- EKEYREVOKED = libc::EKEYREVOKED,
- EKEYREJECTED = libc::EKEYREJECTED,
- EOWNERDEAD = libc::EOWNERDEAD,
- ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
- #[cfg(not(any(target_os = "android", target_arch = "mips")))]
- ERFKILL = libc::ERFKILL,
- #[cfg(not(any(target_os = "android", target_arch = "mips")))]
- EHWPOISON = libc::EHWPOISON,
- }
-
- impl Errno {
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- pub const EDEADLOCK: Errno = Errno::EDEADLK;
- pub const ENOTSUP: Errno = Errno::EOPNOTSUPP;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EAGAIN => EAGAIN,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EDEADLK => EDEADLK,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::ELOOP => ELOOP,
- libc::ENOMSG => ENOMSG,
- libc::EIDRM => EIDRM,
- libc::ECHRNG => ECHRNG,
- libc::EL2NSYNC => EL2NSYNC,
- libc::EL3HLT => EL3HLT,
- libc::EL3RST => EL3RST,
- libc::ELNRNG => ELNRNG,
- libc::EUNATCH => EUNATCH,
- libc::ENOCSI => ENOCSI,
- libc::EL2HLT => EL2HLT,
- libc::EBADE => EBADE,
- libc::EBADR => EBADR,
- libc::EXFULL => EXFULL,
- libc::ENOANO => ENOANO,
- libc::EBADRQC => EBADRQC,
- libc::EBADSLT => EBADSLT,
- libc::EBFONT => EBFONT,
- libc::ENOSTR => ENOSTR,
- libc::ENODATA => ENODATA,
- libc::ETIME => ETIME,
- libc::ENOSR => ENOSR,
- libc::ENONET => ENONET,
- libc::ENOPKG => ENOPKG,
- libc::EREMOTE => EREMOTE,
- libc::ENOLINK => ENOLINK,
- libc::EADV => EADV,
- libc::ESRMNT => ESRMNT,
- libc::ECOMM => ECOMM,
- libc::EPROTO => EPROTO,
- libc::EMULTIHOP => EMULTIHOP,
- libc::EDOTDOT => EDOTDOT,
- libc::EBADMSG => EBADMSG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::ENOTUNIQ => ENOTUNIQ,
- libc::EBADFD => EBADFD,
- libc::EREMCHG => EREMCHG,
- libc::ELIBACC => ELIBACC,
- libc::ELIBBAD => ELIBBAD,
- libc::ELIBSCN => ELIBSCN,
- libc::ELIBMAX => ELIBMAX,
- libc::ELIBEXEC => ELIBEXEC,
- libc::EILSEQ => EILSEQ,
- libc::ERESTART => ERESTART,
- libc::ESTRPIPE => ESTRPIPE,
- libc::EUSERS => EUSERS,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::EOPNOTSUPP => EOPNOTSUPP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::EALREADY => EALREADY,
- libc::EINPROGRESS => EINPROGRESS,
- libc::ESTALE => ESTALE,
- libc::EUCLEAN => EUCLEAN,
- libc::ENOTNAM => ENOTNAM,
- libc::ENAVAIL => ENAVAIL,
- libc::EISNAM => EISNAM,
- libc::EREMOTEIO => EREMOTEIO,
- libc::EDQUOT => EDQUOT,
- libc::ENOMEDIUM => ENOMEDIUM,
- libc::EMEDIUMTYPE => EMEDIUMTYPE,
- libc::ECANCELED => ECANCELED,
- libc::ENOKEY => ENOKEY,
- libc::EKEYEXPIRED => EKEYEXPIRED,
- libc::EKEYREVOKED => EKEYREVOKED,
- libc::EKEYREJECTED => EKEYREJECTED,
- libc::EOWNERDEAD => EOWNERDEAD,
- libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
- #[cfg(not(any(target_os = "android", target_arch = "mips")))]
- libc::ERFKILL => ERFKILL,
- #[cfg(not(any(target_os = "android", target_arch = "mips")))]
- libc::EHWPOISON => EHWPOISON,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- ENOTSUP = libc::ENOTSUP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EPROCLIM = libc::EPROCLIM,
- EUSERS = libc::EUSERS,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- EREMOTE = libc::EREMOTE,
- EBADRPC = libc::EBADRPC,
- ERPCMISMATCH = libc::ERPCMISMATCH,
- EPROGUNAVAIL = libc::EPROGUNAVAIL,
- EPROGMISMATCH = libc::EPROGMISMATCH,
- EPROCUNAVAIL = libc::EPROCUNAVAIL,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EFTYPE = libc::EFTYPE,
- EAUTH = libc::EAUTH,
- ENEEDAUTH = libc::ENEEDAUTH,
- EPWROFF = libc::EPWROFF,
- EDEVERR = libc::EDEVERR,
- EOVERFLOW = libc::EOVERFLOW,
- EBADEXEC = libc::EBADEXEC,
- EBADARCH = libc::EBADARCH,
- ESHLIBVERS = libc::ESHLIBVERS,
- EBADMACHO = libc::EBADMACHO,
- ECANCELED = libc::ECANCELED,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- EILSEQ = libc::EILSEQ,
- ENOATTR = libc::ENOATTR,
- EBADMSG = libc::EBADMSG,
- EMULTIHOP = libc::EMULTIHOP,
- ENODATA = libc::ENODATA,
- ENOLINK = libc::ENOLINK,
- ENOSR = libc::ENOSR,
- ENOSTR = libc::ENOSTR,
- EPROTO = libc::EPROTO,
- ETIME = libc::ETIME,
- EOPNOTSUPP = libc::EOPNOTSUPP,
- ENOPOLICY = libc::ENOPOLICY,
- ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
- EOWNERDEAD = libc::EOWNERDEAD,
- EQFULL = libc::EQFULL,
- }
-
- impl Errno {
- pub const ELAST: Errno = Errno::EQFULL;
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- pub const EDEADLOCK: Errno = Errno::EDEADLK;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::ENOTSUP => ENOTSUP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EPROCLIM => EPROCLIM,
- libc::EUSERS => EUSERS,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::EREMOTE => EREMOTE,
- libc::EBADRPC => EBADRPC,
- libc::ERPCMISMATCH => ERPCMISMATCH,
- libc::EPROGUNAVAIL => EPROGUNAVAIL,
- libc::EPROGMISMATCH => EPROGMISMATCH,
- libc::EPROCUNAVAIL => EPROCUNAVAIL,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EFTYPE => EFTYPE,
- libc::EAUTH => EAUTH,
- libc::ENEEDAUTH => ENEEDAUTH,
- libc::EPWROFF => EPWROFF,
- libc::EDEVERR => EDEVERR,
- libc::EOVERFLOW => EOVERFLOW,
- libc::EBADEXEC => EBADEXEC,
- libc::EBADARCH => EBADARCH,
- libc::ESHLIBVERS => ESHLIBVERS,
- libc::EBADMACHO => EBADMACHO,
- libc::ECANCELED => ECANCELED,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::EILSEQ => EILSEQ,
- libc::ENOATTR => ENOATTR,
- libc::EBADMSG => EBADMSG,
- libc::EMULTIHOP => EMULTIHOP,
- libc::ENODATA => ENODATA,
- libc::ENOLINK => ENOLINK,
- libc::ENOSR => ENOSR,
- libc::ENOSTR => ENOSTR,
- libc::EPROTO => EPROTO,
- libc::ETIME => ETIME,
- libc::EOPNOTSUPP => EOPNOTSUPP,
- libc::ENOPOLICY => ENOPOLICY,
- libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
- libc::EOWNERDEAD => EOWNERDEAD,
- libc::EQFULL => EQFULL,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(target_os = "freebsd")]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- ENOTSUP = libc::ENOTSUP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EPROCLIM = libc::EPROCLIM,
- EUSERS = libc::EUSERS,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- EREMOTE = libc::EREMOTE,
- EBADRPC = libc::EBADRPC,
- ERPCMISMATCH = libc::ERPCMISMATCH,
- EPROGUNAVAIL = libc::EPROGUNAVAIL,
- EPROGMISMATCH = libc::EPROGMISMATCH,
- EPROCUNAVAIL = libc::EPROCUNAVAIL,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EFTYPE = libc::EFTYPE,
- EAUTH = libc::EAUTH,
- ENEEDAUTH = libc::ENEEDAUTH,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- EOVERFLOW = libc::EOVERFLOW,
- ECANCELED = libc::ECANCELED,
- EILSEQ = libc::EILSEQ,
- ENOATTR = libc::ENOATTR,
- EDOOFUS = libc::EDOOFUS,
- EBADMSG = libc::EBADMSG,
- EMULTIHOP = libc::EMULTIHOP,
- ENOLINK = libc::ENOLINK,
- EPROTO = libc::EPROTO,
- ENOTCAPABLE = libc::ENOTCAPABLE,
- ECAPMODE = libc::ECAPMODE,
- ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
- EOWNERDEAD = libc::EOWNERDEAD,
- }
-
- impl Errno {
- pub const ELAST: Errno = Errno::EOWNERDEAD;
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- pub const EDEADLOCK: Errno = Errno::EDEADLK;
- pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::ENOTSUP => ENOTSUP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EPROCLIM => EPROCLIM,
- libc::EUSERS => EUSERS,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::EREMOTE => EREMOTE,
- libc::EBADRPC => EBADRPC,
- libc::ERPCMISMATCH => ERPCMISMATCH,
- libc::EPROGUNAVAIL => EPROGUNAVAIL,
- libc::EPROGMISMATCH => EPROGMISMATCH,
- libc::EPROCUNAVAIL => EPROCUNAVAIL,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EFTYPE => EFTYPE,
- libc::EAUTH => EAUTH,
- libc::ENEEDAUTH => ENEEDAUTH,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::ECANCELED => ECANCELED,
- libc::EILSEQ => EILSEQ,
- libc::ENOATTR => ENOATTR,
- libc::EDOOFUS => EDOOFUS,
- libc::EBADMSG => EBADMSG,
- libc::EMULTIHOP => EMULTIHOP,
- libc::ENOLINK => ENOLINK,
- libc::EPROTO => EPROTO,
- libc::ENOTCAPABLE => ENOTCAPABLE,
- libc::ECAPMODE => ECAPMODE,
- libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
- libc::EOWNERDEAD => EOWNERDEAD,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(target_os = "dragonfly")]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- ENOTSUP = libc::ENOTSUP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EPROCLIM = libc::EPROCLIM,
- EUSERS = libc::EUSERS,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- EREMOTE = libc::EREMOTE,
- EBADRPC = libc::EBADRPC,
- ERPCMISMATCH = libc::ERPCMISMATCH,
- EPROGUNAVAIL = libc::EPROGUNAVAIL,
- EPROGMISMATCH = libc::EPROGMISMATCH,
- EPROCUNAVAIL = libc::EPROCUNAVAIL,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EFTYPE = libc::EFTYPE,
- EAUTH = libc::EAUTH,
- ENEEDAUTH = libc::ENEEDAUTH,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- EOVERFLOW = libc::EOVERFLOW,
- ECANCELED = libc::ECANCELED,
- EILSEQ = libc::EILSEQ,
- ENOATTR = libc::ENOATTR,
- EDOOFUS = libc::EDOOFUS,
- EBADMSG = libc::EBADMSG,
- EMULTIHOP = libc::EMULTIHOP,
- ENOLINK = libc::ENOLINK,
- EPROTO = libc::EPROTO,
- ENOMEDIUM = libc::ENOMEDIUM,
- ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
- EOWNERDEAD = libc::EOWNERDEAD,
- EASYNC = libc::EASYNC,
- }
-
- impl Errno {
- pub const ELAST: Errno = Errno::EASYNC;
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- pub const EDEADLOCK: Errno = Errno::EDEADLK;
- pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::ENOTSUP => ENOTSUP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EPROCLIM => EPROCLIM,
- libc::EUSERS => EUSERS,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::EREMOTE => EREMOTE,
- libc::EBADRPC => EBADRPC,
- libc::ERPCMISMATCH => ERPCMISMATCH,
- libc::EPROGUNAVAIL => EPROGUNAVAIL,
- libc::EPROGMISMATCH => EPROGMISMATCH,
- libc::EPROCUNAVAIL => EPROCUNAVAIL,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EFTYPE => EFTYPE,
- libc::EAUTH => EAUTH,
- libc::ENEEDAUTH => ENEEDAUTH,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::ECANCELED => ECANCELED,
- libc::EILSEQ => EILSEQ,
- libc::ENOATTR => ENOATTR,
- libc::EDOOFUS => EDOOFUS,
- libc::EBADMSG => EBADMSG,
- libc::EMULTIHOP => EMULTIHOP,
- libc::ENOLINK => ENOLINK,
- libc::EPROTO => EPROTO,
- libc::ENOMEDIUM => ENOMEDIUM,
- libc::EASYNC => EASYNC,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(target_os = "openbsd")]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- EOPNOTSUPP = libc::EOPNOTSUPP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EPROCLIM = libc::EPROCLIM,
- EUSERS = libc::EUSERS,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- EREMOTE = libc::EREMOTE,
- EBADRPC = libc::EBADRPC,
- ERPCMISMATCH = libc::ERPCMISMATCH,
- EPROGUNAVAIL = libc::EPROGUNAVAIL,
- EPROGMISMATCH = libc::EPROGMISMATCH,
- EPROCUNAVAIL = libc::EPROCUNAVAIL,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EFTYPE = libc::EFTYPE,
- EAUTH = libc::EAUTH,
- ENEEDAUTH = libc::ENEEDAUTH,
- EIPSEC = libc::EIPSEC,
- ENOATTR = libc::ENOATTR,
- EILSEQ = libc::EILSEQ,
- ENOMEDIUM = libc::ENOMEDIUM,
- EMEDIUMTYPE = libc::EMEDIUMTYPE,
- EOVERFLOW = libc::EOVERFLOW,
- ECANCELED = libc::ECANCELED,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- ENOTSUP = libc::ENOTSUP,
- EBADMSG = libc::EBADMSG,
- ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
- EOWNERDEAD = libc::EOWNERDEAD,
- EPROTO = libc::EPROTO,
- }
-
- impl Errno {
- pub const ELAST: Errno = Errno::ENOTSUP;
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::EOPNOTSUPP => EOPNOTSUPP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EPROCLIM => EPROCLIM,
- libc::EUSERS => EUSERS,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::EREMOTE => EREMOTE,
- libc::EBADRPC => EBADRPC,
- libc::ERPCMISMATCH => ERPCMISMATCH,
- libc::EPROGUNAVAIL => EPROGUNAVAIL,
- libc::EPROGMISMATCH => EPROGMISMATCH,
- libc::EPROCUNAVAIL => EPROCUNAVAIL,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EFTYPE => EFTYPE,
- libc::EAUTH => EAUTH,
- libc::ENEEDAUTH => ENEEDAUTH,
- libc::EIPSEC => EIPSEC,
- libc::ENOATTR => ENOATTR,
- libc::EILSEQ => EILSEQ,
- libc::ENOMEDIUM => ENOMEDIUM,
- libc::EMEDIUMTYPE => EMEDIUMTYPE,
- libc::EOVERFLOW => EOVERFLOW,
- libc::ECANCELED => ECANCELED,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::ENOTSUP => ENOTSUP,
- libc::EBADMSG => EBADMSG,
- libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
- libc::EOWNERDEAD => EOWNERDEAD,
- libc::EPROTO => EPROTO,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(target_os = "netbsd")]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- EOPNOTSUPP = libc::EOPNOTSUPP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EPROCLIM = libc::EPROCLIM,
- EUSERS = libc::EUSERS,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- EREMOTE = libc::EREMOTE,
- EBADRPC = libc::EBADRPC,
- ERPCMISMATCH = libc::ERPCMISMATCH,
- EPROGUNAVAIL = libc::EPROGUNAVAIL,
- EPROGMISMATCH = libc::EPROGMISMATCH,
- EPROCUNAVAIL = libc::EPROCUNAVAIL,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EFTYPE = libc::EFTYPE,
- EAUTH = libc::EAUTH,
- ENEEDAUTH = libc::ENEEDAUTH,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- EOVERFLOW = libc::EOVERFLOW,
- EILSEQ = libc::EILSEQ,
- ENOTSUP = libc::ENOTSUP,
- ECANCELED = libc::ECANCELED,
- EBADMSG = libc::EBADMSG,
- ENODATA = libc::ENODATA,
- ENOSR = libc::ENOSR,
- ENOSTR = libc::ENOSTR,
- ETIME = libc::ETIME,
- ENOATTR = libc::ENOATTR,
- EMULTIHOP = libc::EMULTIHOP,
- ENOLINK = libc::ENOLINK,
- EPROTO = libc::EPROTO,
- }
-
- impl Errno {
- pub const ELAST: Errno = Errno::ENOTSUP;
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::EOPNOTSUPP => EOPNOTSUPP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EPROCLIM => EPROCLIM,
- libc::EUSERS => EUSERS,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::EREMOTE => EREMOTE,
- libc::EBADRPC => EBADRPC,
- libc::ERPCMISMATCH => ERPCMISMATCH,
- libc::EPROGUNAVAIL => EPROGUNAVAIL,
- libc::EPROGMISMATCH => EPROGMISMATCH,
- libc::EPROCUNAVAIL => EPROCUNAVAIL,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EFTYPE => EFTYPE,
- libc::EAUTH => EAUTH,
- libc::ENEEDAUTH => ENEEDAUTH,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::EILSEQ => EILSEQ,
- libc::ENOTSUP => ENOTSUP,
- libc::ECANCELED => ECANCELED,
- libc::EBADMSG => EBADMSG,
- libc::ENODATA => ENODATA,
- libc::ENOSR => ENOSR,
- libc::ENOSTR => ENOSTR,
- libc::ETIME => ETIME,
- libc::ENOATTR => ENOATTR,
- libc::EMULTIHOP => EMULTIHOP,
- libc::ENOLINK => ENOLINK,
- libc::EPROTO => EPROTO,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(target_os = "redox")]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- EOPNOTSUPP = libc::EOPNOTSUPP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EUSERS = libc::EUSERS,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- EREMOTE = libc::EREMOTE,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- EOVERFLOW = libc::EOVERFLOW,
- EILSEQ = libc::EILSEQ,
- ECANCELED = libc::ECANCELED,
- EBADMSG = libc::EBADMSG,
- ENODATA = libc::ENODATA,
- ENOSR = libc::ENOSR,
- ENOSTR = libc::ENOSTR,
- ETIME = libc::ETIME,
- EMULTIHOP = libc::EMULTIHOP,
- ENOLINK = libc::ENOLINK,
- EPROTO = libc::EPROTO,
- }
-
- impl Errno {
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::EOPNOTSUPP => EOPNOTSUPP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EUSERS => EUSERS,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::EREMOTE => EREMOTE,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::EILSEQ => EILSEQ,
- libc::ECANCELED => ECANCELED,
- libc::EBADMSG => EBADMSG,
- libc::ENODATA => ENODATA,
- libc::ENOSR => ENOSR,
- libc::ENOSTR => ENOSTR,
- libc::ETIME => ETIME,
- libc::EMULTIHOP => EMULTIHOP,
- libc::ENOLINK => ENOLINK,
- libc::EPROTO => EPROTO,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(any(target_os = "illumos", target_os = "solaris"))]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EAGAIN = libc::EAGAIN,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- ENOTBLK = libc::ENOTBLK,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- ENOMSG = libc::ENOMSG,
- EIDRM = libc::EIDRM,
- ECHRNG = libc::ECHRNG,
- EL2NSYNC = libc::EL2NSYNC,
- EL3HLT = libc::EL3HLT,
- EL3RST = libc::EL3RST,
- ELNRNG = libc::ELNRNG,
- EUNATCH = libc::EUNATCH,
- ENOCSI = libc::ENOCSI,
- EL2HLT = libc::EL2HLT,
- EDEADLK = libc::EDEADLK,
- ENOLCK = libc::ENOLCK,
- ECANCELED = libc::ECANCELED,
- ENOTSUP = libc::ENOTSUP,
- EDQUOT = libc::EDQUOT,
- EBADE = libc::EBADE,
- EBADR = libc::EBADR,
- EXFULL = libc::EXFULL,
- ENOANO = libc::ENOANO,
- EBADRQC = libc::EBADRQC,
- EBADSLT = libc::EBADSLT,
- EDEADLOCK = libc::EDEADLOCK,
- EBFONT = libc::EBFONT,
- EOWNERDEAD = libc::EOWNERDEAD,
- ENOTRECOVERABLE = libc::ENOTRECOVERABLE,
- ENOSTR = libc::ENOSTR,
- ENODATA = libc::ENODATA,
- ETIME = libc::ETIME,
- ENOSR = libc::ENOSR,
- ENONET = libc::ENONET,
- ENOPKG = libc::ENOPKG,
- EREMOTE = libc::EREMOTE,
- ENOLINK = libc::ENOLINK,
- EADV = libc::EADV,
- ESRMNT = libc::ESRMNT,
- ECOMM = libc::ECOMM,
- EPROTO = libc::EPROTO,
- ELOCKUNMAPPED = libc::ELOCKUNMAPPED,
- ENOTACTIVE = libc::ENOTACTIVE,
- EMULTIHOP = libc::EMULTIHOP,
- EBADMSG = libc::EBADMSG,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EOVERFLOW = libc::EOVERFLOW,
- ENOTUNIQ = libc::ENOTUNIQ,
- EBADFD = libc::EBADFD,
- EREMCHG = libc::EREMCHG,
- ELIBACC = libc::ELIBACC,
- ELIBBAD = libc::ELIBBAD,
- ELIBSCN = libc::ELIBSCN,
- ELIBMAX = libc::ELIBMAX,
- ELIBEXEC = libc::ELIBEXEC,
- EILSEQ = libc::EILSEQ,
- ENOSYS = libc::ENOSYS,
- ELOOP = libc::ELOOP,
- ERESTART = libc::ERESTART,
- ESTRPIPE = libc::ESTRPIPE,
- ENOTEMPTY = libc::ENOTEMPTY,
- EUSERS = libc::EUSERS,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ESOCKTNOSUPPORT = libc::ESOCKTNOSUPPORT,
- EOPNOTSUPP = libc::EOPNOTSUPP,
- EPFNOSUPPORT = libc::EPFNOSUPPORT,
- EAFNOSUPPORT = libc::EAFNOSUPPORT,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETOOMANYREFS = libc::ETOOMANYREFS,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- EALREADY = libc::EALREADY,
- EINPROGRESS = libc::EINPROGRESS,
- ESTALE = libc::ESTALE,
- }
-
- impl Errno {
- pub const ELAST: Errno = Errno::ESTALE;
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EAGAIN => EAGAIN,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::ENOTBLK => ENOTBLK,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::ENOMSG => ENOMSG,
- libc::EIDRM => EIDRM,
- libc::ECHRNG => ECHRNG,
- libc::EL2NSYNC => EL2NSYNC,
- libc::EL3HLT => EL3HLT,
- libc::EL3RST => EL3RST,
- libc::ELNRNG => ELNRNG,
- libc::EUNATCH => EUNATCH,
- libc::ENOCSI => ENOCSI,
- libc::EL2HLT => EL2HLT,
- libc::EDEADLK => EDEADLK,
- libc::ENOLCK => ENOLCK,
- libc::ECANCELED => ECANCELED,
- libc::ENOTSUP => ENOTSUP,
- libc::EDQUOT => EDQUOT,
- libc::EBADE => EBADE,
- libc::EBADR => EBADR,
- libc::EXFULL => EXFULL,
- libc::ENOANO => ENOANO,
- libc::EBADRQC => EBADRQC,
- libc::EBADSLT => EBADSLT,
- libc::EDEADLOCK => EDEADLOCK,
- libc::EBFONT => EBFONT,
- libc::EOWNERDEAD => EOWNERDEAD,
- libc::ENOTRECOVERABLE => ENOTRECOVERABLE,
- libc::ENOSTR => ENOSTR,
- libc::ENODATA => ENODATA,
- libc::ETIME => ETIME,
- libc::ENOSR => ENOSR,
- libc::ENONET => ENONET,
- libc::ENOPKG => ENOPKG,
- libc::EREMOTE => EREMOTE,
- libc::ENOLINK => ENOLINK,
- libc::EADV => EADV,
- libc::ESRMNT => ESRMNT,
- libc::ECOMM => ECOMM,
- libc::EPROTO => EPROTO,
- libc::ELOCKUNMAPPED => ELOCKUNMAPPED,
- libc::ENOTACTIVE => ENOTACTIVE,
- libc::EMULTIHOP => EMULTIHOP,
- libc::EBADMSG => EBADMSG,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::ENOTUNIQ => ENOTUNIQ,
- libc::EBADFD => EBADFD,
- libc::EREMCHG => EREMCHG,
- libc::ELIBACC => ELIBACC,
- libc::ELIBBAD => ELIBBAD,
- libc::ELIBSCN => ELIBSCN,
- libc::ELIBMAX => ELIBMAX,
- libc::ELIBEXEC => ELIBEXEC,
- libc::EILSEQ => EILSEQ,
- libc::ENOSYS => ENOSYS,
- libc::ELOOP => ELOOP,
- libc::ERESTART => ERESTART,
- libc::ESTRPIPE => ESTRPIPE,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EUSERS => EUSERS,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ESOCKTNOSUPPORT => ESOCKTNOSUPPORT,
- libc::EOPNOTSUPP => EOPNOTSUPP,
- libc::EPFNOSUPPORT => EPFNOSUPPORT,
- libc::EAFNOSUPPORT => EAFNOSUPPORT,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETOOMANYREFS => ETOOMANYREFS,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::EALREADY => EALREADY,
- libc::EINPROGRESS => EINPROGRESS,
- libc::ESTALE => ESTALE,
- _ => UnknownErrno,
- }
- }
-}
-
-#[cfg(target_os = "haiku")]
-mod consts {
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- #[repr(i32)]
- #[non_exhaustive]
- pub enum Errno {
- UnknownErrno = 0,
- EPERM = libc::EPERM,
- ENOENT = libc::ENOENT,
- ESRCH = libc::ESRCH,
- EINTR = libc::EINTR,
- EIO = libc::EIO,
- ENXIO = libc::ENXIO,
- E2BIG = libc::E2BIG,
- ENOEXEC = libc::ENOEXEC,
- EBADF = libc::EBADF,
- ECHILD = libc::ECHILD,
- EDEADLK = libc::EDEADLK,
- ENOMEM = libc::ENOMEM,
- EACCES = libc::EACCES,
- EFAULT = libc::EFAULT,
- EBUSY = libc::EBUSY,
- EEXIST = libc::EEXIST,
- EXDEV = libc::EXDEV,
- ENODEV = libc::ENODEV,
- ENOTDIR = libc::ENOTDIR,
- EISDIR = libc::EISDIR,
- EINVAL = libc::EINVAL,
- ENFILE = libc::ENFILE,
- EMFILE = libc::EMFILE,
- ENOTTY = libc::ENOTTY,
- ETXTBSY = libc::ETXTBSY,
- EFBIG = libc::EFBIG,
- ENOSPC = libc::ENOSPC,
- ESPIPE = libc::ESPIPE,
- EROFS = libc::EROFS,
- EMLINK = libc::EMLINK,
- EPIPE = libc::EPIPE,
- EDOM = libc::EDOM,
- ERANGE = libc::ERANGE,
- EAGAIN = libc::EAGAIN,
- EINPROGRESS = libc::EINPROGRESS,
- EALREADY = libc::EALREADY,
- ENOTSOCK = libc::ENOTSOCK,
- EDESTADDRREQ = libc::EDESTADDRREQ,
- EMSGSIZE = libc::EMSGSIZE,
- EPROTOTYPE = libc::EPROTOTYPE,
- ENOPROTOOPT = libc::ENOPROTOOPT,
- EPROTONOSUPPORT = libc::EPROTONOSUPPORT,
- ENOTSUP = libc::ENOTSUP,
- EADDRINUSE = libc::EADDRINUSE,
- EADDRNOTAVAIL = libc::EADDRNOTAVAIL,
- ENETDOWN = libc::ENETDOWN,
- ENETUNREACH = libc::ENETUNREACH,
- ENETRESET = libc::ENETRESET,
- ECONNABORTED = libc::ECONNABORTED,
- ECONNRESET = libc::ECONNRESET,
- ENOBUFS = libc::ENOBUFS,
- EISCONN = libc::EISCONN,
- ENOTCONN = libc::ENOTCONN,
- ESHUTDOWN = libc::ESHUTDOWN,
- ETIMEDOUT = libc::ETIMEDOUT,
- ECONNREFUSED = libc::ECONNREFUSED,
- ELOOP = libc::ELOOP,
- ENAMETOOLONG = libc::ENAMETOOLONG,
- EHOSTDOWN = libc::EHOSTDOWN,
- EHOSTUNREACH = libc::EHOSTUNREACH,
- ENOTEMPTY = libc::ENOTEMPTY,
- EDQUOT = libc::EDQUOT,
- ESTALE = libc::ESTALE,
- ENOLCK = libc::ENOLCK,
- ENOSYS = libc::ENOSYS,
- EIDRM = libc::EIDRM,
- ENOMSG = libc::ENOMSG,
- EOVERFLOW = libc::EOVERFLOW,
- ECANCELED = libc::ECANCELED,
- EILSEQ = libc::EILSEQ,
- ENOATTR = libc::ENOATTR,
- EBADMSG = libc::EBADMSG,
- EMULTIHOP = libc::EMULTIHOP,
- ENOLINK = libc::ENOLINK,
- EPROTO = libc::EPROTO,
- }
-
- impl Errno {
- pub const EWOULDBLOCK: Errno = Errno::EAGAIN;
- pub const EDEADLOCK: Errno = Errno::EDEADLK;
- pub const EOPNOTSUPP: Errno = Errno::ENOTSUP;
- }
-
- pub const fn from_i32(e: i32) -> Errno {
- use self::Errno::*;
-
- match e {
- libc::EPERM => EPERM,
- libc::ENOENT => ENOENT,
- libc::ESRCH => ESRCH,
- libc::EINTR => EINTR,
- libc::EIO => EIO,
- libc::ENXIO => ENXIO,
- libc::E2BIG => E2BIG,
- libc::ENOEXEC => ENOEXEC,
- libc::EBADF => EBADF,
- libc::ECHILD => ECHILD,
- libc::EDEADLK => EDEADLK,
- libc::ENOMEM => ENOMEM,
- libc::EACCES => EACCES,
- libc::EFAULT => EFAULT,
- libc::EBUSY => EBUSY,
- libc::EEXIST => EEXIST,
- libc::EXDEV => EXDEV,
- libc::ENODEV => ENODEV,
- libc::ENOTDIR => ENOTDIR,
- libc::EISDIR => EISDIR,
- libc::EINVAL => EINVAL,
- libc::ENFILE => ENFILE,
- libc::EMFILE => EMFILE,
- libc::ENOTTY => ENOTTY,
- libc::ETXTBSY => ETXTBSY,
- libc::EFBIG => EFBIG,
- libc::ENOSPC => ENOSPC,
- libc::ESPIPE => ESPIPE,
- libc::EROFS => EROFS,
- libc::EMLINK => EMLINK,
- libc::EPIPE => EPIPE,
- libc::EDOM => EDOM,
- libc::ERANGE => ERANGE,
- libc::EAGAIN => EAGAIN,
- libc::EINPROGRESS => EINPROGRESS,
- libc::EALREADY => EALREADY,
- libc::ENOTSOCK => ENOTSOCK,
- libc::EDESTADDRREQ => EDESTADDRREQ,
- libc::EMSGSIZE => EMSGSIZE,
- libc::EPROTOTYPE => EPROTOTYPE,
- libc::ENOPROTOOPT => ENOPROTOOPT,
- libc::EPROTONOSUPPORT => EPROTONOSUPPORT,
- libc::ENOTSUP => ENOTSUP,
- libc::EADDRINUSE => EADDRINUSE,
- libc::EADDRNOTAVAIL => EADDRNOTAVAIL,
- libc::ENETDOWN => ENETDOWN,
- libc::ENETUNREACH => ENETUNREACH,
- libc::ENETRESET => ENETRESET,
- libc::ECONNABORTED => ECONNABORTED,
- libc::ECONNRESET => ECONNRESET,
- libc::ENOBUFS => ENOBUFS,
- libc::EISCONN => EISCONN,
- libc::ENOTCONN => ENOTCONN,
- libc::ESHUTDOWN => ESHUTDOWN,
- libc::ETIMEDOUT => ETIMEDOUT,
- libc::ECONNREFUSED => ECONNREFUSED,
- libc::ELOOP => ELOOP,
- libc::ENAMETOOLONG => ENAMETOOLONG,
- libc::EHOSTDOWN => EHOSTDOWN,
- libc::EHOSTUNREACH => EHOSTUNREACH,
- libc::ENOTEMPTY => ENOTEMPTY,
- libc::EDQUOT => EDQUOT,
- libc::ESTALE => ESTALE,
- libc::ENOLCK => ENOLCK,
- libc::ENOSYS => ENOSYS,
- libc::EIDRM => EIDRM,
- libc::ENOMSG => ENOMSG,
- libc::EOVERFLOW => EOVERFLOW,
- libc::ECANCELED => ECANCELED,
- libc::EILSEQ => EILSEQ,
- libc::ENOATTR => ENOATTR,
- libc::EBADMSG => EBADMSG,
- libc::EMULTIHOP => EMULTIHOP,
- libc::ENOLINK => ENOLINK,
- libc::EPROTO => EPROTO,
- _ => UnknownErrno,
- }
- }
-}
diff --git a/vendor/nix/src/fcntl.rs b/vendor/nix/src/fcntl.rs
deleted file mode 100644
index 650828345..000000000
--- a/vendor/nix/src/fcntl.rs
+++ /dev/null
@@ -1,882 +0,0 @@
-use crate::errno::Errno;
-use libc::{self, c_char, c_int, c_uint, size_t, ssize_t};
-use std::ffi::OsString;
-#[cfg(not(target_os = "redox"))]
-use std::os::raw;
-use std::os::unix::ffi::OsStringExt;
-use std::os::unix::io::RawFd;
-
-#[cfg(feature = "fs")]
-use crate::{sys::stat::Mode, NixPath, Result};
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use std::ptr; // For splice and copy_file_range
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "wasi",
- target_env = "uclibc",
- target_os = "freebsd"
-))]
-#[cfg(feature = "fs")]
-pub use self::posix_fadvise::{posix_fadvise, PosixFadviseAdvice};
-
-#[cfg(not(target_os = "redox"))]
-#[cfg(any(feature = "fs", feature = "process"))]
-libc_bitflags! {
- #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "process"))))]
- pub struct AtFlags: c_int {
- AT_REMOVEDIR;
- AT_SYMLINK_FOLLOW;
- AT_SYMLINK_NOFOLLOW;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- AT_NO_AUTOMOUNT;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- AT_EMPTY_PATH;
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- AT_EACCESS;
- }
-}
-
-#[cfg(any(feature = "fs", feature = "term"))]
-libc_bitflags!(
- /// Configuration options for opened files.
- #[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "term"))))]
- pub struct OFlag: c_int {
- /// Mask for the access mode of the file.
- O_ACCMODE;
- /// Use alternate I/O semantics.
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_ALT_IO;
- /// Open the file in append-only mode.
- O_APPEND;
- /// Generate a signal when input or output becomes possible.
- #[cfg(not(any(target_os = "illumos", target_os = "solaris", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_ASYNC;
- /// Closes the file descriptor once an `execve` call is made.
- ///
- /// Also sets the file offset to the beginning of the file.
- O_CLOEXEC;
- /// Create the file if it does not exist.
- O_CREAT;
- /// Try to minimize cache effects of the I/O for this file.
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_DIRECT;
- /// If the specified path isn't a directory, fail.
- #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_DIRECTORY;
- /// Implicitly follow each `write()` with an `fdatasync()`.
- #[cfg(any(target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_DSYNC;
- /// Error out if a file was not created.
- O_EXCL;
- /// Open for execute only.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_EXEC;
- /// Open with an exclusive file lock.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_EXLOCK;
- /// Same as `O_SYNC`.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- all(target_os = "linux", not(target_env = "musl")),
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_FSYNC;
- /// Allow files whose sizes can't be represented in an `off_t` to be opened.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_LARGEFILE;
- /// Do not update the file last access time during `read(2)`s.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_NOATIME;
- /// Don't attach the device as the process' controlling terminal.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_NOCTTY;
- /// Same as `O_NONBLOCK`.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_NDELAY;
- /// `open()` will fail if the given path is a symbolic link.
- O_NOFOLLOW;
- /// When possible, open the file in nonblocking mode.
- O_NONBLOCK;
- /// Don't deliver `SIGPIPE`.
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_NOSIGPIPE;
- /// Obtain a file descriptor for low-level access.
- ///
- /// The file itself is not opened and other file operations will fail.
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_PATH;
- /// Only allow reading.
- ///
- /// This should not be combined with `O_WRONLY` or `O_RDWR`.
- O_RDONLY;
- /// Allow both reading and writing.
- ///
- /// This should not be combined with `O_WRONLY` or `O_RDONLY`.
- O_RDWR;
- /// Similar to `O_DSYNC` but applies to `read`s instead.
- #[cfg(any(target_os = "linux", target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_RSYNC;
- /// Skip search permission checks.
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_SEARCH;
- /// Open with a shared file lock.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_SHLOCK;
- /// Implicitly follow each `write()` with an `fsync()`.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_SYNC;
- /// Create an unnamed temporary file.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_TMPFILE;
- /// Truncate an existing regular file to 0 length if it allows writing.
- O_TRUNC;
- /// Restore default TTY attributes.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_TTY_INIT;
- /// Only allow writing.
- ///
- /// This should not be combined with `O_RDONLY` or `O_RDWR`.
- O_WRONLY;
- }
-);
-
-feature! {
-#![feature = "fs"]
-
-// The conversion is not identical on all operating systems.
-#[allow(clippy::useless_conversion)]
-pub fn open<P: ?Sized + NixPath>(path: &P, oflag: OFlag, mode: Mode) -> Result<RawFd> {
- let fd = path.with_nix_path(|cstr| {
- unsafe { libc::open(cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
- })?;
-
- Errno::result(fd)
-}
-
-// The conversion is not identical on all operating systems.
-#[allow(clippy::useless_conversion)]
-#[cfg(not(target_os = "redox"))]
-pub fn openat<P: ?Sized + NixPath>(
- dirfd: RawFd,
- path: &P,
- oflag: OFlag,
- mode: Mode,
-) -> Result<RawFd> {
- let fd = path.with_nix_path(|cstr| {
- unsafe { libc::openat(dirfd, cstr.as_ptr(), oflag.bits(), mode.bits() as c_uint) }
- })?;
- Errno::result(fd)
-}
-
-#[cfg(not(target_os = "redox"))]
-pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
- old_dirfd: Option<RawFd>,
- old_path: &P1,
- new_dirfd: Option<RawFd>,
- new_path: &P2,
-) -> Result<()> {
- let res = old_path.with_nix_path(|old_cstr| {
- new_path.with_nix_path(|new_cstr| unsafe {
- libc::renameat(
- at_rawfd(old_dirfd),
- old_cstr.as_ptr(),
- at_rawfd(new_dirfd),
- new_cstr.as_ptr(),
- )
- })
- })??;
- Errno::result(res).map(drop)
-}
-}
-
-#[cfg(all(target_os = "linux", target_env = "gnu",))]
-#[cfg(feature = "fs")]
-libc_bitflags! {
- #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
- pub struct RenameFlags: u32 {
- RENAME_EXCHANGE;
- RENAME_NOREPLACE;
- RENAME_WHITEOUT;
- }
-}
-
-feature! {
-#![feature = "fs"]
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
-))]
-pub fn renameat2<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
- old_dirfd: Option<RawFd>,
- old_path: &P1,
- new_dirfd: Option<RawFd>,
- new_path: &P2,
- flags: RenameFlags,
-) -> Result<()> {
- let res = old_path.with_nix_path(|old_cstr| {
- new_path.with_nix_path(|new_cstr| unsafe {
- libc::renameat2(
- at_rawfd(old_dirfd),
- old_cstr.as_ptr(),
- at_rawfd(new_dirfd),
- new_cstr.as_ptr(),
- flags.bits(),
- )
- })
- })??;
- Errno::result(res).map(drop)
-}
-
-fn wrap_readlink_result(mut v: Vec<u8>, len: ssize_t) -> Result<OsString> {
- unsafe { v.set_len(len as usize) }
- v.shrink_to_fit();
- Ok(OsString::from_vec(v.to_vec()))
-}
-
-fn readlink_maybe_at<P: ?Sized + NixPath>(
- dirfd: Option<RawFd>,
- path: &P,
- v: &mut Vec<u8>,
-) -> Result<libc::ssize_t> {
- path.with_nix_path(|cstr| unsafe {
- match dirfd {
- #[cfg(target_os = "redox")]
- Some(_) => unreachable!(),
- #[cfg(not(target_os = "redox"))]
- Some(dirfd) => libc::readlinkat(
- dirfd,
- cstr.as_ptr(),
- v.as_mut_ptr() as *mut c_char,
- v.capacity() as size_t,
- ),
- None => libc::readlink(
- cstr.as_ptr(),
- v.as_mut_ptr() as *mut c_char,
- v.capacity() as size_t,
- ),
- }
- })
-}
-
-fn inner_readlink<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P) -> Result<OsString> {
- let mut v = Vec::with_capacity(libc::PATH_MAX as usize);
- // simple case: result is strictly less than `PATH_MAX`
- let res = readlink_maybe_at(dirfd, path, &mut v)?;
- let len = Errno::result(res)?;
- debug_assert!(len >= 0);
- if (len as usize) < v.capacity() {
- return wrap_readlink_result(v, res);
- }
- // Uh oh, the result is too long...
- // Let's try to ask lstat how many bytes to allocate.
- let reported_size = match dirfd {
- #[cfg(target_os = "redox")]
- Some(_) => unreachable!(),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- Some(dirfd) => {
- let flags = if path.is_empty() { AtFlags::AT_EMPTY_PATH } else { AtFlags::empty() };
- super::sys::stat::fstatat(dirfd, path, flags | AtFlags::AT_SYMLINK_NOFOLLOW)
- },
- #[cfg(not(any(target_os = "android", target_os = "linux", target_os = "redox")))]
- Some(dirfd) => super::sys::stat::fstatat(dirfd, path, AtFlags::AT_SYMLINK_NOFOLLOW),
- None => super::sys::stat::lstat(path)
- }
- .map(|x| x.st_size)
- .unwrap_or(0);
- let mut try_size = if reported_size > 0 {
- // Note: even if `lstat`'s apparently valid answer turns out to be
- // wrong, we will still read the full symlink no matter what.
- reported_size as usize + 1
- } else {
- // If lstat doesn't cooperate, or reports an error, be a little less
- // precise.
- (libc::PATH_MAX as usize).max(128) << 1
- };
- loop {
- v.reserve_exact(try_size);
- let res = readlink_maybe_at(dirfd, path, &mut v)?;
- let len = Errno::result(res)?;
- debug_assert!(len >= 0);
- if (len as usize) < v.capacity() {
- break wrap_readlink_result(v, res);
- } else {
- // Ugh! Still not big enough!
- match try_size.checked_shl(1) {
- Some(next_size) => try_size = next_size,
- // It's absurd that this would happen, but handle it sanely
- // anyway.
- None => break Err(Errno::ENAMETOOLONG),
- }
- }
- }
-}
-
-pub fn readlink<P: ?Sized + NixPath>(path: &P) -> Result<OsString> {
- inner_readlink(None, path)
-}
-
-#[cfg(not(target_os = "redox"))]
-pub fn readlinkat<P: ?Sized + NixPath>(dirfd: RawFd, path: &P) -> Result<OsString> {
- inner_readlink(Some(dirfd), path)
-}
-
-/// Computes the raw fd consumed by a function of the form `*at`.
-#[cfg(not(target_os = "redox"))]
-pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
- match fd {
- None => libc::AT_FDCWD,
- Some(fd) => fd,
- }
-}
-}
-
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
-#[cfg(feature = "fs")]
-libc_bitflags!(
- /// Additional flags for file sealing, which allows for limiting operations on a file.
- #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
- pub struct SealFlag: c_int {
- /// Prevents further calls to `fcntl()` with `F_ADD_SEALS`.
- F_SEAL_SEAL;
- /// The file cannot be reduced in size.
- F_SEAL_SHRINK;
- /// The size of the file cannot be increased.
- F_SEAL_GROW;
- /// The file contents cannot be modified.
- F_SEAL_WRITE;
- }
-);
-
-#[cfg(feature = "fs")]
-libc_bitflags!(
- /// Additional configuration flags for `fcntl`'s `F_SETFD`.
- #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
- pub struct FdFlag: c_int {
- /// The file descriptor will automatically be closed during a successful `execve(2)`.
- FD_CLOEXEC;
- }
-);
-
-feature! {
-#![feature = "fs"]
-
-#[cfg(not(target_os = "redox"))]
-#[derive(Debug, Eq, Hash, PartialEq)]
-#[non_exhaustive]
-pub enum FcntlArg<'a> {
- F_DUPFD(RawFd),
- F_DUPFD_CLOEXEC(RawFd),
- F_GETFD,
- F_SETFD(FdFlag), // FD_FLAGS
- F_GETFL,
- F_SETFL(OFlag), // O_NONBLOCK
- F_SETLK(&'a libc::flock),
- F_SETLKW(&'a libc::flock),
- F_GETLK(&'a mut libc::flock),
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_OFD_SETLK(&'a libc::flock),
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_OFD_SETLKW(&'a libc::flock),
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_OFD_GETLK(&'a mut libc::flock),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
- F_ADD_SEALS(SealFlag),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
- F_GET_SEALS,
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- F_FULLFSYNC,
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_GETPIPE_SZ,
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_SETPIPE_SZ(c_int),
- // TODO: Rest of flags
-}
-
-#[cfg(target_os = "redox")]
-#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
-#[non_exhaustive]
-pub enum FcntlArg {
- F_DUPFD(RawFd),
- F_DUPFD_CLOEXEC(RawFd),
- F_GETFD,
- F_SETFD(FdFlag), // FD_FLAGS
- F_GETFL,
- F_SETFL(OFlag), // O_NONBLOCK
-}
-pub use self::FcntlArg::*;
-
-// TODO: Figure out how to handle value fcntl returns
-pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
- let res = unsafe {
- match arg {
- F_DUPFD(rawfd) => libc::fcntl(fd, libc::F_DUPFD, rawfd),
- F_DUPFD_CLOEXEC(rawfd) => libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, rawfd),
- F_GETFD => libc::fcntl(fd, libc::F_GETFD),
- F_SETFD(flag) => libc::fcntl(fd, libc::F_SETFD, flag.bits()),
- F_GETFL => libc::fcntl(fd, libc::F_GETFL),
- F_SETFL(flag) => libc::fcntl(fd, libc::F_SETFL, flag.bits()),
- #[cfg(not(target_os = "redox"))]
- F_SETLK(flock) => libc::fcntl(fd, libc::F_SETLK, flock),
- #[cfg(not(target_os = "redox"))]
- F_SETLKW(flock) => libc::fcntl(fd, libc::F_SETLKW, flock),
- #[cfg(not(target_os = "redox"))]
- F_GETLK(flock) => libc::fcntl(fd, libc::F_GETLK, flock),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- F_OFD_SETLK(flock) => libc::fcntl(fd, libc::F_OFD_SETLK, flock),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- F_OFD_SETLKW(flock) => libc::fcntl(fd, libc::F_OFD_SETLKW, flock),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- F_OFD_GETLK(flock) => libc::fcntl(fd, libc::F_OFD_GETLK, flock),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
- F_ADD_SEALS(flag) => libc::fcntl(fd, libc::F_ADD_SEALS, flag.bits()),
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
- F_GET_SEALS => libc::fcntl(fd, libc::F_GET_SEALS),
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- F_FULLFSYNC => libc::fcntl(fd, libc::F_FULLFSYNC),
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_GETPIPE_SZ => libc::fcntl(fd, libc::F_GETPIPE_SZ),
- #[cfg(any(target_os = "linux", target_os = "android"))]
- F_SETPIPE_SZ(size) => libc::fcntl(fd, libc::F_SETPIPE_SZ, size),
- }
- };
-
- Errno::result(res)
-}
-
-// TODO: convert to libc_enum
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[non_exhaustive]
-pub enum FlockArg {
- LockShared,
- LockExclusive,
- Unlock,
- LockSharedNonblock,
- LockExclusiveNonblock,
- UnlockNonblock,
-}
-
-#[cfg(not(target_os = "redox"))]
-pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
- use self::FlockArg::*;
-
- let res = unsafe {
- match arg {
- LockShared => libc::flock(fd, libc::LOCK_SH),
- LockExclusive => libc::flock(fd, libc::LOCK_EX),
- Unlock => libc::flock(fd, libc::LOCK_UN),
- LockSharedNonblock => libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB),
- LockExclusiveNonblock => libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB),
- UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
- }
- };
-
- Errno::result(res).map(drop)
-}
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg(feature = "zerocopy")]
-libc_bitflags! {
- /// Additional flags to `splice` and friends.
- #[cfg_attr(docsrs, doc(cfg(feature = "zerocopy")))]
- pub struct SpliceFFlags: c_uint {
- /// Request that pages be moved instead of copied.
- ///
- /// Not applicable to `vmsplice`.
- SPLICE_F_MOVE;
- /// Do not block on I/O.
- SPLICE_F_NONBLOCK;
- /// Hint that more data will be coming in a subsequent splice.
- ///
- /// Not applicable to `vmsplice`.
- SPLICE_F_MORE;
- /// Gift the user pages to the kernel.
- ///
- /// Not applicable to `splice`.
- SPLICE_F_GIFT;
- }
-}
-
-feature! {
-#![feature = "zerocopy"]
-
-/// Copy a range of data from one file to another
-///
-/// The `copy_file_range` system call performs an in-kernel copy between
-/// file descriptors `fd_in` and `fd_out` without the additional cost of
-/// transferring data from the kernel to user space and then back into the
-/// kernel. It copies up to `len` bytes of data from file descriptor `fd_in` to
-/// file descriptor `fd_out`, overwriting any data that exists within the
-/// requested range of the target file.
-///
-/// If the `off_in` and/or `off_out` arguments are used, the values
-/// will be mutated to reflect the new position within the file after
-/// copying. If they are not used, the relevant filedescriptors will be seeked
-/// to the new position.
-///
-/// On successful completion the number of bytes actually copied will be
-/// returned.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub fn copy_file_range(
- fd_in: RawFd,
- off_in: Option<&mut libc::loff_t>,
- fd_out: RawFd,
- off_out: Option<&mut libc::loff_t>,
- len: usize,
-) -> Result<usize> {
- let off_in = off_in
- .map(|offset| offset as *mut libc::loff_t)
- .unwrap_or(ptr::null_mut());
- let off_out = off_out
- .map(|offset| offset as *mut libc::loff_t)
- .unwrap_or(ptr::null_mut());
-
- let ret = unsafe {
- libc::syscall(
- libc::SYS_copy_file_range,
- fd_in,
- off_in,
- fd_out,
- off_out,
- len,
- 0,
- )
- };
- Errno::result(ret).map(|r| r as usize)
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn splice(
- fd_in: RawFd,
- off_in: Option<&mut libc::loff_t>,
- fd_out: RawFd,
- off_out: Option<&mut libc::loff_t>,
- len: usize,
- flags: SpliceFFlags,
-) -> Result<usize> {
- let off_in = off_in
- .map(|offset| offset as *mut libc::loff_t)
- .unwrap_or(ptr::null_mut());
- let off_out = off_out
- .map(|offset| offset as *mut libc::loff_t)
- .unwrap_or(ptr::null_mut());
-
- let ret = unsafe { libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits()) };
- Errno::result(ret).map(|r| r as usize)
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn tee(fd_in: RawFd, fd_out: RawFd, len: usize, flags: SpliceFFlags) -> Result<usize> {
- let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
- Errno::result(ret).map(|r| r as usize)
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn vmsplice(
- fd: RawFd,
- iov: &[std::io::IoSlice<'_>],
- flags: SpliceFFlags
- ) -> Result<usize>
-{
- let ret = unsafe {
- libc::vmsplice(
- fd,
- iov.as_ptr() as *const libc::iovec,
- iov.len(),
- flags.bits(),
- )
- };
- Errno::result(ret).map(|r| r as usize)
-}
-}
-
-#[cfg(any(target_os = "linux"))]
-#[cfg(feature = "fs")]
-libc_bitflags!(
- /// Mode argument flags for fallocate determining operation performed on a given range.
- #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
- pub struct FallocateFlags: c_int {
- /// File size is not changed.
- ///
- /// offset + len can be greater than file size.
- FALLOC_FL_KEEP_SIZE;
- /// Deallocates space by creating a hole.
- ///
- /// Must be ORed with FALLOC_FL_KEEP_SIZE. Byte range starts at offset and continues for len bytes.
- FALLOC_FL_PUNCH_HOLE;
- /// Removes byte range from a file without leaving a hole.
- ///
- /// Byte range to collapse starts at offset and continues for len bytes.
- FALLOC_FL_COLLAPSE_RANGE;
- /// Zeroes space in specified byte range.
- ///
- /// Byte range starts at offset and continues for len bytes.
- FALLOC_FL_ZERO_RANGE;
- /// Increases file space by inserting a hole within the file size.
- ///
- /// Does not overwrite existing data. Hole starts at offset and continues for len bytes.
- FALLOC_FL_INSERT_RANGE;
- /// Shared file data extants are made private to the file.
- ///
- /// Gaurantees that a subsequent write will not fail due to lack of space.
- FALLOC_FL_UNSHARE_RANGE;
- }
-);
-
-feature! {
-#![feature = "fs"]
-
-/// Manipulates file space.
-///
-/// Allows the caller to directly manipulate the allocated disk space for the
-/// file referred to by fd.
-#[cfg(any(target_os = "linux"))]
-#[cfg(feature = "fs")]
-pub fn fallocate(
- fd: RawFd,
- mode: FallocateFlags,
- offset: libc::off_t,
- len: libc::off_t,
-) -> Result<()> {
- let res = unsafe { libc::fallocate(fd, mode.bits(), offset, len) };
- Errno::result(res).map(drop)
-}
-
-/// Argument to [`fspacectl`] describing the range to zero. The first member is
-/// the file offset, and the second is the length of the region.
-#[cfg(any(target_os = "freebsd"))]
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct SpacectlRange(pub libc::off_t, pub libc::off_t);
-
-#[cfg(any(target_os = "freebsd"))]
-impl SpacectlRange {
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.1 == 0
- }
-
- #[inline]
- pub fn len(&self) -> libc::off_t {
- self.1
- }
-
- #[inline]
- pub fn offset(&self) -> libc::off_t {
- self.0
- }
-}
-
-/// Punch holes in a file.
-///
-/// `fspacectl` instructs the file system to deallocate a portion of a file.
-/// After a successful operation, this region of the file will return all zeroes
-/// if read. If the file system supports deallocation, then it may free the
-/// underlying storage, too.
-///
-/// # Arguments
-///
-/// - `fd` - File to operate on
-/// - `range.0` - File offset at which to begin deallocation
-/// - `range.1` - Length of the region to deallocate
-///
-/// # Returns
-///
-/// The operation may deallocate less than the entire requested region. On
-/// success, it returns the region that still remains to be deallocated. The
-/// caller should loop until the returned region is empty.
-///
-/// # Example
-///
-#[cfg_attr(fbsd14, doc = " ```")]
-#[cfg_attr(not(fbsd14), doc = " ```no_run")]
-/// # use std::io::Write;
-/// # use std::os::unix::fs::FileExt;
-/// # use std::os::unix::io::AsRawFd;
-/// # use nix::fcntl::*;
-/// # use tempfile::tempfile;
-/// const INITIAL: &[u8] = b"0123456789abcdef";
-/// let mut f = tempfile().unwrap();
-/// f.write_all(INITIAL).unwrap();
-/// let mut range = SpacectlRange(3, 6);
-/// while (!range.is_empty()) {
-/// range = fspacectl(f.as_raw_fd(), range).unwrap();
-/// }
-/// let mut buf = vec![0; INITIAL.len()];
-/// f.read_exact_at(&mut buf, 0).unwrap();
-/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef");
-/// ```
-#[cfg(target_os = "freebsd")]
-pub fn fspacectl(fd: RawFd, range: SpacectlRange) -> Result<SpacectlRange> {
- let mut rqsr = libc::spacectl_range{r_offset: range.0, r_len: range.1};
- let res = unsafe { libc::fspacectl(
- fd,
- libc::SPACECTL_DEALLOC, // Only one command is supported ATM
- &rqsr,
- 0, // No flags are currently supported
- &mut rqsr
- )};
- Errno::result(res).map(|_| SpacectlRange(rqsr.r_offset, rqsr.r_len))
-}
-
-/// Like [`fspacectl`], but will never return incomplete.
-///
-/// # Arguments
-///
-/// - `fd` - File to operate on
-/// - `offset` - File offset at which to begin deallocation
-/// - `len` - Length of the region to deallocate
-///
-/// # Returns
-///
-/// Returns `()` on success. On failure, the region may or may not be partially
-/// deallocated.
-///
-/// # Example
-///
-#[cfg_attr(fbsd14, doc = " ```")]
-#[cfg_attr(not(fbsd14), doc = " ```no_run")]
-/// # use std::io::Write;
-/// # use std::os::unix::fs::FileExt;
-/// # use std::os::unix::io::AsRawFd;
-/// # use nix::fcntl::*;
-/// # use tempfile::tempfile;
-/// const INITIAL: &[u8] = b"0123456789abcdef";
-/// let mut f = tempfile().unwrap();
-/// f.write_all(INITIAL).unwrap();
-/// fspacectl_all(f.as_raw_fd(), 3, 6).unwrap();
-/// let mut buf = vec![0; INITIAL.len()];
-/// f.read_exact_at(&mut buf, 0).unwrap();
-/// assert_eq!(buf, b"012\0\0\0\0\0\09abcdef");
-/// ```
-#[cfg(target_os = "freebsd")]
-pub fn fspacectl_all(fd: RawFd, offset: libc::off_t, len: libc::off_t)
- -> Result<()>
-{
- let mut rqsr = libc::spacectl_range{r_offset: offset, r_len: len};
- while rqsr.r_len > 0 {
- let res = unsafe { libc::fspacectl(
- fd,
- libc::SPACECTL_DEALLOC, // Only one command is supported ATM
- &rqsr,
- 0, // No flags are currently supported
- &mut rqsr
- )};
- Errno::result(res)?;
- }
- Ok(())
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "wasi",
- target_env = "uclibc",
- target_os = "freebsd"
-))]
-mod posix_fadvise {
- use crate::errno::Errno;
- use std::os::unix::io::RawFd;
- use crate::Result;
-
- #[cfg(feature = "fs")]
- libc_enum! {
- #[repr(i32)]
- #[non_exhaustive]
- #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
- pub enum PosixFadviseAdvice {
- POSIX_FADV_NORMAL,
- POSIX_FADV_SEQUENTIAL,
- POSIX_FADV_RANDOM,
- POSIX_FADV_NOREUSE,
- POSIX_FADV_WILLNEED,
- POSIX_FADV_DONTNEED,
- }
- }
-
- feature! {
- #![feature = "fs"]
- pub fn posix_fadvise(
- fd: RawFd,
- offset: libc::off_t,
- len: libc::off_t,
- advice: PosixFadviseAdvice,
- ) -> Result<()> {
- let res = unsafe { libc::posix_fadvise(fd, offset, len, advice as libc::c_int) };
-
- if res == 0 {
- Ok(())
- } else {
- Err(Errno::from_i32(res))
- }
- }
- }
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "wasi",
- target_os = "freebsd"
-))]
-pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<()> {
- let res = unsafe { libc::posix_fallocate(fd, offset, len) };
- match Errno::result(res) {
- Err(err) => Err(err),
- Ok(0) => Ok(()),
- Ok(errno) => Err(Errno::from_i32(errno)),
- }
-}
-}
diff --git a/vendor/nix/src/features.rs b/vendor/nix/src/features.rs
deleted file mode 100644
index 39d17604e..000000000
--- a/vendor/nix/src/features.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-//! Feature tests for OS functionality
-pub use self::os::*;
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod os {
- use crate::sys::utsname::uname;
- use crate::Result;
- use std::os::unix::ffi::OsStrExt;
-
- // Features:
- // * atomic cloexec on socket: 2.6.27
- // * pipe2: 2.6.27
- // * accept4: 2.6.28
-
- static VERS_UNKNOWN: usize = 1;
- static VERS_2_6_18: usize = 2;
- static VERS_2_6_27: usize = 3;
- static VERS_2_6_28: usize = 4;
- static VERS_3: usize = 5;
-
- #[inline]
- fn digit(dst: &mut usize, b: u8) {
- *dst *= 10;
- *dst += (b - b'0') as usize;
- }
-
- fn parse_kernel_version() -> Result<usize> {
- let u = uname()?;
-
- let mut curr: usize = 0;
- let mut major: usize = 0;
- let mut minor: usize = 0;
- let mut patch: usize = 0;
-
- for &b in u.release().as_bytes() {
- if curr >= 3 {
- break;
- }
-
- match b {
- b'.' | b'-' => {
- curr += 1;
- }
- b'0'..=b'9' => match curr {
- 0 => digit(&mut major, b),
- 1 => digit(&mut minor, b),
- _ => digit(&mut patch, b),
- },
- _ => break,
- }
- }
-
- Ok(if major >= 3 {
- VERS_3
- } else if major >= 2 {
- if minor >= 7 {
- VERS_UNKNOWN
- } else if minor >= 6 {
- if patch >= 28 {
- VERS_2_6_28
- } else if patch >= 27 {
- VERS_2_6_27
- } else {
- VERS_2_6_18
- }
- } else {
- VERS_UNKNOWN
- }
- } else {
- VERS_UNKNOWN
- })
- }
-
- fn kernel_version() -> Result<usize> {
- static mut KERNEL_VERS: usize = 0;
-
- unsafe {
- if KERNEL_VERS == 0 {
- KERNEL_VERS = parse_kernel_version()?;
- }
-
- Ok(KERNEL_VERS)
- }
- }
-
- /// Check if the OS supports atomic close-on-exec for sockets
- pub fn socket_atomic_cloexec() -> bool {
- kernel_version()
- .map(|version| version >= VERS_2_6_27)
- .unwrap_or(false)
- }
-
- #[test]
- pub fn test_parsing_kernel_version() {
- assert!(kernel_version().unwrap() > 0);
- }
-}
-
-#[cfg(any(
- target_os = "dragonfly", // Since ???
- target_os = "freebsd", // Since 10.0
- target_os = "illumos", // Since ???
- target_os = "netbsd", // Since 6.0
- target_os = "openbsd", // Since 5.7
- target_os = "redox", // Since 1-july-2020
-))]
-mod os {
- /// Check if the OS supports atomic close-on-exec for sockets
- pub const fn socket_atomic_cloexec() -> bool {
- true
- }
-}
-
-#[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "solaris"
-))]
-mod os {
- /// Check if the OS supports atomic close-on-exec for sockets
- pub const fn socket_atomic_cloexec() -> bool {
- false
- }
-}
diff --git a/vendor/nix/src/ifaddrs.rs b/vendor/nix/src/ifaddrs.rs
deleted file mode 100644
index 70b50b01e..000000000
--- a/vendor/nix/src/ifaddrs.rs
+++ /dev/null
@@ -1,213 +0,0 @@
-//! Query network interface addresses
-//!
-//! Uses the Linux and/or BSD specific function `getifaddrs` to query the list
-//! of interfaces and their associated addresses.
-
-use cfg_if::cfg_if;
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-use std::convert::TryFrom;
-use std::ffi;
-use std::iter::Iterator;
-use std::mem;
-use std::option::Option;
-
-use crate::net::if_::*;
-use crate::sys::socket::{SockaddrLike, SockaddrStorage};
-use crate::{Errno, Result};
-
-/// Describes a single address for an interface as returned by `getifaddrs`.
-#[derive(Clone, Debug, Eq, Hash, PartialEq)]
-pub struct InterfaceAddress {
- /// Name of the network interface
- pub interface_name: String,
- /// Flags as from `SIOCGIFFLAGS` ioctl
- pub flags: InterfaceFlags,
- /// Network address of this interface
- pub address: Option<SockaddrStorage>,
- /// Netmask of this interface
- pub netmask: Option<SockaddrStorage>,
- /// Broadcast address of this interface, if applicable
- pub broadcast: Option<SockaddrStorage>,
- /// Point-to-point destination address
- pub destination: Option<SockaddrStorage>,
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] {
- fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr {
- info.ifa_ifu
- }
- } else {
- fn get_ifu_from_sockaddr(info: &libc::ifaddrs) -> *const libc::sockaddr {
- info.ifa_dstaddr
- }
- }
-}
-
-/// Workaround a bug in XNU where netmasks will always have the wrong size in
-/// the sa_len field due to the kernel ignoring trailing zeroes in the structure
-/// when setting the field. See https://github.com/nix-rust/nix/issues/1709#issuecomment-1199304470
-///
-/// To fix this, we stack-allocate a new sockaddr_storage, zero it out, and
-/// memcpy sa_len of the netmask to that new storage. Finally, we reset the
-/// ss_len field to sizeof(sockaddr_storage). This is supposedly valid as all
-/// members of the sockaddr_storage are "ok" with being zeroed out (there are
-/// no pointers).
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-unsafe fn workaround_xnu_bug(info: &libc::ifaddrs) -> Option<SockaddrStorage> {
- let src_sock = info.ifa_netmask;
- if src_sock.is_null() {
- return None;
- }
-
- let mut dst_sock = mem::MaybeUninit::<libc::sockaddr_storage>::zeroed();
-
- // memcpy only sa_len bytes, assume the rest is zero
- std::ptr::copy_nonoverlapping(
- src_sock as *const u8,
- dst_sock.as_mut_ptr() as *mut u8,
- (*src_sock).sa_len.into(),
- );
-
- // Initialize ss_len to sizeof(libc::sockaddr_storage).
- (*dst_sock.as_mut_ptr()).ss_len =
- u8::try_from(mem::size_of::<libc::sockaddr_storage>()).unwrap();
- let dst_sock = dst_sock.assume_init();
-
- let dst_sock_ptr =
- &dst_sock as *const libc::sockaddr_storage as *const libc::sockaddr;
-
- SockaddrStorage::from_raw(dst_sock_ptr, None)
-}
-
-impl InterfaceAddress {
- /// Create an `InterfaceAddress` from the libc struct.
- fn from_libc_ifaddrs(info: &libc::ifaddrs) -> InterfaceAddress {
- let ifname = unsafe { ffi::CStr::from_ptr(info.ifa_name) };
- let address = unsafe { SockaddrStorage::from_raw(info.ifa_addr, None) };
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- let netmask = unsafe { workaround_xnu_bug(info) };
- #[cfg(not(any(target_os = "ios", target_os = "macos")))]
- let netmask =
- unsafe { SockaddrStorage::from_raw(info.ifa_netmask, None) };
- let mut addr = InterfaceAddress {
- interface_name: ifname.to_string_lossy().to_string(),
- flags: InterfaceFlags::from_bits_truncate(info.ifa_flags as i32),
- address,
- netmask,
- broadcast: None,
- destination: None,
- };
-
- let ifu = get_ifu_from_sockaddr(info);
- if addr.flags.contains(InterfaceFlags::IFF_POINTOPOINT) {
- addr.destination = unsafe { SockaddrStorage::from_raw(ifu, None) };
- } else if addr.flags.contains(InterfaceFlags::IFF_BROADCAST) {
- addr.broadcast = unsafe { SockaddrStorage::from_raw(ifu, None) };
- }
-
- addr
- }
-}
-
-/// Holds the results of `getifaddrs`.
-///
-/// Use the function `getifaddrs` to create this Iterator. Note that the
-/// actual list of interfaces can be iterated once and will be freed as
-/// soon as the Iterator goes out of scope.
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct InterfaceAddressIterator {
- base: *mut libc::ifaddrs,
- next: *mut libc::ifaddrs,
-}
-
-impl Drop for InterfaceAddressIterator {
- fn drop(&mut self) {
- unsafe { libc::freeifaddrs(self.base) };
- }
-}
-
-impl Iterator for InterfaceAddressIterator {
- type Item = InterfaceAddress;
- fn next(&mut self) -> Option<<Self as Iterator>::Item> {
- match unsafe { self.next.as_ref() } {
- Some(ifaddr) => {
- self.next = ifaddr.ifa_next;
- Some(InterfaceAddress::from_libc_ifaddrs(ifaddr))
- }
- None => None,
- }
- }
-}
-
-/// Get interface addresses using libc's `getifaddrs`
-///
-/// Note that the underlying implementation differs between OSes. Only the
-/// most common address families are supported by the nix crate (due to
-/// lack of time and complexity of testing). The address family is encoded
-/// in the specific variant of `SockaddrStorage` returned for the fields
-/// `address`, `netmask`, `broadcast`, and `destination`. For any entry not
-/// supported, the returned list will contain a `None` entry.
-///
-/// # Example
-/// ```
-/// let addrs = nix::ifaddrs::getifaddrs().unwrap();
-/// for ifaddr in addrs {
-/// match ifaddr.address {
-/// Some(address) => {
-/// println!("interface {} address {}",
-/// ifaddr.interface_name, address);
-/// },
-/// None => {
-/// println!("interface {} with unsupported address family",
-/// ifaddr.interface_name);
-/// }
-/// }
-/// }
-/// ```
-pub fn getifaddrs() -> Result<InterfaceAddressIterator> {
- let mut addrs = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit();
- unsafe {
- Errno::result(libc::getifaddrs(addrs.as_mut_ptr())).map(|_| {
- InterfaceAddressIterator {
- base: addrs.assume_init(),
- next: addrs.assume_init(),
- }
- })
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- // Only checks if `getifaddrs` can be invoked without panicking.
- #[test]
- fn test_getifaddrs() {
- let _ = getifaddrs();
- }
-
- // Ensures getting the netmask works, and in particular that
- // `workaround_xnu_bug` works properly.
- #[test]
- fn test_getifaddrs_netmask_correct() {
- let addrs = getifaddrs().unwrap();
- for iface in addrs {
- let sock = if let Some(sock) = iface.netmask {
- sock
- } else {
- continue;
- };
- if sock.family() == Some(crate::sys::socket::AddressFamily::Inet) {
- let _ = sock.as_sockaddr_in().unwrap();
- return;
- } else if sock.family()
- == Some(crate::sys::socket::AddressFamily::Inet6)
- {
- let _ = sock.as_sockaddr_in6().unwrap();
- return;
- }
- }
- panic!("No address?");
- }
-}
diff --git a/vendor/nix/src/kmod.rs b/vendor/nix/src/kmod.rs
deleted file mode 100644
index 1fa6c170d..000000000
--- a/vendor/nix/src/kmod.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-//! Load and unload kernel modules.
-//!
-//! For more details see
-
-use std::ffi::CStr;
-use std::os::unix::io::AsRawFd;
-
-use crate::errno::Errno;
-use crate::Result;
-
-/// Loads a kernel module from a buffer.
-///
-/// It loads an ELF image into kernel space,
-/// performs any necessary symbol relocations,
-/// initializes module parameters to values provided by the caller,
-/// and then runs the module's init function.
-///
-/// This function requires `CAP_SYS_MODULE` privilege.
-///
-/// The `module_image` argument points to a buffer containing the binary image
-/// to be loaded. The buffer should contain a valid ELF image
-/// built for the running kernel.
-///
-/// The `param_values` argument is a string containing space-delimited specifications
-/// of the values for module parameters.
-/// Each of the parameter specifications has the form:
-///
-/// `name[=value[,value...]]`
-///
-/// # Example
-///
-/// ```no_run
-/// use std::fs::File;
-/// use std::io::Read;
-/// use std::ffi::CString;
-/// use nix::kmod::init_module;
-///
-/// let mut f = File::open("mykernel.ko").unwrap();
-/// let mut contents: Vec<u8> = Vec::new();
-/// f.read_to_end(&mut contents).unwrap();
-/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap();
-/// ```
-///
-/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
-pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> {
- let res = unsafe {
- libc::syscall(
- libc::SYS_init_module,
- module_image.as_ptr(),
- module_image.len(),
- param_values.as_ptr(),
- )
- };
-
- Errno::result(res).map(drop)
-}
-
-libc_bitflags!(
- /// Flags used by the `finit_module` function.
- pub struct ModuleInitFlags: libc::c_uint {
- /// Ignore symbol version hashes.
- MODULE_INIT_IGNORE_MODVERSIONS;
- /// Ignore kernel version magic.
- MODULE_INIT_IGNORE_VERMAGIC;
- }
-);
-
-/// Loads a kernel module from a given file descriptor.
-///
-/// # Example
-///
-/// ```no_run
-/// use std::fs::File;
-/// use std::ffi::CString;
-/// use nix::kmod::{finit_module, ModuleInitFlags};
-///
-/// let f = File::open("mymod.ko").unwrap();
-/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap();
-/// ```
-///
-/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
-pub fn finit_module<T: AsRawFd>(
- fd: &T,
- param_values: &CStr,
- flags: ModuleInitFlags,
-) -> Result<()> {
- let res = unsafe {
- libc::syscall(
- libc::SYS_finit_module,
- fd.as_raw_fd(),
- param_values.as_ptr(),
- flags.bits(),
- )
- };
-
- Errno::result(res).map(drop)
-}
-
-libc_bitflags!(
- /// Flags used by `delete_module`.
- ///
- /// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html)
- /// for a detailed description how these flags work.
- pub struct DeleteModuleFlags: libc::c_int {
- O_NONBLOCK;
- O_TRUNC;
- }
-);
-
-/// Unloads the kernel module with the given name.
-///
-/// # Example
-///
-/// ```no_run
-/// use std::ffi::CString;
-/// use nix::kmod::{delete_module, DeleteModuleFlags};
-///
-/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap();
-/// ```
-///
-/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
-pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
- let res = unsafe {
- libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits())
- };
-
- Errno::result(res).map(drop)
-}
diff --git a/vendor/nix/src/lib.rs b/vendor/nix/src/lib.rs
deleted file mode 100644
index 6b8212576..000000000
--- a/vendor/nix/src/lib.rs
+++ /dev/null
@@ -1,333 +0,0 @@
-//! Rust friendly bindings to the various *nix system functions.
-//!
-//! Modules are structured according to the C header file that they would be
-//! defined in.
-//!
-//! # Features
-//!
-//! Nix uses the following Cargo features to enable optional functionality.
-//! They may be enabled in any combination.
-//! * `acct` - Process accounting
-//! * `aio` - POSIX AIO
-//! * `dir` - Stuff relating to directory iteration
-//! * `env` - Manipulate environment variables
-//! * `event` - Event-driven APIs, like `kqueue` and `epoll`
-//! * `feature` - Query characteristics of the OS at runtime
-//! * `fs` - File system functionality
-//! * `hostname` - Get and set the system's hostname
-//! * `inotify` - Linux's `inotify` file system notification API
-//! * `ioctl` - The `ioctl` syscall, and wrappers for my specific instances
-//! * `kmod` - Load and unload kernel modules
-//! * `mman` - Stuff relating to memory management
-//! * `mount` - Mount and unmount file systems
-//! * `mqueue` - POSIX message queues
-//! * `net` - Networking-related functionality
-//! * `personality` - Set the process execution domain
-//! * `poll` - APIs like `poll` and `select`
-//! * `process` - Stuff relating to running processes
-//! * `pthread` - POSIX threads
-//! * `ptrace` - Process tracing and debugging
-//! * `quota` - File system quotas
-//! * `reboot` - Reboot the system
-//! * `resource` - Process resource limits
-//! * `sched` - Manipulate process's scheduling
-//! * `socket` - Sockets, whether for networking or local use
-//! * `signal` - Send and receive signals to processes
-//! * `term` - Terminal control APIs
-//! * `time` - Query the operating system's clocks
-//! * `ucontext` - User thread context
-//! * `uio` - Vectored I/O
-//! * `user` - Stuff relating to users and groups
-//! * `zerocopy` - APIs like `sendfile` and `copy_file_range`
-#![crate_name = "nix"]
-#![cfg(unix)]
-#![cfg_attr(docsrs, doc(cfg(all())))]
-#![allow(non_camel_case_types)]
-#![cfg_attr(test, deny(warnings))]
-#![recursion_limit = "500"]
-#![deny(unused)]
-#![allow(unused_macros)]
-#![cfg_attr(not(feature = "default"), allow(unused_imports))]
-#![deny(unstable_features)]
-#![deny(missing_copy_implementations)]
-#![deny(missing_debug_implementations)]
-#![warn(missing_docs)]
-#![cfg_attr(docsrs, feature(doc_cfg))]
-#![deny(clippy::cast_ptr_alignment)]
-
-// Re-exported external crates
-pub use libc;
-
-// Private internal modules
-#[macro_use]
-mod macros;
-
-// Public crates
-#[cfg(not(target_os = "redox"))]
-feature! {
- #![feature = "dir"]
- pub mod dir;
-}
-feature! {
- #![feature = "env"]
- pub mod env;
-}
-#[allow(missing_docs)]
-pub mod errno;
-feature! {
- #![feature = "feature"]
-
- #[deny(missing_docs)]
- pub mod features;
-}
-#[allow(missing_docs)]
-pub mod fcntl;
-feature! {
- #![feature = "net"]
-
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"))]
- #[deny(missing_docs)]
- pub mod ifaddrs;
- #[cfg(not(target_os = "redox"))]
- #[deny(missing_docs)]
- pub mod net;
-}
-#[cfg(any(target_os = "android", target_os = "linux"))]
-feature! {
- #![feature = "kmod"]
- #[allow(missing_docs)]
- pub mod kmod;
-}
-feature! {
- #![feature = "mount"]
- pub mod mount;
-}
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd"
-))]
-feature! {
- #![feature = "mqueue"]
- pub mod mqueue;
-}
-feature! {
- #![feature = "poll"]
- pub mod poll;
-}
-#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
-feature! {
- #![feature = "term"]
- #[deny(missing_docs)]
- pub mod pty;
-}
-feature! {
- #![feature = "sched"]
- pub mod sched;
-}
-pub mod sys;
-feature! {
- #![feature = "time"]
- #[allow(missing_docs)]
- pub mod time;
-}
-// This can be implemented for other platforms as soon as libc
-// provides bindings for them.
-#[cfg(all(
- target_os = "linux",
- any(target_arch = "s390x", target_arch = "x86", target_arch = "x86_64")
-))]
-feature! {
- #![feature = "ucontext"]
- #[allow(missing_docs)]
- pub mod ucontext;
-}
-#[allow(missing_docs)]
-pub mod unistd;
-
-use std::ffi::{CStr, CString, OsStr};
-use std::mem::MaybeUninit;
-use std::os::unix::ffi::OsStrExt;
-use std::path::{Path, PathBuf};
-use std::{ptr, result, slice};
-
-use errno::Errno;
-
-/// Nix Result Type
-pub type Result<T> = result::Result<T, Errno>;
-
-/// Nix's main error type.
-///
-/// It's a wrapper around Errno. As such, it's very interoperable with
-/// [`std::io::Error`], but it has the advantages of:
-/// * `Clone`
-/// * `Copy`
-/// * `Eq`
-/// * Small size
-/// * Represents all of the system's errnos, instead of just the most common
-/// ones.
-pub type Error = Errno;
-
-/// Common trait used to represent file system paths by many Nix functions.
-pub trait NixPath {
- /// Is the path empty?
- fn is_empty(&self) -> bool;
-
- /// Length of the path in bytes
- fn len(&self) -> usize;
-
- /// Execute a function with this path as a `CStr`.
- ///
- /// Mostly used internally by Nix.
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T;
-}
-
-impl NixPath for str {
- fn is_empty(&self) -> bool {
- NixPath::is_empty(OsStr::new(self))
- }
-
- fn len(&self) -> usize {
- NixPath::len(OsStr::new(self))
- }
-
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T,
- {
- OsStr::new(self).with_nix_path(f)
- }
-}
-
-impl NixPath for OsStr {
- fn is_empty(&self) -> bool {
- self.as_bytes().is_empty()
- }
-
- fn len(&self) -> usize {
- self.as_bytes().len()
- }
-
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T,
- {
- self.as_bytes().with_nix_path(f)
- }
-}
-
-impl NixPath for CStr {
- fn is_empty(&self) -> bool {
- self.to_bytes().is_empty()
- }
-
- fn len(&self) -> usize {
- self.to_bytes().len()
- }
-
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T,
- {
- Ok(f(self))
- }
-}
-
-impl NixPath for [u8] {
- fn is_empty(&self) -> bool {
- self.is_empty()
- }
-
- fn len(&self) -> usize {
- self.len()
- }
-
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T,
- {
- // The real PATH_MAX is typically 4096, but it's statistically unlikely to have a path
- // longer than ~300 bytes. See the the PR description to get stats for your own machine.
- // https://github.com/nix-rust/nix/pull/1656
- //
- // By being smaller than a memory page, we also avoid the compiler inserting a probe frame:
- // https://docs.rs/compiler_builtins/latest/compiler_builtins/probestack/index.html
- const MAX_STACK_ALLOCATION: usize = 1024;
-
- if self.len() >= MAX_STACK_ALLOCATION {
- return with_nix_path_allocating(self, f);
- }
-
- let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit();
- let buf_ptr = buf.as_mut_ptr() as *mut u8;
-
- unsafe {
- ptr::copy_nonoverlapping(self.as_ptr(), buf_ptr, self.len());
- buf_ptr.add(self.len()).write(0);
- }
-
- match CStr::from_bytes_with_nul(unsafe {
- slice::from_raw_parts(buf_ptr, self.len() + 1)
- }) {
- Ok(s) => Ok(f(s)),
- Err(_) => Err(Errno::EINVAL),
- }
- }
-}
-
-#[cold]
-#[inline(never)]
-fn with_nix_path_allocating<T, F>(from: &[u8], f: F) -> Result<T>
-where
- F: FnOnce(&CStr) -> T,
-{
- match CString::new(from) {
- Ok(s) => Ok(f(&s)),
- Err(_) => Err(Errno::EINVAL),
- }
-}
-
-impl NixPath for Path {
- fn is_empty(&self) -> bool {
- NixPath::is_empty(self.as_os_str())
- }
-
- fn len(&self) -> usize {
- NixPath::len(self.as_os_str())
- }
-
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T,
- {
- self.as_os_str().with_nix_path(f)
- }
-}
-
-impl NixPath for PathBuf {
- fn is_empty(&self) -> bool {
- NixPath::is_empty(self.as_os_str())
- }
-
- fn len(&self) -> usize {
- NixPath::len(self.as_os_str())
- }
-
- fn with_nix_path<T, F>(&self, f: F) -> Result<T>
- where
- F: FnOnce(&CStr) -> T,
- {
- self.as_os_str().with_nix_path(f)
- }
-}
diff --git a/vendor/nix/src/macros.rs b/vendor/nix/src/macros.rs
deleted file mode 100644
index 99e0de886..000000000
--- a/vendor/nix/src/macros.rs
+++ /dev/null
@@ -1,328 +0,0 @@
-// Thanks to Tokio for this macro
-macro_rules! feature {
- (
- #![$meta:meta]
- $($item:item)*
- ) => {
- $(
- #[cfg($meta)]
- #[cfg_attr(docsrs, doc(cfg($meta)))]
- $item
- )*
- }
-}
-
-/// The `libc_bitflags!` macro helps with a common use case of defining a public bitflags type
-/// with values from the libc crate. It is used the same way as the `bitflags!` macro, except
-/// that only the name of the flag value has to be given.
-///
-/// The `libc` crate must be in scope with the name `libc`.
-///
-/// # Example
-/// ```ignore
-/// libc_bitflags!{
-/// pub struct ProtFlags: libc::c_int {
-/// PROT_NONE;
-/// PROT_READ;
-/// /// PROT_WRITE enables write protect
-/// PROT_WRITE;
-/// PROT_EXEC;
-/// #[cfg(any(target_os = "linux", target_os = "android"))]
-/// PROT_GROWSDOWN;
-/// #[cfg(any(target_os = "linux", target_os = "android"))]
-/// PROT_GROWSUP;
-/// }
-/// }
-/// ```
-///
-/// Example with casting, due to a mistake in libc. In this example, the
-/// various flags have different types, so we cast the broken ones to the right
-/// type.
-///
-/// ```ignore
-/// libc_bitflags!{
-/// pub struct SaFlags: libc::c_ulong {
-/// SA_NOCLDSTOP as libc::c_ulong;
-/// SA_NOCLDWAIT;
-/// SA_NODEFER as libc::c_ulong;
-/// SA_ONSTACK;
-/// SA_RESETHAND as libc::c_ulong;
-/// SA_RESTART as libc::c_ulong;
-/// SA_SIGINFO;
-/// }
-/// }
-/// ```
-macro_rules! libc_bitflags {
- (
- $(#[$outer:meta])*
- pub struct $BitFlags:ident: $T:ty {
- $(
- $(#[$inner:ident $($args:tt)*])*
- $Flag:ident $(as $cast:ty)*;
- )+
- }
- ) => {
- ::bitflags::bitflags! {
- $(#[$outer])*
- pub struct $BitFlags: $T {
- $(
- $(#[$inner $($args)*])*
- const $Flag = libc::$Flag $(as $cast)*;
- )+
- }
- }
- };
-}
-
-/// The `libc_enum!` macro helps with a common use case of defining an enum exclusively using
-/// values from the `libc` crate. This macro supports both `pub` and private `enum`s.
-///
-/// The `libc` crate must be in scope with the name `libc`.
-///
-/// # Example
-/// ```ignore
-/// libc_enum!{
-/// pub enum ProtFlags {
-/// PROT_NONE,
-/// PROT_READ,
-/// PROT_WRITE,
-/// PROT_EXEC,
-/// #[cfg(any(target_os = "linux", target_os = "android"))]
-/// PROT_GROWSDOWN,
-/// #[cfg(any(target_os = "linux", target_os = "android"))]
-/// PROT_GROWSUP,
-/// }
-/// }
-/// ```
-// Some targets don't use all rules.
-#[allow(unknown_lints)]
-#[allow(unused_macro_rules)]
-macro_rules! libc_enum {
- // Exit rule.
- (@make_enum
- name: $BitFlags:ident,
- {
- $v:vis
- attrs: [$($attrs:tt)*],
- entries: [$($entries:tt)*],
- }
- ) => {
- $($attrs)*
- #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
- $v enum $BitFlags {
- $($entries)*
- }
- };
-
- // Exit rule including TryFrom
- (@make_enum
- name: $BitFlags:ident,
- {
- $v:vis
- attrs: [$($attrs:tt)*],
- entries: [$($entries:tt)*],
- from_type: $repr:path,
- try_froms: [$($try_froms:tt)*]
- }
- ) => {
- $($attrs)*
- #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
- $v enum $BitFlags {
- $($entries)*
- }
- impl ::std::convert::TryFrom<$repr> for $BitFlags {
- type Error = $crate::Error;
- #[allow(unused_doc_comments)]
- fn try_from(x: $repr) -> $crate::Result<Self> {
- match x {
- $($try_froms)*
- _ => Err($crate::Error::EINVAL)
- }
- }
- }
- };
-
- // Done accumulating.
- (@accumulate_entries
- name: $BitFlags:ident,
- {
- $v:vis
- attrs: $attrs:tt,
- },
- $entries:tt,
- $try_froms:tt;
- ) => {
- libc_enum! {
- @make_enum
- name: $BitFlags,
- {
- $v
- attrs: $attrs,
- entries: $entries,
- }
- }
- };
-
- // Done accumulating and want TryFrom
- (@accumulate_entries
- name: $BitFlags:ident,
- {
- $v:vis
- attrs: $attrs:tt,
- from_type: $repr:path,
- },
- $entries:tt,
- $try_froms:tt;
- ) => {
- libc_enum! {
- @make_enum
- name: $BitFlags,
- {
- $v
- attrs: $attrs,
- entries: $entries,
- from_type: $repr,
- try_froms: $try_froms
- }
- }
- };
-
- // Munch an attr.
- (@accumulate_entries
- name: $BitFlags:ident,
- $prefix:tt,
- [$($entries:tt)*],
- [$($try_froms:tt)*];
- #[$attr:meta] $($tail:tt)*
- ) => {
- libc_enum! {
- @accumulate_entries
- name: $BitFlags,
- $prefix,
- [
- $($entries)*
- #[$attr]
- ],
- [
- $($try_froms)*
- #[$attr]
- ];
- $($tail)*
- }
- };
-
- // Munch last ident if not followed by a comma.
- (@accumulate_entries
- name: $BitFlags:ident,
- $prefix:tt,
- [$($entries:tt)*],
- [$($try_froms:tt)*];
- $entry:ident
- ) => {
- libc_enum! {
- @accumulate_entries
- name: $BitFlags,
- $prefix,
- [
- $($entries)*
- $entry = libc::$entry,
- ],
- [
- $($try_froms)*
- libc::$entry => Ok($BitFlags::$entry),
- ];
- }
- };
-
- // Munch an ident; covers terminating comma case.
- (@accumulate_entries
- name: $BitFlags:ident,
- $prefix:tt,
- [$($entries:tt)*],
- [$($try_froms:tt)*];
- $entry:ident,
- $($tail:tt)*
- ) => {
- libc_enum! {
- @accumulate_entries
- name: $BitFlags,
- $prefix,
- [
- $($entries)*
- $entry = libc::$entry,
- ],
- [
- $($try_froms)*
- libc::$entry => Ok($BitFlags::$entry),
- ];
- $($tail)*
- }
- };
-
- // Munch an ident and cast it to the given type; covers terminating comma.
- (@accumulate_entries
- name: $BitFlags:ident,
- $prefix:tt,
- [$($entries:tt)*],
- [$($try_froms:tt)*];
- $entry:ident as $ty:ty,
- $($tail:tt)*
- ) => {
- libc_enum! {
- @accumulate_entries
- name: $BitFlags,
- $prefix,
- [
- $($entries)*
- $entry = libc::$entry as $ty,
- ],
- [
- $($try_froms)*
- libc::$entry as $ty => Ok($BitFlags::$entry),
- ];
- $($tail)*
- }
- };
-
- // Entry rule.
- (
- $(#[$attr:meta])*
- $v:vis enum $BitFlags:ident {
- $($vals:tt)*
- }
- ) => {
- libc_enum! {
- @accumulate_entries
- name: $BitFlags,
- {
- $v
- attrs: [$(#[$attr])*],
- },
- [],
- [];
- $($vals)*
- }
- };
-
- // Entry rule including TryFrom
- (
- $(#[$attr:meta])*
- $v:vis enum $BitFlags:ident {
- $($vals:tt)*
- }
- impl TryFrom<$repr:path>
- ) => {
- libc_enum! {
- @accumulate_entries
- name: $BitFlags,
- {
- $v
- attrs: [$(#[$attr])*],
- from_type: $repr,
- },
- [],
- [];
- $($vals)*
- }
- };
-}
diff --git a/vendor/nix/src/mount/bsd.rs b/vendor/nix/src/mount/bsd.rs
deleted file mode 100644
index d124f1f9a..000000000
--- a/vendor/nix/src/mount/bsd.rs
+++ /dev/null
@@ -1,453 +0,0 @@
-#[cfg(target_os = "freebsd")]
-use crate::Error;
-use crate::{Errno, NixPath, Result};
-use libc::c_int;
-#[cfg(target_os = "freebsd")]
-use libc::{c_char, c_uint, c_void};
-#[cfg(target_os = "freebsd")]
-use std::{
- borrow::Cow,
- ffi::{CStr, CString},
- fmt, io,
- marker::PhantomData,
-};
-
-libc_bitflags!(
- /// Used with [`Nmount::nmount`].
- pub struct MntFlags: c_int {
- /// ACL support enabled.
- #[cfg(any(target_os = "netbsd", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_ACLS;
- /// All I/O to the file system should be done asynchronously.
- MNT_ASYNC;
- /// dir should instead be a file system ID encoded as “FSID:val0:val1”.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_BYFSID;
- /// Force a read-write mount even if the file system appears to be
- /// unclean.
- MNT_FORCE;
- /// GEOM journal support enabled.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_GJOURNAL;
- /// MAC support for objects.
- #[cfg(any(target_os = "macos", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_MULTILABEL;
- /// Disable read clustering.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_NOCLUSTERR;
- /// Disable write clustering.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_NOCLUSTERW;
- /// Enable NFS version 4 ACLs.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_NFS4ACLS;
- /// Do not update access times.
- MNT_NOATIME;
- /// Disallow program execution.
- MNT_NOEXEC;
- /// Do not honor setuid or setgid bits on files when executing them.
- MNT_NOSUID;
- /// Do not follow symlinks.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_NOSYMFOLLOW;
- /// Mount read-only.
- MNT_RDONLY;
- /// Causes the vfs subsystem to update its data structures pertaining to
- /// the specified already mounted file system.
- MNT_RELOAD;
- /// Create a snapshot of the file system.
- ///
- /// See [mksnap_ffs(8)](https://www.freebsd.org/cgi/man.cgi?query=mksnap_ffs)
- #[cfg(any(target_os = "macos", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_SNAPSHOT;
- /// Using soft updates.
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_SOFTDEP;
- /// Directories with the SUID bit set chown new files to their own
- /// owner.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_SUIDDIR;
- /// All I/O to the file system should be done synchronously.
- MNT_SYNCHRONOUS;
- /// Union with underlying fs.
- #[cfg(any(
- target_os = "macos",
- target_os = "freebsd",
- target_os = "netbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_UNION;
- /// Indicates that the mount command is being applied to an already
- /// mounted file system.
- MNT_UPDATE;
- /// Check vnode use counts.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MNT_NONBUSY;
- }
-);
-
-/// The Error type of [`Nmount::nmount`].
-///
-/// It wraps an [`Errno`], but also may contain an additional message returned
-/// by `nmount(2)`.
-#[cfg(target_os = "freebsd")]
-#[derive(Debug)]
-pub struct NmountError {
- errno: Error,
- errmsg: Option<String>,
-}
-
-#[cfg(target_os = "freebsd")]
-impl NmountError {
- /// Returns the additional error string sometimes generated by `nmount(2)`.
- pub fn errmsg(&self) -> Option<&str> {
- self.errmsg.as_deref()
- }
-
- /// Returns the inner [`Error`]
- pub const fn error(&self) -> Error {
- self.errno
- }
-
- fn new(error: Error, errmsg: Option<&CStr>) -> Self {
- Self {
- errno: error,
- errmsg: errmsg.map(CStr::to_string_lossy).map(Cow::into_owned),
- }
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl std::error::Error for NmountError {}
-
-#[cfg(target_os = "freebsd")]
-impl fmt::Display for NmountError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if let Some(errmsg) = &self.errmsg {
- write!(f, "{:?}: {}: {}", self.errno, errmsg, self.errno.desc())
- } else {
- write!(f, "{:?}: {}", self.errno, self.errno.desc())
- }
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl From<NmountError> for io::Error {
- fn from(err: NmountError) -> Self {
- err.errno.into()
- }
-}
-
-/// Result type of [`Nmount::nmount`].
-#[cfg(target_os = "freebsd")]
-pub type NmountResult = std::result::Result<(), NmountError>;
-
-/// Mount a FreeBSD file system.
-///
-/// The `nmount(2)` system call works similarly to the `mount(8)` program; it
-/// takes its options as a series of name-value pairs. Most of the values are
-/// strings, as are all of the names. The `Nmount` structure builds up an
-/// argument list and then executes the syscall.
-///
-/// # Examples
-///
-/// To mount `target` onto `mountpoint` with `nullfs`:
-/// ```
-/// # use nix::unistd::Uid;
-/// # use ::sysctl::{CtlValue, Sysctl};
-/// # let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap();
-/// # if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap() {
-/// # return;
-/// # };
-/// use nix::mount::{MntFlags, Nmount, unmount};
-/// use std::ffi::CString;
-/// use tempfile::tempdir;
-///
-/// let mountpoint = tempdir().unwrap();
-/// let target = tempdir().unwrap();
-///
-/// let fstype = CString::new("fstype").unwrap();
-/// let nullfs = CString::new("nullfs").unwrap();
-/// Nmount::new()
-/// .str_opt(&fstype, &nullfs)
-/// .str_opt_owned("fspath", mountpoint.path().to_str().unwrap())
-/// .str_opt_owned("target", target.path().to_str().unwrap())
-/// .nmount(MntFlags::empty()).unwrap();
-///
-/// unmount(mountpoint.path(), MntFlags::empty()).unwrap();
-/// ```
-///
-/// # See Also
-/// * [`nmount(2)`](https://www.freebsd.org/cgi/man.cgi?query=nmount)
-/// * [`nullfs(5)`](https://www.freebsd.org/cgi/man.cgi?query=nullfs)
-#[cfg(target_os = "freebsd")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-#[derive(Debug, Default)]
-pub struct Nmount<'a> {
- // n.b. notgull: In reality, this is a list that contains
- // both mutable and immutable pointers.
- // Be careful using this.
- iov: Vec<libc::iovec>,
- is_owned: Vec<bool>,
- marker: PhantomData<&'a ()>,
-}
-
-#[cfg(target_os = "freebsd")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-impl<'a> Nmount<'a> {
- /// Helper function to push a slice onto the `iov` array.
- fn push_slice(&mut self, val: &'a [u8], is_owned: bool) {
- self.iov.push(libc::iovec {
- iov_base: val.as_ptr() as *mut _,
- iov_len: val.len(),
- });
- self.is_owned.push(is_owned);
- }
-
- /// Helper function to push a pointer and its length onto the `iov` array.
- fn push_pointer_and_length(
- &mut self,
- val: *const u8,
- len: usize,
- is_owned: bool,
- ) {
- self.iov.push(libc::iovec {
- iov_base: val as *mut _,
- iov_len: len,
- });
- self.is_owned.push(is_owned);
- }
-
- /// Helper function to push a `nix` path as owned.
- fn push_nix_path<P: ?Sized + NixPath>(&mut self, val: &P) {
- val.with_nix_path(|s| {
- let len = s.to_bytes_with_nul().len();
- let ptr = s.to_owned().into_raw() as *const u8;
-
- self.push_pointer_and_length(ptr, len, true);
- })
- .unwrap();
- }
-
- /// Add an opaque mount option.
- ///
- /// Some file systems take binary-valued mount options. They can be set
- /// with this method.
- ///
- /// # Safety
- ///
- /// Unsafe because it will cause `Nmount::nmount` to dereference a raw
- /// pointer. The user is responsible for ensuring that `val` is valid and
- /// its lifetime outlives `self`! An easy way to do that is to give the
- /// value a larger scope than `name`
- ///
- /// # Examples
- /// ```
- /// use libc::c_void;
- /// use nix::mount::Nmount;
- /// use std::ffi::CString;
- /// use std::mem;
- ///
- /// // Note that flags outlives name
- /// let mut flags: u32 = 0xdeadbeef;
- /// let name = CString::new("flags").unwrap();
- /// let p = &mut flags as *mut u32 as *mut c_void;
- /// let len = mem::size_of_val(&flags);
- /// let mut nmount = Nmount::new();
- /// unsafe { nmount.mut_ptr_opt(&name, p, len) };
- /// ```
- pub unsafe fn mut_ptr_opt(
- &mut self,
- name: &'a CStr,
- val: *mut c_void,
- len: usize,
- ) -> &mut Self {
- self.push_slice(name.to_bytes_with_nul(), false);
- self.push_pointer_and_length(val.cast(), len, false);
- self
- }
-
- /// Add a mount option that does not take a value.
- ///
- /// # Examples
- /// ```
- /// use nix::mount::Nmount;
- /// use std::ffi::CString;
- ///
- /// let read_only = CString::new("ro").unwrap();
- /// Nmount::new()
- /// .null_opt(&read_only);
- /// ```
- pub fn null_opt(&mut self, name: &'a CStr) -> &mut Self {
- self.push_slice(name.to_bytes_with_nul(), false);
- self.push_slice(&[], false);
- self
- }
-
- /// Add a mount option that does not take a value, but whose name must be
- /// owned.
- ///
- ///
- /// This has higher runtime cost than [`Nmount::null_opt`], but is useful
- /// when the name's lifetime doesn't outlive the `Nmount`, or it's a
- /// different string type than `CStr`.
- ///
- /// # Examples
- /// ```
- /// use nix::mount::Nmount;
- ///
- /// let read_only = "ro";
- /// let mut nmount: Nmount<'static> = Nmount::new();
- /// nmount.null_opt_owned(read_only);
- /// ```
- pub fn null_opt_owned<P: ?Sized + NixPath>(
- &mut self,
- name: &P,
- ) -> &mut Self {
- self.push_nix_path(name);
- self.push_slice(&[], false);
- self
- }
-
- /// Add a mount option as a [`CStr`].
- ///
- /// # Examples
- /// ```
- /// use nix::mount::Nmount;
- /// use std::ffi::CString;
- ///
- /// let fstype = CString::new("fstype").unwrap();
- /// let nullfs = CString::new("nullfs").unwrap();
- /// Nmount::new()
- /// .str_opt(&fstype, &nullfs);
- /// ```
- pub fn str_opt(&mut self, name: &'a CStr, val: &'a CStr) -> &mut Self {
- self.push_slice(name.to_bytes_with_nul(), false);
- self.push_slice(val.to_bytes_with_nul(), false);
- self
- }
-
- /// Add a mount option as an owned string.
- ///
- /// This has higher runtime cost than [`Nmount::str_opt`], but is useful
- /// when the value's lifetime doesn't outlive the `Nmount`, or it's a
- /// different string type than `CStr`.
- ///
- /// # Examples
- /// ```
- /// use nix::mount::Nmount;
- /// use std::path::Path;
- ///
- /// let mountpoint = Path::new("/mnt");
- /// Nmount::new()
- /// .str_opt_owned("fspath", mountpoint.to_str().unwrap());
- /// ```
- pub fn str_opt_owned<P1, P2>(&mut self, name: &P1, val: &P2) -> &mut Self
- where
- P1: ?Sized + NixPath,
- P2: ?Sized + NixPath,
- {
- self.push_nix_path(name);
- self.push_nix_path(val);
- self
- }
-
- /// Create a new `Nmount` struct with no options
- pub fn new() -> Self {
- Self::default()
- }
-
- /// Actually mount the file system.
- pub fn nmount(&mut self, flags: MntFlags) -> NmountResult {
- const ERRMSG_NAME: &[u8] = b"errmsg\0";
- let mut errmsg = vec![0u8; 255];
-
- // nmount can return extra error information via a "errmsg" return
- // argument.
- self.push_slice(ERRMSG_NAME, false);
-
- // SAFETY: we are pushing a mutable iovec here, so we can't use
- // the above method
- self.iov.push(libc::iovec {
- iov_base: errmsg.as_mut_ptr() as *mut c_void,
- iov_len: errmsg.len(),
- });
-
- let niov = self.iov.len() as c_uint;
- let iovp = self.iov.as_mut_ptr() as *mut libc::iovec;
- let res = unsafe { libc::nmount(iovp, niov, flags.bits) };
- match Errno::result(res) {
- Ok(_) => Ok(()),
- Err(error) => {
- let errmsg = match errmsg.iter().position(|&x| x == 0) {
- None => None,
- Some(0) => None,
- Some(n) => {
- let sl = &errmsg[0..n + 1];
- Some(CStr::from_bytes_with_nul(sl).unwrap())
- }
- };
- Err(NmountError::new(error, errmsg))
- }
- }
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> Drop for Nmount<'a> {
- fn drop(&mut self) {
- for (iov, is_owned) in self.iov.iter().zip(self.is_owned.iter()) {
- if *is_owned {
- // Free the owned string. Safe because we recorded ownership,
- // and Nmount does not implement Clone.
- unsafe {
- drop(CString::from_raw(iov.iov_base as *mut c_char));
- }
- }
- }
- }
-}
-
-/// Unmount the file system mounted at `mountpoint`.
-///
-/// Useful flags include
-/// * `MNT_FORCE` - Unmount even if still in use.
-#[cfg_attr(
- target_os = "freebsd",
- doc = "
-* `MNT_BYFSID` - `mountpoint` is not a path, but a file system ID
- encoded as `FSID:val0:val1`, where `val0` and `val1`
- are the contents of the `fsid_t val[]` array in decimal.
- The file system that has the specified file system ID
- will be unmounted. See
- [`statfs`](crate::sys::statfs::statfs) to determine the
- `fsid`.
-"
-)]
-pub fn unmount<P>(mountpoint: &P, flags: MntFlags) -> Result<()>
-where
- P: ?Sized + NixPath,
-{
- let res = mountpoint.with_nix_path(|cstr| unsafe {
- libc::unmount(cstr.as_ptr(), flags.bits)
- })?;
-
- Errno::result(res).map(drop)
-}
diff --git a/vendor/nix/src/mount/linux.rs b/vendor/nix/src/mount/linux.rs
deleted file mode 100644
index cf6a60b01..000000000
--- a/vendor/nix/src/mount/linux.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-#![allow(missing_docs)]
-use crate::errno::Errno;
-use crate::{NixPath, Result};
-use libc::{self, c_int, c_ulong};
-
-libc_bitflags!(
- pub struct MsFlags: c_ulong {
- /// Mount read-only
- MS_RDONLY;
- /// Ignore suid and sgid bits
- MS_NOSUID;
- /// Disallow access to device special files
- MS_NODEV;
- /// Disallow program execution
- MS_NOEXEC;
- /// Writes are synced at once
- MS_SYNCHRONOUS;
- /// Alter flags of a mounted FS
- MS_REMOUNT;
- /// Allow mandatory locks on a FS
- MS_MANDLOCK;
- /// Directory modifications are synchronous
- MS_DIRSYNC;
- /// Do not update access times
- MS_NOATIME;
- /// Do not update directory access times
- MS_NODIRATIME;
- /// Linux 2.4.0 - Bind directory at different place
- MS_BIND;
- MS_MOVE;
- MS_REC;
- MS_SILENT;
- MS_POSIXACL;
- MS_UNBINDABLE;
- MS_PRIVATE;
- MS_SLAVE;
- MS_SHARED;
- MS_RELATIME;
- MS_KERNMOUNT;
- MS_I_VERSION;
- MS_STRICTATIME;
- MS_LAZYTIME;
- MS_ACTIVE;
- MS_NOUSER;
- MS_RMT_MASK;
- MS_MGC_VAL;
- MS_MGC_MSK;
- }
-);
-
-libc_bitflags!(
- pub struct MntFlags: c_int {
- MNT_FORCE;
- MNT_DETACH;
- MNT_EXPIRE;
- UMOUNT_NOFOLLOW;
- }
-);
-
-pub fn mount<
- P1: ?Sized + NixPath,
- P2: ?Sized + NixPath,
- P3: ?Sized + NixPath,
- P4: ?Sized + NixPath,
->(
- source: Option<&P1>,
- target: &P2,
- fstype: Option<&P3>,
- flags: MsFlags,
- data: Option<&P4>,
-) -> Result<()> {
- fn with_opt_nix_path<P, T, F>(p: Option<&P>, f: F) -> Result<T>
- where
- P: ?Sized + NixPath,
- F: FnOnce(*const libc::c_char) -> T,
- {
- match p {
- Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
- None => Ok(f(std::ptr::null())),
- }
- }
-
- let res = with_opt_nix_path(source, |s| {
- target.with_nix_path(|t| {
- with_opt_nix_path(fstype, |ty| {
- with_opt_nix_path(data, |d| unsafe {
- libc::mount(
- s,
- t.as_ptr(),
- ty,
- flags.bits,
- d as *const libc::c_void,
- )
- })
- })
- })
- })????;
-
- Errno::result(res).map(drop)
-}
-
-pub fn umount<P: ?Sized + NixPath>(target: &P) -> Result<()> {
- let res =
- target.with_nix_path(|cstr| unsafe { libc::umount(cstr.as_ptr()) })?;
-
- Errno::result(res).map(drop)
-}
-
-pub fn umount2<P: ?Sized + NixPath>(target: &P, flags: MntFlags) -> Result<()> {
- let res = target.with_nix_path(|cstr| unsafe {
- libc::umount2(cstr.as_ptr(), flags.bits)
- })?;
-
- Errno::result(res).map(drop)
-}
diff --git a/vendor/nix/src/mount/mod.rs b/vendor/nix/src/mount/mod.rs
deleted file mode 100644
index e98b49c34..000000000
--- a/vendor/nix/src/mount/mod.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//! Mount file systems
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod linux;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use self::linux::*;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod bsd;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-pub use self::bsd::*;
diff --git a/vendor/nix/src/mqueue.rs b/vendor/nix/src/mqueue.rs
deleted file mode 100644
index 33599bf91..000000000
--- a/vendor/nix/src/mqueue.rs
+++ /dev/null
@@ -1,276 +0,0 @@
-//! Posix Message Queue functions
-//!
-//! # Example
-//!
-// no_run because a kernel module may be required.
-//! ```no_run
-//! # use std::ffi::CString;
-//! # use nix::mqueue::*;
-//! use nix::sys::stat::Mode;
-//!
-//! const MSG_SIZE: mq_attr_member_t = 32;
-//! let mq_name= CString::new("/a_nix_test_queue").unwrap();
-//!
-//! let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
-//! let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
-//! let mqd0 = mq_open(&mq_name, oflag0, mode, None).unwrap();
-//! let msg_to_send = b"msg_1";
-//! mq_send(&mqd0, msg_to_send, 1).unwrap();
-//!
-//! let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
-//! let mqd1 = mq_open(&mq_name, oflag1, mode, None).unwrap();
-//! let mut buf = [0u8; 32];
-//! let mut prio = 0u32;
-//! let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap();
-//! assert_eq!(prio, 1);
-//! assert_eq!(msg_to_send, &buf[0..len]);
-//!
-//! mq_close(mqd1).unwrap();
-//! mq_close(mqd0).unwrap();
-//! ```
-//! [Further reading and details on the C API](https://man7.org/linux/man-pages/man7/mq_overview.7.html)
-
-use crate::errno::Errno;
-use crate::Result;
-
-use crate::sys::stat::Mode;
-use libc::{self, c_char, mqd_t, size_t};
-use std::ffi::CStr;
-use std::mem;
-
-libc_bitflags! {
- /// Used with [`mq_open`].
- pub struct MQ_OFlag: libc::c_int {
- /// Open the message queue for receiving messages.
- O_RDONLY;
- /// Open the queue for sending messages.
- O_WRONLY;
- /// Open the queue for both receiving and sending messages
- O_RDWR;
- /// Create a message queue.
- O_CREAT;
- /// If set along with `O_CREAT`, `mq_open` will fail if the message
- /// queue name exists.
- O_EXCL;
- /// `mq_send` and `mq_receive` should fail with `EAGAIN` rather than
- /// wait for resources that are not currently available.
- O_NONBLOCK;
- /// Set the close-on-exec flag for the message queue descriptor.
- O_CLOEXEC;
- }
-}
-
-/// A message-queue attribute, optionally used with [`mq_setattr`] and
-/// [`mq_getattr`] and optionally [`mq_open`],
-#[repr(C)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct MqAttr {
- mq_attr: libc::mq_attr,
-}
-
-/// Identifies an open POSIX Message Queue
-// A safer wrapper around libc::mqd_t, which is a pointer on some platforms
-// Deliberately is not Clone to prevent use-after-close scenarios
-#[repr(transparent)]
-#[derive(Debug)]
-#[allow(missing_copy_implementations)]
-pub struct MqdT(mqd_t);
-
-// x32 compatibility
-// See https://sourceware.org/bugzilla/show_bug.cgi?id=21279
-/// Size of a message queue attribute member
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub type mq_attr_member_t = i64;
-/// Size of a message queue attribute member
-#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub type mq_attr_member_t = libc::c_long;
-
-impl MqAttr {
- /// Create a new message queue attribute
- ///
- /// # Arguments
- ///
- /// - `mq_flags`: Either `0` or `O_NONBLOCK`.
- /// - `mq_maxmsg`: Maximum number of messages on the queue.
- /// - `mq_msgsize`: Maximum message size in bytes.
- /// - `mq_curmsgs`: Number of messages currently in the queue.
- pub fn new(
- mq_flags: mq_attr_member_t,
- mq_maxmsg: mq_attr_member_t,
- mq_msgsize: mq_attr_member_t,
- mq_curmsgs: mq_attr_member_t,
- ) -> MqAttr {
- let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
- unsafe {
- let p = attr.as_mut_ptr();
- (*p).mq_flags = mq_flags;
- (*p).mq_maxmsg = mq_maxmsg;
- (*p).mq_msgsize = mq_msgsize;
- (*p).mq_curmsgs = mq_curmsgs;
- MqAttr {
- mq_attr: attr.assume_init(),
- }
- }
- }
-
- /// The current flags, either `0` or `O_NONBLOCK`.
- pub const fn flags(&self) -> mq_attr_member_t {
- self.mq_attr.mq_flags
- }
-
- /// The max number of messages that can be held by the queue
- pub const fn maxmsg(&self) -> mq_attr_member_t {
- self.mq_attr.mq_maxmsg
- }
-
- /// The maximum size of each message (in bytes)
- pub const fn msgsize(&self) -> mq_attr_member_t {
- self.mq_attr.mq_msgsize
- }
-
- /// The number of messages currently held in the queue
- pub const fn curmsgs(&self) -> mq_attr_member_t {
- self.mq_attr.mq_curmsgs
- }
-}
-
-/// Open a message queue
-///
-/// See also [`mq_open(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_open.html)
-// The mode.bits cast is only lossless on some OSes
-#[allow(clippy::cast_lossless)]
-pub fn mq_open(
- name: &CStr,
- oflag: MQ_OFlag,
- mode: Mode,
- attr: Option<&MqAttr>,
-) -> Result<MqdT> {
- let res = match attr {
- Some(mq_attr) => unsafe {
- libc::mq_open(
- name.as_ptr(),
- oflag.bits(),
- mode.bits() as libc::c_int,
- &mq_attr.mq_attr as *const libc::mq_attr,
- )
- },
- None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) },
- };
- Errno::result(res).map(MqdT)
-}
-
-/// Remove a message queue
-///
-/// See also [`mq_unlink(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_unlink.html)
-pub fn mq_unlink(name: &CStr) -> Result<()> {
- let res = unsafe { libc::mq_unlink(name.as_ptr()) };
- Errno::result(res).map(drop)
-}
-
-/// Close a message queue
-///
-/// See also [`mq_close(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_close.html)
-pub fn mq_close(mqdes: MqdT) -> Result<()> {
- let res = unsafe { libc::mq_close(mqdes.0) };
- Errno::result(res).map(drop)
-}
-
-/// Receive a message from a message queue
-///
-/// See also [`mq_receive(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
-pub fn mq_receive(
- mqdes: &MqdT,
- message: &mut [u8],
- msg_prio: &mut u32,
-) -> Result<usize> {
- let len = message.len() as size_t;
- let res = unsafe {
- libc::mq_receive(
- mqdes.0,
- message.as_mut_ptr() as *mut c_char,
- len,
- msg_prio as *mut u32,
- )
- };
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Send a message to a message queue
-///
-/// See also [`mq_send(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
-pub fn mq_send(mqdes: &MqdT, message: &[u8], msq_prio: u32) -> Result<()> {
- let res = unsafe {
- libc::mq_send(
- mqdes.0,
- message.as_ptr() as *const c_char,
- message.len(),
- msq_prio,
- )
- };
- Errno::result(res).map(drop)
-}
-
-/// Get message queue attributes
-///
-/// See also [`mq_getattr(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_getattr.html)
-pub fn mq_getattr(mqd: &MqdT) -> Result<MqAttr> {
- let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
- let res = unsafe { libc::mq_getattr(mqd.0, attr.as_mut_ptr()) };
- Errno::result(res).map(|_| unsafe {
- MqAttr {
- mq_attr: attr.assume_init(),
- }
- })
-}
-
-/// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored
-/// Returns the old attributes
-/// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_setattr.html)
-pub fn mq_setattr(mqd: &MqdT, newattr: &MqAttr) -> Result<MqAttr> {
- let mut attr = mem::MaybeUninit::<libc::mq_attr>::uninit();
- let res = unsafe {
- libc::mq_setattr(
- mqd.0,
- &newattr.mq_attr as *const libc::mq_attr,
- attr.as_mut_ptr(),
- )
- };
- Errno::result(res).map(|_| unsafe {
- MqAttr {
- mq_attr: attr.assume_init(),
- }
- })
-}
-
-/// Convenience function.
-/// Sets the `O_NONBLOCK` attribute for a given message queue descriptor
-/// Returns the old attributes
-#[allow(clippy::useless_conversion)] // Not useless on all OSes
-pub fn mq_set_nonblock(mqd: &MqdT) -> Result<MqAttr> {
- let oldattr = mq_getattr(mqd)?;
- let newattr = MqAttr::new(
- mq_attr_member_t::from(MQ_OFlag::O_NONBLOCK.bits()),
- oldattr.mq_attr.mq_maxmsg,
- oldattr.mq_attr.mq_msgsize,
- oldattr.mq_attr.mq_curmsgs,
- );
- mq_setattr(mqd, &newattr)
-}
-
-/// Convenience function.
-/// Removes `O_NONBLOCK` attribute for a given message queue descriptor
-/// Returns the old attributes
-pub fn mq_remove_nonblock(mqd: &MqdT) -> Result<MqAttr> {
- let oldattr = mq_getattr(mqd)?;
- let newattr = MqAttr::new(
- 0,
- oldattr.mq_attr.mq_maxmsg,
- oldattr.mq_attr.mq_msgsize,
- oldattr.mq_attr.mq_curmsgs,
- );
- mq_setattr(mqd, &newattr)
-}
diff --git a/vendor/nix/src/net/if_.rs b/vendor/nix/src/net/if_.rs
deleted file mode 100644
index b2423bc67..000000000
--- a/vendor/nix/src/net/if_.rs
+++ /dev/null
@@ -1,469 +0,0 @@
-//! Network interface name resolution.
-//!
-//! Uses Linux and/or POSIX functions to resolve interface names like "eth0"
-//! or "socan1" into device numbers.
-
-use crate::{Error, NixPath, Result};
-use libc::c_uint;
-
-/// Resolve an interface into a interface number.
-pub fn if_nametoindex<P: ?Sized + NixPath>(name: &P) -> Result<c_uint> {
- let if_index = name
- .with_nix_path(|name| unsafe { libc::if_nametoindex(name.as_ptr()) })?;
-
- if if_index == 0 {
- Err(Error::last())
- } else {
- Ok(if_index)
- }
-}
-
-libc_bitflags!(
- /// Standard interface flags, used by `getifaddrs`
- pub struct InterfaceFlags: libc::c_int {
- /// Interface is running. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_UP;
- /// Valid broadcast address set. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_BROADCAST;
- /// Internal debugging flag. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(not(target_os = "haiku"))]
- IFF_DEBUG;
- /// Interface is a loopback interface. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_LOOPBACK;
- /// Interface is a point-to-point link. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_POINTOPOINT;
- /// Avoid use of trailers. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NOTRAILERS;
- /// Interface manages own routes.
- #[cfg(any(target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_SMART;
- /// Resources allocated. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_RUNNING;
- /// No arp protocol, L2 destination address not set. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_NOARP;
- /// Interface is in promiscuous mode. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_PROMISC;
- /// Receive all multicast packets. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_ALLMULTI;
- /// Master of a load balancing bundle. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_MASTER;
- /// transmission in progress, tx hardware queue is full
- #[cfg(any(target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "ios"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_OACTIVE;
- /// Protocol code on board.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_INTELLIGENT;
- /// Slave of a load balancing bundle. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_SLAVE;
- /// Can't hear own transmissions.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_SIMPLEX;
- /// Supports multicast. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- IFF_MULTICAST;
- /// Per link layer defined bit.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "ios"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_LINK0;
- /// Multicast using broadcast.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_MULTI_BCAST;
- /// Is able to select media type via ifmap. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_PORTSEL;
- /// Per link layer defined bit.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "ios"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_LINK1;
- /// Non-unique address.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_UNNUMBERED;
- /// Auto media selection active. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_AUTOMEDIA;
- /// Per link layer defined bit.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "ios"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_LINK2;
- /// Use alternate physical connection.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_ALTPHYS;
- /// DHCP controls interface.
- #[cfg(any(target_os = "solaris", target_os = "illumos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_DHCPRUNNING;
- /// The addresses are lost when the interface goes down. (see
- /// [`netdevice(7)`](https://man7.org/linux/man-pages/man7/netdevice.7.html))
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_DYNAMIC;
- /// Do not advertise.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_PRIVATE;
- /// Driver signals L1 up. Volatile.
- #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_LOWER_UP;
- /// Interface is in polling mode.
- #[cfg(any(target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_POLLING_COMPAT;
- /// Unconfigurable using ioctl(2).
- #[cfg(any(target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_CANTCONFIG;
- /// Do not transmit packets.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NOXMIT;
- /// Driver signals dormant. Volatile.
- #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_DORMANT;
- /// User-requested promisc mode.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_PPROMISC;
- /// Just on-link subnet.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NOLOCAL;
- /// Echo sent packets. Volatile.
- #[cfg(any(target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_ECHO;
- /// User-requested monitor mode.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_MONITOR;
- /// Address is deprecated.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_DEPRECATED;
- /// Static ARP.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_STATICARP;
- /// Address from stateless addrconf.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_ADDRCONF;
- /// Interface is in polling mode.
- #[cfg(any(target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NPOLLING;
- /// Router on interface.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_ROUTER;
- /// Interface is in polling mode.
- #[cfg(any(target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_IDIRECT;
- /// Interface is winding down
- #[cfg(any(target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_DYING;
- /// No NUD on interface.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NONUD;
- /// Interface is being renamed
- #[cfg(any(target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_RENAMING;
- /// Anycast address.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_ANYCAST;
- /// Don't exchange routing info.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NORTEXCH;
- /// Do not provide packet information
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NO_PI as libc::c_int;
- /// TUN device (no Ethernet headers)
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_TUN as libc::c_int;
- /// TAP device
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_TAP as libc::c_int;
- /// IPv4 interface.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_IPV4;
- /// IPv6 interface.
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_IPV6;
- /// in.mpathd test address
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_NOFAILOVER;
- /// Interface has failed
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_FAILED;
- /// Interface is a hot-spare
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_STANDBY;
- /// Functioning but not used
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_INACTIVE;
- /// Interface is offline
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_OFFLINE;
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_COS_ENABLED;
- /// Prefer as source addr.
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_PREFERRED;
- /// RFC3041
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_TEMPORARY;
- /// MTU set with SIOCSLIFMTU
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_FIXEDMTU;
- /// Cannot send / receive packets
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_VIRTUAL;
- /// Local address in use
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_DUPLICATE;
- /// IPMP IP interface
- #[cfg(target_os = "solaris")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IFF_IPMP;
- }
-);
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod if_nameindex {
- use super::*;
-
- use std::ffi::CStr;
- use std::fmt;
- use std::marker::PhantomData;
- use std::ptr::NonNull;
-
- /// A network interface. Has a name like "eth0" or "wlp4s0" or "wlan0", as well as an index
- /// (1, 2, 3, etc) that identifies it in the OS's networking stack.
- #[allow(missing_copy_implementations)]
- #[repr(transparent)]
- pub struct Interface(libc::if_nameindex);
-
- impl Interface {
- /// Obtain the index of this interface.
- pub fn index(&self) -> c_uint {
- self.0.if_index
- }
-
- /// Obtain the name of this interface.
- pub fn name(&self) -> &CStr {
- unsafe { CStr::from_ptr(self.0.if_name) }
- }
- }
-
- impl fmt::Debug for Interface {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("Interface")
- .field("index", &self.index())
- .field("name", &self.name())
- .finish()
- }
- }
-
- /// A list of the network interfaces available on this system. Obtained from [`if_nameindex()`].
- pub struct Interfaces {
- ptr: NonNull<libc::if_nameindex>,
- }
-
- impl Interfaces {
- /// Iterate over the interfaces in this list.
- #[inline]
- pub fn iter(&self) -> InterfacesIter<'_> {
- self.into_iter()
- }
-
- /// Convert this to a slice of interfaces. Note that the underlying interfaces list is
- /// null-terminated, so calling this calculates the length. If random access isn't needed,
- /// [`Interfaces::iter()`] should be used instead.
- pub fn to_slice(&self) -> &[Interface] {
- let ifs = self.ptr.as_ptr() as *const Interface;
- let len = self.iter().count();
- unsafe { std::slice::from_raw_parts(ifs, len) }
- }
- }
-
- impl Drop for Interfaces {
- fn drop(&mut self) {
- unsafe { libc::if_freenameindex(self.ptr.as_ptr()) };
- }
- }
-
- impl fmt::Debug for Interfaces {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.to_slice().fmt(f)
- }
- }
-
- impl<'a> IntoIterator for &'a Interfaces {
- type IntoIter = InterfacesIter<'a>;
- type Item = &'a Interface;
- #[inline]
- fn into_iter(self) -> Self::IntoIter {
- InterfacesIter {
- ptr: self.ptr.as_ptr(),
- _marker: PhantomData,
- }
- }
- }
-
- /// An iterator over the interfaces in an [`Interfaces`].
- #[derive(Debug)]
- pub struct InterfacesIter<'a> {
- ptr: *const libc::if_nameindex,
- _marker: PhantomData<&'a Interfaces>,
- }
-
- impl<'a> Iterator for InterfacesIter<'a> {
- type Item = &'a Interface;
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- unsafe {
- if (*self.ptr).if_index == 0 {
- None
- } else {
- let ret = &*(self.ptr as *const Interface);
- self.ptr = self.ptr.add(1);
- Some(ret)
- }
- }
- }
- }
-
- /// Retrieve a list of the network interfaces available on the local system.
- ///
- /// ```
- /// let interfaces = nix::net::if_::if_nameindex().unwrap();
- /// for iface in &interfaces {
- /// println!("Interface #{} is called {}", iface.index(), iface.name().to_string_lossy());
- /// }
- /// ```
- pub fn if_nameindex() -> Result<Interfaces> {
- unsafe {
- let ifs = libc::if_nameindex();
- let ptr = NonNull::new(ifs).ok_or_else(Error::last)?;
- Ok(Interfaces { ptr })
- }
- }
-}
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-pub use if_nameindex::*;
diff --git a/vendor/nix/src/net/mod.rs b/vendor/nix/src/net/mod.rs
deleted file mode 100644
index 079fcfde6..000000000
--- a/vendor/nix/src/net/mod.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//! Functionality involving network interfaces
-// To avoid clashing with the keyword "if", we use "if_" as the module name.
-// The original header is called "net/if.h".
-pub mod if_;
diff --git a/vendor/nix/src/poll.rs b/vendor/nix/src/poll.rs
deleted file mode 100644
index 6f227fee9..000000000
--- a/vendor/nix/src/poll.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-//! Wait for events to trigger on specific file descriptors
-use std::os::unix::io::{AsRawFd, RawFd};
-
-use crate::errno::Errno;
-use crate::Result;
-
-/// This is a wrapper around `libc::pollfd`.
-///
-/// It's meant to be used as an argument to the [`poll`](fn.poll.html) and
-/// [`ppoll`](fn.ppoll.html) functions to specify the events of interest
-/// for a specific file descriptor.
-///
-/// After a call to `poll` or `ppoll`, the events that occurred can be
-/// retrieved by calling [`revents()`](#method.revents) on the `PollFd`.
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct PollFd {
- pollfd: libc::pollfd,
-}
-
-impl PollFd {
- /// Creates a new `PollFd` specifying the events of interest
- /// for a given file descriptor.
- pub const fn new(fd: RawFd, events: PollFlags) -> PollFd {
- PollFd {
- pollfd: libc::pollfd {
- fd,
- events: events.bits(),
- revents: PollFlags::empty().bits(),
- },
- }
- }
-
- /// Returns the events that occurred in the last call to `poll` or `ppoll`. Will only return
- /// `None` if the kernel provides status flags that Nix does not know about.
- pub fn revents(self) -> Option<PollFlags> {
- PollFlags::from_bits(self.pollfd.revents)
- }
-
- /// Returns if any of the events of interest occured in the last call to `poll` or `ppoll`. Will
- /// only return `None` if the kernel provides status flags that Nix does not know about.
- ///
- /// Equivalent to `x.revents()? != PollFlags::empty()`.
- ///
- /// This is marginally more efficient than [`PollFd::all`].
- pub fn any(self) -> Option<bool> {
- Some(self.revents()? != PollFlags::empty())
- }
-
- /// Returns if all the events of interest occured in the last call to `poll` or `ppoll`. Will
- /// only return `None` if the kernel provides status flags that Nix does not know about.
- ///
- /// Equivalent to `x.revents()? & x.events() == x.events()`.
- ///
- /// This is marginally less efficient than [`PollFd::any`].
- pub fn all(self) -> Option<bool> {
- Some(self.revents()? & self.events() == self.events())
- }
-
- /// The events of interest for this `PollFd`.
- pub fn events(self) -> PollFlags {
- PollFlags::from_bits(self.pollfd.events).unwrap()
- }
-
- /// Modify the events of interest for this `PollFd`.
- pub fn set_events(&mut self, events: PollFlags) {
- self.pollfd.events = events.bits();
- }
-}
-
-impl AsRawFd for PollFd {
- fn as_raw_fd(&self) -> RawFd {
- self.pollfd.fd
- }
-}
-
-libc_bitflags! {
- /// These flags define the different events that can be monitored by `poll` and `ppoll`
- pub struct PollFlags: libc::c_short {
- /// There is data to read.
- POLLIN;
- /// There is some exceptional condition on the file descriptor.
- ///
- /// Possibilities include:
- ///
- /// * There is out-of-band data on a TCP socket (see
- /// [tcp(7)](https://man7.org/linux/man-pages/man7/tcp.7.html)).
- /// * A pseudoterminal master in packet mode has seen a state
- /// change on the slave (see
- /// [ioctl_tty(2)](https://man7.org/linux/man-pages/man2/ioctl_tty.2.html)).
- /// * A cgroup.events file has been modified (see
- /// [cgroups(7)](https://man7.org/linux/man-pages/man7/cgroups.7.html)).
- POLLPRI;
- /// Writing is now possible, though a write larger that the
- /// available space in a socket or pipe will still block (unless
- /// `O_NONBLOCK` is set).
- POLLOUT;
- /// Equivalent to [`POLLIN`](constant.POLLIN.html)
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- POLLRDNORM;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Equivalent to [`POLLOUT`](constant.POLLOUT.html)
- POLLWRNORM;
- /// Priority band data can be read (generally unused on Linux).
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- POLLRDBAND;
- /// Priority data may be written.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- POLLWRBAND;
- /// Error condition (only returned in
- /// [`PollFd::revents`](struct.PollFd.html#method.revents);
- /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
- /// This bit is also set for a file descriptor referring to the
- /// write end of a pipe when the read end has been closed.
- POLLERR;
- /// Hang up (only returned in [`PollFd::revents`](struct.PollFd.html#method.revents);
- /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
- /// Note that when reading from a channel such as a pipe or a stream
- /// socket, this event merely indicates that the peer closed its
- /// end of the channel. Subsequent reads from the channel will
- /// return 0 (end of file) only after all outstanding data in the
- /// channel has been consumed.
- POLLHUP;
- /// Invalid request: `fd` not open (only returned in
- /// [`PollFd::revents`](struct.PollFd.html#method.revents);
- /// ignored in [`PollFd::new`](struct.PollFd.html#method.new)).
- POLLNVAL;
- }
-}
-
-/// `poll` waits for one of a set of file descriptors to become ready to perform I/O.
-/// ([`poll(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html))
-///
-/// `fds` contains all [`PollFd`](struct.PollFd.html) to poll.
-/// The function will return as soon as any event occur for any of these `PollFd`s.
-///
-/// The `timeout` argument specifies the number of milliseconds that `poll()`
-/// should block waiting for a file descriptor to become ready. The call
-/// will block until either:
-///
-/// * a file descriptor becomes ready;
-/// * the call is interrupted by a signal handler; or
-/// * the timeout expires.
-///
-/// Note that the timeout interval will be rounded up to the system clock
-/// granularity, and kernel scheduling delays mean that the blocking
-/// interval may overrun by a small amount. Specifying a negative value
-/// in timeout means an infinite timeout. Specifying a timeout of zero
-/// causes `poll()` to return immediately, even if no file descriptors are
-/// ready.
-pub fn poll(fds: &mut [PollFd], timeout: libc::c_int) -> Result<libc::c_int> {
- let res = unsafe {
- libc::poll(
- fds.as_mut_ptr() as *mut libc::pollfd,
- fds.len() as libc::nfds_t,
- timeout,
- )
- };
-
- Errno::result(res)
-}
-
-feature! {
-#![feature = "signal"]
-/// `ppoll()` allows an application to safely wait until either a file
-/// descriptor becomes ready or until a signal is caught.
-/// ([`poll(2)`](https://man7.org/linux/man-pages/man2/poll.2.html))
-///
-/// `ppoll` behaves like `poll`, but let you specify what signals may interrupt it
-/// with the `sigmask` argument. If you want `ppoll` to block indefinitely,
-/// specify `None` as `timeout` (it is like `timeout = -1` for `poll`).
-/// If `sigmask` is `None`, then no signal mask manipulation is performed,
-/// so in that case `ppoll` differs from `poll` only in the precision of the
-/// timeout argument.
-///
-#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux"))]
-pub fn ppoll(
- fds: &mut [PollFd],
- timeout: Option<crate::sys::time::TimeSpec>,
- sigmask: Option<crate::sys::signal::SigSet>
- ) -> Result<libc::c_int>
-{
- let timeout = timeout.as_ref().map_or(core::ptr::null(), |r| r.as_ref());
- let sigmask = sigmask.as_ref().map_or(core::ptr::null(), |r| r.as_ref());
- let res = unsafe {
- libc::ppoll(fds.as_mut_ptr() as *mut libc::pollfd,
- fds.len() as libc::nfds_t,
- timeout,
- sigmask)
- };
- Errno::result(res)
-}
-}
diff --git a/vendor/nix/src/pty.rs b/vendor/nix/src/pty.rs
deleted file mode 100644
index 28ae5e924..000000000
--- a/vendor/nix/src/pty.rs
+++ /dev/null
@@ -1,371 +0,0 @@
-//! Create master and slave virtual pseudo-terminals (PTYs)
-
-pub use libc::pid_t as SessionId;
-pub use libc::winsize as Winsize;
-
-use std::ffi::CStr;
-use std::io;
-use std::mem;
-use std::os::unix::prelude::*;
-
-use crate::errno::Errno;
-use crate::sys::termios::Termios;
-#[cfg(feature = "process")]
-use crate::unistd::{ForkResult, Pid};
-use crate::{fcntl, unistd, Result};
-
-/// Representation of a master/slave pty pair
-///
-/// This is returned by `openpty`. Note that this type does *not* implement `Drop`, so the user
-/// must manually close the file descriptors.
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct OpenptyResult {
- /// The master port in a virtual pty pair
- pub master: RawFd,
- /// The slave port in a virtual pty pair
- pub slave: RawFd,
-}
-
-feature! {
-#![feature = "process"]
-/// Representation of a master with a forked pty
-///
-/// This is returned by `forkpty`. Note that this type does *not* implement `Drop`, so the user
-/// must manually close the file descriptors.
-#[derive(Clone, Copy, Debug)]
-pub struct ForkptyResult {
- /// The master port in a virtual pty pair
- pub master: RawFd,
- /// Metadata about forked process
- pub fork_result: ForkResult,
-}
-}
-
-/// Representation of the Master device in a master/slave pty pair
-///
-/// While this datatype is a thin wrapper around `RawFd`, it enforces that the available PTY
-/// functions are given the correct file descriptor. Additionally this type implements `Drop`,
-/// so that when it's consumed or goes out of scope, it's automatically cleaned-up.
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct PtyMaster(RawFd);
-
-impl AsRawFd for PtyMaster {
- fn as_raw_fd(&self) -> RawFd {
- self.0
- }
-}
-
-impl IntoRawFd for PtyMaster {
- fn into_raw_fd(self) -> RawFd {
- let fd = self.0;
- mem::forget(self);
- fd
- }
-}
-
-impl Drop for PtyMaster {
- fn drop(&mut self) {
- // On drop, we ignore errors like EINTR and EIO because there's no clear
- // way to handle them, we can't return anything, and (on FreeBSD at
- // least) the file descriptor is deallocated in these cases. However,
- // we must panic on EBADF, because it is always an error to close an
- // invalid file descriptor. That frequently indicates a double-close
- // condition, which can cause confusing errors for future I/O
- // operations.
- let e = unistd::close(self.0);
- if e == Err(Errno::EBADF) {
- panic!("Closing an invalid file descriptor!");
- };
- }
-}
-
-impl io::Read for PtyMaster {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- unistd::read(self.0, buf).map_err(io::Error::from)
- }
-}
-
-impl io::Write for PtyMaster {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- unistd::write(self.0, buf).map_err(io::Error::from)
- }
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-impl io::Read for &PtyMaster {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- unistd::read(self.0, buf).map_err(io::Error::from)
- }
-}
-
-impl io::Write for &PtyMaster {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- unistd::write(self.0, buf).map_err(io::Error::from)
- }
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-/// Grant access to a slave pseudoterminal (see
-/// [`grantpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html))
-///
-/// `grantpt()` changes the mode and owner of the slave pseudoterminal device corresponding to the
-/// master pseudoterminal referred to by `fd`. This is a necessary step towards opening the slave.
-#[inline]
-pub fn grantpt(fd: &PtyMaster) -> Result<()> {
- if unsafe { libc::grantpt(fd.as_raw_fd()) } < 0 {
- return Err(Errno::last());
- }
-
- Ok(())
-}
-
-/// Open a pseudoterminal device (see
-/// [`posix_openpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html))
-///
-/// `posix_openpt()` returns a file descriptor to an existing unused pseudoterminal master device.
-///
-/// # Examples
-///
-/// A common use case with this function is to open both a master and slave PTY pair. This can be
-/// done as follows:
-///
-/// ```
-/// use std::path::Path;
-/// use nix::fcntl::{OFlag, open};
-/// use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt};
-/// use nix::sys::stat::Mode;
-///
-/// # #[allow(dead_code)]
-/// # fn run() -> nix::Result<()> {
-/// // Open a new PTY master
-/// let master_fd = posix_openpt(OFlag::O_RDWR)?;
-///
-/// // Allow a slave to be generated for it
-/// grantpt(&master_fd)?;
-/// unlockpt(&master_fd)?;
-///
-/// // Get the name of the slave
-/// let slave_name = unsafe { ptsname(&master_fd) }?;
-///
-/// // Try to open the slave
-/// let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?;
-/// # Ok(())
-/// # }
-/// ```
-#[inline]
-pub fn posix_openpt(flags: fcntl::OFlag) -> Result<PtyMaster> {
- let fd = unsafe { libc::posix_openpt(flags.bits()) };
-
- if fd < 0 {
- return Err(Errno::last());
- }
-
- Ok(PtyMaster(fd))
-}
-
-/// Get the name of the slave pseudoterminal (see
-/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html))
-///
-/// `ptsname()` returns the name of the slave pseudoterminal device corresponding to the master
-/// referred to by `fd`.
-///
-/// This value is useful for opening the slave pty once the master has already been opened with
-/// `posix_openpt()`.
-///
-/// # Safety
-///
-/// `ptsname()` mutates global variables and is *not* threadsafe.
-/// Mutating global variables is always considered `unsafe` by Rust and this
-/// function is marked as `unsafe` to reflect that.
-///
-/// For a threadsafe and non-`unsafe` alternative on Linux, see `ptsname_r()`.
-#[inline]
-pub unsafe fn ptsname(fd: &PtyMaster) -> Result<String> {
- let name_ptr = libc::ptsname(fd.as_raw_fd());
- if name_ptr.is_null() {
- return Err(Errno::last());
- }
-
- let name = CStr::from_ptr(name_ptr);
- Ok(name.to_string_lossy().into_owned())
-}
-
-/// Get the name of the slave pseudoterminal (see
-/// [`ptsname(3)`](https://man7.org/linux/man-pages/man3/ptsname.3.html))
-///
-/// `ptsname_r()` returns the name of the slave pseudoterminal device corresponding to the master
-/// referred to by `fd`. This is the threadsafe version of `ptsname()`, but it is not part of the
-/// POSIX standard and is instead a Linux-specific extension.
-///
-/// This value is useful for opening the slave ptty once the master has already been opened with
-/// `posix_openpt()`.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-#[inline]
-pub fn ptsname_r(fd: &PtyMaster) -> Result<String> {
- let mut name_buf = Vec::<libc::c_char>::with_capacity(64);
- let name_buf_ptr = name_buf.as_mut_ptr();
- let cname = unsafe {
- let cap = name_buf.capacity();
- if libc::ptsname_r(fd.as_raw_fd(), name_buf_ptr, cap) != 0 {
- return Err(crate::Error::last());
- }
- CStr::from_ptr(name_buf.as_ptr())
- };
-
- let name = cname.to_string_lossy().into_owned();
- Ok(name)
-}
-
-/// Unlock a pseudoterminal master/slave pseudoterminal pair (see
-/// [`unlockpt(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html))
-///
-/// `unlockpt()` unlocks the slave pseudoterminal device corresponding to the master pseudoterminal
-/// referred to by `fd`. This must be called before trying to open the slave side of a
-/// pseudoterminal.
-#[inline]
-pub fn unlockpt(fd: &PtyMaster) -> Result<()> {
- if unsafe { libc::unlockpt(fd.as_raw_fd()) } < 0 {
- return Err(Errno::last());
- }
-
- Ok(())
-}
-
-/// Create a new pseudoterminal, returning the slave and master file descriptors
-/// in `OpenptyResult`
-/// (see [`openpty`](https://man7.org/linux/man-pages/man3/openpty.3.html)).
-///
-/// If `winsize` is not `None`, the window size of the slave will be set to
-/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
-/// terminal settings of the slave will be set to the values in `termios`.
-#[inline]
-pub fn openpty<
- 'a,
- 'b,
- T: Into<Option<&'a Winsize>>,
- U: Into<Option<&'b Termios>>,
->(
- winsize: T,
- termios: U,
-) -> Result<OpenptyResult> {
- use std::ptr;
-
- let mut slave = mem::MaybeUninit::<libc::c_int>::uninit();
- let mut master = mem::MaybeUninit::<libc::c_int>::uninit();
- let ret = {
- match (termios.into(), winsize.into()) {
- (Some(termios), Some(winsize)) => {
- let inner_termios = termios.get_libc_termios();
- unsafe {
- libc::openpty(
- master.as_mut_ptr(),
- slave.as_mut_ptr(),
- ptr::null_mut(),
- &*inner_termios as *const libc::termios as *mut _,
- winsize as *const Winsize as *mut _,
- )
- }
- }
- (None, Some(winsize)) => unsafe {
- libc::openpty(
- master.as_mut_ptr(),
- slave.as_mut_ptr(),
- ptr::null_mut(),
- ptr::null_mut(),
- winsize as *const Winsize as *mut _,
- )
- },
- (Some(termios), None) => {
- let inner_termios = termios.get_libc_termios();
- unsafe {
- libc::openpty(
- master.as_mut_ptr(),
- slave.as_mut_ptr(),
- ptr::null_mut(),
- &*inner_termios as *const libc::termios as *mut _,
- ptr::null_mut(),
- )
- }
- }
- (None, None) => unsafe {
- libc::openpty(
- master.as_mut_ptr(),
- slave.as_mut_ptr(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- )
- },
- }
- };
-
- Errno::result(ret)?;
-
- unsafe {
- Ok(OpenptyResult {
- master: master.assume_init(),
- slave: slave.assume_init(),
- })
- }
-}
-
-feature! {
-#![feature = "process"]
-/// Create a new pseudoterminal, returning the master file descriptor and forked pid.
-/// in `ForkptyResult`
-/// (see [`forkpty`](https://man7.org/linux/man-pages/man3/forkpty.3.html)).
-///
-/// If `winsize` is not `None`, the window size of the slave will be set to
-/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
-/// terminal settings of the slave will be set to the values in `termios`.
-///
-/// # Safety
-///
-/// In a multithreaded program, only [async-signal-safe] functions like `pause`
-/// and `_exit` may be called by the child (the parent isn't restricted). Note
-/// that memory allocation may **not** be async-signal-safe and thus must be
-/// prevented.
-///
-/// Those functions are only a small subset of your operating system's API, so
-/// special care must be taken to only invoke code you can control and audit.
-///
-/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html
-pub unsafe fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(
- winsize: T,
- termios: U,
-) -> Result<ForkptyResult> {
- use std::ptr;
-
- let mut master = mem::MaybeUninit::<libc::c_int>::uninit();
-
- let term = match termios.into() {
- Some(termios) => {
- let inner_termios = termios.get_libc_termios();
- &*inner_termios as *const libc::termios as *mut _
- },
- None => ptr::null_mut(),
- };
-
- let win = winsize
- .into()
- .map(|ws| ws as *const Winsize as *mut _)
- .unwrap_or(ptr::null_mut());
-
- let res = libc::forkpty(master.as_mut_ptr(), ptr::null_mut(), term, win);
-
- let fork_result = Errno::result(res).map(|res| match res {
- 0 => ForkResult::Child,
- res => ForkResult::Parent { child: Pid::from_raw(res) },
- })?;
-
- Ok(ForkptyResult {
- master: master.assume_init(),
- fork_result,
- })
-}
-}
diff --git a/vendor/nix/src/sched.rs b/vendor/nix/src/sched.rs
deleted file mode 100644
index d5b1233cf..000000000
--- a/vendor/nix/src/sched.rs
+++ /dev/null
@@ -1,324 +0,0 @@
-//! Execution scheduling
-//!
-//! See Also
-//! [sched.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sched.h.html)
-use crate::{Errno, Result};
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use self::sched_linux_like::*;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod sched_linux_like {
- use crate::errno::Errno;
- use crate::unistd::Pid;
- use crate::Result;
- use libc::{self, c_int, c_void};
- use std::mem;
- use std::option::Option;
- use std::os::unix::io::RawFd;
-
- // For some functions taking with a parameter of type CloneFlags,
- // only a subset of these flags have an effect.
- libc_bitflags! {
- /// Options for use with [`clone`]
- pub struct CloneFlags: c_int {
- /// The calling process and the child process run in the same
- /// memory space.
- CLONE_VM;
- /// The caller and the child process share the same filesystem
- /// information.
- CLONE_FS;
- /// The calling process and the child process share the same file
- /// descriptor table.
- CLONE_FILES;
- /// The calling process and the child process share the same table
- /// of signal handlers.
- CLONE_SIGHAND;
- /// If the calling process is being traced, then trace the child
- /// also.
- CLONE_PTRACE;
- /// The execution of the calling process is suspended until the
- /// child releases its virtual memory resources via a call to
- /// execve(2) or _exit(2) (as with vfork(2)).
- CLONE_VFORK;
- /// The parent of the new child (as returned by getppid(2))
- /// will be the same as that of the calling process.
- CLONE_PARENT;
- /// The child is placed in the same thread group as the calling
- /// process.
- CLONE_THREAD;
- /// The cloned child is started in a new mount namespace.
- CLONE_NEWNS;
- /// The child and the calling process share a single list of System
- /// V semaphore adjustment values
- CLONE_SYSVSEM;
- // Not supported by Nix due to lack of varargs support in Rust FFI
- // CLONE_SETTLS;
- // Not supported by Nix due to lack of varargs support in Rust FFI
- // CLONE_PARENT_SETTID;
- // Not supported by Nix due to lack of varargs support in Rust FFI
- // CLONE_CHILD_CLEARTID;
- /// Unused since Linux 2.6.2
- #[deprecated(since = "0.23.0", note = "Deprecated by Linux 2.6.2")]
- CLONE_DETACHED;
- /// A tracing process cannot force `CLONE_PTRACE` on this child
- /// process.
- CLONE_UNTRACED;
- // Not supported by Nix due to lack of varargs support in Rust FFI
- // CLONE_CHILD_SETTID;
- /// Create the process in a new cgroup namespace.
- CLONE_NEWCGROUP;
- /// Create the process in a new UTS namespace.
- CLONE_NEWUTS;
- /// Create the process in a new IPC namespace.
- CLONE_NEWIPC;
- /// Create the process in a new user namespace.
- CLONE_NEWUSER;
- /// Create the process in a new PID namespace.
- CLONE_NEWPID;
- /// Create the process in a new network namespace.
- CLONE_NEWNET;
- /// The new process shares an I/O context with the calling process.
- CLONE_IO;
- }
- }
-
- /// Type for the function executed by [`clone`].
- pub type CloneCb<'a> = Box<dyn FnMut() -> isize + 'a>;
-
- /// `clone` create a child process
- /// ([`clone(2)`](https://man7.org/linux/man-pages/man2/clone.2.html))
- ///
- /// `stack` is a reference to an array which will hold the stack of the new
- /// process. Unlike when calling `clone(2)` from C, the provided stack
- /// address need not be the highest address of the region. Nix will take
- /// care of that requirement. The user only needs to provide a reference to
- /// a normally allocated buffer.
- pub fn clone(
- mut cb: CloneCb,
- stack: &mut [u8],
- flags: CloneFlags,
- signal: Option<c_int>,
- ) -> Result<Pid> {
- extern "C" fn callback(data: *mut CloneCb) -> c_int {
- let cb: &mut CloneCb = unsafe { &mut *data };
- (*cb)() as c_int
- }
-
- let res = unsafe {
- let combined = flags.bits() | signal.unwrap_or(0);
- let ptr = stack.as_mut_ptr().add(stack.len());
- let ptr_aligned = ptr.sub(ptr as usize % 16);
- libc::clone(
- mem::transmute(
- callback
- as extern "C" fn(*mut Box<dyn FnMut() -> isize>) -> i32,
- ),
- ptr_aligned as *mut c_void,
- combined,
- &mut cb as *mut _ as *mut c_void,
- )
- };
-
- Errno::result(res).map(Pid::from_raw)
- }
-
- /// disassociate parts of the process execution context
- ///
- /// See also [unshare(2)](https://man7.org/linux/man-pages/man2/unshare.2.html)
- pub fn unshare(flags: CloneFlags) -> Result<()> {
- let res = unsafe { libc::unshare(flags.bits()) };
-
- Errno::result(res).map(drop)
- }
-
- /// reassociate thread with a namespace
- ///
- /// See also [setns(2)](https://man7.org/linux/man-pages/man2/setns.2.html)
- pub fn setns(fd: RawFd, nstype: CloneFlags) -> Result<()> {
- let res = unsafe { libc::setns(fd, nstype.bits()) };
-
- Errno::result(res).map(drop)
- }
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
-))]
-pub use self::sched_affinity::*;
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
-))]
-mod sched_affinity {
- use crate::errno::Errno;
- use crate::unistd::Pid;
- use crate::Result;
- use std::mem;
-
- /// CpuSet represent a bit-mask of CPUs.
- /// CpuSets are used by sched_setaffinity and
- /// sched_getaffinity for example.
- ///
- /// This is a wrapper around `libc::cpu_set_t`.
- #[repr(transparent)]
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- pub struct CpuSet {
- #[cfg(not(target_os = "freebsd"))]
- cpu_set: libc::cpu_set_t,
- #[cfg(target_os = "freebsd")]
- cpu_set: libc::cpuset_t,
- }
-
- impl CpuSet {
- /// Create a new and empty CpuSet.
- pub fn new() -> CpuSet {
- CpuSet {
- cpu_set: unsafe { mem::zeroed() },
- }
- }
-
- /// Test to see if a CPU is in the CpuSet.
- /// `field` is the CPU id to test
- pub fn is_set(&self, field: usize) -> Result<bool> {
- if field >= CpuSet::count() {
- Err(Errno::EINVAL)
- } else {
- Ok(unsafe { libc::CPU_ISSET(field, &self.cpu_set) })
- }
- }
-
- /// Add a CPU to CpuSet.
- /// `field` is the CPU id to add
- pub fn set(&mut self, field: usize) -> Result<()> {
- if field >= CpuSet::count() {
- Err(Errno::EINVAL)
- } else {
- unsafe {
- libc::CPU_SET(field, &mut self.cpu_set);
- }
- Ok(())
- }
- }
-
- /// Remove a CPU from CpuSet.
- /// `field` is the CPU id to remove
- pub fn unset(&mut self, field: usize) -> Result<()> {
- if field >= CpuSet::count() {
- Err(Errno::EINVAL)
- } else {
- unsafe {
- libc::CPU_CLR(field, &mut self.cpu_set);
- }
- Ok(())
- }
- }
-
- /// Return the maximum number of CPU in CpuSet
- pub const fn count() -> usize {
- #[cfg(not(target_os = "freebsd"))]
- let bytes = mem::size_of::<libc::cpu_set_t>();
- #[cfg(target_os = "freebsd")]
- let bytes = mem::size_of::<libc::cpuset_t>();
-
- 8 * bytes
- }
- }
-
- impl Default for CpuSet {
- fn default() -> Self {
- Self::new()
- }
- }
-
- /// `sched_setaffinity` set a thread's CPU affinity mask
- /// ([`sched_setaffinity(2)`](https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html))
- ///
- /// `pid` is the thread ID to update.
- /// If pid is zero, then the calling thread is updated.
- ///
- /// The `cpuset` argument specifies the set of CPUs on which the thread
- /// will be eligible to run.
- ///
- /// # Example
- ///
- /// Binding the current thread to CPU 0 can be done as follows:
- ///
- /// ```rust,no_run
- /// use nix::sched::{CpuSet, sched_setaffinity};
- /// use nix::unistd::Pid;
- ///
- /// let mut cpu_set = CpuSet::new();
- /// cpu_set.set(0).unwrap();
- /// sched_setaffinity(Pid::from_raw(0), &cpu_set).unwrap();
- /// ```
- pub fn sched_setaffinity(pid: Pid, cpuset: &CpuSet) -> Result<()> {
- let res = unsafe {
- libc::sched_setaffinity(
- pid.into(),
- mem::size_of::<CpuSet>() as libc::size_t,
- &cpuset.cpu_set,
- )
- };
-
- Errno::result(res).map(drop)
- }
-
- /// `sched_getaffinity` get a thread's CPU affinity mask
- /// ([`sched_getaffinity(2)`](https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html))
- ///
- /// `pid` is the thread ID to check.
- /// If pid is zero, then the calling thread is checked.
- ///
- /// Returned `cpuset` is the set of CPUs on which the thread
- /// is eligible to run.
- ///
- /// # Example
- ///
- /// Checking if the current thread can run on CPU 0 can be done as follows:
- ///
- /// ```rust,no_run
- /// use nix::sched::sched_getaffinity;
- /// use nix::unistd::Pid;
- ///
- /// let cpu_set = sched_getaffinity(Pid::from_raw(0)).unwrap();
- /// if cpu_set.is_set(0).unwrap() {
- /// println!("Current thread can run on CPU 0");
- /// }
- /// ```
- pub fn sched_getaffinity(pid: Pid) -> Result<CpuSet> {
- let mut cpuset = CpuSet::new();
- let res = unsafe {
- libc::sched_getaffinity(
- pid.into(),
- mem::size_of::<CpuSet>() as libc::size_t,
- &mut cpuset.cpu_set,
- )
- };
-
- Errno::result(res).and(Ok(cpuset))
- }
-
- /// Determines the CPU on which the calling thread is running.
- pub fn sched_getcpu() -> Result<usize> {
- let res = unsafe { libc::sched_getcpu() };
-
- Errno::result(res).map(|int| int as usize)
- }
-}
-
-/// Explicitly yield the processor to other threads.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html)
-pub fn sched_yield() -> Result<()> {
- let res = unsafe { libc::sched_yield() };
-
- Errno::result(res).map(drop)
-}
diff --git a/vendor/nix/src/sys/aio.rs b/vendor/nix/src/sys/aio.rs
deleted file mode 100644
index e2ce19b79..000000000
--- a/vendor/nix/src/sys/aio.rs
+++ /dev/null
@@ -1,1241 +0,0 @@
-// vim: tw=80
-//! POSIX Asynchronous I/O
-//!
-//! The POSIX AIO interface is used for asynchronous I/O on files and disk-like
-//! devices. It supports [`read`](struct.AioRead.html#method.new),
-//! [`write`](struct.AioWrite.html#method.new),
-//! [`fsync`](struct.AioFsync.html#method.new),
-//! [`readv`](struct.AioReadv.html#method.new), and
-//! [`writev`](struct.AioWritev.html#method.new), operations, subject to
-//! platform support. Completion
-//! notifications can optionally be delivered via
-//! [signals](../signal/enum.SigevNotify.html#variant.SigevSignal), via the
-//! [`aio_suspend`](fn.aio_suspend.html) function, or via polling. Some
-//! platforms support other completion
-//! notifications, such as
-//! [kevent](../signal/enum.SigevNotify.html#variant.SigevKevent).
-//!
-//! Multiple operations may be submitted in a batch with
-//! [`lio_listio`](fn.lio_listio.html), though the standard does not guarantee
-//! that they will be executed atomically.
-//!
-//! Outstanding operations may be cancelled with
-//! [`cancel`](trait.Aio.html#method.cancel) or
-//! [`aio_cancel_all`](fn.aio_cancel_all.html), though the operating system may
-//! not support this for all filesystems and devices.
-#[cfg(target_os = "freebsd")]
-use std::io::{IoSlice, IoSliceMut};
-use std::{
- convert::TryFrom,
- fmt::{self, Debug},
- marker::{PhantomData, PhantomPinned},
- mem,
- os::unix::io::RawFd,
- pin::Pin,
- ptr, thread,
-};
-
-use libc::{c_void, off_t};
-use pin_utils::unsafe_pinned;
-
-use crate::{
- errno::Errno,
- sys::{signal::*, time::TimeSpec},
- Result,
-};
-
-libc_enum! {
- /// Mode for `AioCb::fsync`. Controls whether only data or both data and
- /// metadata are synced.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum AioFsyncMode {
- /// do it like `fsync`
- O_SYNC,
- /// on supported operating systems only, do it like `fdatasync`
- #[cfg(any(target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- O_DSYNC
- }
- impl TryFrom<i32>
-}
-
-libc_enum! {
- /// Mode for [`lio_listio`](fn.lio_listio.html)
- #[repr(i32)]
- pub enum LioMode {
- /// Requests that [`lio_listio`](fn.lio_listio.html) block until all
- /// requested operations have been completed
- LIO_WAIT,
- /// Requests that [`lio_listio`](fn.lio_listio.html) return immediately
- LIO_NOWAIT,
- }
-}
-
-/// Return values for [`AioCb::cancel`](struct.AioCb.html#method.cancel) and
-/// [`aio_cancel_all`](fn.aio_cancel_all.html)
-#[repr(i32)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum AioCancelStat {
- /// All outstanding requests were canceled
- AioCanceled = libc::AIO_CANCELED,
- /// Some requests were not canceled. Their status should be checked with
- /// `AioCb::error`
- AioNotCanceled = libc::AIO_NOTCANCELED,
- /// All of the requests have already finished
- AioAllDone = libc::AIO_ALLDONE,
-}
-
-/// Newtype that adds Send and Sync to libc::aiocb, which contains raw pointers
-#[repr(transparent)]
-struct LibcAiocb(libc::aiocb);
-
-unsafe impl Send for LibcAiocb {}
-unsafe impl Sync for LibcAiocb {}
-
-/// Base class for all AIO operations. Should only be used directly when
-/// checking for completion.
-// We could create some kind of AsPinnedMut trait, and implement it for all aio
-// ops, allowing the crate's users to get pinned references to `AioCb`. That
-// could save some code for things like polling methods. But IMHO it would
-// provide polymorphism at the wrong level. Instead, the best place for
-// polymorphism is at the level of `Futures`.
-#[repr(C)]
-struct AioCb {
- aiocb: LibcAiocb,
- /// Could this `AioCb` potentially have any in-kernel state?
- // It would be really nice to perform the in-progress check entirely at
- // compile time. But I can't figure out how, because:
- // * Future::poll takes a `Pin<&mut self>` rather than `self`, and
- // * Rust's lack of an equivalent of C++'s Guaranteed Copy Elision means
- // that there's no way to write an AioCb constructor that neither boxes
- // the object itself, nor moves it during return.
- in_progress: bool,
-}
-
-impl AioCb {
- pin_utils::unsafe_unpinned!(aiocb: LibcAiocb);
-
- fn aio_return(mut self: Pin<&mut Self>) -> Result<usize> {
- self.in_progress = false;
- unsafe {
- let p: *mut libc::aiocb = &mut self.aiocb.0;
- Errno::result(libc::aio_return(p))
- }
- .map(|r| r as usize)
- }
-
- fn cancel(mut self: Pin<&mut Self>) -> Result<AioCancelStat> {
- let r = unsafe {
- libc::aio_cancel(self.aiocb.0.aio_fildes, &mut self.aiocb.0)
- };
- match r {
- libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
- libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
- libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
- -1 => Err(Errno::last()),
- _ => panic!("unknown aio_cancel return value"),
- }
- }
-
- fn common_init(fd: RawFd, prio: i32, sigev_notify: SigevNotify) -> Self {
- // Use mem::zeroed instead of explicitly zeroing each field, because the
- // number and name of reserved fields is OS-dependent. On some OSes,
- // some reserved fields are used the kernel for state, and must be
- // explicitly zeroed when allocated.
- let mut a = unsafe { mem::zeroed::<libc::aiocb>() };
- a.aio_fildes = fd;
- a.aio_reqprio = prio;
- a.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
- AioCb {
- aiocb: LibcAiocb(a),
- in_progress: false,
- }
- }
-
- fn error(self: Pin<&mut Self>) -> Result<()> {
- let r = unsafe { libc::aio_error(&self.aiocb().0) };
- match r {
- 0 => Ok(()),
- num if num > 0 => Err(Errno::from_i32(num)),
- -1 => Err(Errno::last()),
- num => panic!("unknown aio_error return value {:?}", num),
- }
- }
-
- fn in_progress(&self) -> bool {
- self.in_progress
- }
-
- fn set_in_progress(mut self: Pin<&mut Self>) {
- self.as_mut().in_progress = true;
- }
-
- /// Update the notification settings for an existing AIO operation that has
- /// not yet been submitted.
- // Takes a normal reference rather than a pinned one because this method is
- // normally called before the object needs to be pinned, that is, before
- // it's been submitted to the kernel.
- fn set_sigev_notify(&mut self, sigev_notify: SigevNotify) {
- assert!(
- !self.in_progress,
- "Can't change notification settings for an in-progress operation"
- );
- self.aiocb.0.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
- }
-}
-
-impl Debug for AioCb {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.debug_struct("AioCb")
- .field("aiocb", &self.aiocb.0)
- .field("in_progress", &self.in_progress)
- .finish()
- }
-}
-
-impl Drop for AioCb {
- /// If the `AioCb` has no remaining state in the kernel, just drop it.
- /// Otherwise, dropping constitutes a resource leak, which is an error
- fn drop(&mut self) {
- assert!(
- thread::panicking() || !self.in_progress,
- "Dropped an in-progress AioCb"
- );
- }
-}
-
-/// Methods common to all AIO operations
-pub trait Aio {
- /// The return type of [`Aio::aio_return`].
- type Output;
-
- /// Retrieve return status of an asynchronous operation.
- ///
- /// Should only be called once for each operation, after [`Aio::error`]
- /// indicates that it has completed. The result is the same as for the
- /// synchronous `read(2)`, `write(2)`, of `fsync(2)` functions.
- ///
- /// # References
- ///
- /// [aio_return](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_return.html)
- fn aio_return(self: Pin<&mut Self>) -> Result<Self::Output>;
-
- /// Cancels an outstanding AIO request.
- ///
- /// The operating system is not required to implement cancellation for all
- /// file and device types. Even if it does, there is no guarantee that the
- /// operation has not already completed. So the caller must check the
- /// result and handle operations that were not canceled or that have already
- /// completed.
- ///
- /// # Examples
- ///
- /// Cancel an outstanding aio operation. Note that we must still call
- /// `aio_return` to free resources, even though we don't care about the
- /// result.
- ///
- /// ```
- /// # use nix::errno::Errno;
- /// # use nix::Error;
- /// # use nix::sys::aio::*;
- /// # use nix::sys::signal::SigevNotify;
- /// # use std::{thread, time};
- /// # use std::io::Write;
- /// # use std::os::unix::io::AsRawFd;
- /// # use tempfile::tempfile;
- /// let wbuf = b"CDEF";
- /// let mut f = tempfile().unwrap();
- /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
- /// 2, //offset
- /// &wbuf[..],
- /// 0, //priority
- /// SigevNotify::SigevNone));
- /// aiocb.as_mut().submit().unwrap();
- /// let cs = aiocb.as_mut().cancel().unwrap();
- /// if cs == AioCancelStat::AioNotCanceled {
- /// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) {
- /// thread::sleep(time::Duration::from_millis(10));
- /// }
- /// }
- /// // Must call `aio_return`, but ignore the result
- /// let _ = aiocb.as_mut().aio_return();
- /// ```
- ///
- /// # References
- ///
- /// [aio_cancel](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html)
- fn cancel(self: Pin<&mut Self>) -> Result<AioCancelStat>;
-
- /// Retrieve error status of an asynchronous operation.
- ///
- /// If the request has not yet completed, returns `EINPROGRESS`. Otherwise,
- /// returns `Ok` or any other error.
- ///
- /// # Examples
- ///
- /// Issue an aio operation and use `error` to poll for completion. Polling
- /// is an alternative to `aio_suspend`, used by most of the other examples.
- ///
- /// ```
- /// # use nix::errno::Errno;
- /// # use nix::Error;
- /// # use nix::sys::aio::*;
- /// # use nix::sys::signal::SigevNotify;
- /// # use std::{thread, time};
- /// # use std::os::unix::io::AsRawFd;
- /// # use tempfile::tempfile;
- /// const WBUF: &[u8] = b"abcdef123456";
- /// let mut f = tempfile().unwrap();
- /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
- /// 2, //offset
- /// WBUF,
- /// 0, //priority
- /// SigevNotify::SigevNone));
- /// aiocb.as_mut().submit().unwrap();
- /// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) {
- /// thread::sleep(time::Duration::from_millis(10));
- /// }
- /// assert_eq!(aiocb.as_mut().aio_return().unwrap(), WBUF.len());
- /// ```
- ///
- /// # References
- ///
- /// [aio_error](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_error.html)
- fn error(self: Pin<&mut Self>) -> Result<()>;
-
- /// Returns the underlying file descriptor associated with the operation.
- fn fd(&self) -> RawFd;
-
- /// Does this operation currently have any in-kernel state?
- ///
- /// Dropping an operation that does have in-kernel state constitutes a
- /// resource leak.
- ///
- /// # Examples
- ///
- /// ```
- /// # use nix::errno::Errno;
- /// # use nix::Error;
- /// # use nix::sys::aio::*;
- /// # use nix::sys::signal::SigevNotify::SigevNone;
- /// # use std::{thread, time};
- /// # use std::os::unix::io::AsRawFd;
- /// # use tempfile::tempfile;
- /// let f = tempfile().unwrap();
- /// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC,
- /// 0, SigevNone));
- /// assert!(!aiof.as_mut().in_progress());
- /// aiof.as_mut().submit().expect("aio_fsync failed early");
- /// assert!(aiof.as_mut().in_progress());
- /// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) {
- /// thread::sleep(time::Duration::from_millis(10));
- /// }
- /// aiof.as_mut().aio_return().expect("aio_fsync failed late");
- /// assert!(!aiof.as_mut().in_progress());
- /// ```
- fn in_progress(&self) -> bool;
-
- /// Returns the priority of the `AioCb`
- fn priority(&self) -> i32;
-
- /// Update the notification settings for an existing AIO operation that has
- /// not yet been submitted.
- fn set_sigev_notify(&mut self, sev: SigevNotify);
-
- /// Returns the `SigEvent` that will be used for notification.
- fn sigevent(&self) -> SigEvent;
-
- /// Actually start the I/O operation.
- ///
- /// After calling this method and until [`Aio::aio_return`] returns `Ok`,
- /// the structure may not be moved in memory.
- fn submit(self: Pin<&mut Self>) -> Result<()>;
-}
-
-macro_rules! aio_methods {
- () => {
- fn cancel(self: Pin<&mut Self>) -> Result<AioCancelStat> {
- self.aiocb().cancel()
- }
-
- fn error(self: Pin<&mut Self>) -> Result<()> {
- self.aiocb().error()
- }
-
- fn fd(&self) -> RawFd {
- self.aiocb.aiocb.0.aio_fildes
- }
-
- fn in_progress(&self) -> bool {
- self.aiocb.in_progress()
- }
-
- fn priority(&self) -> i32 {
- self.aiocb.aiocb.0.aio_reqprio
- }
-
- fn set_sigev_notify(&mut self, sev: SigevNotify) {
- self.aiocb.set_sigev_notify(sev)
- }
-
- fn sigevent(&self) -> SigEvent {
- SigEvent::from(&self.aiocb.aiocb.0.aio_sigevent)
- }
- };
- ($func:ident) => {
- aio_methods!();
-
- fn aio_return(self: Pin<&mut Self>) -> Result<<Self as Aio>::Output> {
- self.aiocb().aio_return()
- }
-
- fn submit(mut self: Pin<&mut Self>) -> Result<()> {
- let p: *mut libc::aiocb = &mut self.as_mut().aiocb().aiocb.0;
- Errno::result({ unsafe { libc::$func(p) } }).map(|_| {
- self.aiocb().set_in_progress();
- })
- }
- };
-}
-
-/// An asynchronous version of `fsync(2)`.
-///
-/// # References
-///
-/// [aio_fsync](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_fsync.html)
-/// # Examples
-///
-/// ```
-/// # use nix::errno::Errno;
-/// # use nix::Error;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify::SigevNone;
-/// # use std::{thread, time};
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// let f = tempfile().unwrap();
-/// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC,
-/// 0, SigevNone));
-/// aiof.as_mut().submit().expect("aio_fsync failed early");
-/// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// aiof.as_mut().aio_return().expect("aio_fsync failed late");
-/// ```
-#[derive(Debug)]
-#[repr(transparent)]
-pub struct AioFsync {
- aiocb: AioCb,
- _pin: PhantomPinned,
-}
-
-impl AioFsync {
- unsafe_pinned!(aiocb: AioCb);
-
- /// Returns the operation's fsync mode: data and metadata or data only?
- pub fn mode(&self) -> AioFsyncMode {
- AioFsyncMode::try_from(self.aiocb.aiocb.0.aio_lio_opcode).unwrap()
- }
-
- /// Create a new `AioFsync`.
- ///
- /// # Arguments
- ///
- /// * `fd`: File descriptor to sync.
- /// * `mode`: Whether to sync file metadata too, or just data.
- /// * `prio`: If POSIX Prioritized IO is supported, then the
- /// operation will be prioritized at the process's
- /// priority level minus `prio`.
- /// * `sigev_notify`: Determines how you will be notified of event
- /// completion.
- pub fn new(
- fd: RawFd,
- mode: AioFsyncMode,
- prio: i32,
- sigev_notify: SigevNotify,
- ) -> Self {
- let mut aiocb = AioCb::common_init(fd, prio, sigev_notify);
- // To save some memory, store mode in an unused field of the AioCb.
- // True it isn't very much memory, but downstream creates will likely
- // create an enum containing this and other AioCb variants and pack
- // those enums into data structures like Vec, so it adds up.
- aiocb.aiocb.0.aio_lio_opcode = mode as libc::c_int;
- AioFsync {
- aiocb,
- _pin: PhantomPinned,
- }
- }
-}
-
-impl Aio for AioFsync {
- type Output = ();
-
- aio_methods!();
-
- fn aio_return(self: Pin<&mut Self>) -> Result<()> {
- self.aiocb().aio_return().map(drop)
- }
-
- fn submit(mut self: Pin<&mut Self>) -> Result<()> {
- let aiocb = &mut self.as_mut().aiocb().aiocb.0;
- let mode = mem::replace(&mut aiocb.aio_lio_opcode, 0);
- let p: *mut libc::aiocb = aiocb;
- Errno::result(unsafe { libc::aio_fsync(mode, p) }).map(|_| {
- self.aiocb().set_in_progress();
- })
- }
-}
-
-// AioFsync does not need AsMut, since it can't be used with lio_listio
-
-impl AsRef<libc::aiocb> for AioFsync {
- fn as_ref(&self) -> &libc::aiocb {
- &self.aiocb.aiocb.0
- }
-}
-
-/// Asynchronously reads from a file descriptor into a buffer
-///
-/// # References
-///
-/// [aio_read](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_read.html)
-///
-/// # Examples
-///
-///
-/// ```
-/// # use nix::errno::Errno;
-/// # use nix::Error;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use std::{thread, time};
-/// # use std::io::Write;
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// const INITIAL: &[u8] = b"abcdef123456";
-/// const LEN: usize = 4;
-/// let mut rbuf = vec![0; LEN];
-/// let mut f = tempfile().unwrap();
-/// f.write_all(INITIAL).unwrap();
-/// {
-/// let mut aior = Box::pin(
-/// AioRead::new(
-/// f.as_raw_fd(),
-/// 2, //offset
-/// &mut rbuf,
-/// 0, //priority
-/// SigevNotify::SigevNone
-/// )
-/// );
-/// aior.as_mut().submit().unwrap();
-/// while (aior.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// assert_eq!(aior.as_mut().aio_return().unwrap(), LEN);
-/// }
-/// assert_eq!(rbuf, b"cdef");
-/// ```
-#[derive(Debug)]
-#[repr(transparent)]
-pub struct AioRead<'a> {
- aiocb: AioCb,
- _data: PhantomData<&'a [u8]>,
- _pin: PhantomPinned,
-}
-
-impl<'a> AioRead<'a> {
- unsafe_pinned!(aiocb: AioCb);
-
- /// Returns the requested length of the aio operation in bytes
- ///
- /// This method returns the *requested* length of the operation. To get the
- /// number of bytes actually read or written by a completed operation, use
- /// `aio_return` instead.
- pub fn nbytes(&self) -> usize {
- self.aiocb.aiocb.0.aio_nbytes
- }
-
- /// Create a new `AioRead`, placing the data in a mutable slice.
- ///
- /// # Arguments
- ///
- /// * `fd`: File descriptor to read from
- /// * `offs`: File offset
- /// * `buf`: A memory buffer. It must outlive the `AioRead`.
- /// * `prio`: If POSIX Prioritized IO is supported, then the
- /// operation will be prioritized at the process's
- /// priority level minus `prio`
- /// * `sigev_notify`: Determines how you will be notified of event
- /// completion.
- pub fn new(
- fd: RawFd,
- offs: off_t,
- buf: &'a mut [u8],
- prio: i32,
- sigev_notify: SigevNotify,
- ) -> Self {
- let mut aiocb = AioCb::common_init(fd, prio, sigev_notify);
- aiocb.aiocb.0.aio_nbytes = buf.len();
- aiocb.aiocb.0.aio_buf = buf.as_mut_ptr() as *mut c_void;
- aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READ;
- aiocb.aiocb.0.aio_offset = offs;
- AioRead {
- aiocb,
- _data: PhantomData,
- _pin: PhantomPinned,
- }
- }
-
- /// Returns the file offset of the operation.
- pub fn offset(&self) -> off_t {
- self.aiocb.aiocb.0.aio_offset
- }
-}
-
-impl<'a> Aio for AioRead<'a> {
- type Output = usize;
-
- aio_methods!(aio_read);
-}
-
-impl<'a> AsMut<libc::aiocb> for AioRead<'a> {
- fn as_mut(&mut self) -> &mut libc::aiocb {
- &mut self.aiocb.aiocb.0
- }
-}
-
-impl<'a> AsRef<libc::aiocb> for AioRead<'a> {
- fn as_ref(&self) -> &libc::aiocb {
- &self.aiocb.aiocb.0
- }
-}
-
-/// Asynchronously reads from a file descriptor into a scatter/gather list of buffers.
-///
-/// # References
-///
-/// [aio_readv](https://www.freebsd.org/cgi/man.cgi?query=aio_readv)
-///
-/// # Examples
-///
-///
-#[cfg_attr(fbsd14, doc = " ```")]
-#[cfg_attr(not(fbsd14), doc = " ```no_run")]
-/// # use nix::errno::Errno;
-/// # use nix::Error;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use std::{thread, time};
-/// # use std::io::{IoSliceMut, Write};
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// const INITIAL: &[u8] = b"abcdef123456";
-/// let mut rbuf0 = vec![0; 4];
-/// let mut rbuf1 = vec![0; 2];
-/// let expected_len = rbuf0.len() + rbuf1.len();
-/// let mut rbufs = [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)];
-/// let mut f = tempfile().unwrap();
-/// f.write_all(INITIAL).unwrap();
-/// {
-/// let mut aior = Box::pin(
-/// AioReadv::new(
-/// f.as_raw_fd(),
-/// 2, //offset
-/// &mut rbufs,
-/// 0, //priority
-/// SigevNotify::SigevNone
-/// )
-/// );
-/// aior.as_mut().submit().unwrap();
-/// while (aior.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// assert_eq!(aior.as_mut().aio_return().unwrap(), expected_len);
-/// }
-/// assert_eq!(rbuf0, b"cdef");
-/// assert_eq!(rbuf1, b"12");
-/// ```
-#[cfg(target_os = "freebsd")]
-#[derive(Debug)]
-#[repr(transparent)]
-pub struct AioReadv<'a> {
- aiocb: AioCb,
- _data: PhantomData<&'a [&'a [u8]]>,
- _pin: PhantomPinned,
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> AioReadv<'a> {
- unsafe_pinned!(aiocb: AioCb);
-
- /// Returns the number of buffers the operation will read into.
- pub fn iovlen(&self) -> usize {
- self.aiocb.aiocb.0.aio_nbytes
- }
-
- /// Create a new `AioReadv`, placing the data in a list of mutable slices.
- ///
- /// # Arguments
- ///
- /// * `fd`: File descriptor to read from
- /// * `offs`: File offset
- /// * `bufs`: A scatter/gather list of memory buffers. They must
- /// outlive the `AioReadv`.
- /// * `prio`: If POSIX Prioritized IO is supported, then the
- /// operation will be prioritized at the process's
- /// priority level minus `prio`
- /// * `sigev_notify`: Determines how you will be notified of event
- /// completion.
- pub fn new(
- fd: RawFd,
- offs: off_t,
- bufs: &mut [IoSliceMut<'a>],
- prio: i32,
- sigev_notify: SigevNotify,
- ) -> Self {
- let mut aiocb = AioCb::common_init(fd, prio, sigev_notify);
- // In vectored mode, aio_nbytes stores the length of the iovec array,
- // not the byte count.
- aiocb.aiocb.0.aio_nbytes = bufs.len();
- aiocb.aiocb.0.aio_buf = bufs.as_mut_ptr() as *mut c_void;
- aiocb.aiocb.0.aio_lio_opcode = libc::LIO_READV;
- aiocb.aiocb.0.aio_offset = offs;
- AioReadv {
- aiocb,
- _data: PhantomData,
- _pin: PhantomPinned,
- }
- }
-
- /// Returns the file offset of the operation.
- pub fn offset(&self) -> off_t {
- self.aiocb.aiocb.0.aio_offset
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> Aio for AioReadv<'a> {
- type Output = usize;
-
- aio_methods!(aio_readv);
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> AsMut<libc::aiocb> for AioReadv<'a> {
- fn as_mut(&mut self) -> &mut libc::aiocb {
- &mut self.aiocb.aiocb.0
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> AsRef<libc::aiocb> for AioReadv<'a> {
- fn as_ref(&self) -> &libc::aiocb {
- &self.aiocb.aiocb.0
- }
-}
-
-/// Asynchronously writes from a buffer to a file descriptor
-///
-/// # References
-///
-/// [aio_write](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_write.html)
-///
-/// # Examples
-///
-/// ```
-/// # use nix::errno::Errno;
-/// # use nix::Error;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use std::{thread, time};
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// const WBUF: &[u8] = b"abcdef123456";
-/// let mut f = tempfile().unwrap();
-/// let mut aiow = Box::pin(
-/// AioWrite::new(
-/// f.as_raw_fd(),
-/// 2, //offset
-/// WBUF,
-/// 0, //priority
-/// SigevNotify::SigevNone
-/// )
-/// );
-/// aiow.as_mut().submit().unwrap();
-/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
-/// ```
-#[derive(Debug)]
-#[repr(transparent)]
-pub struct AioWrite<'a> {
- aiocb: AioCb,
- _data: PhantomData<&'a [u8]>,
- _pin: PhantomPinned,
-}
-
-impl<'a> AioWrite<'a> {
- unsafe_pinned!(aiocb: AioCb);
-
- /// Returns the requested length of the aio operation in bytes
- ///
- /// This method returns the *requested* length of the operation. To get the
- /// number of bytes actually read or written by a completed operation, use
- /// `aio_return` instead.
- pub fn nbytes(&self) -> usize {
- self.aiocb.aiocb.0.aio_nbytes
- }
-
- /// Construct a new `AioWrite`.
- ///
- /// # Arguments
- ///
- /// * `fd`: File descriptor to write to
- /// * `offs`: File offset
- /// * `buf`: A memory buffer. It must outlive the `AioWrite`.
- /// * `prio`: If POSIX Prioritized IO is supported, then the
- /// operation will be prioritized at the process's
- /// priority level minus `prio`
- /// * `sigev_notify`: Determines how you will be notified of event
- /// completion.
- pub fn new(
- fd: RawFd,
- offs: off_t,
- buf: &'a [u8],
- prio: i32,
- sigev_notify: SigevNotify,
- ) -> Self {
- let mut aiocb = AioCb::common_init(fd, prio, sigev_notify);
- aiocb.aiocb.0.aio_nbytes = buf.len();
- // casting an immutable buffer to a mutable pointer looks unsafe,
- // but technically its only unsafe to dereference it, not to create
- // it. Type Safety guarantees that we'll never pass aiocb to
- // aio_read or aio_readv.
- aiocb.aiocb.0.aio_buf = buf.as_ptr() as *mut c_void;
- aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITE;
- aiocb.aiocb.0.aio_offset = offs;
- AioWrite {
- aiocb,
- _data: PhantomData,
- _pin: PhantomPinned,
- }
- }
-
- /// Returns the file offset of the operation.
- pub fn offset(&self) -> off_t {
- self.aiocb.aiocb.0.aio_offset
- }
-}
-
-impl<'a> Aio for AioWrite<'a> {
- type Output = usize;
-
- aio_methods!(aio_write);
-}
-
-impl<'a> AsMut<libc::aiocb> for AioWrite<'a> {
- fn as_mut(&mut self) -> &mut libc::aiocb {
- &mut self.aiocb.aiocb.0
- }
-}
-
-impl<'a> AsRef<libc::aiocb> for AioWrite<'a> {
- fn as_ref(&self) -> &libc::aiocb {
- &self.aiocb.aiocb.0
- }
-}
-
-/// Asynchronously writes from a scatter/gather list of buffers to a file descriptor.
-///
-/// # References
-///
-/// [aio_writev](https://www.freebsd.org/cgi/man.cgi?query=aio_writev)
-///
-/// # Examples
-///
-#[cfg_attr(fbsd14, doc = " ```")]
-#[cfg_attr(not(fbsd14), doc = " ```no_run")]
-/// # use nix::errno::Errno;
-/// # use nix::Error;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use std::{thread, time};
-/// # use std::io::IoSlice;
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// const wbuf0: &[u8] = b"abcdef";
-/// const wbuf1: &[u8] = b"123456";
-/// let len = wbuf0.len() + wbuf1.len();
-/// let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)];
-/// let mut f = tempfile().unwrap();
-/// let mut aiow = Box::pin(
-/// AioWritev::new(
-/// f.as_raw_fd(),
-/// 2, //offset
-/// &wbufs,
-/// 0, //priority
-/// SigevNotify::SigevNone
-/// )
-/// );
-/// aiow.as_mut().submit().unwrap();
-/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// assert_eq!(aiow.as_mut().aio_return().unwrap(), len);
-/// ```
-#[cfg(target_os = "freebsd")]
-#[derive(Debug)]
-#[repr(transparent)]
-pub struct AioWritev<'a> {
- aiocb: AioCb,
- _data: PhantomData<&'a [&'a [u8]]>,
- _pin: PhantomPinned,
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> AioWritev<'a> {
- unsafe_pinned!(aiocb: AioCb);
-
- /// Returns the number of buffers the operation will read into.
- pub fn iovlen(&self) -> usize {
- self.aiocb.aiocb.0.aio_nbytes
- }
-
- /// Construct a new `AioWritev`.
- ///
- /// # Arguments
- ///
- /// * `fd`: File descriptor to write to
- /// * `offs`: File offset
- /// * `bufs`: A scatter/gather list of memory buffers. They must
- /// outlive the `AioWritev`.
- /// * `prio`: If POSIX Prioritized IO is supported, then the
- /// operation will be prioritized at the process's
- /// priority level minus `prio`
- /// * `sigev_notify`: Determines how you will be notified of event
- /// completion.
- pub fn new(
- fd: RawFd,
- offs: off_t,
- bufs: &[IoSlice<'a>],
- prio: i32,
- sigev_notify: SigevNotify,
- ) -> Self {
- let mut aiocb = AioCb::common_init(fd, prio, sigev_notify);
- // In vectored mode, aio_nbytes stores the length of the iovec array,
- // not the byte count.
- aiocb.aiocb.0.aio_nbytes = bufs.len();
- // casting an immutable buffer to a mutable pointer looks unsafe,
- // but technically its only unsafe to dereference it, not to create
- // it. Type Safety guarantees that we'll never pass aiocb to
- // aio_read or aio_readv.
- aiocb.aiocb.0.aio_buf = bufs.as_ptr() as *mut c_void;
- aiocb.aiocb.0.aio_lio_opcode = libc::LIO_WRITEV;
- aiocb.aiocb.0.aio_offset = offs;
- AioWritev {
- aiocb,
- _data: PhantomData,
- _pin: PhantomPinned,
- }
- }
-
- /// Returns the file offset of the operation.
- pub fn offset(&self) -> off_t {
- self.aiocb.aiocb.0.aio_offset
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> Aio for AioWritev<'a> {
- type Output = usize;
-
- aio_methods!(aio_writev);
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> AsMut<libc::aiocb> for AioWritev<'a> {
- fn as_mut(&mut self) -> &mut libc::aiocb {
- &mut self.aiocb.aiocb.0
- }
-}
-
-#[cfg(target_os = "freebsd")]
-impl<'a> AsRef<libc::aiocb> for AioWritev<'a> {
- fn as_ref(&self) -> &libc::aiocb {
- &self.aiocb.aiocb.0
- }
-}
-
-/// Cancels outstanding AIO requests for a given file descriptor.
-///
-/// # Examples
-///
-/// Issue an aio operation, then cancel all outstanding operations on that file
-/// descriptor.
-///
-/// ```
-/// # use nix::errno::Errno;
-/// # use nix::Error;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use std::{thread, time};
-/// # use std::io::Write;
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// let wbuf = b"CDEF";
-/// let mut f = tempfile().unwrap();
-/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
-/// 2, //offset
-/// &wbuf[..],
-/// 0, //priority
-/// SigevNotify::SigevNone));
-/// aiocb.as_mut().submit().unwrap();
-/// let cs = aio_cancel_all(f.as_raw_fd()).unwrap();
-/// if cs == AioCancelStat::AioNotCanceled {
-/// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// }
-/// // Must call `aio_return`, but ignore the result
-/// let _ = aiocb.as_mut().aio_return();
-/// ```
-///
-/// # References
-///
-/// [`aio_cancel`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_cancel.html)
-pub fn aio_cancel_all(fd: RawFd) -> Result<AioCancelStat> {
- match unsafe { libc::aio_cancel(fd, ptr::null_mut()) } {
- libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
- libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
- libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
- -1 => Err(Errno::last()),
- _ => panic!("unknown aio_cancel return value"),
- }
-}
-
-/// Suspends the calling process until at least one of the specified operations
-/// have completed, a signal is delivered, or the timeout has passed.
-///
-/// If `timeout` is `None`, `aio_suspend` will block indefinitely.
-///
-/// # Examples
-///
-/// Use `aio_suspend` to block until an aio operation completes.
-///
-/// ```
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use std::os::unix::io::AsRawFd;
-/// # use tempfile::tempfile;
-/// const WBUF: &[u8] = b"abcdef123456";
-/// let mut f = tempfile().unwrap();
-/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
-/// 2, //offset
-/// WBUF,
-/// 0, //priority
-/// SigevNotify::SigevNone));
-/// aiocb.as_mut().submit().unwrap();
-/// aio_suspend(&[&*aiocb], None).expect("aio_suspend failed");
-/// assert_eq!(aiocb.as_mut().aio_return().unwrap() as usize, WBUF.len());
-/// ```
-/// # References
-///
-/// [`aio_suspend`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/aio_suspend.html)
-pub fn aio_suspend(
- list: &[&dyn AsRef<libc::aiocb>],
- timeout: Option<TimeSpec>,
-) -> Result<()> {
- let p = list as *const [&dyn AsRef<libc::aiocb>]
- as *const [*const libc::aiocb] as *const *const libc::aiocb;
- let timep = match timeout {
- None => ptr::null::<libc::timespec>(),
- Some(x) => x.as_ref() as *const libc::timespec,
- };
- Errno::result(unsafe { libc::aio_suspend(p, list.len() as i32, timep) })
- .map(drop)
-}
-
-/// Submits multiple asynchronous I/O requests with a single system call.
-///
-/// They are not guaranteed to complete atomically, and the order in which the
-/// requests are carried out is not specified. Reads, and writes may be freely
-/// mixed.
-///
-/// # Examples
-///
-/// Use `lio_listio` to submit an aio operation and wait for its completion. In
-/// this case, there is no need to use aio_suspend to wait or `error` to poll.
-/// This mode is useful for otherwise-synchronous programs that want to execute
-/// a handful of I/O operations in parallel.
-/// ```
-/// # use std::os::unix::io::AsRawFd;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use tempfile::tempfile;
-/// const WBUF: &[u8] = b"abcdef123456";
-/// let mut f = tempfile().unwrap();
-/// let mut aiow = Box::pin(AioWrite::new(
-/// f.as_raw_fd(),
-/// 2, // offset
-/// WBUF,
-/// 0, // priority
-/// SigevNotify::SigevNone
-/// ));
-/// lio_listio(LioMode::LIO_WAIT, &mut[aiow.as_mut()], SigevNotify::SigevNone)
-/// .unwrap();
-/// // At this point, we are guaranteed that aiow is complete.
-/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
-/// ```
-///
-/// Use `lio_listio` to submit multiple asynchronous operations with a single
-/// syscall, but receive notification individually. This is an efficient
-/// technique for reducing overall context-switch overhead, especially when
-/// combined with kqueue.
-/// ```
-/// # use std::os::unix::io::AsRawFd;
-/// # use std::thread;
-/// # use std::time;
-/// # use nix::errno::Errno;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::SigevNotify;
-/// # use tempfile::tempfile;
-/// const WBUF: &[u8] = b"abcdef123456";
-/// let mut f = tempfile().unwrap();
-/// let mut aiow = Box::pin(AioWrite::new(
-/// f.as_raw_fd(),
-/// 2, // offset
-/// WBUF,
-/// 0, // priority
-/// SigevNotify::SigevNone
-/// ));
-/// lio_listio(LioMode::LIO_NOWAIT, &mut[aiow.as_mut()], SigevNotify::SigevNone)
-/// .unwrap();
-/// // We must wait for the completion of each individual operation
-/// while (aiow.as_mut().error() == Err(Errno::EINPROGRESS)) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
-/// ```
-///
-/// Use `lio_listio` to submit multiple operations, and receive notification
-/// only when all of them are complete. This can be useful when there is some
-/// logical relationship between the operations. But beware! Errors or system
-/// resource limitations may cause `lio_listio` to return `EIO`, `EAGAIN`, or
-/// `EINTR`, in which case some but not all operations may have been submitted.
-/// In that case, you must check the status of each individual operation, and
-/// possibly resubmit some.
-/// ```
-/// # use libc::c_int;
-/// # use std::os::unix::io::AsRawFd;
-/// # use std::sync::atomic::{AtomicBool, Ordering};
-/// # use std::thread;
-/// # use std::time;
-/// # use lazy_static::lazy_static;
-/// # use nix::errno::Errno;
-/// # use nix::sys::aio::*;
-/// # use nix::sys::signal::*;
-/// # use tempfile::tempfile;
-/// lazy_static! {
-/// pub static ref SIGNALED: AtomicBool = AtomicBool::new(false);
-/// }
-///
-/// extern fn sigfunc(_: c_int) {
-/// SIGNALED.store(true, Ordering::Relaxed);
-/// }
-/// let sa = SigAction::new(SigHandler::Handler(sigfunc),
-/// SaFlags::SA_RESETHAND,
-/// SigSet::empty());
-/// SIGNALED.store(false, Ordering::Relaxed);
-/// unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
-///
-/// const WBUF: &[u8] = b"abcdef123456";
-/// let mut f = tempfile().unwrap();
-/// let mut aiow = Box::pin(AioWrite::new(
-/// f.as_raw_fd(),
-/// 2, // offset
-/// WBUF,
-/// 0, // priority
-/// SigevNotify::SigevNone
-/// ));
-/// let sev = SigevNotify::SigevSignal { signal: Signal::SIGUSR2, si_value: 0 };
-/// lio_listio(LioMode::LIO_NOWAIT, &mut[aiow.as_mut()], sev).unwrap();
-/// while !SIGNALED.load(Ordering::Relaxed) {
-/// thread::sleep(time::Duration::from_millis(10));
-/// }
-/// // At this point, since `lio_listio` returned success and delivered its
-/// // notification, we know that all operations are complete.
-/// assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
-/// ```
-pub fn lio_listio(
- mode: LioMode,
- list: &mut [Pin<&mut dyn AsMut<libc::aiocb>>],
- sigev_notify: SigevNotify,
-) -> Result<()> {
- let p = list as *mut [Pin<&mut dyn AsMut<libc::aiocb>>]
- as *mut [*mut libc::aiocb] as *mut *mut libc::aiocb;
- let sigev = SigEvent::new(sigev_notify);
- let sigevp = &mut sigev.sigevent() as *mut libc::sigevent;
- Errno::result(unsafe {
- libc::lio_listio(mode as i32, p, list.len() as i32, sigevp)
- })
- .map(drop)
-}
-
-#[cfg(test)]
-mod t {
- use super::*;
-
- /// aio_suspend relies on casting Rust Aio* struct pointers to libc::aiocb
- /// pointers. This test ensures that such casts are valid.
- #[test]
- fn casting() {
- let sev = SigevNotify::SigevNone;
- let aiof = AioFsync::new(666, AioFsyncMode::O_SYNC, 0, sev);
- assert_eq!(
- aiof.as_ref() as *const libc::aiocb,
- &aiof as *const AioFsync as *const libc::aiocb
- );
-
- let mut rbuf = [];
- let aior = AioRead::new(666, 0, &mut rbuf, 0, sev);
- assert_eq!(
- aior.as_ref() as *const libc::aiocb,
- &aior as *const AioRead as *const libc::aiocb
- );
-
- let wbuf = [];
- let aiow = AioWrite::new(666, 0, &wbuf, 0, sev);
- assert_eq!(
- aiow.as_ref() as *const libc::aiocb,
- &aiow as *const AioWrite as *const libc::aiocb
- );
- }
-
- #[cfg(target_os = "freebsd")]
- #[test]
- fn casting_vectored() {
- let sev = SigevNotify::SigevNone;
-
- let mut rbuf = [];
- let mut rbufs = [IoSliceMut::new(&mut rbuf)];
- let aiorv = AioReadv::new(666, 0, &mut rbufs[..], 0, sev);
- assert_eq!(
- aiorv.as_ref() as *const libc::aiocb,
- &aiorv as *const AioReadv as *const libc::aiocb
- );
-
- let wbuf = [];
- let wbufs = [IoSlice::new(&wbuf)];
- let aiowv = AioWritev::new(666, 0, &wbufs, 0, sev);
- assert_eq!(
- aiowv.as_ref() as *const libc::aiocb,
- &aiowv as *const AioWritev as *const libc::aiocb
- );
- }
-}
diff --git a/vendor/nix/src/sys/epoll.rs b/vendor/nix/src/sys/epoll.rs
deleted file mode 100644
index 58def2e78..000000000
--- a/vendor/nix/src/sys/epoll.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-use crate::errno::Errno;
-use crate::Result;
-use libc::{self, c_int};
-use std::mem;
-use std::os::unix::io::RawFd;
-use std::ptr;
-
-libc_bitflags!(
- pub struct EpollFlags: c_int {
- EPOLLIN;
- EPOLLPRI;
- EPOLLOUT;
- EPOLLRDNORM;
- EPOLLRDBAND;
- EPOLLWRNORM;
- EPOLLWRBAND;
- EPOLLMSG;
- EPOLLERR;
- EPOLLHUP;
- EPOLLRDHUP;
- EPOLLEXCLUSIVE;
- #[cfg(not(target_arch = "mips"))]
- EPOLLWAKEUP;
- EPOLLONESHOT;
- EPOLLET;
- }
-);
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(i32)]
-#[non_exhaustive]
-pub enum EpollOp {
- EpollCtlAdd = libc::EPOLL_CTL_ADD,
- EpollCtlDel = libc::EPOLL_CTL_DEL,
- EpollCtlMod = libc::EPOLL_CTL_MOD,
-}
-
-libc_bitflags! {
- pub struct EpollCreateFlags: c_int {
- EPOLL_CLOEXEC;
- }
-}
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(transparent)]
-pub struct EpollEvent {
- event: libc::epoll_event,
-}
-
-impl EpollEvent {
- pub fn new(events: EpollFlags, data: u64) -> Self {
- EpollEvent {
- event: libc::epoll_event {
- events: events.bits() as u32,
- u64: data,
- },
- }
- }
-
- pub fn empty() -> Self {
- unsafe { mem::zeroed::<EpollEvent>() }
- }
-
- pub fn events(&self) -> EpollFlags {
- EpollFlags::from_bits(self.event.events as c_int).unwrap()
- }
-
- pub fn data(&self) -> u64 {
- self.event.u64
- }
-}
-
-#[inline]
-pub fn epoll_create() -> Result<RawFd> {
- let res = unsafe { libc::epoll_create(1024) };
-
- Errno::result(res)
-}
-
-#[inline]
-pub fn epoll_create1(flags: EpollCreateFlags) -> Result<RawFd> {
- let res = unsafe { libc::epoll_create1(flags.bits()) };
-
- Errno::result(res)
-}
-
-#[inline]
-pub fn epoll_ctl<'a, T>(
- epfd: RawFd,
- op: EpollOp,
- fd: RawFd,
- event: T,
-) -> Result<()>
-where
- T: Into<Option<&'a mut EpollEvent>>,
-{
- let mut event: Option<&mut EpollEvent> = event.into();
- if event.is_none() && op != EpollOp::EpollCtlDel {
- Err(Errno::EINVAL)
- } else {
- let res = unsafe {
- if let Some(ref mut event) = event {
- libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event)
- } else {
- libc::epoll_ctl(epfd, op as c_int, fd, ptr::null_mut())
- }
- };
- Errno::result(res).map(drop)
- }
-}
-
-#[inline]
-pub fn epoll_wait(
- epfd: RawFd,
- events: &mut [EpollEvent],
- timeout_ms: isize,
-) -> Result<usize> {
- let res = unsafe {
- libc::epoll_wait(
- epfd,
- events.as_mut_ptr() as *mut libc::epoll_event,
- events.len() as c_int,
- timeout_ms as c_int,
- )
- };
-
- Errno::result(res).map(|r| r as usize)
-}
diff --git a/vendor/nix/src/sys/event.rs b/vendor/nix/src/sys/event.rs
deleted file mode 100644
index d8ad628ea..000000000
--- a/vendor/nix/src/sys/event.rs
+++ /dev/null
@@ -1,374 +0,0 @@
-/* TOOD: Implement for other kqueue based systems
- */
-
-use crate::{Errno, Result};
-#[cfg(not(target_os = "netbsd"))]
-use libc::{c_int, c_long, intptr_t, time_t, timespec, uintptr_t};
-#[cfg(target_os = "netbsd")]
-use libc::{c_long, intptr_t, size_t, time_t, timespec, uintptr_t};
-use std::convert::TryInto;
-use std::mem;
-use std::os::unix::io::RawFd;
-use std::ptr;
-
-// Redefine kevent in terms of programmer-friendly enums and bitfields.
-#[repr(C)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct KEvent {
- kevent: libc::kevent,
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "openbsd"
-))]
-type type_of_udata = *mut libc::c_void;
-#[cfg(any(target_os = "netbsd"))]
-type type_of_udata = intptr_t;
-
-#[cfg(target_os = "netbsd")]
-type type_of_event_filter = u32;
-#[cfg(not(target_os = "netbsd"))]
-type type_of_event_filter = i16;
-libc_enum! {
- #[cfg_attr(target_os = "netbsd", repr(u32))]
- #[cfg_attr(not(target_os = "netbsd"), repr(i16))]
- #[non_exhaustive]
- pub enum EventFilter {
- EVFILT_AIO,
- /// Returns whenever there is no remaining data in the write buffer
- #[cfg(target_os = "freebsd")]
- EVFILT_EMPTY,
- #[cfg(target_os = "dragonfly")]
- EVFILT_EXCEPT,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))]
- EVFILT_FS,
- #[cfg(target_os = "freebsd")]
- EVFILT_LIO,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- EVFILT_MACHPORT,
- EVFILT_PROC,
- /// Returns events associated with the process referenced by a given
- /// process descriptor, created by `pdfork()`. The events to monitor are:
- ///
- /// - NOTE_EXIT: the process has exited. The exit status will be stored in data.
- #[cfg(target_os = "freebsd")]
- EVFILT_PROCDESC,
- EVFILT_READ,
- /// Returns whenever an asynchronous `sendfile()` call completes.
- #[cfg(target_os = "freebsd")]
- EVFILT_SENDFILE,
- EVFILT_SIGNAL,
- EVFILT_TIMER,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))]
- EVFILT_USER,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- EVFILT_VM,
- EVFILT_VNODE,
- EVFILT_WRITE,
- }
- impl TryFrom<type_of_event_filter>
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "openbsd"
-))]
-pub type type_of_event_flag = u16;
-#[cfg(any(target_os = "netbsd"))]
-pub type type_of_event_flag = u32;
-libc_bitflags! {
- pub struct EventFlag: type_of_event_flag {
- EV_ADD;
- EV_CLEAR;
- EV_DELETE;
- EV_DISABLE;
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
- target_os = "ios", target_os = "macos",
- target_os = "netbsd", target_os = "openbsd"))]
- EV_DISPATCH;
- #[cfg(target_os = "freebsd")]
- EV_DROP;
- EV_ENABLE;
- EV_EOF;
- EV_ERROR;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EV_FLAG0;
- EV_FLAG1;
- #[cfg(target_os = "dragonfly")]
- EV_NODATA;
- EV_ONESHOT;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EV_OOBAND;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- EV_POLL;
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
- target_os = "ios", target_os = "macos",
- target_os = "netbsd", target_os = "openbsd"))]
- EV_RECEIPT;
- }
-}
-
-libc_bitflags!(
- pub struct FilterFlag: u32 {
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_ABSOLUTE;
- NOTE_ATTRIB;
- NOTE_CHILD;
- NOTE_DELETE;
- #[cfg(target_os = "openbsd")]
- NOTE_EOF;
- NOTE_EXEC;
- NOTE_EXIT;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_EXITSTATUS;
- NOTE_EXTEND;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_FFAND;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_FFCOPY;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_FFCTRLMASK;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_FFLAGSMASK;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_FFNOP;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_FFOR;
- NOTE_FORK;
- NOTE_LINK;
- NOTE_LOWAT;
- #[cfg(target_os = "freebsd")]
- NOTE_MSECONDS;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_NONE;
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
- NOTE_NSECONDS;
- #[cfg(target_os = "dragonfly")]
- NOTE_OOB;
- NOTE_PCTRLMASK;
- NOTE_PDATAMASK;
- NOTE_RENAME;
- NOTE_REVOKE;
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
- NOTE_SECONDS;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_SIGNAL;
- NOTE_TRACK;
- NOTE_TRACKERR;
- #[cfg(any(target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly"))]
- NOTE_TRIGGER;
- #[cfg(target_os = "openbsd")]
- NOTE_TRUNCATE;
- #[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd"))]
- NOTE_USECONDS;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_VM_ERROR;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_VM_PRESSURE;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_VM_PRESSURE_SUDDEN_TERMINATE;
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- NOTE_VM_PRESSURE_TERMINATE;
- NOTE_WRITE;
- }
-);
-
-pub fn kqueue() -> Result<RawFd> {
- let res = unsafe { libc::kqueue() };
-
- Errno::result(res)
-}
-
-// KEvent can't derive Send because on some operating systems, udata is defined
-// as a void*. However, KEvent's public API always treats udata as an intptr_t,
-// which is safe to Send.
-unsafe impl Send for KEvent {}
-
-impl KEvent {
- #[allow(clippy::needless_update)] // Not needless on all platforms.
- pub fn new(
- ident: uintptr_t,
- filter: EventFilter,
- flags: EventFlag,
- fflags: FilterFlag,
- data: intptr_t,
- udata: intptr_t,
- ) -> KEvent {
- KEvent {
- kevent: libc::kevent {
- ident,
- filter: filter as type_of_event_filter,
- flags: flags.bits(),
- fflags: fflags.bits(),
- // data can be either i64 or intptr_t, depending on platform
- data: data as _,
- udata: udata as type_of_udata,
- ..unsafe { mem::zeroed() }
- },
- }
- }
-
- pub fn ident(&self) -> uintptr_t {
- self.kevent.ident
- }
-
- pub fn filter(&self) -> Result<EventFilter> {
- self.kevent.filter.try_into()
- }
-
- pub fn flags(&self) -> EventFlag {
- EventFlag::from_bits(self.kevent.flags).unwrap()
- }
-
- pub fn fflags(&self) -> FilterFlag {
- FilterFlag::from_bits(self.kevent.fflags).unwrap()
- }
-
- pub fn data(&self) -> intptr_t {
- self.kevent.data as intptr_t
- }
-
- pub fn udata(&self) -> intptr_t {
- self.kevent.udata as intptr_t
- }
-}
-
-pub fn kevent(
- kq: RawFd,
- changelist: &[KEvent],
- eventlist: &mut [KEvent],
- timeout_ms: usize,
-) -> Result<usize> {
- // Convert ms to timespec
- let timeout = timespec {
- tv_sec: (timeout_ms / 1000) as time_t,
- tv_nsec: ((timeout_ms % 1000) * 1_000_000) as c_long,
- };
-
- kevent_ts(kq, changelist, eventlist, Some(timeout))
-}
-
-#[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "openbsd"
-))]
-type type_of_nchanges = c_int;
-#[cfg(target_os = "netbsd")]
-type type_of_nchanges = size_t;
-
-pub fn kevent_ts(
- kq: RawFd,
- changelist: &[KEvent],
- eventlist: &mut [KEvent],
- timeout_opt: Option<timespec>,
-) -> Result<usize> {
- let res = unsafe {
- libc::kevent(
- kq,
- changelist.as_ptr() as *const libc::kevent,
- changelist.len() as type_of_nchanges,
- eventlist.as_mut_ptr() as *mut libc::kevent,
- eventlist.len() as type_of_nchanges,
- if let Some(ref timeout) = timeout_opt {
- timeout as *const timespec
- } else {
- ptr::null()
- },
- )
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-#[inline]
-pub fn ev_set(
- ev: &mut KEvent,
- ident: usize,
- filter: EventFilter,
- flags: EventFlag,
- fflags: FilterFlag,
- udata: intptr_t,
-) {
- ev.kevent.ident = ident as uintptr_t;
- ev.kevent.filter = filter as type_of_event_filter;
- ev.kevent.flags = flags.bits();
- ev.kevent.fflags = fflags.bits();
- ev.kevent.data = 0;
- ev.kevent.udata = udata as type_of_udata;
-}
-
-#[test]
-fn test_struct_kevent() {
- use std::mem;
-
- let udata: intptr_t = 12345;
-
- let actual = KEvent::new(
- 0xdead_beef,
- EventFilter::EVFILT_READ,
- EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
- FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
- 0x1337,
- udata,
- );
- assert_eq!(0xdead_beef, actual.ident());
- let filter = actual.kevent.filter;
- assert_eq!(libc::EVFILT_READ, filter);
- assert_eq!(libc::EV_ONESHOT | libc::EV_ADD, actual.flags().bits());
- assert_eq!(libc::NOTE_CHILD | libc::NOTE_EXIT, actual.fflags().bits());
- assert_eq!(0x1337, actual.data());
- assert_eq!(udata as type_of_udata, actual.udata() as type_of_udata);
- assert_eq!(mem::size_of::<libc::kevent>(), mem::size_of::<KEvent>());
-}
-
-#[test]
-fn test_kevent_filter() {
- let udata: intptr_t = 12345;
-
- let actual = KEvent::new(
- 0xdead_beef,
- EventFilter::EVFILT_READ,
- EventFlag::EV_ONESHOT | EventFlag::EV_ADD,
- FilterFlag::NOTE_CHILD | FilterFlag::NOTE_EXIT,
- 0x1337,
- udata,
- );
- assert_eq!(EventFilter::EVFILT_READ, actual.filter().unwrap());
-}
diff --git a/vendor/nix/src/sys/eventfd.rs b/vendor/nix/src/sys/eventfd.rs
deleted file mode 100644
index cd906720c..000000000
--- a/vendor/nix/src/sys/eventfd.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-use crate::errno::Errno;
-use crate::Result;
-use std::os::unix::io::RawFd;
-
-libc_bitflags! {
- pub struct EfdFlags: libc::c_int {
- EFD_CLOEXEC; // Since Linux 2.6.27
- EFD_NONBLOCK; // Since Linux 2.6.27
- EFD_SEMAPHORE; // Since Linux 2.6.30
- }
-}
-
-pub fn eventfd(initval: libc::c_uint, flags: EfdFlags) -> Result<RawFd> {
- let res = unsafe { libc::eventfd(initval, flags.bits()) };
-
- Errno::result(res).map(|r| r as RawFd)
-}
diff --git a/vendor/nix/src/sys/inotify.rs b/vendor/nix/src/sys/inotify.rs
deleted file mode 100644
index 84356ec70..000000000
--- a/vendor/nix/src/sys/inotify.rs
+++ /dev/null
@@ -1,248 +0,0 @@
-//! Monitoring API for filesystem events.
-//!
-//! Inotify is a Linux-only API to monitor filesystems events.
-//!
-//! For more documentation, please read [inotify(7)](https://man7.org/linux/man-pages/man7/inotify.7.html).
-//!
-//! # Examples
-//!
-//! Monitor all events happening in directory "test":
-//! ```no_run
-//! # use nix::sys::inotify::{AddWatchFlags,InitFlags,Inotify};
-//! #
-//! // We create a new inotify instance.
-//! let instance = Inotify::init(InitFlags::empty()).unwrap();
-//!
-//! // We add a new watch on directory "test" for all events.
-//! let wd = instance.add_watch("test", AddWatchFlags::IN_ALL_EVENTS).unwrap();
-//!
-//! loop {
-//! // We read from our inotify instance for events.
-//! let events = instance.read_events().unwrap();
-//! println!("Events: {:?}", events);
-//! }
-//! ```
-
-use crate::errno::Errno;
-use crate::unistd::read;
-use crate::NixPath;
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{c_char, c_int};
-use std::ffi::{CStr, OsStr, OsString};
-use std::mem::{size_of, MaybeUninit};
-use std::os::unix::ffi::OsStrExt;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
-use std::ptr;
-
-libc_bitflags! {
- /// Configuration options for [`inotify_add_watch`](fn.inotify_add_watch.html).
- pub struct AddWatchFlags: u32 {
- /// File was accessed.
- IN_ACCESS;
- /// File was modified.
- IN_MODIFY;
- /// Metadata changed.
- IN_ATTRIB;
- /// Writable file was closed.
- IN_CLOSE_WRITE;
- /// Nonwritable file was closed.
- IN_CLOSE_NOWRITE;
- /// File was opened.
- IN_OPEN;
- /// File was moved from X.
- IN_MOVED_FROM;
- /// File was moved to Y.
- IN_MOVED_TO;
- /// Subfile was created.
- IN_CREATE;
- /// Subfile was deleted.
- IN_DELETE;
- /// Self was deleted.
- IN_DELETE_SELF;
- /// Self was moved.
- IN_MOVE_SELF;
-
- /// Backing filesystem was unmounted.
- IN_UNMOUNT;
- /// Event queue overflowed.
- IN_Q_OVERFLOW;
- /// File was ignored.
- IN_IGNORED;
-
- /// Combination of `IN_CLOSE_WRITE` and `IN_CLOSE_NOWRITE`.
- IN_CLOSE;
- /// Combination of `IN_MOVED_FROM` and `IN_MOVED_TO`.
- IN_MOVE;
-
- /// Only watch the path if it is a directory.
- IN_ONLYDIR;
- /// Don't follow symlinks.
- IN_DONT_FOLLOW;
-
- /// Event occurred against directory.
- IN_ISDIR;
- /// Only send event once.
- IN_ONESHOT;
- /// All of the events.
- IN_ALL_EVENTS;
- }
-}
-
-libc_bitflags! {
- /// Configuration options for [`inotify_init1`](fn.inotify_init1.html).
- pub struct InitFlags: c_int {
- /// Set the `FD_CLOEXEC` flag on the file descriptor.
- IN_CLOEXEC;
- /// Set the `O_NONBLOCK` flag on the open file description referred to by the new file descriptor.
- IN_NONBLOCK;
- }
-}
-
-/// An inotify instance. This is also a file descriptor, you can feed it to
-/// other interfaces consuming file descriptors, epoll for example.
-#[derive(Debug, Clone, Copy)]
-pub struct Inotify {
- fd: RawFd,
-}
-
-/// This object is returned when you create a new watch on an inotify instance.
-/// It is then returned as part of an event once triggered. It allows you to
-/// know which watch triggered which event.
-#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
-pub struct WatchDescriptor {
- wd: i32,
-}
-
-/// A single inotify event.
-///
-/// For more documentation see, [inotify(7)](https://man7.org/linux/man-pages/man7/inotify.7.html).
-#[derive(Debug)]
-pub struct InotifyEvent {
- /// Watch descriptor. This field corresponds to the watch descriptor you
- /// were issued when calling add_watch. It allows you to know which watch
- /// this event comes from.
- pub wd: WatchDescriptor,
- /// Event mask. This field is a bitfield describing the exact event that
- /// occured.
- pub mask: AddWatchFlags,
- /// This cookie is a number that allows you to connect related events. For
- /// now only IN_MOVED_FROM and IN_MOVED_TO can be connected.
- pub cookie: u32,
- /// Filename. This field exists only if the event was triggered for a file
- /// inside the watched directory.
- pub name: Option<OsString>,
-}
-
-impl Inotify {
- /// Initialize a new inotify instance.
- ///
- /// Returns a Result containing an inotify instance.
- ///
- /// For more information see, [inotify_init(2)](https://man7.org/linux/man-pages/man2/inotify_init.2.html).
- pub fn init(flags: InitFlags) -> Result<Inotify> {
- let res = Errno::result(unsafe { libc::inotify_init1(flags.bits()) });
-
- res.map(|fd| Inotify { fd })
- }
-
- /// Adds a new watch on the target file or directory.
- ///
- /// Returns a watch descriptor. This is not a File Descriptor!
- ///
- /// For more information see, [inotify_add_watch(2)](https://man7.org/linux/man-pages/man2/inotify_add_watch.2.html).
- pub fn add_watch<P: ?Sized + NixPath>(
- self,
- path: &P,
- mask: AddWatchFlags,
- ) -> Result<WatchDescriptor> {
- let res = path.with_nix_path(|cstr| unsafe {
- libc::inotify_add_watch(self.fd, cstr.as_ptr(), mask.bits())
- })?;
-
- Errno::result(res).map(|wd| WatchDescriptor { wd })
- }
-
- /// Removes an existing watch using the watch descriptor returned by
- /// inotify_add_watch.
- ///
- /// Returns an EINVAL error if the watch descriptor is invalid.
- ///
- /// For more information see, [inotify_rm_watch(2)](https://man7.org/linux/man-pages/man2/inotify_rm_watch.2.html).
- pub fn rm_watch(self, wd: WatchDescriptor) -> Result<()> {
- cfg_if! {
- if #[cfg(target_os = "linux")] {
- let arg = wd.wd;
- } else if #[cfg(target_os = "android")] {
- let arg = wd.wd as u32;
- }
- }
- let res = unsafe { libc::inotify_rm_watch(self.fd, arg) };
-
- Errno::result(res).map(drop)
- }
-
- /// Reads a collection of events from the inotify file descriptor. This call
- /// can either be blocking or non blocking depending on whether IN_NONBLOCK
- /// was set at initialization.
- ///
- /// Returns as many events as available. If the call was non blocking and no
- /// events could be read then the EAGAIN error is returned.
- pub fn read_events(self) -> Result<Vec<InotifyEvent>> {
- let header_size = size_of::<libc::inotify_event>();
- const BUFSIZ: usize = 4096;
- let mut buffer = [0u8; BUFSIZ];
- let mut events = Vec::new();
- let mut offset = 0;
-
- let nread = read(self.fd, &mut buffer)?;
-
- while (nread - offset) >= header_size {
- let event = unsafe {
- let mut event = MaybeUninit::<libc::inotify_event>::uninit();
- ptr::copy_nonoverlapping(
- buffer.as_ptr().add(offset),
- event.as_mut_ptr() as *mut u8,
- (BUFSIZ - offset).min(header_size),
- );
- event.assume_init()
- };
-
- let name = match event.len {
- 0 => None,
- _ => {
- let ptr = unsafe {
- buffer.as_ptr().add(offset + header_size)
- as *const c_char
- };
- let cstr = unsafe { CStr::from_ptr(ptr) };
-
- Some(OsStr::from_bytes(cstr.to_bytes()).to_owned())
- }
- };
-
- events.push(InotifyEvent {
- wd: WatchDescriptor { wd: event.wd },
- mask: AddWatchFlags::from_bits_truncate(event.mask),
- cookie: event.cookie,
- name,
- });
-
- offset += header_size + event.len as usize;
- }
-
- Ok(events)
- }
-}
-
-impl AsRawFd for Inotify {
- fn as_raw_fd(&self) -> RawFd {
- self.fd
- }
-}
-
-impl FromRawFd for Inotify {
- unsafe fn from_raw_fd(fd: RawFd) -> Self {
- Inotify { fd }
- }
-}
diff --git a/vendor/nix/src/sys/ioctl/bsd.rs b/vendor/nix/src/sys/ioctl/bsd.rs
deleted file mode 100644
index 307994cb9..000000000
--- a/vendor/nix/src/sys/ioctl/bsd.rs
+++ /dev/null
@@ -1,129 +0,0 @@
-/// The datatype used for the ioctl number
-#[doc(hidden)]
-#[cfg(not(target_os = "illumos"))]
-pub type ioctl_num_type = ::libc::c_ulong;
-
-#[doc(hidden)]
-#[cfg(target_os = "illumos")]
-pub type ioctl_num_type = ::libc::c_int;
-
-/// The datatype used for the 3rd argument
-#[doc(hidden)]
-pub type ioctl_param_type = ::libc::c_int;
-
-mod consts {
- use crate::sys::ioctl::ioctl_num_type;
- #[doc(hidden)]
- pub const VOID: ioctl_num_type = 0x2000_0000;
- #[doc(hidden)]
- pub const OUT: ioctl_num_type = 0x4000_0000;
- #[doc(hidden)]
- #[allow(overflowing_literals)]
- pub const IN: ioctl_num_type = 0x8000_0000;
- #[doc(hidden)]
- pub const INOUT: ioctl_num_type = IN | OUT;
- #[doc(hidden)]
- pub const IOCPARM_MASK: ioctl_num_type = 0x1fff;
-}
-
-pub use self::consts::*;
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! ioc {
- ($inout:expr, $group:expr, $num:expr, $len:expr) => {
- $inout
- | (($len as $crate::sys::ioctl::ioctl_num_type
- & $crate::sys::ioctl::IOCPARM_MASK)
- << 16)
- | (($group as $crate::sys::ioctl::ioctl_num_type) << 8)
- | ($num as $crate::sys::ioctl::ioctl_num_type)
- };
-}
-
-/// Generate an ioctl request code for a command that passes no data.
-///
-/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_none!()` directly.
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// const KVMIO: u8 = 0xAE;
-/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_none {
- ($g:expr, $n:expr) => {
- ioc!($crate::sys::ioctl::VOID, $g, $n, 0)
- };
-}
-
-/// Generate an ioctl request code for a command that passes an integer
-///
-/// This is equivalent to the `_IOWINT()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_write_int!()` directly.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_write_int {
- ($g:expr, $n:expr) => {
- ioc!(
- $crate::sys::ioctl::VOID,
- $g,
- $n,
- ::std::mem::size_of::<$crate::libc::c_int>()
- )
- };
-}
-
-/// Generate an ioctl request code for a command that reads.
-///
-/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_read!()` directly.
-///
-/// The read/write direction is relative to userland, so this
-/// command would be userland is reading and the kernel is
-/// writing.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_read {
- ($g:expr, $n:expr, $len:expr) => {
- ioc!($crate::sys::ioctl::OUT, $g, $n, $len)
- };
-}
-
-/// Generate an ioctl request code for a command that writes.
-///
-/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_write!()` directly.
-///
-/// The read/write direction is relative to userland, so this
-/// command would be userland is writing and the kernel is
-/// reading.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_write {
- ($g:expr, $n:expr, $len:expr) => {
- ioc!($crate::sys::ioctl::IN, $g, $n, $len)
- };
-}
-
-/// Generate an ioctl request code for a command that reads and writes.
-///
-/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_readwrite {
- ($g:expr, $n:expr, $len:expr) => {
- ioc!($crate::sys::ioctl::INOUT, $g, $n, $len)
- };
-}
diff --git a/vendor/nix/src/sys/ioctl/linux.rs b/vendor/nix/src/sys/ioctl/linux.rs
deleted file mode 100644
index 0c0a20905..000000000
--- a/vendor/nix/src/sys/ioctl/linux.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-/// The datatype used for the ioctl number
-#[cfg(any(target_os = "android", target_env = "musl"))]
-#[doc(hidden)]
-pub type ioctl_num_type = ::libc::c_int;
-#[cfg(not(any(target_os = "android", target_env = "musl")))]
-#[doc(hidden)]
-pub type ioctl_num_type = ::libc::c_ulong;
-/// The datatype used for the 3rd argument
-#[doc(hidden)]
-pub type ioctl_param_type = ::libc::c_ulong;
-
-#[doc(hidden)]
-pub const NRBITS: ioctl_num_type = 8;
-#[doc(hidden)]
-pub const TYPEBITS: ioctl_num_type = 8;
-
-#[cfg(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64",
- target_arch = "sparc64"
-))]
-mod consts {
- #[doc(hidden)]
- pub const NONE: u8 = 1;
- #[doc(hidden)]
- pub const READ: u8 = 2;
- #[doc(hidden)]
- pub const WRITE: u8 = 4;
- #[doc(hidden)]
- pub const SIZEBITS: u8 = 13;
- #[doc(hidden)]
- pub const DIRBITS: u8 = 3;
-}
-
-// "Generic" ioctl protocol
-#[cfg(any(
- target_arch = "x86",
- target_arch = "arm",
- target_arch = "s390x",
- target_arch = "x86_64",
- target_arch = "aarch64",
- target_arch = "riscv32",
- target_arch = "riscv64"
-))]
-mod consts {
- #[doc(hidden)]
- pub const NONE: u8 = 0;
- #[doc(hidden)]
- pub const READ: u8 = 2;
- #[doc(hidden)]
- pub const WRITE: u8 = 1;
- #[doc(hidden)]
- pub const SIZEBITS: u8 = 14;
- #[doc(hidden)]
- pub const DIRBITS: u8 = 2;
-}
-
-pub use self::consts::*;
-
-#[doc(hidden)]
-pub const NRSHIFT: ioctl_num_type = 0;
-#[doc(hidden)]
-pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
-#[doc(hidden)]
-pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
-#[doc(hidden)]
-pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
-
-#[doc(hidden)]
-pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
-#[doc(hidden)]
-pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
-#[doc(hidden)]
-pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
-#[doc(hidden)]
-pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
-
-/// Encode an ioctl command.
-#[macro_export]
-#[doc(hidden)]
-macro_rules! ioc {
- ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => {
- (($dir as $crate::sys::ioctl::ioctl_num_type
- & $crate::sys::ioctl::DIRMASK)
- << $crate::sys::ioctl::DIRSHIFT)
- | (($ty as $crate::sys::ioctl::ioctl_num_type
- & $crate::sys::ioctl::TYPEMASK)
- << $crate::sys::ioctl::TYPESHIFT)
- | (($nr as $crate::sys::ioctl::ioctl_num_type
- & $crate::sys::ioctl::NRMASK)
- << $crate::sys::ioctl::NRSHIFT)
- | (($sz as $crate::sys::ioctl::ioctl_num_type
- & $crate::sys::ioctl::SIZEMASK)
- << $crate::sys::ioctl::SIZESHIFT)
- };
-}
-
-/// Generate an ioctl request code for a command that passes no data.
-///
-/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_none!()` directly.
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// const KVMIO: u8 = 0xAE;
-/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_none {
- ($ty:expr, $nr:expr) => {
- ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0)
- };
-}
-
-/// Generate an ioctl request code for a command that reads.
-///
-/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_read!()` directly.
-///
-/// The read/write direction is relative to userland, so this
-/// command would be userland is reading and the kernel is
-/// writing.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_read {
- ($ty:expr, $nr:expr, $sz:expr) => {
- ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz)
- };
-}
-
-/// Generate an ioctl request code for a command that writes.
-///
-/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_write!()` directly.
-///
-/// The read/write direction is relative to userland, so this
-/// command would be userland is writing and the kernel is
-/// reading.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_write {
- ($ty:expr, $nr:expr, $sz:expr) => {
- ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz)
- };
-}
-
-/// Generate an ioctl request code for a command that reads and writes.
-///
-/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
-///
-/// You should only use this macro directly if the `ioctl` you're working
-/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
-#[macro_export(local_inner_macros)]
-macro_rules! request_code_readwrite {
- ($ty:expr, $nr:expr, $sz:expr) => {
- ioc!(
- $crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE,
- $ty,
- $nr,
- $sz
- )
- };
-}
diff --git a/vendor/nix/src/sys/ioctl/mod.rs b/vendor/nix/src/sys/ioctl/mod.rs
deleted file mode 100644
index 98d6b5c99..000000000
--- a/vendor/nix/src/sys/ioctl/mod.rs
+++ /dev/null
@@ -1,786 +0,0 @@
-//! Provide helpers for making ioctl system calls.
-//!
-//! This library is pretty low-level and messy. `ioctl` is not fun.
-//!
-//! What is an `ioctl`?
-//! ===================
-//!
-//! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new
-//! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be
-//! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file
-//! descriptor.
-//!
-//! It is common to see `ioctl`s used for the following purposes:
-//!
-//! * Provide read/write access to out-of-band data related to a device such as configuration
-//! (for instance, setting serial port options)
-//! * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI
-//! devices).
-//! * Provide access to control functions on a device (for example, on Linux you can send
-//! commands like pause, resume, and eject to the CDROM device.
-//! * Do whatever else the device driver creator thought made most sense.
-//!
-//! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard.
-//! They operate on file descriptors and have an identifier that specifies what the ioctl is.
-//! Additionally they may read or write data and therefore need to pass along a data pointer.
-//! Besides the semantics of the ioctls being confusing, the generation of this identifer can also
-//! be difficult.
-//!
-//! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
-//! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
-//! subcomponents (For linux this is documented in
-//! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)):
-//!
-//! * Number: The actual ioctl ID
-//! * Type: A grouping of ioctls for a common purpose or driver
-//! * Size: The size in bytes of the data that will be transferred
-//! * Direction: Whether there is any data and if it's read, write, or both
-//!
-//! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead
-//! preferring to use the 4 components above to generate the final ioctl identifier. Because of
-//! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are
-//! commonly referred to as "bad" in `ioctl` documentation.
-//!
-//! Defining `ioctl`s
-//! =================
-//!
-//! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public
-//! unsafe functions that can then be used for calling the ioctl. This macro has a few different
-//! ways it can be used depending on the specific ioctl you're working with.
-//!
-//! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This
-//! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in
-//! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR`
-//! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows:
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
-//! const SPI_IOC_TYPE_MODE: u8 = 1;
-//! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
-//! # fn main() {}
-//! ```
-//!
-//! This generates the function:
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! # use std::mem;
-//! # use nix::{libc, Result};
-//! # use nix::errno::Errno;
-//! # use nix::libc::c_int as c_int;
-//! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
-//! # const SPI_IOC_TYPE_MODE: u8 = 1;
-//! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> {
-//! let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data);
-//! Errno::result(res)
-//! }
-//! # fn main() {}
-//! ```
-//!
-//! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s.
-//! These are generated by assuming the return value of the ioctl is `-1` on error and everything
-//! else is a valid return value. If this is not the case, `Result::map` can be used to map some
-//! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function.
-//!
-//! Writing `ioctl`s generally use pointers as their data source and these should use the
-//! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the
-//! `ioctl_write_int!` macro. This variant does not take a type as the last argument:
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! const HCI_IOC_MAGIC: u8 = b'k';
-//! const HCI_IOC_HCIDEVUP: u8 = 1;
-//! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
-//! # fn main() {}
-//! ```
-//!
-//! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro
-//! doesn't take a type and so it is declared similar to the `write_int` variant shown above.
-//!
-//! The mode for a given `ioctl` should be clear from the documentation if it has good
-//! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl`
-//! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite"
-//! respectively. To determine the specific `write_` variant to use you'll need to find
-//! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used,
-//! otherwise it should be a pointer and `write_ptr` should be used. On Linux the
-//! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a
-//! large number of `ioctl`s and describes their argument data type.
-//!
-//! Using "bad" `ioctl`s
-//! --------------------
-//!
-//! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
-//! generating `ioctl` numbers and instead use hardcoded values. These can be used with the
-//! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these
-//! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates
-//! the ioctl number and instead use the defined value directly.
-//!
-//! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
-//! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as:
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! # #[cfg(any(target_os = "android", target_os = "linux"))]
-//! # use nix::libc::TCGETS as TCGETS;
-//! # #[cfg(any(target_os = "android", target_os = "linux"))]
-//! # use nix::libc::termios as termios;
-//! # #[cfg(any(target_os = "android", target_os = "linux"))]
-//! ioctl_read_bad!(tcgets, TCGETS, termios);
-//! # fn main() {}
-//! ```
-//!
-//! The generated function has the same form as that generated by `ioctl_read!`:
-//!
-//! ```text
-//! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>;
-//! ```
-//!
-//! Working with Arrays
-//! -------------------
-//!
-//! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf`
-//! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that
-//! there are no "bad" versions for working with buffers. The generated functions include a `len`
-//! argument to specify the number of elements (where the type of each element is specified in the
-//! macro).
-//!
-//! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl`
-//! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs.
-//! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like:
-//!
-//! ```C
-//! #define SPI_IOC_MAGIC 'k'
-//! #define SPI_MSGSIZE(N) ...
-//! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
-//! ```
-//!
-//! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's
-//! needed to define this `ioctl` is:
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
-//! const SPI_IOC_TYPE_MESSAGE: u8 = 0;
-//! # pub struct spi_ioc_transfer(u64);
-//! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
-//! # fn main() {}
-//! ```
-//!
-//! This generates a function like:
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! # use std::mem;
-//! # use nix::{libc, Result};
-//! # use nix::errno::Errno;
-//! # use nix::libc::c_int as c_int;
-//! # const SPI_IOC_MAGIC: u8 = b'k';
-//! # const SPI_IOC_TYPE_MESSAGE: u8 = 0;
-//! # pub struct spi_ioc_transfer(u64);
-//! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> {
-//! let res = libc::ioctl(fd,
-//! request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
-//! data);
-//! Errno::result(res)
-//! }
-//! # fn main() {}
-//! ```
-//!
-//! Finding `ioctl` Documentation
-//! -----------------------------
-//!
-//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
-//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
-//! documented directly in the headers defining their constants, but others have more extensive
-//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
-//!
-//! Documenting the Generated Functions
-//! ===================================
-//!
-//! In many cases, users will wish for the functions generated by the `ioctl`
-//! macro to be public and documented. For this reason, the generated functions
-//! are public by default. If you wish to hide the ioctl, you will need to put
-//! them in a private module.
-//!
-//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
-//! example :
-//!
-//! ```
-//! # #[macro_use] extern crate nix;
-//! # use nix::libc::c_int;
-//! ioctl_read! {
-//! /// Make the given terminal the controlling terminal of the calling process. The calling
-//! /// process must be a session leader and not have a controlling terminal already. If the
-//! /// terminal is already the controlling terminal of a different session group then the
-//! /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
-//! /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
-//! /// and all processes that had it as controlling terminal lose it.
-//! tiocsctty, b't', 19, c_int
-//! }
-//!
-//! # fn main() {}
-//! ```
-use cfg_if::cfg_if;
-
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
-#[macro_use]
-mod linux;
-
-#[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "redox"
-))]
-pub use self::linux::*;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
-))]
-#[macro_use]
-mod bsd;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
-))]
-pub use self::bsd::*;
-
-/// Convert raw ioctl return value to a Nix result
-#[macro_export]
-#[doc(hidden)]
-macro_rules! convert_ioctl_res {
- ($w:expr) => {{
- $crate::errno::Errno::result($w)
- }};
-}
-
-/// Generates a wrapper function for an ioctl that passes no data to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// The `videodev2` driver on Linux defines the `log_status` `ioctl` as:
-///
-/// ```C
-/// #define VIDIOC_LOG_STATUS _IO('V', 70)
-/// ```
-///
-/// This can be implemented in Rust like:
-///
-/// ```no_run
-/// # #[macro_use] extern crate nix;
-/// ioctl_none!(log_status, b'V', 70);
-/// fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_none {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
- }
- )
-}
-
-/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl request code
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// ```no_run
-/// # #[macro_use] extern crate nix;
-/// # use libc::TIOCNXCL;
-/// # use std::fs::File;
-/// # use std::os::unix::io::AsRawFd;
-/// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
-/// fn main() {
-/// let file = File::open("/dev/ttyUSB0").unwrap();
-/// unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
-/// }
-/// ```
-// TODO: add an example using request_code_*!()
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_none_bad {
- ($(#[$attr:meta])* $name:ident, $nr:expr) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
- }
- )
-}
-
-/// Generates a wrapper function for an ioctl that reads data from the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
-/// const SPI_IOC_TYPE_MODE: u8 = 1;
-/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_read {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *mut $ty)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl request code
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// # #[cfg(any(target_os = "android", target_os = "linux"))]
-/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_read_bad {
- ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *mut $ty)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// # pub struct v4l2_audio {}
-/// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_write_ptr {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *const $ty)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl request code
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// # #[cfg(any(target_os = "android", target_os = "linux"))]
-/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_write_ptr_bad {
- ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *const $ty)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
- /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
- ///
- /// The arguments to this macro are:
- ///
- /// * The function name
- /// * The ioctl identifier
- /// * The ioctl sequence number
- ///
- /// The generated function has the following signature:
- ///
- /// ```rust,ignore
- /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
- /// ```
- ///
- /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
- /// * BSD - `libc::c_int`
- /// * Linux - `libc::c_ulong`
- ///
- /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
- ///
- /// # Example
- ///
- /// ```
- /// # #[macro_use] extern crate nix;
- /// ioctl_write_int!(vt_activate, b'v', 4);
- /// # fn main() {}
- /// ```
- #[macro_export(local_inner_macros)]
- macro_rules! ioctl_write_int {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: $crate::sys::ioctl::ioctl_param_type)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
- }
- } else {
- /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
- ///
- /// The arguments to this macro are:
- ///
- /// * The function name
- /// * The ioctl identifier
- /// * The ioctl sequence number
- ///
- /// The generated function has the following signature:
- ///
- /// ```rust,ignore
- /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
- /// ```
- ///
- /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
- /// * BSD - `libc::c_int`
- /// * Linux - `libc::c_ulong`
- ///
- /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
- ///
- /// # Example
- ///
- /// ```
- /// # #[macro_use] extern crate nix;
- /// const HCI_IOC_MAGIC: u8 = b'k';
- /// const HCI_IOC_HCIDEVUP: u8 = 1;
- /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
- /// # fn main() {}
- /// ```
- #[macro_export(local_inner_macros)]
- macro_rules! ioctl_write_int {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: $crate::sys::ioctl::ioctl_param_type)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
- }
- }
-}
-
-/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl request code
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Examples
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// # #[cfg(any(target_os = "android", target_os = "linux"))]
-/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
-/// # fn main() {}
-/// ```
-///
-/// ```rust
-/// # #[macro_use] extern crate nix;
-/// const KVMIO: u8 = 0xAE;
-/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_write_int_bad {
- ($(#[$attr:meta])* $name:ident, $nr:expr) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: $crate::libc::c_int)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Example
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// # pub struct v4l2_audio {}
-/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_readwrite {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *mut $ty)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl request code
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-// TODO: Find an example for ioctl_readwrite_bad
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_readwrite_bad {
- ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: *mut $ty)
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-// TODO: Find an example for ioctl_read_buf
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_read_buf {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: &mut [$ty])
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-///
-/// # Examples
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
-/// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
-/// # pub struct spi_ioc_transfer(u64);
-/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
-/// # fn main() {}
-/// ```
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_write_buf {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: &[$ty])
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
-
-/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
-///
-/// The arguments to this macro are:
-///
-/// * The function name
-/// * The ioctl identifier
-/// * The ioctl sequence number
-/// * The data type passed by this ioctl
-///
-/// The generated function has the following signature:
-///
-/// ```rust,ignore
-/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
-/// ```
-///
-/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
-// TODO: Find an example for readwrite_buf
-#[macro_export(local_inner_macros)]
-macro_rules! ioctl_readwrite_buf {
- ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
- $(#[$attr])*
- pub unsafe fn $name(fd: $crate::libc::c_int,
- data: &mut [$ty])
- -> $crate::Result<$crate::libc::c_int> {
- convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
- }
- )
-}
diff --git a/vendor/nix/src/sys/memfd.rs b/vendor/nix/src/sys/memfd.rs
deleted file mode 100644
index ad9345e89..000000000
--- a/vendor/nix/src/sys/memfd.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-//! Interfaces for managing memory-backed files.
-
-use cfg_if::cfg_if;
-use std::os::unix::io::RawFd;
-
-use crate::errno::Errno;
-use crate::Result;
-use std::ffi::CStr;
-
-libc_bitflags!(
- /// Options that change the behavior of [`memfd_create`].
- pub struct MemFdCreateFlag: libc::c_uint {
- /// Set the close-on-exec ([`FD_CLOEXEC`]) flag on the new file descriptor.
- ///
- /// By default, the new file descriptor is set to remain open across an [`execve`]
- /// (the `FD_CLOEXEC` flag is initially disabled). This flag can be used to change
- /// this default. The file offset is set to the beginning of the file (see [`lseek`]).
- ///
- /// See also the description of the `O_CLOEXEC` flag in [`open(2)`].
- ///
- /// [`execve`]: crate::unistd::execve
- /// [`lseek`]: crate::unistd::lseek
- /// [`FD_CLOEXEC`]: crate::fcntl::FdFlag::FD_CLOEXEC
- /// [`open(2)`]: https://man7.org/linux/man-pages/man2/open.2.html
- MFD_CLOEXEC;
- /// Allow sealing operations on this file.
- ///
- /// See also the file sealing notes given in [`memfd_create(2)`].
- ///
- /// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
- MFD_ALLOW_SEALING;
- }
-);
-
-/// Creates an anonymous file that lives in memory, and return a file-descriptor to it.
-///
-/// The file behaves like a regular file, and so can be modified, truncated, memory-mapped, and so on.
-/// However, unlike a regular file, it lives in RAM and has a volatile backing storage.
-///
-/// For more information, see [`memfd_create(2)`].
-///
-/// [`memfd_create(2)`]: https://man7.org/linux/man-pages/man2/memfd_create.2.html
-pub fn memfd_create(name: &CStr, flags: MemFdCreateFlag) -> Result<RawFd> {
- let res = unsafe {
- cfg_if! {
- if #[cfg(all(
- // Android does not have a memfd_create symbol
- not(target_os = "android"),
- any(
- target_os = "freebsd",
- // If the OS is Linux, gnu and musl expose a memfd_create symbol but not uclibc
- target_env = "gnu",
- target_env = "musl",
- )))]
- {
- libc::memfd_create(name.as_ptr(), flags.bits())
- } else {
- libc::syscall(libc::SYS_memfd_create, name.as_ptr(), flags.bits())
- }
- }
- };
-
- Errno::result(res).map(|r| r as RawFd)
-}
diff --git a/vendor/nix/src/sys/mman.rs b/vendor/nix/src/sys/mman.rs
deleted file mode 100644
index 2bee09161..000000000
--- a/vendor/nix/src/sys/mman.rs
+++ /dev/null
@@ -1,599 +0,0 @@
-//! Memory management declarations.
-
-use crate::errno::Errno;
-#[cfg(not(target_os = "android"))]
-use crate::NixPath;
-use crate::Result;
-#[cfg(not(target_os = "android"))]
-#[cfg(feature = "fs")]
-use crate::{fcntl::OFlag, sys::stat::Mode};
-use libc::{self, c_int, c_void, off_t, size_t};
-use std::{os::unix::io::RawFd, num::NonZeroUsize};
-
-libc_bitflags! {
- /// Desired memory protection of a memory mapping.
- pub struct ProtFlags: c_int {
- /// Pages cannot be accessed.
- PROT_NONE;
- /// Pages can be read.
- PROT_READ;
- /// Pages can be written.
- PROT_WRITE;
- /// Pages can be executed
- PROT_EXEC;
- /// Apply protection up to the end of a mapping that grows upwards.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PROT_GROWSDOWN;
- /// Apply protection down to the beginning of a mapping that grows downwards.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PROT_GROWSUP;
- }
-}
-
-libc_bitflags! {
- /// Additional parameters for [`mmap`].
- pub struct MapFlags: c_int {
- /// Compatibility flag. Ignored.
- MAP_FILE;
- /// Share this mapping. Mutually exclusive with `MAP_PRIVATE`.
- MAP_SHARED;
- /// Create a private copy-on-write mapping. Mutually exclusive with `MAP_SHARED`.
- MAP_PRIVATE;
- /// Place the mapping at exactly the address specified in `addr`.
- MAP_FIXED;
- /// Place the mapping at exactly the address specified in `addr`, but never clobber an existing range.
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_FIXED_NOREPLACE;
- /// To be used with `MAP_FIXED`, to forbid the system
- /// to select a different address than the one specified.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_EXCL;
- /// Synonym for `MAP_ANONYMOUS`.
- MAP_ANON;
- /// The mapping is not backed by any file.
- MAP_ANONYMOUS;
- /// Put the mapping into the first 2GB of the process address space.
- #[cfg(any(all(any(target_os = "android", target_os = "linux"),
- any(target_arch = "x86", target_arch = "x86_64")),
- all(target_os = "linux", target_env = "musl", any(target_arch = "x86", target_arch = "x86_64")),
- all(target_os = "freebsd", target_pointer_width = "64")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_32BIT;
- /// Used for stacks; indicates to the kernel that the mapping should extend downward in memory.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_GROWSDOWN;
- /// Compatibility flag. Ignored.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_DENYWRITE;
- /// Compatibility flag. Ignored.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_EXECUTABLE;
- /// Mark the mmaped region to be locked in the same way as `mlock(2)`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_LOCKED;
- /// Do not reserve swap space for this mapping.
- ///
- /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_NORESERVE;
- /// Populate page tables for a mapping.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_POPULATE;
- /// Only meaningful when used with `MAP_POPULATE`. Don't perform read-ahead.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_NONBLOCK;
- /// Allocate the mapping using "huge pages."
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGETLB;
- /// Make use of 64KB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_64KB;
- /// Make use of 512KB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_512KB;
- /// Make use of 1MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_1MB;
- /// Make use of 2MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_2MB;
- /// Make use of 8MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_8MB;
- /// Make use of 16MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_16MB;
- /// Make use of 32MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_32MB;
- /// Make use of 256MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_256MB;
- /// Make use of 512MB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_512MB;
- /// Make use of 1GB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_1GB;
- /// Make use of 2GB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_2GB;
- /// Make use of 16GB huge page (must be supported by the system)
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HUGE_16GB;
-
- /// Lock the mapped region into memory as with `mlock(2)`.
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_WIRED;
- /// Causes dirtied data in the specified range to be flushed to disk only when necessary.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_NOSYNC;
- /// Rename private pages to a file.
- ///
- /// This was removed in FreeBSD 11 and is unused in DragonFlyBSD.
- #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_RENAME;
- /// Region may contain semaphores.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_HASSEMAPHORE;
- /// Region grows down, like a stack.
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd", target_os = "linux", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_STACK;
- /// Pages in this mapping are not retained in the kernel's memory cache.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_NOCACHE;
- /// Allows the W/X bit on the page, it's necessary on aarch64 architecture.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_JIT;
- /// Allows to use large pages, underlying alignment based on size.
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_ALIGNED_SUPER;
- /// Pages will be discarded in the core dumps.
- #[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_CONCEAL;
- }
-}
-
-#[cfg(any(target_os = "linux", target_os = "netbsd"))]
-libc_bitflags! {
- /// Options for [`mremap`].
- pub struct MRemapFlags: c_int {
- /// Permit the kernel to relocate the mapping to a new virtual address, if necessary.
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MREMAP_MAYMOVE;
- /// Place the mapping at exactly the address specified in `new_address`.
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MREMAP_FIXED;
- /// Place the mapping at exactly the address specified in `new_address`.
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_FIXED;
- /// Allows to duplicate the mapping to be able to apply different flags on the copy.
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MAP_REMAPDUP;
- }
-}
-
-libc_enum! {
- /// Usage information for a range of memory to allow for performance optimizations by the kernel.
- ///
- /// Used by [`madvise`].
- #[repr(i32)]
- #[non_exhaustive]
- pub enum MmapAdvise {
- /// No further special treatment. This is the default.
- MADV_NORMAL,
- /// Expect random page references.
- MADV_RANDOM,
- /// Expect sequential page references.
- MADV_SEQUENTIAL,
- /// Expect access in the near future.
- MADV_WILLNEED,
- /// Do not expect access in the near future.
- MADV_DONTNEED,
- /// Free up a given range of pages and its associated backing store.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_REMOVE,
- /// Do not make pages in this range available to the child after a `fork(2)`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_DONTFORK,
- /// Undo the effect of `MADV_DONTFORK`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_DOFORK,
- /// Poison the given pages.
- ///
- /// Subsequent references to those pages are treated like hardware memory corruption.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_HWPOISON,
- /// Enable Kernel Samepage Merging (KSM) for the given pages.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_MERGEABLE,
- /// Undo the effect of `MADV_MERGEABLE`
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_UNMERGEABLE,
- /// Preserve the memory of each page but offline the original page.
- #[cfg(any(target_os = "android",
- all(target_os = "linux", any(
- target_arch = "aarch64",
- target_arch = "arm",
- target_arch = "powerpc",
- target_arch = "powerpc64",
- target_arch = "s390x",
- target_arch = "x86",
- target_arch = "x86_64",
- target_arch = "sparc64"))))]
- MADV_SOFT_OFFLINE,
- /// Enable Transparent Huge Pages (THP) for pages in the given range.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_HUGEPAGE,
- /// Undo the effect of `MADV_HUGEPAGE`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_NOHUGEPAGE,
- /// Exclude the given range from a core dump.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_DONTDUMP,
- /// Undo the effect of an earlier `MADV_DONTDUMP`.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_DODUMP,
- /// Specify that the application no longer needs the pages in the given range.
- MADV_FREE,
- /// Request that the system not flush the current range to disk unless it needs to.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_NOSYNC,
- /// Undoes the effects of `MADV_NOSYNC` for any future pages dirtied within the given range.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_AUTOSYNC,
- /// Region is not included in a core file.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_NOCORE,
- /// Include region in a core file
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_CORE,
- /// This process should not be killed when swap space is exhausted.
- #[cfg(any(target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_PROTECT,
- /// Invalidate the hardware page table for the given region.
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_INVAL,
- /// Set the offset of the page directory page to `value` for the virtual page table.
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_SETMAP,
- /// Indicates that the application will not need the data in the given range.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_ZERO_WIRED_PAGES,
- /// Pages can be reused (by anyone).
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_FREE_REUSABLE,
- /// Caller wants to reuse those pages.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MADV_FREE_REUSE,
- // Darwin doesn't document this flag's behavior.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(missing_docs)]
- MADV_CAN_REUSE,
- }
-}
-
-libc_bitflags! {
- /// Configuration flags for [`msync`].
- pub struct MsFlags: c_int {
- /// Schedule an update but return immediately.
- MS_ASYNC;
- /// Invalidate all cached data.
- MS_INVALIDATE;
- /// Invalidate pages, but leave them mapped.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MS_KILLPAGES;
- /// Deactivate pages, but leave them mapped.
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MS_DEACTIVATE;
- /// Perform an update and wait for it to complete.
- MS_SYNC;
- }
-}
-
-#[cfg(not(target_os = "haiku"))]
-libc_bitflags! {
- /// Flags for [`mlockall`].
- pub struct MlockAllFlags: c_int {
- /// Lock pages that are currently mapped into the address space of the process.
- MCL_CURRENT;
- /// Lock pages which will become mapped into the address space of the process in the future.
- MCL_FUTURE;
- }
-}
-
-/// Locks all memory pages that contain part of the address range with `length`
-/// bytes starting at `addr`.
-///
-/// Locked pages never move to the swap area.
-///
-/// # Safety
-///
-/// `addr` must meet all the requirements described in the [`mlock(2)`] man page.
-///
-/// [`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html
-pub unsafe fn mlock(addr: *const c_void, length: size_t) -> Result<()> {
- Errno::result(libc::mlock(addr, length)).map(drop)
-}
-
-/// Unlocks all memory pages that contain part of the address range with
-/// `length` bytes starting at `addr`.
-///
-/// # Safety
-///
-/// `addr` must meet all the requirements described in the [`munlock(2)`] man
-/// page.
-///
-/// [`munlock(2)`]: https://man7.org/linux/man-pages/man2/munlock.2.html
-pub unsafe fn munlock(addr: *const c_void, length: size_t) -> Result<()> {
- Errno::result(libc::munlock(addr, length)).map(drop)
-}
-
-/// Locks all memory pages mapped into this process' address space.
-///
-/// Locked pages never move to the swap area. For more information, see [`mlockall(2)`].
-///
-/// [`mlockall(2)`]: https://man7.org/linux/man-pages/man2/mlockall.2.html
-#[cfg(not(target_os = "haiku"))]
-pub fn mlockall(flags: MlockAllFlags) -> Result<()> {
- unsafe { Errno::result(libc::mlockall(flags.bits())) }.map(drop)
-}
-
-/// Unlocks all memory pages mapped into this process' address space.
-///
-/// For more information, see [`munlockall(2)`].
-///
-/// [`munlockall(2)`]: https://man7.org/linux/man-pages/man2/munlockall.2.html
-#[cfg(not(target_os = "haiku"))]
-pub fn munlockall() -> Result<()> {
- unsafe { Errno::result(libc::munlockall()) }.map(drop)
-}
-
-/// allocate memory, or map files or devices into memory
-///
-/// # Safety
-///
-/// See the [`mmap(2)`] man page for detailed requirements.
-///
-/// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
-pub unsafe fn mmap(
- addr: Option<NonZeroUsize>,
- length: NonZeroUsize,
- prot: ProtFlags,
- flags: MapFlags,
- fd: RawFd,
- offset: off_t,
-) -> Result<*mut c_void> {
- let ptr = addr.map_or(
- std::ptr::null_mut(),
- |a| usize::from(a) as *mut c_void
- );
-
- let ret = libc::mmap(ptr, length.into(), prot.bits(), flags.bits(), fd, offset);
-
- if ret == libc::MAP_FAILED {
- Err(Errno::last())
- } else {
- Ok(ret)
- }
-}
-
-/// Expands (or shrinks) an existing memory mapping, potentially moving it at
-/// the same time.
-///
-/// # Safety
-///
-/// See the `mremap(2)` [man page](https://man7.org/linux/man-pages/man2/mremap.2.html) for
-/// detailed requirements.
-#[cfg(any(target_os = "linux", target_os = "netbsd"))]
-pub unsafe fn mremap(
- addr: *mut c_void,
- old_size: size_t,
- new_size: size_t,
- flags: MRemapFlags,
- new_address: Option<*mut c_void>,
-) -> Result<*mut c_void> {
- #[cfg(target_os = "linux")]
- let ret = libc::mremap(
- addr,
- old_size,
- new_size,
- flags.bits(),
- new_address.unwrap_or(std::ptr::null_mut()),
- );
- #[cfg(target_os = "netbsd")]
- let ret = libc::mremap(
- addr,
- old_size,
- new_address.unwrap_or(std::ptr::null_mut()),
- new_size,
- flags.bits(),
- );
-
- if ret == libc::MAP_FAILED {
- Err(Errno::last())
- } else {
- Ok(ret)
- }
-}
-
-/// remove a mapping
-///
-/// # Safety
-///
-/// `addr` must meet all the requirements described in the [`munmap(2)`] man
-/// page.
-///
-/// [`munmap(2)`]: https://man7.org/linux/man-pages/man2/munmap.2.html
-pub unsafe fn munmap(addr: *mut c_void, len: size_t) -> Result<()> {
- Errno::result(libc::munmap(addr, len)).map(drop)
-}
-
-/// give advice about use of memory
-///
-/// # Safety
-///
-/// See the [`madvise(2)`] man page. Take special care when using
-/// [`MmapAdvise::MADV_FREE`].
-///
-/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html
-pub unsafe fn madvise(
- addr: *mut c_void,
- length: size_t,
- advise: MmapAdvise,
-) -> Result<()> {
- Errno::result(libc::madvise(addr, length, advise as i32)).map(drop)
-}
-
-/// Set protection of memory mapping.
-///
-/// See [`mprotect(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mprotect.html) for
-/// details.
-///
-/// # Safety
-///
-/// Calls to `mprotect` are inherently unsafe, as changes to memory protections can lead to
-/// SIGSEGVs.
-///
-/// ```
-/// # use nix::libc::size_t;
-/// # use nix::sys::mman::{mmap, mprotect, MapFlags, ProtFlags};
-/// # use std::ptr;
-/// const ONE_K: size_t = 1024;
-/// let one_k_non_zero = std::num::NonZeroUsize::new(ONE_K).unwrap();
-/// let mut slice: &mut [u8] = unsafe {
-/// let mem = mmap(None, one_k_non_zero, ProtFlags::PROT_NONE,
-/// MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE, -1, 0).unwrap();
-/// mprotect(mem, ONE_K, ProtFlags::PROT_READ | ProtFlags::PROT_WRITE).unwrap();
-/// std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
-/// };
-/// assert_eq!(slice[0], 0x00);
-/// slice[0] = 0xFF;
-/// assert_eq!(slice[0], 0xFF);
-/// ```
-pub unsafe fn mprotect(
- addr: *mut c_void,
- length: size_t,
- prot: ProtFlags,
-) -> Result<()> {
- Errno::result(libc::mprotect(addr, length, prot.bits())).map(drop)
-}
-
-/// synchronize a mapped region
-///
-/// # Safety
-///
-/// `addr` must meet all the requirements described in the [`msync(2)`] man
-/// page.
-///
-/// [`msync(2)`]: https://man7.org/linux/man-pages/man2/msync.2.html
-pub unsafe fn msync(
- addr: *mut c_void,
- length: size_t,
- flags: MsFlags,
-) -> Result<()> {
- Errno::result(libc::msync(addr, length, flags.bits())).map(drop)
-}
-
-#[cfg(not(target_os = "android"))]
-feature! {
-#![feature = "fs"]
-/// Creates and opens a new, or opens an existing, POSIX shared memory object.
-///
-/// For more information, see [`shm_open(3)`].
-///
-/// [`shm_open(3)`]: https://man7.org/linux/man-pages/man3/shm_open.3.html
-pub fn shm_open<P>(
- name: &P,
- flag: OFlag,
- mode: Mode
- ) -> Result<RawFd>
- where P: ?Sized + NixPath
-{
- let ret = name.with_nix_path(|cstr| {
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- unsafe {
- libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::c_uint)
- }
- #[cfg(not(any(target_os = "macos", target_os = "ios")))]
- unsafe {
- libc::shm_open(cstr.as_ptr(), flag.bits(), mode.bits() as libc::mode_t)
- }
- })?;
-
- Errno::result(ret)
-}
-}
-
-/// Performs the converse of [`shm_open`], removing an object previously created.
-///
-/// For more information, see [`shm_unlink(3)`].
-///
-/// [`shm_unlink(3)`]: https://man7.org/linux/man-pages/man3/shm_unlink.3.html
-#[cfg(not(target_os = "android"))]
-pub fn shm_unlink<P: ?Sized + NixPath>(name: &P) -> Result<()> {
- let ret =
- name.with_nix_path(|cstr| unsafe { libc::shm_unlink(cstr.as_ptr()) })?;
-
- Errno::result(ret).map(drop)
-}
diff --git a/vendor/nix/src/sys/mod.rs b/vendor/nix/src/sys/mod.rs
deleted file mode 100644
index 2065059de..000000000
--- a/vendor/nix/src/sys/mod.rs
+++ /dev/null
@@ -1,228 +0,0 @@
-//! Mostly platform-specific functionality
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "macos",
- target_os = "netbsd"
-))]
-feature! {
- #![feature = "aio"]
- pub mod aio;
-}
-
-feature! {
- #![feature = "event"]
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[allow(missing_docs)]
- pub mod epoll;
-
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[allow(missing_docs)]
- pub mod event;
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[allow(missing_docs)]
- pub mod eventfd;
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "redox",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
-))]
-#[cfg(feature = "ioctl")]
-#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
-#[macro_use]
-pub mod ioctl;
-
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-feature! {
- #![feature = "fs"]
- pub mod memfd;
-}
-
-#[cfg(not(target_os = "redox"))]
-feature! {
- #![feature = "mman"]
- pub mod mman;
-}
-
-#[cfg(target_os = "linux")]
-feature! {
- #![feature = "personality"]
- pub mod personality;
-}
-
-feature! {
- #![feature = "pthread"]
- pub mod pthread;
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-feature! {
- #![feature = "ptrace"]
- #[allow(missing_docs)]
- pub mod ptrace;
-}
-
-#[cfg(target_os = "linux")]
-feature! {
- #![feature = "quota"]
- pub mod quota;
-}
-
-#[cfg(target_os = "linux")]
-feature! {
- #![feature = "reboot"]
- pub mod reboot;
-}
-
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "haiku"
-)))]
-feature! {
- #![feature = "resource"]
- pub mod resource;
-}
-
-#[cfg(not(target_os = "redox"))]
-feature! {
- #![feature = "poll"]
- pub mod select;
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"
-))]
-feature! {
- #![feature = "zerocopy"]
- pub mod sendfile;
-}
-
-pub mod signal;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-feature! {
- #![feature = "signal"]
- #[allow(missing_docs)]
- pub mod signalfd;
-}
-
-#[cfg(not(target_os = "redox"))]
-feature! {
- #![feature = "socket"]
- #[allow(missing_docs)]
- pub mod socket;
-}
-
-feature! {
- #![feature = "fs"]
- #[allow(missing_docs)]
- pub mod stat;
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "openbsd"
-))]
-feature! {
- #![feature = "fs"]
- pub mod statfs;
-}
-
-feature! {
- #![feature = "fs"]
- pub mod statvfs;
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-#[allow(missing_docs)]
-pub mod sysinfo;
-
-feature! {
- #![feature = "term"]
- #[allow(missing_docs)]
- pub mod termios;
-}
-
-#[allow(missing_docs)]
-pub mod time;
-
-feature! {
- #![feature = "uio"]
- pub mod uio;
-}
-
-feature! {
- #![feature = "feature"]
- pub mod utsname;
-}
-
-feature! {
- #![feature = "process"]
- pub mod wait;
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-feature! {
- #![feature = "inotify"]
- pub mod inotify;
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-feature! {
- #![feature = "time"]
- pub mod timerfd;
-}
-
-#[cfg(all(
- any(
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd"
- ),
- feature = "time",
- feature = "signal"
-))]
-feature! {
- #![feature = "time"]
- pub mod timer;
-}
diff --git a/vendor/nix/src/sys/personality.rs b/vendor/nix/src/sys/personality.rs
deleted file mode 100644
index f295a05fa..000000000
--- a/vendor/nix/src/sys/personality.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//! Process execution domains
-use crate::errno::Errno;
-use crate::Result;
-
-use libc::{self, c_int, c_ulong};
-
-libc_bitflags! {
- /// Flags used and returned by [`get()`](fn.get.html) and
- /// [`set()`](fn.set.html).
- pub struct Persona: c_int {
- /// Provide the legacy virtual address space layout.
- ADDR_COMPAT_LAYOUT;
- /// Disable address-space-layout randomization.
- ADDR_NO_RANDOMIZE;
- /// Limit the address space to 32 bits.
- ADDR_LIMIT_32BIT;
- /// Use `0xc0000000` as the offset at which to search a virtual memory
- /// chunk on [`mmap(2)`], otherwise use `0xffffe000`.
- ///
- /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
- ADDR_LIMIT_3GB;
- /// User-space function pointers to signal handlers point to descriptors.
- #[cfg(not(any(target_env = "musl", target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- FDPIC_FUNCPTRS;
- /// Map page 0 as read-only.
- MMAP_PAGE_ZERO;
- /// `PROT_READ` implies `PROT_EXEC` for [`mmap(2)`].
- ///
- /// [`mmap(2)`]: https://man7.org/linux/man-pages/man2/mmap.2.html
- READ_IMPLIES_EXEC;
- /// No effects.
- SHORT_INODE;
- /// [`select(2)`], [`pselect(2)`], and [`ppoll(2)`] do not modify the
- /// returned timeout argument when interrupted by a signal handler.
- ///
- /// [`select(2)`]: https://man7.org/linux/man-pages/man2/select.2.html
- /// [`pselect(2)`]: https://man7.org/linux/man-pages/man2/pselect.2.html
- /// [`ppoll(2)`]: https://man7.org/linux/man-pages/man2/ppoll.2.html
- STICKY_TIMEOUTS;
- /// Have [`uname(2)`] report a 2.6.40+ version number rather than a 3.x
- /// version number.
- ///
- /// [`uname(2)`]: https://man7.org/linux/man-pages/man2/uname.2.html
- #[cfg(not(any(target_env = "musl", target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- UNAME26;
- /// No effects.
- WHOLE_SECONDS;
- }
-}
-
-/// Retrieve the current process personality.
-///
-/// Returns a Result containing a Persona instance.
-///
-/// Example:
-///
-/// ```
-/// # use nix::sys::personality::{self, Persona};
-/// let pers = personality::get().unwrap();
-/// assert!(!pers.contains(Persona::WHOLE_SECONDS));
-/// ```
-pub fn get() -> Result<Persona> {
- let res = unsafe { libc::personality(0xFFFFFFFF) };
-
- Errno::result(res).map(Persona::from_bits_truncate)
-}
-
-/// Set the current process personality.
-///
-/// Returns a Result containing the *previous* personality for the
-/// process, as a Persona.
-///
-/// For more information, see [personality(2)](https://man7.org/linux/man-pages/man2/personality.2.html)
-///
-/// **NOTE**: This call **replaces** the current personality entirely.
-/// To **update** the personality, first call `get()` and then `set()`
-/// with the modified persona.
-///
-/// Example:
-///
-/// ```
-/// # use nix::sys::personality::{self, Persona};
-/// let mut pers = personality::get().unwrap();
-/// assert!(!pers.contains(Persona::ADDR_NO_RANDOMIZE));
-/// personality::set(pers | Persona::ADDR_NO_RANDOMIZE).unwrap();
-/// ```
-pub fn set(persona: Persona) -> Result<Persona> {
- let res = unsafe { libc::personality(persona.bits() as c_ulong) };
-
- Errno::result(res).map(Persona::from_bits_truncate)
-}
diff --git a/vendor/nix/src/sys/pthread.rs b/vendor/nix/src/sys/pthread.rs
deleted file mode 100644
index 6bad03a4d..000000000
--- a/vendor/nix/src/sys/pthread.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-//! Low level threading primitives
-
-#[cfg(not(target_os = "redox"))]
-use crate::errno::Errno;
-#[cfg(not(target_os = "redox"))]
-use crate::Result;
-use libc::{self, pthread_t};
-
-/// Identifies an individual thread.
-pub type Pthread = pthread_t;
-
-/// Obtain ID of the calling thread (see
-/// [`pthread_self(3)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html)
-///
-/// The thread ID returned by `pthread_self()` is not the same thing as
-/// the kernel thread ID returned by a call to `gettid(2)`.
-#[inline]
-pub fn pthread_self() -> Pthread {
- unsafe { libc::pthread_self() }
-}
-
-feature! {
-#![feature = "signal"]
-
-/// Send a signal to a thread (see [`pthread_kill(3)`]).
-///
-/// If `signal` is `None`, `pthread_kill` will only preform error checking and
-/// won't send any signal.
-///
-/// [`pthread_kill(3)`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html
-#[allow(clippy::not_unsafe_ptr_arg_deref)]
-#[cfg(not(target_os = "redox"))]
-pub fn pthread_kill<T>(thread: Pthread, signal: T) -> Result<()>
- where T: Into<Option<crate::sys::signal::Signal>>
-{
- let sig = match signal.into() {
- Some(s) => s as libc::c_int,
- None => 0,
- };
- let res = unsafe { libc::pthread_kill(thread, sig) };
- Errno::result(res).map(drop)
-}
-}
diff --git a/vendor/nix/src/sys/ptrace/bsd.rs b/vendor/nix/src/sys/ptrace/bsd.rs
deleted file mode 100644
index ba267c657..000000000
--- a/vendor/nix/src/sys/ptrace/bsd.rs
+++ /dev/null
@@ -1,195 +0,0 @@
-use crate::errno::Errno;
-use crate::sys::signal::Signal;
-use crate::unistd::Pid;
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{self, c_int};
-use std::ptr;
-
-pub type RequestType = c_int;
-
-cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "openbsd"))] {
- #[doc(hidden)]
- pub type AddressType = *mut ::libc::c_char;
- } else {
- #[doc(hidden)]
- pub type AddressType = *mut ::libc::c_void;
- }
-}
-
-libc_enum! {
- #[repr(i32)]
- /// Ptrace Request enum defining the action to be taken.
- #[non_exhaustive]
- pub enum Request {
- PT_TRACE_ME,
- PT_READ_I,
- PT_READ_D,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PT_READ_U,
- PT_WRITE_I,
- PT_WRITE_D,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PT_WRITE_U,
- PT_CONTINUE,
- PT_KILL,
- #[cfg(any(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos"),
- all(target_os = "openbsd", target_arch = "x86_64"),
- all(target_os = "netbsd", any(target_arch = "x86_64",
- target_arch = "powerpc"))))]
- PT_STEP,
- PT_ATTACH,
- PT_DETACH,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PT_SIGEXC,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PT_THUPDATE,
- #[cfg(target_os = "macos")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PT_ATTACHEXC
- }
-}
-
-unsafe fn ptrace_other(
- request: Request,
- pid: Pid,
- addr: AddressType,
- data: c_int,
-) -> Result<c_int> {
- Errno::result(libc::ptrace(
- request as RequestType,
- libc::pid_t::from(pid),
- addr,
- data,
- ))
- .map(|_| 0)
-}
-
-/// Sets the process as traceable, as with `ptrace(PT_TRACEME, ...)`
-///
-/// Indicates that this process is to be traced by its parent.
-/// This is the only ptrace request to be issued by the tracee.
-pub fn traceme() -> Result<()> {
- unsafe {
- ptrace_other(Request::PT_TRACE_ME, Pid::from_raw(0), ptr::null_mut(), 0)
- .map(drop)
- }
-}
-
-/// Attach to a running process, as with `ptrace(PT_ATTACH, ...)`
-///
-/// Attaches to the process specified by `pid`, making it a tracee of the calling process.
-pub fn attach(pid: Pid) -> Result<()> {
- unsafe {
- ptrace_other(Request::PT_ATTACH, pid, ptr::null_mut(), 0).map(drop)
- }
-}
-
-/// Detaches the current running process, as with `ptrace(PT_DETACH, ...)`
-///
-/// Detaches from the process specified by `pid` allowing it to run freely, optionally delivering a
-/// signal specified by `sig`.
-pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as c_int,
- None => 0,
- };
- unsafe {
- ptrace_other(Request::PT_DETACH, pid, ptr::null_mut(), data).map(drop)
- }
-}
-
-/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
-///
-/// Continues the execution of the process with PID `pid`, optionally
-/// delivering a signal specified by `sig`.
-pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as c_int,
- None => 0,
- };
- unsafe {
- // Ignore the useless return value
- ptrace_other(Request::PT_CONTINUE, pid, 1 as AddressType, data)
- .map(drop)
- }
-}
-
-/// Issues a kill request as with `ptrace(PT_KILL, ...)`
-///
-/// This request is equivalent to `ptrace(PT_CONTINUE, ..., SIGKILL);`
-pub fn kill(pid: Pid) -> Result<()> {
- unsafe {
- ptrace_other(Request::PT_KILL, pid, 0 as AddressType, 0).map(drop)
- }
-}
-
-/// Move the stopped tracee process forward by a single step as with
-/// `ptrace(PT_STEP, ...)`
-///
-/// Advances the execution of the process with PID `pid` by a single step optionally delivering a
-/// signal specified by `sig`.
-///
-/// # Example
-/// ```rust
-/// use nix::sys::ptrace::step;
-/// use nix::unistd::Pid;
-/// use nix::sys::signal::Signal;
-/// use nix::sys::wait::*;
-/// // If a process changes state to the stopped state because of a SIGUSR1
-/// // signal, this will step the process forward and forward the user
-/// // signal to the stopped process
-/// match waitpid(Pid::from_raw(-1), None) {
-/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => {
-/// let _ = step(pid, Signal::SIGUSR1);
-/// }
-/// _ => {},
-/// }
-/// ```
-#[cfg(any(
- any(target_os = "dragonfly", target_os = "freebsd", target_os = "macos"),
- all(target_os = "openbsd", target_arch = "x86_64"),
- all(
- target_os = "netbsd",
- any(target_arch = "x86_64", target_arch = "powerpc")
- )
-))]
-pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as c_int,
- None => 0,
- };
- unsafe {
- ptrace_other(Request::PT_STEP, pid, ptr::null_mut(), data).map(drop)
- }
-}
-
-/// Reads a word from a processes memory at the given address
-// Technically, ptrace doesn't dereference the pointer. It passes it directly
-// to the kernel.
-#[allow(clippy::not_unsafe_ptr_arg_deref)]
-pub fn read(pid: Pid, addr: AddressType) -> Result<c_int> {
- unsafe {
- // Traditionally there was a difference between reading data or
- // instruction memory but not in modern systems.
- ptrace_other(Request::PT_READ_D, pid, addr, 0)
- }
-}
-
-/// Writes a word into the processes memory at the given address
-// Technically, ptrace doesn't dereference the pointer. It passes it directly
-// to the kernel.
-#[allow(clippy::not_unsafe_ptr_arg_deref)]
-pub fn write(pid: Pid, addr: AddressType, data: c_int) -> Result<()> {
- unsafe { ptrace_other(Request::PT_WRITE_D, pid, addr, data).map(drop) }
-}
diff --git a/vendor/nix/src/sys/ptrace/linux.rs b/vendor/nix/src/sys/ptrace/linux.rs
deleted file mode 100644
index 9687e05d4..000000000
--- a/vendor/nix/src/sys/ptrace/linux.rs
+++ /dev/null
@@ -1,558 +0,0 @@
-//! For detailed description of the ptrace requests, consult `man ptrace`.
-
-use crate::errno::Errno;
-use crate::sys::signal::Signal;
-use crate::unistd::Pid;
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{self, c_long, c_void, siginfo_t};
-use std::{mem, ptr};
-
-pub type AddressType = *mut ::libc::c_void;
-
-#[cfg(all(
- target_os = "linux",
- any(
- all(
- target_arch = "x86_64",
- any(target_env = "gnu", target_env = "musl")
- ),
- all(target_arch = "x86", target_env = "gnu")
- )
-))]
-use libc::user_regs_struct;
-
-cfg_if! {
- if #[cfg(any(all(target_os = "linux", target_arch = "s390x"),
- all(target_os = "linux", target_env = "gnu"),
- target_env = "uclibc"))] {
- #[doc(hidden)]
- pub type RequestType = ::libc::c_uint;
- } else {
- #[doc(hidden)]
- pub type RequestType = ::libc::c_int;
- }
-}
-
-libc_enum! {
- #[cfg_attr(not(any(target_env = "musl", target_env = "uclibc", target_os = "android")), repr(u32))]
- #[cfg_attr(any(target_env = "musl", target_env = "uclibc", target_os = "android"), repr(i32))]
- /// Ptrace Request enum defining the action to be taken.
- #[non_exhaustive]
- pub enum Request {
- PTRACE_TRACEME,
- PTRACE_PEEKTEXT,
- PTRACE_PEEKDATA,
- PTRACE_PEEKUSER,
- PTRACE_POKETEXT,
- PTRACE_POKEDATA,
- PTRACE_POKEUSER,
- PTRACE_CONT,
- PTRACE_KILL,
- PTRACE_SINGLESTEP,
- #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
- all(target_os = "linux", any(target_env = "musl",
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "x86_64",
- target_pointer_width = "32"))))]
- PTRACE_GETREGS,
- #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
- all(target_os = "linux", any(target_env = "musl",
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "x86_64",
- target_pointer_width = "32"))))]
- PTRACE_SETREGS,
- #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
- all(target_os = "linux", any(target_env = "musl",
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "x86_64",
- target_pointer_width = "32"))))]
- PTRACE_GETFPREGS,
- #[cfg(any(all(target_os = "android", target_pointer_width = "32"),
- all(target_os = "linux", any(target_env = "musl",
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "x86_64",
- target_pointer_width = "32"))))]
- PTRACE_SETFPREGS,
- PTRACE_ATTACH,
- PTRACE_DETACH,
- #[cfg(all(target_os = "linux", any(target_env = "musl",
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "x86",
- target_arch = "x86_64")))]
- PTRACE_GETFPXREGS,
- #[cfg(all(target_os = "linux", any(target_env = "musl",
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "x86",
- target_arch = "x86_64")))]
- PTRACE_SETFPXREGS,
- PTRACE_SYSCALL,
- PTRACE_SETOPTIONS,
- PTRACE_GETEVENTMSG,
- PTRACE_GETSIGINFO,
- PTRACE_SETSIGINFO,
- #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
- PTRACE_GETREGSET,
- #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
- PTRACE_SETREGSET,
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PTRACE_SEIZE,
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PTRACE_INTERRUPT,
- #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
- PTRACE_LISTEN,
- #[cfg(all(target_os = "linux", not(any(target_arch = "mips",
- target_arch = "mips64"))))]
- PTRACE_PEEKSIGINFO,
- #[cfg(all(target_os = "linux", target_env = "gnu",
- any(target_arch = "x86", target_arch = "x86_64")))]
- PTRACE_SYSEMU,
- #[cfg(all(target_os = "linux", target_env = "gnu",
- any(target_arch = "x86", target_arch = "x86_64")))]
- PTRACE_SYSEMU_SINGLESTEP,
- }
-}
-
-libc_enum! {
- #[repr(i32)]
- /// Using the ptrace options the tracer can configure the tracee to stop
- /// at certain events. This enum is used to define those events as defined
- /// in `man ptrace`.
- #[non_exhaustive]
- pub enum Event {
- /// Event that stops before a return from fork or clone.
- PTRACE_EVENT_FORK,
- /// Event that stops before a return from vfork or clone.
- PTRACE_EVENT_VFORK,
- /// Event that stops before a return from clone.
- PTRACE_EVENT_CLONE,
- /// Event that stops before a return from execve.
- PTRACE_EVENT_EXEC,
- /// Event for a return from vfork.
- PTRACE_EVENT_VFORK_DONE,
- /// Event for a stop before an exit. Unlike the waitpid Exit status program.
- /// registers can still be examined
- PTRACE_EVENT_EXIT,
- /// Stop triggered by a seccomp rule on a tracee.
- PTRACE_EVENT_SECCOMP,
- /// Stop triggered by the `INTERRUPT` syscall, or a group stop,
- /// or when a new child is attached.
- PTRACE_EVENT_STOP,
- }
-}
-
-libc_bitflags! {
- /// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
- /// See `man ptrace` for more details.
- pub struct Options: libc::c_int {
- /// When delivering system call traps set a bit to allow tracer to
- /// distinguish between normal stops or syscall stops. May not work on
- /// all systems.
- PTRACE_O_TRACESYSGOOD;
- /// Stop tracee at next fork and start tracing the forked process.
- PTRACE_O_TRACEFORK;
- /// Stop tracee at next vfork call and trace the vforked process.
- PTRACE_O_TRACEVFORK;
- /// Stop tracee at next clone call and trace the cloned process.
- PTRACE_O_TRACECLONE;
- /// Stop tracee at next execve call.
- PTRACE_O_TRACEEXEC;
- /// Stop tracee at vfork completion.
- PTRACE_O_TRACEVFORKDONE;
- /// Stop tracee at next exit call. Stops before exit commences allowing
- /// tracer to see location of exit and register states.
- PTRACE_O_TRACEEXIT;
- /// Stop tracee when a SECCOMP_RET_TRACE rule is triggered. See `man seccomp` for more
- /// details.
- PTRACE_O_TRACESECCOMP;
- /// Send a SIGKILL to the tracee if the tracer exits. This is useful
- /// for ptrace jailers to prevent tracees from escaping their control.
- PTRACE_O_EXITKILL;
- }
-}
-
-fn ptrace_peek(
- request: Request,
- pid: Pid,
- addr: AddressType,
- data: *mut c_void,
-) -> Result<c_long> {
- let ret = unsafe {
- Errno::clear();
- libc::ptrace(request as RequestType, libc::pid_t::from(pid), addr, data)
- };
- match Errno::result(ret) {
- Ok(..) | Err(Errno::UnknownErrno) => Ok(ret),
- err @ Err(..) => err,
- }
-}
-
-/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
-#[cfg(all(
- target_os = "linux",
- any(
- all(
- target_arch = "x86_64",
- any(target_env = "gnu", target_env = "musl")
- ),
- all(target_arch = "x86", target_env = "gnu")
- )
-))]
-pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
- ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
-}
-
-/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
-#[cfg(all(
- target_os = "linux",
- any(
- all(
- target_arch = "x86_64",
- any(target_env = "gnu", target_env = "musl")
- ),
- all(target_arch = "x86", target_env = "gnu")
- )
-))]
-pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
- let res = unsafe {
- libc::ptrace(
- Request::PTRACE_SETREGS as RequestType,
- libc::pid_t::from(pid),
- ptr::null_mut::<c_void>(),
- &regs as *const _ as *const c_void,
- )
- };
- Errno::result(res).map(drop)
-}
-
-/// Function for ptrace requests that return values from the data field.
-/// Some ptrace get requests populate structs or larger elements than `c_long`
-/// and therefore use the data field to return values. This function handles these
-/// requests.
-fn ptrace_get_data<T>(request: Request, pid: Pid) -> Result<T> {
- let mut data = mem::MaybeUninit::uninit();
- let res = unsafe {
- libc::ptrace(
- request as RequestType,
- libc::pid_t::from(pid),
- ptr::null_mut::<T>(),
- data.as_mut_ptr() as *const _ as *const c_void,
- )
- };
- Errno::result(res)?;
- Ok(unsafe { data.assume_init() })
-}
-
-unsafe fn ptrace_other(
- request: Request,
- pid: Pid,
- addr: AddressType,
- data: *mut c_void,
-) -> Result<c_long> {
- Errno::result(libc::ptrace(
- request as RequestType,
- libc::pid_t::from(pid),
- addr,
- data,
- ))
- .map(|_| 0)
-}
-
-/// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`.
-pub fn setoptions(pid: Pid, options: Options) -> Result<()> {
- let res = unsafe {
- libc::ptrace(
- Request::PTRACE_SETOPTIONS as RequestType,
- libc::pid_t::from(pid),
- ptr::null_mut::<c_void>(),
- options.bits() as *mut c_void,
- )
- };
- Errno::result(res).map(drop)
-}
-
-/// Gets a ptrace event as described by `ptrace(PTRACE_GETEVENTMSG,...)`
-pub fn getevent(pid: Pid) -> Result<c_long> {
- ptrace_get_data::<c_long>(Request::PTRACE_GETEVENTMSG, pid)
-}
-
-/// Get siginfo as with `ptrace(PTRACE_GETSIGINFO,...)`
-pub fn getsiginfo(pid: Pid) -> Result<siginfo_t> {
- ptrace_get_data::<siginfo_t>(Request::PTRACE_GETSIGINFO, pid)
-}
-
-/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)`
-pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> {
- let ret = unsafe {
- Errno::clear();
- libc::ptrace(
- Request::PTRACE_SETSIGINFO as RequestType,
- libc::pid_t::from(pid),
- ptr::null_mut::<c_void>(),
- sig as *const _ as *const c_void,
- )
- };
- match Errno::result(ret) {
- Ok(_) => Ok(()),
- Err(e) => Err(e),
- }
-}
-
-/// Sets the process as traceable, as with `ptrace(PTRACE_TRACEME, ...)`
-///
-/// Indicates that this process is to be traced by its parent.
-/// This is the only ptrace request to be issued by the tracee.
-pub fn traceme() -> Result<()> {
- unsafe {
- ptrace_other(
- Request::PTRACE_TRACEME,
- Pid::from_raw(0),
- ptr::null_mut(),
- ptr::null_mut(),
- )
- .map(drop) // ignore the useless return value
- }
-}
-
-/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
-///
-/// Arranges for the tracee to be stopped at the next entry to or exit from a system call,
-/// optionally delivering a signal specified by `sig`.
-pub fn syscall<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as i32 as *mut c_void,
- None => ptr::null_mut(),
- };
- unsafe {
- ptrace_other(Request::PTRACE_SYSCALL, pid, ptr::null_mut(), data)
- .map(drop) // ignore the useless return value
- }
-}
-
-/// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSEMU, ...)`
-///
-/// In contrast to the `syscall` function, the syscall stopped at will not be executed.
-/// Thus the the tracee will only be stopped once per syscall,
-/// optionally delivering a signal specified by `sig`.
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
- any(target_arch = "x86", target_arch = "x86_64")
-))]
-pub fn sysemu<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as i32 as *mut c_void,
- None => ptr::null_mut(),
- };
- unsafe {
- ptrace_other(Request::PTRACE_SYSEMU, pid, ptr::null_mut(), data)
- .map(drop)
- // ignore the useless return value
- }
-}
-
-/// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)`
-///
-/// Attaches to the process specified by `pid`, making it a tracee of the calling process.
-pub fn attach(pid: Pid) -> Result<()> {
- unsafe {
- ptrace_other(
- Request::PTRACE_ATTACH,
- pid,
- ptr::null_mut(),
- ptr::null_mut(),
- )
- .map(drop) // ignore the useless return value
- }
-}
-
-/// Attach to a running process, as with `ptrace(PTRACE_SEIZE, ...)`
-///
-/// Attaches to the process specified in pid, making it a tracee of the calling process.
-#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn seize(pid: Pid, options: Options) -> Result<()> {
- unsafe {
- ptrace_other(
- Request::PTRACE_SEIZE,
- pid,
- ptr::null_mut(),
- options.bits() as *mut c_void,
- )
- .map(drop) // ignore the useless return value
- }
-}
-
-/// Detaches the current running process, as with `ptrace(PTRACE_DETACH, ...)`
-///
-/// Detaches from the process specified by `pid` allowing it to run freely, optionally delivering a
-/// signal specified by `sig`.
-pub fn detach<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as i32 as *mut c_void,
- None => ptr::null_mut(),
- };
- unsafe {
- ptrace_other(Request::PTRACE_DETACH, pid, ptr::null_mut(), data)
- .map(drop)
- }
-}
-
-/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)`
-///
-/// Continues the execution of the process with PID `pid`, optionally
-/// delivering a signal specified by `sig`.
-pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as i32 as *mut c_void,
- None => ptr::null_mut(),
- };
- unsafe {
- ptrace_other(Request::PTRACE_CONT, pid, ptr::null_mut(), data).map(drop)
- // ignore the useless return value
- }
-}
-
-/// Stop a tracee, as with `ptrace(PTRACE_INTERRUPT, ...)`
-///
-/// This request is equivalent to `ptrace(PTRACE_INTERRUPT, ...)`
-#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn interrupt(pid: Pid) -> Result<()> {
- unsafe {
- ptrace_other(
- Request::PTRACE_INTERRUPT,
- pid,
- ptr::null_mut(),
- ptr::null_mut(),
- )
- .map(drop)
- }
-}
-
-/// Issues a kill request as with `ptrace(PTRACE_KILL, ...)`
-///
-/// This request is equivalent to `ptrace(PTRACE_CONT, ..., SIGKILL);`
-pub fn kill(pid: Pid) -> Result<()> {
- unsafe {
- ptrace_other(
- Request::PTRACE_KILL,
- pid,
- ptr::null_mut(),
- ptr::null_mut(),
- )
- .map(drop)
- }
-}
-
-/// Move the stopped tracee process forward by a single step as with
-/// `ptrace(PTRACE_SINGLESTEP, ...)`
-///
-/// Advances the execution of the process with PID `pid` by a single step optionally delivering a
-/// signal specified by `sig`.
-///
-/// # Example
-/// ```rust
-/// use nix::sys::ptrace::step;
-/// use nix::unistd::Pid;
-/// use nix::sys::signal::Signal;
-/// use nix::sys::wait::*;
-///
-/// // If a process changes state to the stopped state because of a SIGUSR1
-/// // signal, this will step the process forward and forward the user
-/// // signal to the stopped process
-/// match waitpid(Pid::from_raw(-1), None) {
-/// Ok(WaitStatus::Stopped(pid, Signal::SIGUSR1)) => {
-/// let _ = step(pid, Signal::SIGUSR1);
-/// }
-/// _ => {},
-/// }
-/// ```
-pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as i32 as *mut c_void,
- None => ptr::null_mut(),
- };
- unsafe {
- ptrace_other(Request::PTRACE_SINGLESTEP, pid, ptr::null_mut(), data)
- .map(drop)
- }
-}
-
-/// Move the stopped tracee process forward by a single step or stop at the next syscall
-/// as with `ptrace(PTRACE_SYSEMU_SINGLESTEP, ...)`
-///
-/// Advances the execution by a single step or until the next syscall.
-/// In case the tracee is stopped at a syscall, the syscall will not be executed.
-/// Optionally, the signal specified by `sig` is delivered to the tracee upon continuation.
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
- any(target_arch = "x86", target_arch = "x86_64")
-))]
-pub fn sysemu_step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
- let data = match sig.into() {
- Some(s) => s as i32 as *mut c_void,
- None => ptr::null_mut(),
- };
- unsafe {
- ptrace_other(
- Request::PTRACE_SYSEMU_SINGLESTEP,
- pid,
- ptr::null_mut(),
- data,
- )
- .map(drop) // ignore the useless return value
- }
-}
-
-/// Reads a word from a processes memory at the given address
-pub fn read(pid: Pid, addr: AddressType) -> Result<c_long> {
- ptrace_peek(Request::PTRACE_PEEKDATA, pid, addr, ptr::null_mut())
-}
-
-/// Writes a word into the processes memory at the given address
-///
-/// # Safety
-///
-/// The `data` argument is passed directly to `ptrace(2)`. Read that man page
-/// for guidance.
-pub unsafe fn write(
- pid: Pid,
- addr: AddressType,
- data: *mut c_void,
-) -> Result<()> {
- ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop)
-}
-
-/// Reads a word from a user area at `offset`.
-/// The user struct definition can be found in `/usr/include/sys/user.h`.
-pub fn read_user(pid: Pid, offset: AddressType) -> Result<c_long> {
- ptrace_peek(Request::PTRACE_PEEKUSER, pid, offset, ptr::null_mut())
-}
-
-/// Writes a word to a user area at `offset`.
-/// The user struct definition can be found in `/usr/include/sys/user.h`.
-///
-/// # Safety
-///
-/// The `data` argument is passed directly to `ptrace(2)`. Read that man page
-/// for guidance.
-pub unsafe fn write_user(
- pid: Pid,
- offset: AddressType,
- data: *mut c_void,
-) -> Result<()> {
- ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop)
-}
diff --git a/vendor/nix/src/sys/ptrace/mod.rs b/vendor/nix/src/sys/ptrace/mod.rs
deleted file mode 100644
index 2b121c0b4..000000000
--- a/vendor/nix/src/sys/ptrace/mod.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-///! Provides helpers for making ptrace system calls
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod linux;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use self::linux::*;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-mod bsd;
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-pub use self::bsd::*;
diff --git a/vendor/nix/src/sys/quota.rs b/vendor/nix/src/sys/quota.rs
deleted file mode 100644
index b3c44ca70..000000000
--- a/vendor/nix/src/sys/quota.rs
+++ /dev/null
@@ -1,338 +0,0 @@
-//! Set and configure disk quotas for users, groups, or projects.
-//!
-//! # Examples
-//!
-//! Enabling and setting a quota:
-//!
-//! ```rust,no_run
-//! # use nix::sys::quota::{Dqblk, quotactl_on, quotactl_set, QuotaFmt, QuotaType, QuotaValidFlags};
-//! quotactl_on(QuotaType::USRQUOTA, "/dev/sda1", QuotaFmt::QFMT_VFS_V1, "aquota.user").unwrap();
-//! let mut dqblk: Dqblk = Default::default();
-//! dqblk.set_blocks_hard_limit(10000);
-//! dqblk.set_blocks_soft_limit(8000);
-//! quotactl_set(QuotaType::USRQUOTA, "/dev/sda1", 50, &dqblk, QuotaValidFlags::QIF_BLIMITS).unwrap();
-//! ```
-use crate::errno::Errno;
-use crate::{NixPath, Result};
-use libc::{self, c_char, c_int};
-use std::default::Default;
-use std::{mem, ptr};
-
-struct QuotaCmd(QuotaSubCmd, QuotaType);
-
-impl QuotaCmd {
- #[allow(unused_unsafe)]
- fn as_int(&self) -> c_int {
- unsafe { libc::QCMD(self.0 as i32, self.1 as i32) }
- }
-}
-
-// linux quota version >= 2
-libc_enum! {
- #[repr(i32)]
- enum QuotaSubCmd {
- Q_SYNC,
- Q_QUOTAON,
- Q_QUOTAOFF,
- Q_GETQUOTA,
- Q_SETQUOTA,
- }
-}
-
-libc_enum! {
- /// The scope of the quota.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum QuotaType {
- /// Specify a user quota
- USRQUOTA,
- /// Specify a group quota
- GRPQUOTA,
- }
-}
-
-libc_enum! {
- /// The type of quota format to use.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum QuotaFmt {
- /// Use the original quota format.
- QFMT_VFS_OLD,
- /// Use the standard VFS v0 quota format.
- ///
- /// Handles 32-bit UIDs/GIDs and quota limits up to 2<sup>32</sup> bytes/2<sup>32</sup> inodes.
- QFMT_VFS_V0,
- /// Use the VFS v1 quota format.
- ///
- /// Handles 32-bit UIDs/GIDs and quota limits of 2<sup>64</sup> bytes/2<sup>64</sup> inodes.
- QFMT_VFS_V1,
- }
-}
-
-libc_bitflags!(
- /// Indicates the quota fields that are valid to read from.
- #[derive(Default)]
- pub struct QuotaValidFlags: u32 {
- /// The block hard & soft limit fields.
- QIF_BLIMITS;
- /// The current space field.
- QIF_SPACE;
- /// The inode hard & soft limit fields.
- QIF_ILIMITS;
- /// The current inodes field.
- QIF_INODES;
- /// The disk use time limit field.
- QIF_BTIME;
- /// The file quote time limit field.
- QIF_ITIME;
- /// All block & inode limits.
- QIF_LIMITS;
- /// The space & inodes usage fields.
- QIF_USAGE;
- /// The time limit fields.
- QIF_TIMES;
- /// All fields.
- QIF_ALL;
- }
-);
-
-/// Wrapper type for `if_dqblk`
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct Dqblk(libc::dqblk);
-
-impl Default for Dqblk {
- fn default() -> Dqblk {
- Dqblk(libc::dqblk {
- dqb_bhardlimit: 0,
- dqb_bsoftlimit: 0,
- dqb_curspace: 0,
- dqb_ihardlimit: 0,
- dqb_isoftlimit: 0,
- dqb_curinodes: 0,
- dqb_btime: 0,
- dqb_itime: 0,
- dqb_valid: 0,
- })
- }
-}
-
-impl Dqblk {
- /// The absolute limit on disk quota blocks allocated.
- pub fn blocks_hard_limit(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
- Some(self.0.dqb_bhardlimit)
- } else {
- None
- }
- }
-
- /// Set the absolute limit on disk quota blocks allocated.
- pub fn set_blocks_hard_limit(&mut self, limit: u64) {
- self.0.dqb_bhardlimit = limit;
- }
-
- /// Preferred limit on disk quota blocks
- pub fn blocks_soft_limit(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_BLIMITS) {
- Some(self.0.dqb_bsoftlimit)
- } else {
- None
- }
- }
-
- /// Set the preferred limit on disk quota blocks allocated.
- pub fn set_blocks_soft_limit(&mut self, limit: u64) {
- self.0.dqb_bsoftlimit = limit;
- }
-
- /// Current occupied space (bytes).
- pub fn occupied_space(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_SPACE) {
- Some(self.0.dqb_curspace)
- } else {
- None
- }
- }
-
- /// Maximum number of allocated inodes.
- pub fn inodes_hard_limit(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
- Some(self.0.dqb_ihardlimit)
- } else {
- None
- }
- }
-
- /// Set the maximum number of allocated inodes.
- pub fn set_inodes_hard_limit(&mut self, limit: u64) {
- self.0.dqb_ihardlimit = limit;
- }
-
- /// Preferred inode limit
- pub fn inodes_soft_limit(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_ILIMITS) {
- Some(self.0.dqb_isoftlimit)
- } else {
- None
- }
- }
-
- /// Set the preferred limit of allocated inodes.
- pub fn set_inodes_soft_limit(&mut self, limit: u64) {
- self.0.dqb_isoftlimit = limit;
- }
-
- /// Current number of allocated inodes.
- pub fn allocated_inodes(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_INODES) {
- Some(self.0.dqb_curinodes)
- } else {
- None
- }
- }
-
- /// Time limit for excessive disk use.
- pub fn block_time_limit(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_BTIME) {
- Some(self.0.dqb_btime)
- } else {
- None
- }
- }
-
- /// Set the time limit for excessive disk use.
- pub fn set_block_time_limit(&mut self, limit: u64) {
- self.0.dqb_btime = limit;
- }
-
- /// Time limit for excessive files.
- pub fn inode_time_limit(&self) -> Option<u64> {
- let valid_fields =
- QuotaValidFlags::from_bits_truncate(self.0.dqb_valid);
- if valid_fields.contains(QuotaValidFlags::QIF_ITIME) {
- Some(self.0.dqb_itime)
- } else {
- None
- }
- }
-
- /// Set the time limit for excessive files.
- pub fn set_inode_time_limit(&mut self, limit: u64) {
- self.0.dqb_itime = limit;
- }
-}
-
-fn quotactl<P: ?Sized + NixPath>(
- cmd: QuotaCmd,
- special: Option<&P>,
- id: c_int,
- addr: *mut c_char,
-) -> Result<()> {
- unsafe {
- Errno::clear();
- let res = match special {
- Some(dev) => dev.with_nix_path(|path| {
- libc::quotactl(cmd.as_int(), path.as_ptr(), id, addr)
- }),
- None => Ok(libc::quotactl(cmd.as_int(), ptr::null(), id, addr)),
- }?;
-
- Errno::result(res).map(drop)
- }
-}
-
-/// Turn on disk quotas for a block device.
-pub fn quotactl_on<P: ?Sized + NixPath>(
- which: QuotaType,
- special: &P,
- format: QuotaFmt,
- quota_file: &P,
-) -> Result<()> {
- quota_file.with_nix_path(|path| {
- let mut path_copy = path.to_bytes_with_nul().to_owned();
- let p: *mut c_char = path_copy.as_mut_ptr() as *mut c_char;
- quotactl(
- QuotaCmd(QuotaSubCmd::Q_QUOTAON, which),
- Some(special),
- format as c_int,
- p,
- )
- })?
-}
-
-/// Disable disk quotas for a block device.
-pub fn quotactl_off<P: ?Sized + NixPath>(
- which: QuotaType,
- special: &P,
-) -> Result<()> {
- quotactl(
- QuotaCmd(QuotaSubCmd::Q_QUOTAOFF, which),
- Some(special),
- 0,
- ptr::null_mut(),
- )
-}
-
-/// Update the on-disk copy of quota usages for a filesystem.
-///
-/// If `special` is `None`, then all file systems with active quotas are sync'd.
-pub fn quotactl_sync<P: ?Sized + NixPath>(
- which: QuotaType,
- special: Option<&P>,
-) -> Result<()> {
- quotactl(
- QuotaCmd(QuotaSubCmd::Q_SYNC, which),
- special,
- 0,
- ptr::null_mut(),
- )
-}
-
-/// Get disk quota limits and current usage for the given user/group id.
-pub fn quotactl_get<P: ?Sized + NixPath>(
- which: QuotaType,
- special: &P,
- id: c_int,
-) -> Result<Dqblk> {
- let mut dqblk = mem::MaybeUninit::uninit();
- quotactl(
- QuotaCmd(QuotaSubCmd::Q_GETQUOTA, which),
- Some(special),
- id,
- dqblk.as_mut_ptr() as *mut c_char,
- )?;
- Ok(unsafe { Dqblk(dqblk.assume_init()) })
-}
-
-/// Configure quota values for the specified fields for a given user/group id.
-pub fn quotactl_set<P: ?Sized + NixPath>(
- which: QuotaType,
- special: &P,
- id: c_int,
- dqblk: &Dqblk,
- fields: QuotaValidFlags,
-) -> Result<()> {
- let mut dqblk_copy = *dqblk;
- dqblk_copy.0.dqb_valid = fields.bits();
- quotactl(
- QuotaCmd(QuotaSubCmd::Q_SETQUOTA, which),
- Some(special),
- id,
- &mut dqblk_copy as *mut _ as *mut c_char,
- )
-}
diff --git a/vendor/nix/src/sys/reboot.rs b/vendor/nix/src/sys/reboot.rs
deleted file mode 100644
index 02d98162b..000000000
--- a/vendor/nix/src/sys/reboot.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-//! Reboot/shutdown or enable/disable Ctrl-Alt-Delete.
-
-use crate::errno::Errno;
-use crate::Result;
-use std::convert::Infallible;
-use std::mem::drop;
-
-libc_enum! {
- /// How exactly should the system be rebooted.
- ///
- /// See [`set_cad_enabled()`](fn.set_cad_enabled.html) for
- /// enabling/disabling Ctrl-Alt-Delete.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum RebootMode {
- /// Halt the system.
- RB_HALT_SYSTEM,
- /// Execute a kernel that has been loaded earlier with
- /// [`kexec_load(2)`](https://man7.org/linux/man-pages/man2/kexec_load.2.html).
- RB_KEXEC,
- /// Stop the system and switch off power, if possible.
- RB_POWER_OFF,
- /// Restart the system.
- RB_AUTOBOOT,
- // we do not support Restart2.
- /// Suspend the system using software suspend.
- RB_SW_SUSPEND,
- }
-}
-
-/// Reboots or shuts down the system.
-pub fn reboot(how: RebootMode) -> Result<Infallible> {
- unsafe { libc::reboot(how as libc::c_int) };
- Err(Errno::last())
-}
-
-/// Enable or disable the reboot keystroke (Ctrl-Alt-Delete).
-///
-/// Corresponds to calling `reboot(RB_ENABLE_CAD)` or `reboot(RB_DISABLE_CAD)` in C.
-pub fn set_cad_enabled(enable: bool) -> Result<()> {
- let cmd = if enable {
- libc::RB_ENABLE_CAD
- } else {
- libc::RB_DISABLE_CAD
- };
- let res = unsafe { libc::reboot(cmd) };
- Errno::result(res).map(drop)
-}
diff --git a/vendor/nix/src/sys/resource.rs b/vendor/nix/src/sys/resource.rs
deleted file mode 100644
index 892773776..000000000
--- a/vendor/nix/src/sys/resource.rs
+++ /dev/null
@@ -1,443 +0,0 @@
-//! Configure the process resource limits.
-use cfg_if::cfg_if;
-use libc::{c_int, c_long, rusage};
-
-use crate::errno::Errno;
-use crate::sys::time::TimeVal;
-use crate::Result;
-pub use libc::rlim_t;
-pub use libc::RLIM_INFINITY;
-use std::mem;
-
-cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
- use libc::{__rlimit_resource_t, rlimit};
- } else if #[cfg(any(
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "dragonfly",
- all(target_os = "linux", not(target_env = "gnu"))
- ))]{
- use libc::rlimit;
- }
-}
-
-libc_enum! {
- /// Types of process resources.
- ///
- /// The Resource enum is platform dependent. Check different platform
- /// manuals for more details. Some platform links have been provided for
- /// easier reference (non-exhaustive).
- ///
- /// * [Linux](https://man7.org/linux/man-pages/man2/getrlimit.2.html)
- /// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=setrlimit)
- /// * [NetBSD](https://man.netbsd.org/setrlimit.2)
-
- // linux-gnu uses u_int as resource enum, which is implemented in libc as
- // well.
- //
- // https://gcc.gnu.org/legacy-ml/gcc/2015-08/msg00441.html
- // https://github.com/rust-lang/libc/blob/master/src/unix/linux_like/linux/gnu/mod.rs
- #[cfg_attr(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")), repr(u32))]
- #[cfg_attr(any(
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "dragonfly",
- all(target_os = "linux", not(any(target_env = "gnu", target_env = "uclibc")))
- ), repr(i32))]
- #[non_exhaustive]
- pub enum Resource {
- #[cfg(not(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum amount (in bytes) of virtual memory the process is
- /// allowed to map.
- RLIMIT_AS,
- /// The largest size (in bytes) core(5) file that may be created.
- RLIMIT_CORE,
- /// The maximum amount of cpu time (in seconds) to be used by each
- /// process.
- RLIMIT_CPU,
- /// The maximum size (in bytes) of the data segment for a process
- RLIMIT_DATA,
- /// The largest size (in bytes) file that may be created.
- RLIMIT_FSIZE,
- /// The maximum number of open files for this process.
- RLIMIT_NOFILE,
- /// The maximum size (in bytes) of the stack segment for a process.
- RLIMIT_STACK,
-
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum number of kqueues this user id is allowed to create.
- RLIMIT_KQUEUES,
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// A limit on the combined number of flock locks and fcntl leases that
- /// this process may establish.
- RLIMIT_LOCKS,
-
- #[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "linux",
- target_os = "netbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum size (in bytes) which a process may lock into memory
- /// using the mlock(2) system call.
- RLIMIT_MEMLOCK,
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// A limit on the number of bytes that can be allocated for POSIX
- /// message queues for the real user ID of the calling process.
- RLIMIT_MSGQUEUE,
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// A ceiling to which the process's nice value can be raised using
- /// setpriority or nice.
- RLIMIT_NICE,
-
- #[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum number of simultaneous processes for this user id.
- RLIMIT_NPROC,
-
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum number of pseudo-terminals this user id is allowed to
- /// create.
- RLIMIT_NPTS,
-
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// When there is memory pressure and swap is available, prioritize
- /// eviction of a process' resident pages beyond this amount (in bytes).
- RLIMIT_RSS,
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// A ceiling on the real-time priority that may be set for this process
- /// using sched_setscheduler and sched_set‐ param.
- RLIMIT_RTPRIO,
-
- #[cfg(any(target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// A limit (in microseconds) on the amount of CPU time that a process
- /// scheduled under a real-time scheduling policy may con‐ sume without
- /// making a blocking system call.
- RLIMIT_RTTIME,
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// A limit on the number of signals that may be queued for the real
- /// user ID of the calling process.
- RLIMIT_SIGPENDING,
-
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum size (in bytes) of socket buffer usage for this user.
- RLIMIT_SBSIZE,
-
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum size (in bytes) of the swap space that may be reserved
- /// or used by all of this user id's processes.
- RLIMIT_SWAP,
-
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// An alias for RLIMIT_AS.
- RLIMIT_VMEM,
- }
-}
-
-/// Get the current processes resource limits
-///
-/// The special value [`RLIM_INFINITY`] indicates that no limit will be
-/// enforced.
-///
-/// # Parameters
-///
-/// * `resource`: The [`Resource`] that we want to get the limits of.
-///
-/// # Examples
-///
-/// ```
-/// # use nix::sys::resource::{getrlimit, Resource};
-///
-/// let (soft_limit, hard_limit) = getrlimit(Resource::RLIMIT_NOFILE).unwrap();
-/// println!("current soft_limit: {}", soft_limit);
-/// println!("current hard_limit: {}", hard_limit);
-/// ```
-///
-/// # References
-///
-/// [getrlimit(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html#tag_16_215)
-///
-/// [`Resource`]: enum.Resource.html
-pub fn getrlimit(resource: Resource) -> Result<(rlim_t, rlim_t)> {
- let mut old_rlim = mem::MaybeUninit::<rlimit>::uninit();
-
- cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
- let res = unsafe { libc::getrlimit(resource as __rlimit_resource_t, old_rlim.as_mut_ptr()) };
- } else {
- let res = unsafe { libc::getrlimit(resource as c_int, old_rlim.as_mut_ptr()) };
- }
- }
-
- Errno::result(res).map(|_| {
- let rlimit { rlim_cur, rlim_max } = unsafe { old_rlim.assume_init() };
- (rlim_cur, rlim_max)
- })
-}
-
-/// Set the current processes resource limits
-///
-/// # Parameters
-///
-/// * `resource`: The [`Resource`] that we want to set the limits of.
-/// * `soft_limit`: The value that the kernel enforces for the corresponding
-/// resource.
-/// * `hard_limit`: The ceiling for the soft limit. Must be lower or equal to
-/// the current hard limit for non-root users.
-///
-/// The special value [`RLIM_INFINITY`] indicates that no limit will be
-/// enforced.
-///
-/// # Examples
-///
-/// ```
-/// # use nix::sys::resource::{setrlimit, Resource};
-///
-/// let soft_limit = 512;
-/// let hard_limit = 1024;
-/// setrlimit(Resource::RLIMIT_NOFILE, soft_limit, hard_limit).unwrap();
-/// ```
-///
-/// # References
-///
-/// [setrlimit(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html#tag_16_215)
-///
-/// [`Resource`]: enum.Resource.html
-///
-/// Note: `setrlimit` provides a safe wrapper to libc's `setrlimit`.
-pub fn setrlimit(
- resource: Resource,
- soft_limit: rlim_t,
- hard_limit: rlim_t,
-) -> Result<()> {
- let new_rlim = rlimit {
- rlim_cur: soft_limit,
- rlim_max: hard_limit,
- };
- cfg_if! {
- if #[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))]{
- let res = unsafe { libc::setrlimit(resource as __rlimit_resource_t, &new_rlim as *const rlimit) };
- }else{
- let res = unsafe { libc::setrlimit(resource as c_int, &new_rlim as *const rlimit) };
- }
- }
-
- Errno::result(res).map(drop)
-}
-
-libc_enum! {
- /// Whose resource usage should be returned by [`getrusage`].
- #[repr(i32)]
- #[non_exhaustive]
- pub enum UsageWho {
- /// Resource usage for the current process.
- RUSAGE_SELF,
-
- /// Resource usage for all the children that have terminated and been waited for.
- RUSAGE_CHILDREN,
-
- #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Resource usage for the calling thread.
- RUSAGE_THREAD,
- }
-}
-
-/// Output of `getrusage` with information about resource usage. Some of the fields
-/// may be unused in some platforms, and will be always zeroed out. See their manuals
-/// for details.
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct Usage(rusage);
-
-impl AsRef<rusage> for Usage {
- fn as_ref(&self) -> &rusage {
- &self.0
- }
-}
-
-impl AsMut<rusage> for Usage {
- fn as_mut(&mut self) -> &mut rusage {
- &mut self.0
- }
-}
-
-impl Usage {
- /// Total amount of time spent executing in user mode.
- pub fn user_time(&self) -> TimeVal {
- TimeVal::from(self.0.ru_utime)
- }
-
- /// Total amount of time spent executing in kernel mode.
- pub fn system_time(&self) -> TimeVal {
- TimeVal::from(self.0.ru_stime)
- }
-
- /// The resident set size at its peak, in kilobytes.
- pub fn max_rss(&self) -> c_long {
- self.0.ru_maxrss
- }
-
- /// Integral value expressed in kilobytes times ticks of execution indicating
- /// the amount of text memory shared with other processes.
- pub fn shared_integral(&self) -> c_long {
- self.0.ru_ixrss
- }
-
- /// Integral value expressed in kilobytes times ticks of execution indicating
- /// the amount of unshared memory used by data.
- pub fn unshared_data_integral(&self) -> c_long {
- self.0.ru_idrss
- }
-
- /// Integral value expressed in kilobytes times ticks of execution indicating
- /// the amount of unshared memory used for stack space.
- pub fn unshared_stack_integral(&self) -> c_long {
- self.0.ru_isrss
- }
-
- /// Number of page faults that were served without resorting to I/O, with pages
- /// that have been allocated previously by the kernel.
- pub fn minor_page_faults(&self) -> c_long {
- self.0.ru_minflt
- }
-
- /// Number of page faults that were served through I/O (i.e. swap).
- pub fn major_page_faults(&self) -> c_long {
- self.0.ru_majflt
- }
-
- /// Number of times all of the memory was fully swapped out.
- pub fn full_swaps(&self) -> c_long {
- self.0.ru_nswap
- }
-
- /// Number of times a read was done from a block device.
- pub fn block_reads(&self) -> c_long {
- self.0.ru_inblock
- }
-
- /// Number of times a write was done to a block device.
- pub fn block_writes(&self) -> c_long {
- self.0.ru_oublock
- }
-
- /// Number of IPC messages sent.
- pub fn ipc_sends(&self) -> c_long {
- self.0.ru_msgsnd
- }
-
- /// Number of IPC messages received.
- pub fn ipc_receives(&self) -> c_long {
- self.0.ru_msgrcv
- }
-
- /// Number of signals received.
- pub fn signals(&self) -> c_long {
- self.0.ru_nsignals
- }
-
- /// Number of times a context switch was voluntarily invoked.
- pub fn voluntary_context_switches(&self) -> c_long {
- self.0.ru_nvcsw
- }
-
- /// Number of times a context switch was imposed by the kernel (usually due to
- /// time slice expiring or preemption by a higher priority process).
- pub fn involuntary_context_switches(&self) -> c_long {
- self.0.ru_nivcsw
- }
-}
-
-/// Get usage information for a process, its children or the current thread
-///
-/// Real time information can be obtained for either the current process or (in some
-/// systems) thread, but information about children processes is only provided for
-/// those that have terminated and been waited for (see [`super::wait::wait`]).
-///
-/// Some information may be missing depending on the platform, and the way information
-/// is provided for children may also vary. Check the manuals for details.
-///
-/// # References
-///
-/// * [getrusage(2)](https://pubs.opengroup.org/onlinepubs/009696699/functions/getrusage.html)
-/// * [Linux](https://man7.org/linux/man-pages/man2/getrusage.2.html)
-/// * [FreeBSD](https://www.freebsd.org/cgi/man.cgi?query=getrusage)
-/// * [NetBSD](https://man.netbsd.org/getrusage.2)
-/// * [MacOS](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getrusage.2.html)
-///
-/// [`UsageWho`]: enum.UsageWho.html
-///
-/// Note: `getrusage` provides a safe wrapper to libc's [`libc::getrusage`].
-pub fn getrusage(who: UsageWho) -> Result<Usage> {
- unsafe {
- let mut rusage = mem::MaybeUninit::<rusage>::uninit();
- let res = libc::getrusage(who as c_int, rusage.as_mut_ptr());
- Errno::result(res).map(|_| Usage(rusage.assume_init()))
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::{getrusage, UsageWho};
-
- #[test]
- pub fn test_self_cpu_time() {
- // Make sure some CPU time is used.
- let mut numbers: Vec<i32> = (1..1_000_000).collect();
- numbers.iter_mut().for_each(|item| *item *= 2);
-
- // FIXME: this is here to help ensure the compiler does not optimize the whole
- // thing away. Replace the assert with test::black_box once stabilized.
- assert_eq!(numbers[100..200].iter().sum::<i32>(), 30_100);
-
- let usage = getrusage(UsageWho::RUSAGE_SELF)
- .expect("Failed to call getrusage for SELF");
- let rusage = usage.as_ref();
-
- let user = usage.user_time();
- assert!(user.tv_sec() > 0 || user.tv_usec() > 0);
- assert_eq!(user.tv_sec(), rusage.ru_utime.tv_sec);
- assert_eq!(user.tv_usec(), rusage.ru_utime.tv_usec);
- }
-}
diff --git a/vendor/nix/src/sys/select.rs b/vendor/nix/src/sys/select.rs
deleted file mode 100644
index 7a94cff87..000000000
--- a/vendor/nix/src/sys/select.rs
+++ /dev/null
@@ -1,455 +0,0 @@
-//! Portably monitor a group of file descriptors for readiness.
-use crate::errno::Errno;
-use crate::sys::time::{TimeSpec, TimeVal};
-use crate::Result;
-use libc::{self, c_int};
-use std::convert::TryFrom;
-use std::iter::FusedIterator;
-use std::mem;
-use std::ops::Range;
-use std::os::unix::io::RawFd;
-use std::ptr::{null, null_mut};
-
-pub use libc::FD_SETSIZE;
-
-/// Contains a set of file descriptors used by [`select`]
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct FdSet(libc::fd_set);
-
-fn assert_fd_valid(fd: RawFd) {
- assert!(
- usize::try_from(fd).map_or(false, |fd| fd < FD_SETSIZE),
- "fd must be in the range 0..FD_SETSIZE",
- );
-}
-
-impl FdSet {
- /// Create an empty `FdSet`
- pub fn new() -> FdSet {
- let mut fdset = mem::MaybeUninit::uninit();
- unsafe {
- libc::FD_ZERO(fdset.as_mut_ptr());
- FdSet(fdset.assume_init())
- }
- }
-
- /// Add a file descriptor to an `FdSet`
- pub fn insert(&mut self, fd: RawFd) {
- assert_fd_valid(fd);
- unsafe { libc::FD_SET(fd, &mut self.0) };
- }
-
- /// Remove a file descriptor from an `FdSet`
- pub fn remove(&mut self, fd: RawFd) {
- assert_fd_valid(fd);
- unsafe { libc::FD_CLR(fd, &mut self.0) };
- }
-
- /// Test an `FdSet` for the presence of a certain file descriptor.
- pub fn contains(&self, fd: RawFd) -> bool {
- assert_fd_valid(fd);
- unsafe { libc::FD_ISSET(fd, &self.0) }
- }
-
- /// Remove all file descriptors from this `FdSet`.
- pub fn clear(&mut self) {
- unsafe { libc::FD_ZERO(&mut self.0) };
- }
-
- /// Finds the highest file descriptor in the set.
- ///
- /// Returns `None` if the set is empty.
- ///
- /// This can be used to calculate the `nfds` parameter of the [`select`] function.
- ///
- /// # Example
- ///
- /// ```
- /// # use nix::sys::select::FdSet;
- /// let mut set = FdSet::new();
- /// set.insert(4);
- /// set.insert(9);
- /// assert_eq!(set.highest(), Some(9));
- /// ```
- ///
- /// [`select`]: fn.select.html
- pub fn highest(&self) -> Option<RawFd> {
- self.fds(None).next_back()
- }
-
- /// Returns an iterator over the file descriptors in the set.
- ///
- /// For performance, it takes an optional higher bound: the iterator will
- /// not return any elements of the set greater than the given file
- /// descriptor.
- ///
- /// # Examples
- ///
- /// ```
- /// # use nix::sys::select::FdSet;
- /// # use std::os::unix::io::RawFd;
- /// let mut set = FdSet::new();
- /// set.insert(4);
- /// set.insert(9);
- /// let fds: Vec<RawFd> = set.fds(None).collect();
- /// assert_eq!(fds, vec![4, 9]);
- /// ```
- #[inline]
- pub fn fds(&self, highest: Option<RawFd>) -> Fds {
- Fds {
- set: self,
- range: 0..highest.map(|h| h as usize + 1).unwrap_or(FD_SETSIZE),
- }
- }
-}
-
-impl Default for FdSet {
- fn default() -> Self {
- Self::new()
- }
-}
-
-/// Iterator over `FdSet`.
-#[derive(Debug)]
-pub struct Fds<'a> {
- set: &'a FdSet,
- range: Range<usize>,
-}
-
-impl<'a> Iterator for Fds<'a> {
- type Item = RawFd;
-
- fn next(&mut self) -> Option<RawFd> {
- for i in &mut self.range {
- if self.set.contains(i as RawFd) {
- return Some(i as RawFd);
- }
- }
- None
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (_, upper) = self.range.size_hint();
- (0, upper)
- }
-}
-
-impl<'a> DoubleEndedIterator for Fds<'a> {
- #[inline]
- fn next_back(&mut self) -> Option<RawFd> {
- while let Some(i) = self.range.next_back() {
- if self.set.contains(i as RawFd) {
- return Some(i as RawFd);
- }
- }
- None
- }
-}
-
-impl<'a> FusedIterator for Fds<'a> {}
-
-/// Monitors file descriptors for readiness
-///
-/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
-/// file descriptors that are ready for the given operation are set.
-///
-/// When this function returns, `timeout` has an implementation-defined value.
-///
-/// # Parameters
-///
-/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this
-/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1
-/// to the maximum of that.
-/// * `readfds`: File descriptors to check for being ready to read.
-/// * `writefds`: File descriptors to check for being ready to write.
-/// * `errorfds`: File descriptors to check for pending error conditions.
-/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
-/// indefinitely).
-///
-/// # References
-///
-/// [select(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/select.html)
-///
-/// [`FdSet::highest`]: struct.FdSet.html#method.highest
-pub fn select<'a, N, R, W, E, T>(
- nfds: N,
- readfds: R,
- writefds: W,
- errorfds: E,
- timeout: T,
-) -> Result<c_int>
-where
- N: Into<Option<c_int>>,
- R: Into<Option<&'a mut FdSet>>,
- W: Into<Option<&'a mut FdSet>>,
- E: Into<Option<&'a mut FdSet>>,
- T: Into<Option<&'a mut TimeVal>>,
-{
- let mut readfds = readfds.into();
- let mut writefds = writefds.into();
- let mut errorfds = errorfds.into();
- let timeout = timeout.into();
-
- let nfds = nfds.into().unwrap_or_else(|| {
- readfds
- .iter_mut()
- .chain(writefds.iter_mut())
- .chain(errorfds.iter_mut())
- .map(|set| set.highest().unwrap_or(-1))
- .max()
- .unwrap_or(-1)
- + 1
- });
-
- let readfds = readfds
- .map(|set| set as *mut _ as *mut libc::fd_set)
- .unwrap_or(null_mut());
- let writefds = writefds
- .map(|set| set as *mut _ as *mut libc::fd_set)
- .unwrap_or(null_mut());
- let errorfds = errorfds
- .map(|set| set as *mut _ as *mut libc::fd_set)
- .unwrap_or(null_mut());
- let timeout = timeout
- .map(|tv| tv as *mut _ as *mut libc::timeval)
- .unwrap_or(null_mut());
-
- let res =
- unsafe { libc::select(nfds, readfds, writefds, errorfds, timeout) };
-
- Errno::result(res)
-}
-
-feature! {
-#![feature = "signal"]
-
-use crate::sys::signal::SigSet;
-
-/// Monitors file descriptors for readiness with an altered signal mask.
-///
-/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
-/// file descriptors that are ready for the given operation are set.
-///
-/// When this function returns, the original signal mask is restored.
-///
-/// Unlike [`select`](#fn.select), `pselect` does not mutate the `timeout` value.
-///
-/// # Parameters
-///
-/// * `nfds`: The highest file descriptor set in any of the passed `FdSet`s, plus 1. If `None`, this
-/// is calculated automatically by calling [`FdSet::highest`] on all descriptor sets and adding 1
-/// to the maximum of that.
-/// * `readfds`: File descriptors to check for read readiness
-/// * `writefds`: File descriptors to check for write readiness
-/// * `errorfds`: File descriptors to check for pending error conditions.
-/// * `timeout`: Maximum time to wait for descriptors to become ready (`None` to block
-/// indefinitely).
-/// * `sigmask`: Signal mask to activate while waiting for file descriptors to turn
-/// ready (`None` to set no alternative signal mask).
-///
-/// # References
-///
-/// [pselect(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html)
-///
-/// [The new pselect() system call](https://lwn.net/Articles/176911/)
-///
-/// [`FdSet::highest`]: struct.FdSet.html#method.highest
-pub fn pselect<'a, N, R, W, E, T, S>(nfds: N,
- readfds: R,
- writefds: W,
- errorfds: E,
- timeout: T,
- sigmask: S) -> Result<c_int>
-where
- N: Into<Option<c_int>>,
- R: Into<Option<&'a mut FdSet>>,
- W: Into<Option<&'a mut FdSet>>,
- E: Into<Option<&'a mut FdSet>>,
- T: Into<Option<&'a TimeSpec>>,
- S: Into<Option<&'a SigSet>>,
-{
- let mut readfds = readfds.into();
- let mut writefds = writefds.into();
- let mut errorfds = errorfds.into();
- let sigmask = sigmask.into();
- let timeout = timeout.into();
-
- let nfds = nfds.into().unwrap_or_else(|| {
- readfds.iter_mut()
- .chain(writefds.iter_mut())
- .chain(errorfds.iter_mut())
- .map(|set| set.highest().unwrap_or(-1))
- .max()
- .unwrap_or(-1) + 1
- });
-
- let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
- let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
- let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
- let timeout = timeout.map(|ts| ts.as_ref() as *const libc::timespec).unwrap_or(null());
- let sigmask = sigmask.map(|sm| sm.as_ref() as *const libc::sigset_t).unwrap_or(null());
-
- let res = unsafe {
- libc::pselect(nfds, readfds, writefds, errorfds, timeout, sigmask)
- };
-
- Errno::result(res)
-}
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::sys::time::{TimeVal, TimeValLike};
- use crate::unistd::{pipe, write};
- use std::os::unix::io::RawFd;
-
- #[test]
- fn fdset_insert() {
- let mut fd_set = FdSet::new();
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i as RawFd));
- }
-
- fd_set.insert(7);
-
- assert!(fd_set.contains(7));
- }
-
- #[test]
- fn fdset_remove() {
- let mut fd_set = FdSet::new();
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i as RawFd));
- }
-
- fd_set.insert(7);
- fd_set.remove(7);
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i as RawFd));
- }
- }
-
- #[test]
- fn fdset_clear() {
- let mut fd_set = FdSet::new();
- fd_set.insert(1);
- fd_set.insert((FD_SETSIZE / 2) as RawFd);
- fd_set.insert((FD_SETSIZE - 1) as RawFd);
-
- fd_set.clear();
-
- for i in 0..FD_SETSIZE {
- assert!(!fd_set.contains(i as RawFd));
- }
- }
-
- #[test]
- fn fdset_highest() {
- let mut set = FdSet::new();
- assert_eq!(set.highest(), None);
- set.insert(0);
- assert_eq!(set.highest(), Some(0));
- set.insert(90);
- assert_eq!(set.highest(), Some(90));
- set.remove(0);
- assert_eq!(set.highest(), Some(90));
- set.remove(90);
- assert_eq!(set.highest(), None);
-
- set.insert(4);
- set.insert(5);
- set.insert(7);
- assert_eq!(set.highest(), Some(7));
- }
-
- #[test]
- fn fdset_fds() {
- let mut set = FdSet::new();
- assert_eq!(set.fds(None).collect::<Vec<_>>(), vec![]);
- set.insert(0);
- assert_eq!(set.fds(None).collect::<Vec<_>>(), vec![0]);
- set.insert(90);
- assert_eq!(set.fds(None).collect::<Vec<_>>(), vec![0, 90]);
-
- // highest limit
- assert_eq!(set.fds(Some(89)).collect::<Vec<_>>(), vec![0]);
- assert_eq!(set.fds(Some(90)).collect::<Vec<_>>(), vec![0, 90]);
- }
-
- #[test]
- fn test_select() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let mut timeout = TimeVal::seconds(10);
- assert_eq!(
- 1,
- select(None, &mut fd_set, None, None, &mut timeout).unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
- }
-
- #[test]
- fn test_select_nfds() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let mut timeout = TimeVal::seconds(10);
- assert_eq!(
- 1,
- select(
- Some(fd_set.highest().unwrap() + 1),
- &mut fd_set,
- None,
- None,
- &mut timeout
- )
- .unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
- }
-
- #[test]
- fn test_select_nfds2() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let mut timeout = TimeVal::seconds(10);
- assert_eq!(
- 1,
- select(
- ::std::cmp::max(r1, r2) + 1,
- &mut fd_set,
- None,
- None,
- &mut timeout
- )
- .unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
- }
-}
diff --git a/vendor/nix/src/sys/sendfile.rs b/vendor/nix/src/sys/sendfile.rs
deleted file mode 100644
index fb293a4e7..000000000
--- a/vendor/nix/src/sys/sendfile.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-//! Send data from a file to a socket, bypassing userland.
-
-use cfg_if::cfg_if;
-use std::os::unix::io::RawFd;
-use std::ptr;
-
-use libc::{self, off_t};
-
-use crate::errno::Errno;
-use crate::Result;
-
-/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`.
-///
-/// Returns a `Result` with the number of bytes written.
-///
-/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will
-/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified
-/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to
-/// the byte after the last byte copied.
-///
-/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket.
-///
-/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html)
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn sendfile(
- out_fd: RawFd,
- in_fd: RawFd,
- offset: Option<&mut off_t>,
- count: usize,
-) -> Result<usize> {
- let offset = offset
- .map(|offset| offset as *mut _)
- .unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::sendfile(out_fd, in_fd, offset, count) };
- Errno::result(ret).map(|r| r as usize)
-}
-
-/// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`.
-///
-/// Returns a `Result` with the number of bytes written.
-///
-/// If `offset` is `None`, `sendfile` will begin reading at the current offset of `in_fd`and will
-/// update the offset of `in_fd`. If `offset` is `Some`, `sendfile` will begin at the specified
-/// offset and will not update the offset of `in_fd`. Instead, it will mutate `offset` to point to
-/// the byte after the last byte copied.
-///
-/// `in_fd` must support `mmap`-like operations and therefore cannot be a socket.
-///
-/// For more information, see [the sendfile(2) man page.](https://man7.org/linux/man-pages/man2/sendfile.2.html)
-#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn sendfile64(
- out_fd: RawFd,
- in_fd: RawFd,
- offset: Option<&mut libc::off64_t>,
- count: usize,
-) -> Result<usize> {
- let offset = offset
- .map(|offset| offset as *mut _)
- .unwrap_or(ptr::null_mut());
- let ret = unsafe { libc::sendfile64(out_fd, in_fd, offset, count) };
- Errno::result(ret).map(|r| r as usize)
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos"))] {
- use std::io::IoSlice;
-
- #[derive(Clone, Debug)]
- struct SendfileHeaderTrailer<'a>(
- libc::sf_hdtr,
- Option<Vec<IoSlice<'a>>>,
- Option<Vec<IoSlice<'a>>>,
- );
-
- impl<'a> SendfileHeaderTrailer<'a> {
- fn new(
- headers: Option<&'a [&'a [u8]]>,
- trailers: Option<&'a [&'a [u8]]>
- ) -> SendfileHeaderTrailer<'a> {
- let header_iovecs: Option<Vec<IoSlice<'_>>> =
- headers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect());
- let trailer_iovecs: Option<Vec<IoSlice<'_>>> =
- trailers.map(|s| s.iter().map(|b| IoSlice::new(b)).collect());
- SendfileHeaderTrailer(
- libc::sf_hdtr {
- headers: {
- header_iovecs
- .as_ref()
- .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
- },
- hdr_cnt: header_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32,
- trailers: {
- trailer_iovecs
- .as_ref()
- .map_or(ptr::null(), |v| v.as_ptr()) as *mut libc::iovec
- },
- trl_cnt: trailer_iovecs.as_ref().map(|v| v.len()).unwrap_or(0) as i32
- },
- header_iovecs,
- trailer_iovecs,
- )
- }
- }
- }
-}
-
-cfg_if! {
- if #[cfg(target_os = "freebsd")] {
- use libc::c_int;
-
- libc_bitflags!{
- /// Configuration options for [`sendfile`.](fn.sendfile.html)
- pub struct SfFlags: c_int {
- /// Causes `sendfile` to return EBUSY instead of blocking when attempting to read a
- /// busy page.
- SF_NODISKIO;
- /// Causes `sendfile` to sleep until the network stack releases its reference to the
- /// VM pages read. When `sendfile` returns, the data is not guaranteed to have been
- /// sent, but it is safe to modify the file.
- SF_SYNC;
- /// Causes `sendfile` to cache exactly the number of pages specified in the
- /// `readahead` parameter, disabling caching heuristics.
- SF_USER_READAHEAD;
- /// Causes `sendfile` not to cache the data read.
- SF_NOCACHE;
- }
- }
-
- /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`.
- ///
- /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
- /// an error occurs.
- ///
- /// `in_fd` must describe a regular file or shared memory object. `out_sock` must describe a
- /// stream socket.
- ///
- /// If `offset` falls past the end of the file, the function returns success and zero bytes
- /// written.
- ///
- /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
- /// file (EOF).
- ///
- /// `headers` and `trailers` specify optional slices of byte slices to be sent before and
- /// after the data read from `in_fd`, respectively. The length of headers and trailers sent
- /// is included in the returned count of bytes written. The values of `offset` and `count`
- /// do not apply to headers or trailers.
- ///
- /// `readahead` specifies the minimum number of pages to cache in memory ahead of the page
- /// currently being sent.
- ///
- /// For more information, see
- /// [the sendfile(2) man page.](https://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2)
- #[allow(clippy::too_many_arguments)]
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
- offset: off_t,
- count: Option<usize>,
- headers: Option<&[&[u8]]>,
- trailers: Option<&[&[u8]]>,
- flags: SfFlags,
- readahead: u16
- ) -> (Result<()>, off_t) {
- // Readahead goes in upper 16 bits
- // Flags goes in lower 16 bits
- // see `man 2 sendfile`
- let ra32 = u32::from(readahead);
- let flags: u32 = (ra32 << 16) | (flags.bits() as u32);
- let mut bytes_sent: off_t = 0;
- let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
- let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
- let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
- offset,
- count.unwrap_or(0),
- hdtr_ptr as *mut libc::sf_hdtr,
- &mut bytes_sent as *mut off_t,
- flags as c_int)
- };
- (Errno::result(return_code).and(Ok(())), bytes_sent)
- }
- } else if #[cfg(target_os = "dragonfly")] {
- /// Read up to `count` bytes from `in_fd` starting at `offset` and write to `out_sock`.
- ///
- /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
- /// an error occurs.
- ///
- /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket.
- ///
- /// If `offset` falls past the end of the file, the function returns success and zero bytes
- /// written.
- ///
- /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
- /// file (EOF).
- ///
- /// `headers` and `trailers` specify optional slices of byte slices to be sent before and
- /// after the data read from `in_fd`, respectively. The length of headers and trailers sent
- /// is included in the returned count of bytes written. The values of `offset` and `count`
- /// do not apply to headers or trailers.
- ///
- /// For more information, see
- /// [the sendfile(2) man page.](https://leaf.dragonflybsd.org/cgi/web-man?command=sendfile&section=2)
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
- offset: off_t,
- count: Option<usize>,
- headers: Option<&[&[u8]]>,
- trailers: Option<&[&[u8]]>,
- ) -> (Result<()>, off_t) {
- let mut bytes_sent: off_t = 0;
- let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
- let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
- let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
- offset,
- count.unwrap_or(0),
- hdtr_ptr as *mut libc::sf_hdtr,
- &mut bytes_sent as *mut off_t,
- 0)
- };
- (Errno::result(return_code).and(Ok(())), bytes_sent)
- }
- } else if #[cfg(any(target_os = "ios", target_os = "macos"))] {
- /// Read bytes from `in_fd` starting at `offset` and write up to `count` bytes to
- /// `out_sock`.
- ///
- /// Returns a `Result` and a count of bytes written. Bytes written may be non-zero even if
- /// an error occurs.
- ///
- /// `in_fd` must describe a regular file. `out_sock` must describe a stream socket.
- ///
- /// If `offset` falls past the end of the file, the function returns success and zero bytes
- /// written.
- ///
- /// If `count` is `None` or 0, bytes will be read from `in_fd` until reaching the end of
- /// file (EOF).
- ///
- /// `hdtr` specifies an optional list of headers and trailers to be sent before and after
- /// the data read from `in_fd`, respectively. The length of headers and trailers sent is
- /// included in the returned count of bytes written. If any headers are specified and
- /// `count` is non-zero, the length of the headers will be counted in the limit of total
- /// bytes sent. Trailers do not count toward the limit of bytes sent and will always be sent
- /// regardless. The value of `offset` does not affect headers or trailers.
- ///
- /// For more information, see
- /// [the sendfile(2) man page.](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html)
- pub fn sendfile(
- in_fd: RawFd,
- out_sock: RawFd,
- offset: off_t,
- count: Option<off_t>,
- headers: Option<&[&[u8]]>,
- trailers: Option<&[&[u8]]>
- ) -> (Result<()>, off_t) {
- let mut len = count.unwrap_or(0);
- let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers));
- let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr);
- let return_code = unsafe {
- libc::sendfile(in_fd,
- out_sock,
- offset,
- &mut len as *mut off_t,
- hdtr_ptr as *mut libc::sf_hdtr,
- 0)
- };
- (Errno::result(return_code).and(Ok(())), len)
- }
- }
-}
diff --git a/vendor/nix/src/sys/signal.rs b/vendor/nix/src/sys/signal.rs
deleted file mode 100644
index d3746e609..000000000
--- a/vendor/nix/src/sys/signal.rs
+++ /dev/null
@@ -1,1348 +0,0 @@
-// Portions of this file are Copyright 2014 The Rust Project Developers.
-// See https://www.rust-lang.org/policies/licenses.
-
-//! Operating system signals.
-
-use crate::errno::Errno;
-use crate::{Error, Result};
-use cfg_if::cfg_if;
-use std::fmt;
-use std::mem;
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
-use std::os::unix::io::RawFd;
-use std::ptr;
-use std::str::FromStr;
-
-#[cfg(not(any(target_os = "openbsd", target_os = "redox")))]
-#[cfg(any(feature = "aio", feature = "signal"))]
-pub use self::sigevent::*;
-
-#[cfg(any(feature = "aio", feature = "process", feature = "signal"))]
-libc_enum! {
- /// Types of operating system signals
- // Currently there is only one definition of c_int in libc, as well as only one
- // type for signal constants.
- // We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately
- // this is not (yet) possible.
- #[repr(i32)]
- #[non_exhaustive]
- #[cfg_attr(docsrs, doc(cfg(any(feature = "aio", feature = "signal"))))]
- pub enum Signal {
- /// Hangup
- SIGHUP,
- /// Interrupt
- SIGINT,
- /// Quit
- SIGQUIT,
- /// Illegal instruction (not reset when caught)
- SIGILL,
- /// Trace trap (not reset when caught)
- SIGTRAP,
- /// Abort
- SIGABRT,
- /// Bus error
- SIGBUS,
- /// Floating point exception
- SIGFPE,
- /// Kill (cannot be caught or ignored)
- SIGKILL,
- /// User defined signal 1
- SIGUSR1,
- /// Segmentation violation
- SIGSEGV,
- /// User defined signal 2
- SIGUSR2,
- /// Write on a pipe with no one to read it
- SIGPIPE,
- /// Alarm clock
- SIGALRM,
- /// Software termination signal from kill
- SIGTERM,
- /// Stack fault (obsolete)
- #[cfg(all(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux"),
- not(any(target_arch = "mips", target_arch = "mips64",
- target_arch = "sparc64"))))]
- SIGSTKFLT,
- /// To parent on child stop or exit
- SIGCHLD,
- /// Continue a stopped process
- SIGCONT,
- /// Sendable stop signal not from tty
- SIGSTOP,
- /// Stop signal from tty
- SIGTSTP,
- /// To readers pgrp upon background tty read
- SIGTTIN,
- /// Like TTIN if (tp->t_local&LTOSTOP)
- SIGTTOU,
- /// Urgent condition on IO channel
- SIGURG,
- /// Exceeded CPU time limit
- SIGXCPU,
- /// Exceeded file size limit
- SIGXFSZ,
- /// Virtual time alarm
- SIGVTALRM,
- /// Profiling time alarm
- SIGPROF,
- /// Window size changes
- SIGWINCH,
- /// Input/output possible signal
- #[cfg(not(target_os = "haiku"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SIGIO,
- #[cfg(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Power failure imminent.
- SIGPWR,
- /// Bad system call
- SIGSYS,
- #[cfg(not(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux",
- target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Emulator trap
- SIGEMT,
- #[cfg(not(any(target_os = "android", target_os = "emscripten",
- target_os = "fuchsia", target_os = "linux",
- target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Information request
- SIGINFO,
- }
- impl TryFrom<i32>
-}
-
-#[cfg(feature = "signal")]
-impl FromStr for Signal {
- type Err = Error;
- fn from_str(s: &str) -> Result<Signal> {
- Ok(match s {
- "SIGHUP" => Signal::SIGHUP,
- "SIGINT" => Signal::SIGINT,
- "SIGQUIT" => Signal::SIGQUIT,
- "SIGILL" => Signal::SIGILL,
- "SIGTRAP" => Signal::SIGTRAP,
- "SIGABRT" => Signal::SIGABRT,
- "SIGBUS" => Signal::SIGBUS,
- "SIGFPE" => Signal::SIGFPE,
- "SIGKILL" => Signal::SIGKILL,
- "SIGUSR1" => Signal::SIGUSR1,
- "SIGSEGV" => Signal::SIGSEGV,
- "SIGUSR2" => Signal::SIGUSR2,
- "SIGPIPE" => Signal::SIGPIPE,
- "SIGALRM" => Signal::SIGALRM,
- "SIGTERM" => Signal::SIGTERM,
- #[cfg(all(
- any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ),
- not(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "sparc64"
- ))
- ))]
- "SIGSTKFLT" => Signal::SIGSTKFLT,
- "SIGCHLD" => Signal::SIGCHLD,
- "SIGCONT" => Signal::SIGCONT,
- "SIGSTOP" => Signal::SIGSTOP,
- "SIGTSTP" => Signal::SIGTSTP,
- "SIGTTIN" => Signal::SIGTTIN,
- "SIGTTOU" => Signal::SIGTTOU,
- "SIGURG" => Signal::SIGURG,
- "SIGXCPU" => Signal::SIGXCPU,
- "SIGXFSZ" => Signal::SIGXFSZ,
- "SIGVTALRM" => Signal::SIGVTALRM,
- "SIGPROF" => Signal::SIGPROF,
- "SIGWINCH" => Signal::SIGWINCH,
- #[cfg(not(target_os = "haiku"))]
- "SIGIO" => Signal::SIGIO,
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- "SIGPWR" => Signal::SIGPWR,
- "SIGSYS" => Signal::SIGSYS,
- #[cfg(not(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux",
- target_os = "redox",
- target_os = "haiku"
- )))]
- "SIGEMT" => Signal::SIGEMT,
- #[cfg(not(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux",
- target_os = "redox",
- target_os = "haiku"
- )))]
- "SIGINFO" => Signal::SIGINFO,
- _ => return Err(Errno::EINVAL),
- })
- }
-}
-
-#[cfg(feature = "signal")]
-impl Signal {
- /// Returns name of signal.
- ///
- /// This function is equivalent to `<Signal as AsRef<str>>::as_ref()`,
- /// with difference that returned string is `'static`
- /// and not bound to `self`'s lifetime.
- pub const fn as_str(self) -> &'static str {
- match self {
- Signal::SIGHUP => "SIGHUP",
- Signal::SIGINT => "SIGINT",
- Signal::SIGQUIT => "SIGQUIT",
- Signal::SIGILL => "SIGILL",
- Signal::SIGTRAP => "SIGTRAP",
- Signal::SIGABRT => "SIGABRT",
- Signal::SIGBUS => "SIGBUS",
- Signal::SIGFPE => "SIGFPE",
- Signal::SIGKILL => "SIGKILL",
- Signal::SIGUSR1 => "SIGUSR1",
- Signal::SIGSEGV => "SIGSEGV",
- Signal::SIGUSR2 => "SIGUSR2",
- Signal::SIGPIPE => "SIGPIPE",
- Signal::SIGALRM => "SIGALRM",
- Signal::SIGTERM => "SIGTERM",
- #[cfg(all(
- any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ),
- not(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "sparc64"
- ))
- ))]
- Signal::SIGSTKFLT => "SIGSTKFLT",
- Signal::SIGCHLD => "SIGCHLD",
- Signal::SIGCONT => "SIGCONT",
- Signal::SIGSTOP => "SIGSTOP",
- Signal::SIGTSTP => "SIGTSTP",
- Signal::SIGTTIN => "SIGTTIN",
- Signal::SIGTTOU => "SIGTTOU",
- Signal::SIGURG => "SIGURG",
- Signal::SIGXCPU => "SIGXCPU",
- Signal::SIGXFSZ => "SIGXFSZ",
- Signal::SIGVTALRM => "SIGVTALRM",
- Signal::SIGPROF => "SIGPROF",
- Signal::SIGWINCH => "SIGWINCH",
- #[cfg(not(target_os = "haiku"))]
- Signal::SIGIO => "SIGIO",
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- Signal::SIGPWR => "SIGPWR",
- Signal::SIGSYS => "SIGSYS",
- #[cfg(not(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux",
- target_os = "redox",
- target_os = "haiku"
- )))]
- Signal::SIGEMT => "SIGEMT",
- #[cfg(not(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux",
- target_os = "redox",
- target_os = "haiku"
- )))]
- Signal::SIGINFO => "SIGINFO",
- }
- }
-}
-
-#[cfg(feature = "signal")]
-impl AsRef<str> for Signal {
- fn as_ref(&self) -> &str {
- self.as_str()
- }
-}
-
-#[cfg(feature = "signal")]
-impl fmt::Display for Signal {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str(self.as_ref())
- }
-}
-
-#[cfg(feature = "signal")]
-pub use self::Signal::*;
-
-#[cfg(target_os = "redox")]
-#[cfg(feature = "signal")]
-const SIGNALS: [Signal; 29] = [
- SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
- SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
- SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
- SIGPROF, SIGWINCH, SIGIO, SIGSYS,
-];
-#[cfg(target_os = "haiku")]
-#[cfg(feature = "signal")]
-const SIGNALS: [Signal; 28] = [
- SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
- SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
- SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
- SIGPROF, SIGWINCH, SIGSYS,
-];
-#[cfg(all(
- any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia"
- ),
- not(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "sparc64"
- ))
-))]
-#[cfg(feature = "signal")]
-const SIGNALS: [Signal; 31] = [
- SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
- SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGSTKFLT, SIGCHLD,
- SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ,
- SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS,
-];
-#[cfg(all(
- any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia"
- ),
- any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64")
-))]
-#[cfg(feature = "signal")]
-const SIGNALS: [Signal; 30] = [
- SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
- SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
- SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
- SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS,
-];
-#[cfg(not(any(
- target_os = "linux",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "emscripten",
- target_os = "redox",
- target_os = "haiku"
-)))]
-#[cfg(feature = "signal")]
-const SIGNALS: [Signal; 31] = [
- SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
- SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
- SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
- SIGPROF, SIGWINCH, SIGIO, SIGSYS, SIGEMT, SIGINFO,
-];
-
-feature! {
-#![feature = "signal"]
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-/// Iterate through all signals defined by this operating system
-pub struct SignalIterator {
- next: usize,
-}
-
-impl Iterator for SignalIterator {
- type Item = Signal;
-
- fn next(&mut self) -> Option<Signal> {
- if self.next < SIGNALS.len() {
- let next_signal = SIGNALS[self.next];
- self.next += 1;
- Some(next_signal)
- } else {
- None
- }
- }
-}
-
-impl Signal {
- /// Iterate through all signals defined by this OS
- pub const fn iterator() -> SignalIterator {
- SignalIterator{next: 0}
- }
-}
-
-/// Alias for [`SIGABRT`]
-pub const SIGIOT : Signal = SIGABRT;
-/// Alias for [`SIGIO`]
-#[cfg(not(target_os = "haiku"))]
-pub const SIGPOLL : Signal = SIGIO;
-/// Alias for [`SIGSYS`]
-pub const SIGUNUSED : Signal = SIGSYS;
-
-cfg_if! {
- if #[cfg(target_os = "redox")] {
- type SaFlags_t = libc::c_ulong;
- } else if #[cfg(target_env = "uclibc")] {
- type SaFlags_t = libc::c_ulong;
- } else {
- type SaFlags_t = libc::c_int;
- }
-}
-}
-
-#[cfg(feature = "signal")]
-libc_bitflags! {
- /// Controls the behavior of a [`SigAction`]
- #[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
- pub struct SaFlags: SaFlags_t {
- /// When catching a [`Signal::SIGCHLD`] signal, the signal will be
- /// generated only when a child process exits, not when a child process
- /// stops.
- SA_NOCLDSTOP;
- /// When catching a [`Signal::SIGCHLD`] signal, the system will not
- /// create zombie processes when children of the calling process exit.
- SA_NOCLDWAIT;
- /// Further occurrences of the delivered signal are not masked during
- /// the execution of the handler.
- SA_NODEFER;
- /// The system will deliver the signal to the process on a signal stack,
- /// specified by each thread with sigaltstack(2).
- SA_ONSTACK;
- /// The handler is reset back to the default at the moment the signal is
- /// delivered.
- SA_RESETHAND;
- /// Requests that certain system calls restart if interrupted by this
- /// signal. See the man page for complete details.
- SA_RESTART;
- /// This flag is controlled internally by Nix.
- SA_SIGINFO;
- }
-}
-
-#[cfg(feature = "signal")]
-libc_enum! {
- /// Specifies how certain functions should manipulate a signal mask
- #[repr(i32)]
- #[non_exhaustive]
- #[cfg_attr(docsrs, doc(cfg(feature = "signal")))]
- pub enum SigmaskHow {
- /// The new mask is the union of the current mask and the specified set.
- SIG_BLOCK,
- /// The new mask is the intersection of the current mask and the
- /// complement of the specified set.
- SIG_UNBLOCK,
- /// The current mask is replaced by the specified set.
- SIG_SETMASK,
- }
-}
-
-feature! {
-#![feature = "signal"]
-
-use crate::unistd::Pid;
-use std::iter::Extend;
-use std::iter::FromIterator;
-use std::iter::IntoIterator;
-
-/// Specifies a set of [`Signal`]s that may be blocked, waited for, etc.
-// We are using `transparent` here to be super sure that `SigSet`
-// is represented exactly like the `sigset_t` struct from C.
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct SigSet {
- sigset: libc::sigset_t
-}
-
-impl SigSet {
- /// Initialize to include all signals.
- #[doc(alias("sigfillset"))]
- pub fn all() -> SigSet {
- let mut sigset = mem::MaybeUninit::uninit();
- let _ = unsafe { libc::sigfillset(sigset.as_mut_ptr()) };
-
- unsafe{ SigSet { sigset: sigset.assume_init() } }
- }
-
- /// Initialize to include nothing.
- #[doc(alias("sigemptyset"))]
- pub fn empty() -> SigSet {
- let mut sigset = mem::MaybeUninit::uninit();
- let _ = unsafe { libc::sigemptyset(sigset.as_mut_ptr()) };
-
- unsafe{ SigSet { sigset: sigset.assume_init() } }
- }
-
- /// Add the specified signal to the set.
- #[doc(alias("sigaddset"))]
- pub fn add(&mut self, signal: Signal) {
- unsafe { libc::sigaddset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) };
- }
-
- /// Remove all signals from this set.
- #[doc(alias("sigemptyset"))]
- pub fn clear(&mut self) {
- unsafe { libc::sigemptyset(&mut self.sigset as *mut libc::sigset_t) };
- }
-
- /// Remove the specified signal from this set.
- #[doc(alias("sigdelset"))]
- pub fn remove(&mut self, signal: Signal) {
- unsafe { libc::sigdelset(&mut self.sigset as *mut libc::sigset_t, signal as libc::c_int) };
- }
-
- /// Return whether this set includes the specified signal.
- #[doc(alias("sigismember"))]
- pub fn contains(&self, signal: Signal) -> bool {
- let res = unsafe { libc::sigismember(&self.sigset as *const libc::sigset_t, signal as libc::c_int) };
-
- match res {
- 1 => true,
- 0 => false,
- _ => unreachable!("unexpected value from sigismember"),
- }
- }
-
- /// Returns an iterator that yields the signals contained in this set.
- pub fn iter(&self) -> SigSetIter<'_> {
- self.into_iter()
- }
-
- /// Gets the currently blocked (masked) set of signals for the calling thread.
- pub fn thread_get_mask() -> Result<SigSet> {
- let mut oldmask = mem::MaybeUninit::uninit();
- do_pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(oldmask.as_mut_ptr()))?;
- Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}})
- }
-
- /// Sets the set of signals as the signal mask for the calling thread.
- pub fn thread_set_mask(&self) -> Result<()> {
- pthread_sigmask(SigmaskHow::SIG_SETMASK, Some(self), None)
- }
-
- /// Adds the set of signals to the signal mask for the calling thread.
- pub fn thread_block(&self) -> Result<()> {
- pthread_sigmask(SigmaskHow::SIG_BLOCK, Some(self), None)
- }
-
- /// Removes the set of signals from the signal mask for the calling thread.
- pub fn thread_unblock(&self) -> Result<()> {
- pthread_sigmask(SigmaskHow::SIG_UNBLOCK, Some(self), None)
- }
-
- /// Sets the set of signals as the signal mask, and returns the old mask.
- pub fn thread_swap_mask(&self, how: SigmaskHow) -> Result<SigSet> {
- let mut oldmask = mem::MaybeUninit::uninit();
- do_pthread_sigmask(how, Some(self), Some(oldmask.as_mut_ptr()))?;
- Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}})
- }
-
- /// Suspends execution of the calling thread until one of the signals in the
- /// signal mask becomes pending, and returns the accepted signal.
- #[cfg(not(target_os = "redox"))] // RedoxFS does not yet support sigwait
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn wait(&self) -> Result<Signal> {
- use std::convert::TryFrom;
-
- let mut signum = mem::MaybeUninit::uninit();
- let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, signum.as_mut_ptr()) };
-
- Errno::result(res).map(|_| unsafe {
- Signal::try_from(signum.assume_init()).unwrap()
- })
- }
-
- /// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the
- /// `libc::sigset_t` is already initialized.
- ///
- /// # Safety
- ///
- /// The `sigset` passed in must be a valid an initialized `libc::sigset_t` by calling either
- /// [`sigemptyset(3)`](https://man7.org/linux/man-pages/man3/sigemptyset.3p.html) or
- /// [`sigfillset(3)`](https://man7.org/linux/man-pages/man3/sigfillset.3p.html).
- /// Otherwise, the results are undefined.
- pub unsafe fn from_sigset_t_unchecked(sigset: libc::sigset_t) -> SigSet {
- SigSet { sigset }
- }
-}
-
-impl AsRef<libc::sigset_t> for SigSet {
- fn as_ref(&self) -> &libc::sigset_t {
- &self.sigset
- }
-}
-
-// TODO: Consider specialization for the case where T is &SigSet and libc::sigorset is available.
-impl Extend<Signal> for SigSet {
- fn extend<T>(&mut self, iter: T)
- where T: IntoIterator<Item = Signal> {
- for signal in iter {
- self.add(signal);
- }
- }
-}
-
-impl FromIterator<Signal> for SigSet {
- fn from_iter<T>(iter: T) -> Self
- where T: IntoIterator<Item = Signal> {
- let mut sigset = SigSet::empty();
- sigset.extend(iter);
- sigset
- }
-}
-
-/// Iterator for a [`SigSet`].
-///
-/// Call [`SigSet::iter`] to create an iterator.
-#[derive(Clone, Debug)]
-pub struct SigSetIter<'a> {
- sigset: &'a SigSet,
- inner: SignalIterator,
-}
-
-impl Iterator for SigSetIter<'_> {
- type Item = Signal;
- fn next(&mut self) -> Option<Signal> {
- loop {
- match self.inner.next() {
- None => return None,
- Some(signal) if self.sigset.contains(signal) => return Some(signal),
- Some(_signal) => continue,
- }
- }
- }
-}
-
-impl<'a> IntoIterator for &'a SigSet {
- type Item = Signal;
- type IntoIter = SigSetIter<'a>;
- fn into_iter(self) -> Self::IntoIter {
- SigSetIter { sigset: self, inner: Signal::iterator() }
- }
-}
-
-/// A signal handler.
-#[allow(unknown_lints)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum SigHandler {
- /// Default signal handling.
- SigDfl,
- /// Request that the signal be ignored.
- SigIgn,
- /// Use the given signal-catching function, which takes in the signal.
- Handler(extern fn(libc::c_int)),
- /// Use the given signal-catching function, which takes in the signal, information about how
- /// the signal was generated, and a pointer to the threads `ucontext_t`.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SigAction(extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void))
-}
-
-/// Action to take on receipt of a signal. Corresponds to `sigaction`.
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct SigAction {
- sigaction: libc::sigaction
-}
-
-impl SigAction {
- /// Creates a new action.
- ///
- /// The `SA_SIGINFO` bit in the `flags` argument is ignored (it will be set only if `handler`
- /// is the `SigAction` variant). `mask` specifies other signals to block during execution of
- /// the signal-catching function.
- pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction {
- unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) {
- (*p).sa_sigaction = match handler {
- SigHandler::SigDfl => libc::SIG_DFL,
- SigHandler::SigIgn => libc::SIG_IGN,
- SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
- #[cfg(not(target_os = "redox"))]
- SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
- };
- }
-
- let mut s = mem::MaybeUninit::<libc::sigaction>::uninit();
- unsafe {
- let p = s.as_mut_ptr();
- install_sig(p, handler);
- (*p).sa_flags = match handler {
- #[cfg(not(target_os = "redox"))]
- SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(),
- _ => (flags - SaFlags::SA_SIGINFO).bits(),
- };
- (*p).sa_mask = mask.sigset;
-
- SigAction { sigaction: s.assume_init() }
- }
- }
-
- /// Returns the flags set on the action.
- pub fn flags(&self) -> SaFlags {
- SaFlags::from_bits_truncate(self.sigaction.sa_flags)
- }
-
- /// Returns the set of signals that are blocked during execution of the action's
- /// signal-catching function.
- pub fn mask(&self) -> SigSet {
- SigSet { sigset: self.sigaction.sa_mask }
- }
-
- /// Returns the action's handler.
- pub fn handler(&self) -> SigHandler {
- match self.sigaction.sa_sigaction {
- libc::SIG_DFL => SigHandler::SigDfl,
- libc::SIG_IGN => SigHandler::SigIgn,
- #[cfg(not(target_os = "redox"))]
- p if self.flags().contains(SaFlags::SA_SIGINFO) =>
- SigHandler::SigAction(
- // Safe for one of two reasons:
- // * The SigHandler was created by SigHandler::new, in which
- // case the pointer is correct, or
- // * The SigHandler was created by signal or sigaction, which
- // are unsafe functions, so the caller should've somehow
- // ensured that it is correctly initialized.
- unsafe{
- *(&p as *const usize
- as *const extern fn(_, _, _))
- }
- as extern fn(_, _, _)),
- p => SigHandler::Handler(
- // Safe for one of two reasons:
- // * The SigHandler was created by SigHandler::new, in which
- // case the pointer is correct, or
- // * The SigHandler was created by signal or sigaction, which
- // are unsafe functions, so the caller should've somehow
- // ensured that it is correctly initialized.
- unsafe{
- *(&p as *const usize
- as *const extern fn(libc::c_int))
- }
- as extern fn(libc::c_int)),
- }
- }
-}
-
-/// Changes the action taken by a process on receipt of a specific signal.
-///
-/// `signal` can be any signal except `SIGKILL` or `SIGSTOP`. On success, it returns the previous
-/// action for the given signal. If `sigaction` fails, no new signal handler is installed.
-///
-/// # Safety
-///
-/// * Signal handlers may be called at any point during execution, which limits
-/// what is safe to do in the body of the signal-catching function. Be certain
-/// to only make syscalls that are explicitly marked safe for signal handlers
-/// and only share global data using atomics.
-///
-/// * There is also no guarantee that the old signal handler was installed
-/// correctly. If it was installed by this crate, it will be. But if it was
-/// installed by, for example, C code, then there is no guarantee its function
-/// pointer is valid. In that case, this function effectively dereferences a
-/// raw pointer of unknown provenance.
-pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
- let mut oldact = mem::MaybeUninit::<libc::sigaction>::uninit();
-
- let res = libc::sigaction(signal as libc::c_int,
- &sigaction.sigaction as *const libc::sigaction,
- oldact.as_mut_ptr());
-
- Errno::result(res).map(|_| SigAction { sigaction: oldact.assume_init() })
-}
-
-/// Signal management (see [signal(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html))
-///
-/// Installs `handler` for the given `signal`, returning the previous signal
-/// handler. `signal` should only be used following another call to `signal` or
-/// if the current handler is the default. The return value of `signal` is
-/// undefined after setting the handler with [`sigaction`][SigActionFn].
-///
-/// # Safety
-///
-/// If the pointer to the previous signal handler is invalid, undefined
-/// behavior could be invoked when casting it back to a [`SigAction`][SigActionStruct].
-///
-/// # Examples
-///
-/// Ignore `SIGINT`:
-///
-/// ```no_run
-/// # use nix::sys::signal::{self, Signal, SigHandler};
-/// unsafe { signal::signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
-/// ```
-///
-/// Use a signal handler to set a flag variable:
-///
-/// ```no_run
-/// # #[macro_use] extern crate lazy_static;
-/// # use std::convert::TryFrom;
-/// # use std::sync::atomic::{AtomicBool, Ordering};
-/// # use nix::sys::signal::{self, Signal, SigHandler};
-/// lazy_static! {
-/// static ref SIGNALED: AtomicBool = AtomicBool::new(false);
-/// }
-///
-/// extern fn handle_sigint(signal: libc::c_int) {
-/// let signal = Signal::try_from(signal).unwrap();
-/// SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
-/// }
-///
-/// fn main() {
-/// let handler = SigHandler::Handler(handle_sigint);
-/// unsafe { signal::signal(Signal::SIGINT, handler) }.unwrap();
-/// }
-/// ```
-///
-/// # Errors
-///
-/// Returns [`Error(Errno::EOPNOTSUPP)`] if `handler` is
-/// [`SigAction`][SigActionStruct]. Use [`sigaction`][SigActionFn] instead.
-///
-/// `signal` also returns any error from `libc::signal`, such as when an attempt
-/// is made to catch a signal that cannot be caught or to ignore a signal that
-/// cannot be ignored.
-///
-/// [`Error::UnsupportedOperation`]: ../../enum.Error.html#variant.UnsupportedOperation
-/// [SigActionStruct]: struct.SigAction.html
-/// [sigactionFn]: fn.sigaction.html
-pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler> {
- let signal = signal as libc::c_int;
- let res = match handler {
- SigHandler::SigDfl => libc::signal(signal, libc::SIG_DFL),
- SigHandler::SigIgn => libc::signal(signal, libc::SIG_IGN),
- SigHandler::Handler(handler) => libc::signal(signal, handler as libc::sighandler_t),
- #[cfg(not(target_os = "redox"))]
- SigHandler::SigAction(_) => return Err(Errno::ENOTSUP),
- };
- Errno::result(res).map(|oldhandler| {
- match oldhandler {
- libc::SIG_DFL => SigHandler::SigDfl,
- libc::SIG_IGN => SigHandler::SigIgn,
- p => SigHandler::Handler(
- *(&p as *const usize
- as *const extern fn(libc::c_int))
- as extern fn(libc::c_int)),
- }
- })
-}
-
-fn do_pthread_sigmask(how: SigmaskHow,
- set: Option<&SigSet>,
- oldset: Option<*mut libc::sigset_t>) -> Result<()> {
- if set.is_none() && oldset.is_none() {
- return Ok(())
- }
-
- let res = unsafe {
- // if set or oldset is None, pass in null pointers instead
- libc::pthread_sigmask(how as libc::c_int,
- set.map_or_else(ptr::null::<libc::sigset_t>,
- |s| &s.sigset as *const libc::sigset_t),
- oldset.unwrap_or(ptr::null_mut())
- )
- };
-
- Errno::result(res).map(drop)
-}
-
-/// Manages the signal mask (set of blocked signals) for the calling thread.
-///
-/// If the `set` parameter is `Some(..)`, then the signal mask will be updated with the signal set.
-/// The `how` flag decides the type of update. If `set` is `None`, `how` will be ignored,
-/// and no modification will take place.
-///
-/// If the 'oldset' parameter is `Some(..)` then the current signal mask will be written into it.
-///
-/// If both `set` and `oldset` is `Some(..)`, the current signal mask will be written into oldset,
-/// and then it will be updated with `set`.
-///
-/// If both `set` and `oldset` is None, this function is a no-op.
-///
-/// For more information, visit the [`pthread_sigmask`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_sigmask.html),
-/// or [`sigprocmask`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages.
-pub fn pthread_sigmask(how: SigmaskHow,
- set: Option<&SigSet>,
- oldset: Option<&mut SigSet>) -> Result<()>
-{
- do_pthread_sigmask(how, set, oldset.map(|os| &mut os.sigset as *mut _ ))
-}
-
-/// Examine and change blocked signals.
-///
-/// For more information see the [`sigprocmask` man
-/// pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html).
-pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut SigSet>) -> Result<()> {
- if set.is_none() && oldset.is_none() {
- return Ok(())
- }
-
- let res = unsafe {
- // if set or oldset is None, pass in null pointers instead
- libc::sigprocmask(how as libc::c_int,
- set.map_or_else(ptr::null::<libc::sigset_t>,
- |s| &s.sigset as *const libc::sigset_t),
- oldset.map_or_else(ptr::null_mut::<libc::sigset_t>,
- |os| &mut os.sigset as *mut libc::sigset_t))
- };
-
- Errno::result(res).map(drop)
-}
-
-/// Send a signal to a process
-///
-/// # Arguments
-///
-/// * `pid` - Specifies which processes should receive the signal.
-/// - If positive, specifies an individual process.
-/// - If zero, the signal will be sent to all processes whose group
-/// ID is equal to the process group ID of the sender. This is a
-#[cfg_attr(target_os = "fuchsia", doc = "variant of `killpg`.")]
-#[cfg_attr(not(target_os = "fuchsia"), doc = "variant of [`killpg`].")]
-/// - If `-1` and the process has super-user privileges, the signal
-/// is sent to all processes exclusing system processes.
-/// - If less than `-1`, the signal is sent to all processes whose
-/// process group ID is equal to the absolute value of `pid`.
-/// * `signal` - Signal to send. If `None`, error checking is performed
-/// but no signal is actually sent.
-///
-/// See Also
-/// [`kill(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html)
-pub fn kill<T: Into<Option<Signal>>>(pid: Pid, signal: T) -> Result<()> {
- let res = unsafe { libc::kill(pid.into(),
- match signal.into() {
- Some(s) => s as libc::c_int,
- None => 0,
- }) };
-
- Errno::result(res).map(drop)
-}
-
-/// Send a signal to a process group
-///
-/// # Arguments
-///
-/// * `pgrp` - Process group to signal. If less then or equal 1, the behavior
-/// is platform-specific.
-/// * `signal` - Signal to send. If `None`, `killpg` will only preform error
-/// checking and won't send any signal.
-///
-/// See Also [killpg(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/killpg.html).
-#[cfg(not(target_os = "fuchsia"))]
-pub fn killpg<T: Into<Option<Signal>>>(pgrp: Pid, signal: T) -> Result<()> {
- let res = unsafe { libc::killpg(pgrp.into(),
- match signal.into() {
- Some(s) => s as libc::c_int,
- None => 0,
- }) };
-
- Errno::result(res).map(drop)
-}
-
-/// Send a signal to the current thread
-///
-/// See Also [raise(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html)
-pub fn raise(signal: Signal) -> Result<()> {
- let res = unsafe { libc::raise(signal as libc::c_int) };
-
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![any(feature = "aio", feature = "signal")]
-
-/// Identifies a thread for [`SigevNotify::SigevThreadId`]
-#[cfg(target_os = "freebsd")]
-pub type type_of_thread_id = libc::lwpid_t;
-/// Identifies a thread for [`SigevNotify::SigevThreadId`]
-#[cfg(target_os = "linux")]
-pub type type_of_thread_id = libc::pid_t;
-
-/// Specifies the notification method used by a [`SigEvent`]
-// sigval is actually a union of a int and a void*. But it's never really used
-// as a pointer, because neither libc nor the kernel ever dereference it. nix
-// therefore presents it as an intptr_t, which is how kevent uses it.
-#[cfg(not(any(target_os = "openbsd", target_os = "redox")))]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum SigevNotify {
- /// No notification will be delivered
- SigevNone,
- /// Notify by delivering a signal to the process.
- SigevSignal {
- /// Signal to deliver
- signal: Signal,
- /// Will be present in the `si_value` field of the [`libc::siginfo_t`]
- /// structure of the queued signal.
- si_value: libc::intptr_t
- },
- // Note: SIGEV_THREAD is not implemented because libc::sigevent does not
- // expose a way to set the union members needed by SIGEV_THREAD.
- /// Notify by delivering an event to a kqueue.
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SigevKevent {
- /// File descriptor of the kqueue to notify.
- kq: RawFd,
- /// Will be contained in the kevent's `udata` field.
- udata: libc::intptr_t
- },
- /// Notify by delivering a signal to a thread.
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SigevThreadId {
- /// Signal to send
- signal: Signal,
- /// LWP ID of the thread to notify
- thread_id: type_of_thread_id,
- /// Will be present in the `si_value` field of the [`libc::siginfo_t`]
- /// structure of the queued signal.
- si_value: libc::intptr_t
- },
-}
-}
-
-#[cfg(not(any(target_os = "openbsd", target_os = "redox")))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod sigevent {
- feature! {
- #![any(feature = "aio", feature = "signal")]
-
- use std::mem;
- use std::ptr;
- use super::SigevNotify;
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- use super::type_of_thread_id;
-
- /// Used to request asynchronous notification of the completion of certain
- /// events, such as POSIX AIO and timers.
- #[repr(C)]
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- pub struct SigEvent {
- sigevent: libc::sigevent
- }
-
- impl SigEvent {
- /// **Note:** this constructor does not allow the user to set the
- /// `sigev_notify_kevent_flags` field. That's considered ok because on FreeBSD
- /// at least those flags don't do anything useful. That field is part of a
- /// union that shares space with the more genuinely useful fields.
- ///
- /// **Note:** This constructor also doesn't allow the caller to set the
- /// `sigev_notify_function` or `sigev_notify_attributes` fields, which are
- /// required for `SIGEV_THREAD`. That's considered ok because on no operating
- /// system is `SIGEV_THREAD` the most efficient way to deliver AIO
- /// notification. FreeBSD and DragonFly BSD programs should prefer `SIGEV_KEVENT`.
- /// Linux, Solaris, and portable programs should prefer `SIGEV_THREAD_ID` or
- /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the
- /// more genuinely useful `sigev_notify_thread_id`
- // Allow invalid_value warning on Fuchsia only.
- // See https://github.com/nix-rust/nix/issues/1441
- #[cfg_attr(target_os = "fuchsia", allow(invalid_value))]
- pub fn new(sigev_notify: SigevNotify) -> SigEvent {
- let mut sev = unsafe { mem::MaybeUninit::<libc::sigevent>::zeroed().assume_init() };
- sev.sigev_notify = match sigev_notify {
- SigevNotify::SigevNone => libc::SIGEV_NONE,
- SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL,
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT,
- #[cfg(target_os = "freebsd")]
- SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
- #[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))]
- SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
- #[cfg(all(target_os = "linux", target_env = "uclibc"))]
- SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
- #[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
- SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
- };
- sev.sigev_signo = match sigev_notify {
- SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- SigevNotify::SigevKevent{ kq, ..} => kq,
- #[cfg(any(target_os = "linux", target_os = "freebsd"))]
- SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
- _ => 0
- };
- sev.sigev_value.sival_ptr = match sigev_notify {
- SigevNotify::SigevNone => ptr::null_mut::<libc::c_void>(),
- SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void,
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
- };
- SigEvent::set_tid(&mut sev, &sigev_notify);
- SigEvent{sigevent: sev}
- }
-
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) {
- sev.sigev_notify_thread_id = match *sigev_notify {
- SigevNotify::SigevThreadId { thread_id, .. } => thread_id,
- _ => 0 as type_of_thread_id
- };
- }
-
- #[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
- fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) {
- }
-
- /// Return a copy of the inner structure
- pub fn sigevent(&self) -> libc::sigevent {
- self.sigevent
- }
-
- /// Returns a mutable pointer to the `sigevent` wrapped by `self`
- pub fn as_mut_ptr(&mut self) -> *mut libc::sigevent {
- &mut self.sigevent
- }
- }
-
- impl<'a> From<&'a libc::sigevent> for SigEvent {
- fn from(sigevent: &libc::sigevent) -> Self {
- SigEvent{ sigevent: *sigevent }
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[cfg(not(target_os = "redox"))]
- use std::thread;
-
- #[test]
- fn test_contains() {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- assert!(mask.contains(SIGUSR1));
- assert!(!mask.contains(SIGUSR2));
-
- let all = SigSet::all();
- assert!(all.contains(SIGUSR1));
- assert!(all.contains(SIGUSR2));
- }
-
- #[test]
- fn test_clear() {
- let mut set = SigSet::all();
- set.clear();
- for signal in Signal::iterator() {
- assert!(!set.contains(signal));
- }
- }
-
- #[test]
- fn test_from_str_round_trips() {
- for signal in Signal::iterator() {
- assert_eq!(signal.as_ref().parse::<Signal>().unwrap(), signal);
- assert_eq!(signal.to_string().parse::<Signal>().unwrap(), signal);
- }
- }
-
- #[test]
- fn test_from_str_invalid_value() {
- let errval = Err(Errno::EINVAL);
- assert_eq!("NOSIGNAL".parse::<Signal>(), errval);
- assert_eq!("kill".parse::<Signal>(), errval);
- assert_eq!("9".parse::<Signal>(), errval);
- }
-
- #[test]
- fn test_extend() {
- let mut one_signal = SigSet::empty();
- one_signal.add(SIGUSR1);
-
- let mut two_signals = SigSet::empty();
- two_signals.add(SIGUSR2);
- two_signals.extend(&one_signal);
-
- assert!(two_signals.contains(SIGUSR1));
- assert!(two_signals.contains(SIGUSR2));
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_set_mask() {
- thread::spawn(|| {
- let prev_mask = SigSet::thread_get_mask()
- .expect("Failed to get existing signal mask!");
-
- let mut test_mask = prev_mask;
- test_mask.add(SIGUSR1);
-
- test_mask.thread_set_mask().expect("assertion failed");
- let new_mask =
- SigSet::thread_get_mask().expect("Failed to get new mask!");
-
- assert!(new_mask.contains(SIGUSR1));
- assert!(!new_mask.contains(SIGUSR2));
-
- prev_mask
- .thread_set_mask()
- .expect("Failed to revert signal mask!");
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_block() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- mask.thread_block().expect("assertion failed");
-
- assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_unblock() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- mask.thread_unblock().expect("assertion failed");
-
- assert!(!SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_thread_signal_swap() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
- mask.thread_block().unwrap();
-
- assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR1));
-
- let mut mask2 = SigSet::empty();
- mask2.add(SIGUSR2);
-
- let oldmask =
- mask2.thread_swap_mask(SigmaskHow::SIG_SETMASK).unwrap();
-
- assert!(oldmask.contains(SIGUSR1));
- assert!(!oldmask.contains(SIGUSR2));
-
- assert!(SigSet::thread_get_mask().unwrap().contains(SIGUSR2));
- })
- .join()
- .unwrap();
- }
-
- #[test]
- fn test_from_and_into_iterator() {
- let sigset = SigSet::from_iter(vec![Signal::SIGUSR1, Signal::SIGUSR2]);
- let signals = sigset.into_iter().collect::<Vec<Signal>>();
- assert_eq!(signals, [Signal::SIGUSR1, Signal::SIGUSR2]);
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_sigaction() {
- thread::spawn(|| {
- extern "C" fn test_sigaction_handler(_: libc::c_int) {}
- extern "C" fn test_sigaction_action(
- _: libc::c_int,
- _: *mut libc::siginfo_t,
- _: *mut libc::c_void,
- ) {
- }
-
- let handler_sig = SigHandler::Handler(test_sigaction_handler);
-
- let flags =
- SaFlags::SA_ONSTACK | SaFlags::SA_RESTART | SaFlags::SA_SIGINFO;
-
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
-
- let action_sig = SigAction::new(handler_sig, flags, mask);
-
- assert_eq!(
- action_sig.flags(),
- SaFlags::SA_ONSTACK | SaFlags::SA_RESTART
- );
- assert_eq!(action_sig.handler(), handler_sig);
-
- mask = action_sig.mask();
- assert!(mask.contains(SIGUSR1));
- assert!(!mask.contains(SIGUSR2));
-
- let handler_act = SigHandler::SigAction(test_sigaction_action);
- let action_act = SigAction::new(handler_act, flags, mask);
- assert_eq!(action_act.handler(), handler_act);
-
- let action_dfl = SigAction::new(SigHandler::SigDfl, flags, mask);
- assert_eq!(action_dfl.handler(), SigHandler::SigDfl);
-
- let action_ign = SigAction::new(SigHandler::SigIgn, flags, mask);
- assert_eq!(action_ign.handler(), SigHandler::SigIgn);
- })
- .join()
- .unwrap();
- }
-
- #[test]
- #[cfg(not(target_os = "redox"))]
- fn test_sigwait() {
- thread::spawn(|| {
- let mut mask = SigSet::empty();
- mask.add(SIGUSR1);
- mask.add(SIGUSR2);
- mask.thread_block().unwrap();
-
- raise(SIGUSR1).unwrap();
- assert_eq!(mask.wait().unwrap(), SIGUSR1);
- })
- .join()
- .unwrap();
- }
-
- #[test]
- fn test_from_sigset_t_unchecked() {
- let src_set = SigSet::empty();
- let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) };
-
- for signal in Signal::iterator() {
- assert!(!set.contains(signal));
- }
-
- let src_set = SigSet::all();
- let set = unsafe { SigSet::from_sigset_t_unchecked(src_set.sigset) };
-
- for signal in Signal::iterator() {
- assert!(set.contains(signal));
- }
- }
-}
diff --git a/vendor/nix/src/sys/signalfd.rs b/vendor/nix/src/sys/signalfd.rs
deleted file mode 100644
index 095e59085..000000000
--- a/vendor/nix/src/sys/signalfd.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-//! Interface for the `signalfd` syscall.
-//!
-//! # Signal discarding
-//! When a signal can't be delivered to a process (or thread), it will become a pending signal.
-//! Failure to deliver could happen if the signal is blocked by every thread in the process or if
-//! the signal handler is still handling a previous signal.
-//!
-//! If a signal is sent to a process (or thread) that already has a pending signal of the same
-//! type, it will be discarded. This means that if signals of the same type are received faster than
-//! they are processed, some of those signals will be dropped. Because of this limitation,
-//! `signalfd` in itself cannot be used for reliable communication between processes or threads.
-//!
-//! Once the signal is unblocked, or the signal handler is finished, and a signal is still pending
-//! (ie. not consumed from a signalfd) it will be delivered to the signal handler.
-//!
-//! Please note that signal discarding is not specific to `signalfd`, but also happens with regular
-//! signal handlers.
-use crate::errno::Errno;
-pub use crate::sys::signal::{self, SigSet};
-use crate::unistd;
-use crate::Result;
-pub use libc::signalfd_siginfo as siginfo;
-
-use std::mem;
-use std::os::unix::io::{AsRawFd, RawFd};
-
-libc_bitflags! {
- pub struct SfdFlags: libc::c_int {
- SFD_NONBLOCK;
- SFD_CLOEXEC;
- }
-}
-
-pub const SIGNALFD_NEW: RawFd = -1;
-#[deprecated(since = "0.23.0", note = "use mem::size_of::<siginfo>() instead")]
-pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();
-
-/// Creates a new file descriptor for reading signals.
-///
-/// **Important:** please read the module level documentation about signal discarding before using
-/// this function!
-///
-/// The `mask` parameter specifies the set of signals that can be accepted via this file descriptor.
-///
-/// A signal must be blocked on every thread in a process, otherwise it won't be visible from
-/// signalfd (the default handler will be invoked instead).
-///
-/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
-pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
- unsafe {
- Errno::result(libc::signalfd(
- fd as libc::c_int,
- mask.as_ref(),
- flags.bits(),
- ))
- }
-}
-
-/// A helper struct for creating, reading and closing a `signalfd` instance.
-///
-/// **Important:** please read the module level documentation about signal discarding before using
-/// this struct!
-///
-/// # Examples
-///
-/// ```
-/// # use nix::sys::signalfd::*;
-/// // Set the thread to block the SIGUSR1 signal, otherwise the default handler will be used
-/// let mut mask = SigSet::empty();
-/// mask.add(signal::SIGUSR1);
-/// mask.thread_block().unwrap();
-///
-/// // Signals are queued up on the file descriptor
-/// let mut sfd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
-///
-/// match sfd.read_signal() {
-/// // we caught a signal
-/// Ok(Some(sig)) => (),
-/// // there were no signals waiting (only happens when the SFD_NONBLOCK flag is set,
-/// // otherwise the read_signal call blocks)
-/// Ok(None) => (),
-/// Err(err) => (), // some error happend
-/// }
-/// ```
-#[derive(Debug, Eq, Hash, PartialEq)]
-pub struct SignalFd(RawFd);
-
-impl SignalFd {
- pub fn new(mask: &SigSet) -> Result<SignalFd> {
- Self::with_flags(mask, SfdFlags::empty())
- }
-
- pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result<SignalFd> {
- let fd = signalfd(SIGNALFD_NEW, mask, flags)?;
-
- Ok(SignalFd(fd))
- }
-
- pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
- signalfd(self.0, mask, SfdFlags::empty()).map(drop)
- }
-
- pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
- let mut buffer = mem::MaybeUninit::<siginfo>::uninit();
-
- let size = mem::size_of_val(&buffer);
- let res = Errno::result(unsafe {
- libc::read(self.0, buffer.as_mut_ptr() as *mut libc::c_void, size)
- })
- .map(|r| r as usize);
- match res {
- Ok(x) if x == size => Ok(Some(unsafe { buffer.assume_init() })),
- Ok(_) => unreachable!("partial read on signalfd"),
- Err(Errno::EAGAIN) => Ok(None),
- Err(error) => Err(error),
- }
- }
-}
-
-impl Drop for SignalFd {
- fn drop(&mut self) {
- let e = unistd::close(self.0);
- if !std::thread::panicking() && e == Err(Errno::EBADF) {
- panic!("Closing an invalid file descriptor!");
- };
- }
-}
-
-impl AsRawFd for SignalFd {
- fn as_raw_fd(&self) -> RawFd {
- self.0
- }
-}
-
-impl Iterator for SignalFd {
- type Item = siginfo;
-
- fn next(&mut self) -> Option<Self::Item> {
- match self.read_signal() {
- Ok(Some(sig)) => Some(sig),
- Ok(None) | Err(_) => None,
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn create_signalfd() {
- let mask = SigSet::empty();
- SignalFd::new(&mask).unwrap();
- }
-
- #[test]
- fn create_signalfd_with_opts() {
- let mask = SigSet::empty();
- SignalFd::with_flags(
- &mask,
- SfdFlags::SFD_CLOEXEC | SfdFlags::SFD_NONBLOCK,
- )
- .unwrap();
- }
-
- #[test]
- fn read_empty_signalfd() {
- let mask = SigSet::empty();
- let mut fd =
- SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
-
- let res = fd.read_signal();
- assert!(res.unwrap().is_none());
- }
-}
diff --git a/vendor/nix/src/sys/socket/addr.rs b/vendor/nix/src/sys/socket/addr.rs
deleted file mode 100644
index 4e565a5b6..000000000
--- a/vendor/nix/src/sys/socket/addr.rs
+++ /dev/null
@@ -1,3247 +0,0 @@
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "haiku",
- target_os = "fuchsia"
-))]
-#[cfg(feature = "net")]
-pub use self::datalink::LinkAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use self::vsock::VsockAddr;
-use super::sa_family_t;
-use crate::errno::Errno;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use crate::sys::socket::addr::alg::AlgAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use crate::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
-))]
-use crate::sys::socket::addr::sys_control::SysControlAddr;
-use crate::{NixPath, Result};
-use cfg_if::cfg_if;
-use memoffset::offset_of;
-use std::convert::TryInto;
-use std::ffi::OsStr;
-use std::hash::{Hash, Hasher};
-use std::os::unix::ffi::OsStrExt;
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-use std::os::unix::io::RawFd;
-use std::path::Path;
-use std::{fmt, mem, net, ptr, slice};
-
-/// Convert a std::net::Ipv4Addr into the libc form.
-#[cfg(feature = "net")]
-pub(crate) const fn ipv4addr_to_libc(addr: net::Ipv4Addr) -> libc::in_addr {
- static_assertions::assert_eq_size!(net::Ipv4Addr, libc::in_addr);
- // Safe because both types have the same memory layout, and no fancy Drop
- // impls.
- unsafe {
- mem::transmute(addr)
- }
-}
-
-/// Convert a std::net::Ipv6Addr into the libc form.
-#[cfg(feature = "net")]
-pub(crate) const fn ipv6addr_to_libc(addr: &net::Ipv6Addr) -> libc::in6_addr {
- static_assertions::assert_eq_size!(net::Ipv6Addr, libc::in6_addr);
- // Safe because both are Newtype wrappers around the same libc type
- unsafe {
- mem::transmute(*addr)
- }
-}
-
-/// These constants specify the protocol family to be used
-/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
-///
-/// # References
-///
-/// [address_families(7)](https://man7.org/linux/man-pages/man7/address_families.7.html)
-// Should this be u8?
-#[repr(i32)]
-#[non_exhaustive]
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
-pub enum AddressFamily {
- /// Local communication (see [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html))
- Unix = libc::AF_UNIX,
- /// IPv4 Internet protocols (see [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html))
- Inet = libc::AF_INET,
- /// IPv6 Internet protocols (see [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html))
- Inet6 = libc::AF_INET6,
- /// Kernel user interface device (see [`netlink(7)`](https://man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Netlink = libc::AF_NETLINK,
- /// Low level packet interface (see [`packet(7)`](https://man7.org/linux/man-pages/man7/packet.7.html))
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "illumos",
- target_os = "fuchsia",
- target_os = "solaris"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Packet = libc::AF_PACKET,
- /// KEXT Controls and Notifications
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- System = libc::AF_SYSTEM,
- /// Amateur radio AX.25 protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Ax25 = libc::AF_AX25,
- /// IPX - Novell protocols
- Ipx = libc::AF_IPX,
- /// AppleTalk
- AppleTalk = libc::AF_APPLETALK,
- /// AX.25 packet layer protocol.
- /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetRom = libc::AF_NETROM,
- /// Can't be used for creating sockets; mostly used for bridge
- /// links in
- /// [rtnetlink(7)](https://man7.org/linux/man-pages/man7/rtnetlink.7.html)
- /// protocol commands.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Bridge = libc::AF_BRIDGE,
- /// Access to raw ATM PVCs
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AtmPvc = libc::AF_ATMPVC,
- /// ITU-T X.25 / ISO-8208 protocol (see [`x25(7)`](https://man7.org/linux/man-pages/man7/x25.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- X25 = libc::AF_X25,
- /// RATS (Radio Amateur Telecommunications Society) Open
- /// Systems environment (ROSE) AX.25 packet layer protocol.
- /// (see [netrom(4)](https://www.unix.com/man-page/linux/4/netrom/))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Rose = libc::AF_ROSE,
- /// DECet protocol sockets.
- #[cfg(not(target_os = "haiku"))]
- Decnet = libc::AF_DECnet,
- /// Reserved for "802.2LLC project"; never used.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetBeui = libc::AF_NETBEUI,
- /// This was a short-lived (between Linux 2.1.30 and
- /// 2.1.99pre2) protocol family for firewall upcalls.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Security = libc::AF_SECURITY,
- /// Key management protocol.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Key = libc::AF_KEY,
- #[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Ash = libc::AF_ASH,
- /// Acorn Econet protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Econet = libc::AF_ECONET,
- /// Access to ATM Switched Virtual Circuits
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AtmSvc = libc::AF_ATMSVC,
- /// Reliable Datagram Sockets (RDS) protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Rds = libc::AF_RDS,
- /// IBM SNA
- #[cfg(not(target_os = "haiku"))]
- Sna = libc::AF_SNA,
- /// Socket interface over IrDA
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Irda = libc::AF_IRDA,
- /// Generic PPP transport layer, for setting up L2 tunnels (L2TP and PPPoE)
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Pppox = libc::AF_PPPOX,
- /// Legacy protocol for wide area network (WAN) connectivity that was used
- /// by Sangoma WAN cards
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Wanpipe = libc::AF_WANPIPE,
- /// Logical link control (IEEE 802.2 LLC) protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Llc = libc::AF_LLC,
- /// InfiniBand native addressing
- #[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Ib = libc::AF_IB,
- /// Multiprotocol Label Switching
- #[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Mpls = libc::AF_MPLS,
- /// Controller Area Network automotive bus protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Can = libc::AF_CAN,
- /// TIPC, "cluster domain sockets" protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Tipc = libc::AF_TIPC,
- /// Bluetooth low-level socket protocol
- #[cfg(not(any(
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "solaris"
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Bluetooth = libc::AF_BLUETOOTH,
- /// IUCV (inter-user communication vehicle) z/VM protocol for
- /// hypervisor-guest interaction
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Iucv = libc::AF_IUCV,
- /// Rx, Andrew File System remote procedure call protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- RxRpc = libc::AF_RXRPC,
- /// New "modular ISDN" driver interface protocol
- #[cfg(not(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Isdn = libc::AF_ISDN,
- /// Nokia cellular modem IPC/RPC interface
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Phonet = libc::AF_PHONET,
- /// IEEE 802.15.4 WPAN (wireless personal area network) raw packet protocol
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Ieee802154 = libc::AF_IEEE802154,
- /// Ericsson's Communication CPU to Application CPU interface (CAIF)
- /// protocol.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Caif = libc::AF_CAIF,
- /// Interface to kernel crypto API
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Alg = libc::AF_ALG,
- /// Near field communication
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Nfc = libc::AF_NFC,
- /// VMWare VSockets protocol for hypervisor-guest interaction.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Vsock = libc::AF_VSOCK,
- /// ARPANet IMP addresses
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ImpLink = libc::AF_IMPLINK,
- /// PUP protocols, e.g. BSP
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Pup = libc::AF_PUP,
- /// MIT CHAOS protocols
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Chaos = libc::AF_CHAOS,
- /// Novell and Xerox protocol
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Ns = libc::AF_NS,
- #[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Iso = libc::AF_ISO,
- /// Bell Labs virtual circuit switch ?
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Datakit = libc::AF_DATAKIT,
- /// CCITT protocols, X.25 etc
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Ccitt = libc::AF_CCITT,
- /// DEC Direct data link interface
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Dli = libc::AF_DLI,
- #[allow(missing_docs)] // Not documented anywhere that I can find
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Lat = libc::AF_LAT,
- /// NSC Hyperchannel
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Hylink = libc::AF_HYLINK,
- /// Link layer interface
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Link = libc::AF_LINK,
- /// connection-oriented IP, aka ST II
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Coip = libc::AF_COIP,
- /// Computer Network Technology
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Cnt = libc::AF_CNT,
- /// Native ATM access
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Natm = libc::AF_NATM,
- /// Unspecified address family, (see [`getaddrinfo(3)`](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Unspec = libc::AF_UNSPEC,
-}
-
-impl AddressFamily {
- /// Create a new `AddressFamily` from an integer value retrieved from `libc`, usually from
- /// the `sa_family` field of a `sockaddr`.
- ///
- /// Currently only supports these address families: Unix, Inet (v4 & v6), Netlink, Link/Packet
- /// and System. Returns None for unsupported or unknown address families.
- pub const fn from_i32(family: i32) -> Option<AddressFamily> {
- match family {
- libc::AF_UNIX => Some(AddressFamily::Unix),
- libc::AF_INET => Some(AddressFamily::Inet),
- libc::AF_INET6 => Some(AddressFamily::Inet6),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => Some(AddressFamily::Netlink),
- #[cfg(any(target_os = "macos", target_os = "macos"))]
- libc::AF_SYSTEM => Some(AddressFamily::System),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_PACKET => Some(AddressFamily::Packet),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
- ))]
- libc::AF_LINK => Some(AddressFamily::Link),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_VSOCK => Some(AddressFamily::Vsock),
- _ => None,
- }
- }
-}
-
-feature! {
-#![feature = "net"]
-
-#[deprecated(
- since = "0.24.0",
- note = "use SockaddrIn, SockaddrIn6, or SockaddrStorage instead"
-)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum InetAddr {
- V4(libc::sockaddr_in),
- V6(libc::sockaddr_in6),
-}
-
-#[allow(missing_docs)] // It's deprecated anyway
-#[allow(deprecated)]
-impl InetAddr {
- #[allow(clippy::needless_update)] // It isn't needless on all OSes
- pub fn from_std(std: &net::SocketAddr) -> InetAddr {
- match *std {
- net::SocketAddr::V4(ref addr) => {
- InetAddr::V4(libc::sockaddr_in {
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
- target_os = "haiku", target_os = "hermit",
- target_os = "ios", target_os = "macos",
- target_os = "netbsd", target_os = "openbsd"))]
- sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
- sin_family: AddressFamily::Inet as sa_family_t,
- sin_port: addr.port().to_be(), // network byte order
- sin_addr: Ipv4Addr::from_std(addr.ip()).0,
- .. unsafe { mem::zeroed() }
- })
- }
- net::SocketAddr::V6(ref addr) => {
- InetAddr::V6(libc::sockaddr_in6 {
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
- target_os = "haiku", target_os = "hermit",
- target_os = "ios", target_os = "macos",
- target_os = "netbsd", target_os = "openbsd"))]
- sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8,
- sin6_family: AddressFamily::Inet6 as sa_family_t,
- sin6_port: addr.port().to_be(), // network byte order
- sin6_addr: Ipv6Addr::from_std(addr.ip()).0,
- sin6_flowinfo: addr.flowinfo(), // host byte order
- sin6_scope_id: addr.scope_id(), // host byte order
- .. unsafe { mem::zeroed() }
- })
- }
- }
- }
-
- #[allow(clippy::needless_update)] // It isn't needless on all OSes
- pub fn new(ip: IpAddr, port: u16) -> InetAddr {
- match ip {
- IpAddr::V4(ref ip) => {
- InetAddr::V4(libc::sockaddr_in {
- sin_family: AddressFamily::Inet as sa_family_t,
- sin_port: port.to_be(),
- sin_addr: ip.0,
- .. unsafe { mem::zeroed() }
- })
- }
- IpAddr::V6(ref ip) => {
- InetAddr::V6(libc::sockaddr_in6 {
- sin6_family: AddressFamily::Inet6 as sa_family_t,
- sin6_port: port.to_be(),
- sin6_addr: ip.0,
- .. unsafe { mem::zeroed() }
- })
- }
- }
- }
- /// Gets the IP address associated with this socket address.
- pub const fn ip(&self) -> IpAddr {
- match *self {
- InetAddr::V4(ref sa) => IpAddr::V4(Ipv4Addr(sa.sin_addr)),
- InetAddr::V6(ref sa) => IpAddr::V6(Ipv6Addr(sa.sin6_addr)),
- }
- }
-
- /// Gets the port number associated with this socket address
- pub const fn port(&self) -> u16 {
- match *self {
- InetAddr::V6(ref sa) => u16::from_be(sa.sin6_port),
- InetAddr::V4(ref sa) => u16::from_be(sa.sin_port),
- }
- }
-
- pub fn to_std(&self) -> net::SocketAddr {
- match *self {
- InetAddr::V4(ref sa) => net::SocketAddr::V4(
- net::SocketAddrV4::new(
- Ipv4Addr(sa.sin_addr).to_std(),
- self.port())),
- InetAddr::V6(ref sa) => net::SocketAddr::V6(
- net::SocketAddrV6::new(
- Ipv6Addr(sa.sin6_addr).to_std(),
- self.port(),
- sa.sin6_flowinfo,
- sa.sin6_scope_id)),
- }
- }
-
- #[deprecated(since = "0.23.0", note = "use .to_string() instead")]
- pub fn to_str(&self) -> String {
- format!("{}", self)
- }
-}
-
-#[allow(deprecated)]
-impl fmt::Display for InetAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- InetAddr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()),
- InetAddr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()),
- }
- }
-}
-
-/*
- *
- * ===== IpAddr =====
- *
- */
-#[allow(missing_docs)] // Since they're all deprecated anyway
-#[allow(deprecated)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[deprecated(
- since = "0.24.0",
- note = "Use std::net::IpAddr instead"
-)]
-pub enum IpAddr {
- V4(Ipv4Addr),
- V6(Ipv6Addr),
-}
-
-#[allow(deprecated)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-impl IpAddr {
- /// Create a new IpAddr that contains an IPv4 address.
- ///
- /// The result will represent the IP address a.b.c.d
- pub const fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
- IpAddr::V4(Ipv4Addr::new(a, b, c, d))
- }
-
- /// Create a new IpAddr that contains an IPv6 address.
- ///
- /// The result will represent the IP address a:b:c:d:e:f
- #[allow(clippy::many_single_char_names)]
- #[allow(clippy::too_many_arguments)]
- pub const fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr {
- IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
- }
-
- pub fn from_std(std: &net::IpAddr) -> IpAddr {
- match *std {
- net::IpAddr::V4(ref std) => IpAddr::V4(Ipv4Addr::from_std(std)),
- net::IpAddr::V6(ref std) => IpAddr::V6(Ipv6Addr::from_std(std)),
- }
- }
-
- pub const fn to_std(&self) -> net::IpAddr {
- match *self {
- IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()),
- IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()),
- }
- }
-}
-
-#[allow(deprecated)]
-impl fmt::Display for IpAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- IpAddr::V4(ref v4) => v4.fmt(f),
- IpAddr::V6(ref v6) => v6.fmt(f)
- }
- }
-}
-
-/*
- *
- * ===== Ipv4Addr =====
- *
- */
-
-#[deprecated(
- since = "0.24.0",
- note = "Use std::net::Ipv4Addr instead"
-)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(transparent)]
-pub struct Ipv4Addr(pub libc::in_addr);
-
-#[allow(deprecated)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-impl Ipv4Addr {
- #[allow(clippy::identity_op)] // More readable this way
- pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
- let ip = (((a as u32) << 24) |
- ((b as u32) << 16) |
- ((c as u32) << 8) |
- ((d as u32) << 0)).to_be();
-
- Ipv4Addr(libc::in_addr { s_addr: ip })
- }
-
- // Use pass by reference for symmetry with Ipv6Addr::from_std
- #[allow(clippy::trivially_copy_pass_by_ref)]
- pub fn from_std(std: &net::Ipv4Addr) -> Ipv4Addr {
- let bits = std.octets();
- Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
- }
-
- pub const fn any() -> Ipv4Addr {
- Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
- }
-
- pub const fn octets(self) -> [u8; 4] {
- let bits = u32::from_be(self.0.s_addr);
- [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
- }
-
- pub const fn to_std(self) -> net::Ipv4Addr {
- let bits = self.octets();
- net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
- }
-}
-
-#[allow(deprecated)]
-impl fmt::Display for Ipv4Addr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- let octets = self.octets();
- write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
- }
-}
-
-/*
- *
- * ===== Ipv6Addr =====
- *
- */
-
-#[deprecated(
- since = "0.24.0",
- note = "Use std::net::Ipv6Addr instead"
-)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(transparent)]
-pub struct Ipv6Addr(pub libc::in6_addr);
-
-// Note that IPv6 addresses are stored in big endian order on all architectures.
-// See https://tools.ietf.org/html/rfc1700 or consult your favorite search
-// engine.
-
-macro_rules! to_u8_array {
- ($($num:ident),*) => {
- [ $(($num>>8) as u8, ($num&0xff) as u8,)* ]
- }
-}
-
-macro_rules! to_u16_array {
- ($slf:ident, $($first:expr, $second:expr),*) => {
- [$( (($slf.0.s6_addr[$first] as u16) << 8) + $slf.0.s6_addr[$second] as u16,)*]
- }
-}
-
-#[allow(deprecated)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-impl Ipv6Addr {
- #[allow(clippy::many_single_char_names)]
- #[allow(clippy::too_many_arguments)]
- pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
- Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)})
- }
-
- pub fn from_std(std: &net::Ipv6Addr) -> Ipv6Addr {
- let s = std.segments();
- Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
- }
-
- /// Return the eight 16-bit segments that make up this address
- pub const fn segments(&self) -> [u16; 8] {
- to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
- }
-
- pub const fn to_std(&self) -> net::Ipv6Addr {
- let s = self.segments();
- net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
- }
-}
-
-#[allow(deprecated)]
-impl fmt::Display for Ipv6Addr {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- self.to_std().fmt(fmt)
- }
-}
-}
-
-/// A wrapper around `sockaddr_un`.
-#[derive(Clone, Copy, Debug)]
-#[repr(C)]
-pub struct UnixAddr {
- // INVARIANT: sun & sun_len are valid as defined by docs for from_raw_parts
- sun: libc::sockaddr_un,
- /// The length of the valid part of `sun`, including the sun_family field
- /// but excluding any trailing nul.
- // On the BSDs, this field is built into sun
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- sun_len: u8,
-}
-
-// linux man page unix(7) says there are 3 kinds of unix socket:
-// pathname: addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1
-// unnamed: addrlen = sizeof(sa_family_t)
-// abstract: addren > sizeof(sa_family_t), name = sun_path[..(addrlen - sizeof(sa_family_t))]
-//
-// what we call path_len = addrlen - offsetof(struct sockaddr_un, sun_path)
-#[derive(PartialEq, Eq, Hash)]
-enum UnixAddrKind<'a> {
- Pathname(&'a Path),
- Unnamed,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- Abstract(&'a [u8]),
-}
-impl<'a> UnixAddrKind<'a> {
- /// Safety: sun & sun_len must be valid
- unsafe fn get(sun: &'a libc::sockaddr_un, sun_len: u8) -> Self {
- assert!(sun_len as usize >= offset_of!(libc::sockaddr_un, sun_path));
- let path_len =
- sun_len as usize - offset_of!(libc::sockaddr_un, sun_path);
- if path_len == 0 {
- return Self::Unnamed;
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- if sun.sun_path[0] == 0 {
- let name = slice::from_raw_parts(
- sun.sun_path.as_ptr().add(1) as *const u8,
- path_len - 1,
- );
- return Self::Abstract(name);
- }
- let pathname =
- slice::from_raw_parts(sun.sun_path.as_ptr() as *const u8, path_len);
- if pathname.last() == Some(&0) {
- // A trailing NUL is not considered part of the path, and it does
- // not need to be included in the addrlen passed to functions like
- // bind(). However, Linux adds a trailing NUL, even if one was not
- // originally present, when returning addrs from functions like
- // getsockname() (the BSDs do not do that). So we need to filter
- // out any trailing NUL here, so sockaddrs can round-trip through
- // the kernel and still compare equal.
- Self::Pathname(Path::new(OsStr::from_bytes(
- &pathname[0..pathname.len() - 1],
- )))
- } else {
- Self::Pathname(Path::new(OsStr::from_bytes(pathname)))
- }
- }
-}
-
-impl UnixAddr {
- /// Create a new sockaddr_un representing a filesystem path.
- pub fn new<P: ?Sized + NixPath>(path: &P) -> Result<UnixAddr> {
- path.with_nix_path(|cstr| unsafe {
- let mut ret = libc::sockaddr_un {
- sun_family: AddressFamily::Unix as sa_family_t,
- ..mem::zeroed()
- };
-
- let bytes = cstr.to_bytes();
-
- if bytes.len() >= ret.sun_path.len() {
- return Err(Errno::ENAMETOOLONG);
- }
-
- let sun_len = (bytes.len()
- + offset_of!(libc::sockaddr_un, sun_path))
- .try_into()
- .unwrap();
-
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- {
- ret.sun_len = sun_len;
- }
- ptr::copy_nonoverlapping(
- bytes.as_ptr(),
- ret.sun_path.as_mut_ptr() as *mut u8,
- bytes.len(),
- );
-
- Ok(UnixAddr::from_raw_parts(ret, sun_len))
- })?
- }
-
- /// Create a new `sockaddr_un` representing an address in the "abstract namespace".
- ///
- /// The leading nul byte for the abstract namespace is automatically added;
- /// thus the input `path` is expected to be the bare name, not NUL-prefixed.
- /// This is a Linux-specific extension, primarily used to allow chrooted
- /// processes to communicate with processes having a different filesystem view.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn new_abstract(path: &[u8]) -> Result<UnixAddr> {
- unsafe {
- let mut ret = libc::sockaddr_un {
- sun_family: AddressFamily::Unix as sa_family_t,
- ..mem::zeroed()
- };
-
- if path.len() >= ret.sun_path.len() {
- return Err(Errno::ENAMETOOLONG);
- }
- let sun_len =
- (path.len() + 1 + offset_of!(libc::sockaddr_un, sun_path))
- .try_into()
- .unwrap();
-
- // Abstract addresses are represented by sun_path[0] ==
- // b'\0', so copy starting one byte in.
- ptr::copy_nonoverlapping(
- path.as_ptr(),
- ret.sun_path.as_mut_ptr().offset(1) as *mut u8,
- path.len(),
- );
-
- Ok(UnixAddr::from_raw_parts(ret, sun_len))
- }
- }
-
- /// Create a new `sockaddr_un` representing an "unnamed" unix socket address.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn new_unnamed() -> UnixAddr {
- let ret = libc::sockaddr_un {
- sun_family: AddressFamily::Unix as sa_family_t,
- .. unsafe { mem::zeroed() }
- };
-
- let sun_len: u8 = offset_of!(libc::sockaddr_un, sun_path).try_into().unwrap();
-
- unsafe { UnixAddr::from_raw_parts(ret, sun_len) }
- }
-
- /// Create a UnixAddr from a raw `sockaddr_un` struct and a size. `sun_len`
- /// is the size of the valid portion of the struct, excluding any trailing
- /// NUL.
- ///
- /// # Safety
- /// This pair of sockaddr_un & sun_len must be a valid unix addr, which
- /// means:
- /// - sun_len >= offset_of(sockaddr_un, sun_path)
- /// - sun_len <= sockaddr_un.sun_path.len() - offset_of(sockaddr_un, sun_path)
- /// - if this is a unix addr with a pathname, sun.sun_path is a
- /// fs path, not necessarily nul-terminated.
- pub(crate) unsafe fn from_raw_parts(
- sun: libc::sockaddr_un,
- sun_len: u8,
- ) -> UnixAddr {
- cfg_if! {
- if #[cfg(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- {
- UnixAddr { sun, sun_len }
- } else {
- assert_eq!(sun_len, sun.sun_len);
- UnixAddr {sun}
- }
- }
- }
-
- fn kind(&self) -> UnixAddrKind<'_> {
- // SAFETY: our sockaddr is always valid because of the invariant on the struct
- unsafe { UnixAddrKind::get(&self.sun, self.sun_len()) }
- }
-
- /// If this address represents a filesystem path, return that path.
- pub fn path(&self) -> Option<&Path> {
- match self.kind() {
- UnixAddrKind::Pathname(path) => Some(path),
- _ => None,
- }
- }
-
- /// If this address represents an abstract socket, return its name.
- ///
- /// For abstract sockets only the bare name is returned, without the
- /// leading NUL byte. `None` is returned for unnamed or path-backed sockets.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn as_abstract(&self) -> Option<&[u8]> {
- match self.kind() {
- UnixAddrKind::Abstract(name) => Some(name),
- _ => None,
- }
- }
-
- /// Check if this address is an "unnamed" unix socket address.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[inline]
- pub fn is_unnamed(&self) -> bool {
- matches!(self.kind(), UnixAddrKind::Unnamed)
- }
-
- /// Returns the addrlen of this socket - `offsetof(struct sockaddr_un, sun_path)`
- #[inline]
- pub fn path_len(&self) -> usize {
- self.sun_len() as usize - offset_of!(libc::sockaddr_un, sun_path)
- }
- /// Returns a pointer to the raw `sockaddr_un` struct
- #[inline]
- pub fn as_ptr(&self) -> *const libc::sockaddr_un {
- &self.sun
- }
- /// Returns a mutable pointer to the raw `sockaddr_un` struct
- #[inline]
- pub fn as_mut_ptr(&mut self) -> *mut libc::sockaddr_un {
- &mut self.sun
- }
-
- fn sun_len(&self) -> u8 {
- cfg_if! {
- if #[cfg(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- {
- self.sun_len
- } else {
- self.sun.sun_len
- }
- }
- }
-}
-
-impl private::SockaddrLikePriv for UnixAddr {}
-impl SockaddrLike for UnixAddr {
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- fn len(&self) -> libc::socklen_t {
- self.sun_len.into()
- }
-
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if let Some(l) = len {
- if (l as usize) < offset_of!(libc::sockaddr_un, sun_path)
- || l > u8::MAX as libc::socklen_t
- {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_UNIX {
- return None;
- }
- let mut su: libc::sockaddr_un = mem::zeroed();
- let sup = &mut su as *mut libc::sockaddr_un as *mut u8;
- cfg_if! {
- if #[cfg(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))] {
- let su_len = len.unwrap_or(
- mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
- );
- } else {
- let su_len = len.unwrap_or((*addr).sa_len as libc::socklen_t);
- }
- };
- ptr::copy(addr as *const u8, sup, su_len as usize);
- Some(Self::from_raw_parts(su, su_len as u8))
- }
-
- fn size() -> libc::socklen_t
- where
- Self: Sized,
- {
- mem::size_of::<libc::sockaddr_un>() as libc::socklen_t
- }
-}
-
-impl AsRef<libc::sockaddr_un> for UnixAddr {
- fn as_ref(&self) -> &libc::sockaddr_un {
- &self.sun
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn fmt_abstract(abs: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
- use fmt::Write;
- f.write_str("@\"")?;
- for &b in abs {
- use fmt::Display;
- char::from(b).escape_default().fmt(f)?;
- }
- f.write_char('"')?;
- Ok(())
-}
-
-impl fmt::Display for UnixAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self.kind() {
- UnixAddrKind::Pathname(path) => path.display().fmt(f),
- UnixAddrKind::Unnamed => f.pad("<unbound UNIX socket>"),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- UnixAddrKind::Abstract(name) => fmt_abstract(name, f),
- }
- }
-}
-
-impl PartialEq for UnixAddr {
- fn eq(&self, other: &UnixAddr) -> bool {
- self.kind() == other.kind()
- }
-}
-
-impl Eq for UnixAddr {}
-
-impl Hash for UnixAddr {
- fn hash<H: Hasher>(&self, s: &mut H) {
- self.kind().hash(s)
- }
-}
-
-/// Anything that, in C, can be cast back and forth to `sockaddr`.
-///
-/// Most implementors also implement `AsRef<libc::XXX>` to access their
-/// inner type read-only.
-#[allow(clippy::len_without_is_empty)]
-pub trait SockaddrLike: private::SockaddrLikePriv {
- /// Returns a raw pointer to the inner structure. Useful for FFI.
- fn as_ptr(&self) -> *const libc::sockaddr {
- self as *const Self as *const libc::sockaddr
- }
-
- /// Unsafe constructor from a variable length source
- ///
- /// Some C APIs from provide `len`, and others do not. If it's provided it
- /// will be validated. If not, it will be guessed based on the family.
- ///
- /// # Arguments
- ///
- /// - `addr`: raw pointer to something that can be cast to a
- /// `libc::sockaddr`. For example, `libc::sockaddr_in`,
- /// `libc::sockaddr_in6`, etc.
- /// - `len`: For fixed-width types like `sockaddr_in`, it will be
- /// validated if present and ignored if not. For variable-width
- /// types it is required and must be the total length of valid
- /// data. For example, if `addr` points to a
- /// named `sockaddr_un`, then `len` must be the length of the
- /// structure up to but not including the trailing NUL.
- ///
- /// # Safety
- ///
- /// `addr` must be valid for the specific type of sockaddr. `len`, if
- /// present, must not exceed the length of valid data in `addr`.
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized;
-
- /// Return the address family of this socket
- ///
- /// # Examples
- /// One common use is to match on the family of a union type, like this:
- /// ```
- /// # use nix::sys::socket::*;
- /// let fd = socket(AddressFamily::Inet, SockType::Stream,
- /// SockFlag::empty(), None).unwrap();
- /// let ss: SockaddrStorage = getsockname(fd).unwrap();
- /// match ss.family().unwrap() {
- /// AddressFamily::Inet => println!("{}", ss.as_sockaddr_in().unwrap()),
- /// AddressFamily::Inet6 => println!("{}", ss.as_sockaddr_in6().unwrap()),
- /// _ => println!("Unexpected address family")
- /// }
- /// ```
- fn family(&self) -> Option<AddressFamily> {
- // Safe since all implementors have a sa_family field at the same
- // address, and they're all repr(C)
- AddressFamily::from_i32(unsafe {
- (*(self as *const Self as *const libc::sockaddr)).sa_family as i32
- })
- }
-
- cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))] {
- /// Return the length of valid data in the sockaddr structure.
- ///
- /// For fixed-size sockaddrs, this should be the size of the
- /// structure. But for variable-sized types like [`UnixAddr`] it
- /// may be less.
- fn len(&self) -> libc::socklen_t {
- // Safe since all implementors have a sa_len field at the same
- // address, and they're all repr(transparent).
- // Robust for all implementors.
- unsafe {
- (*(self as *const Self as *const libc::sockaddr)).sa_len
- }.into()
- }
- } else {
- /// Return the length of valid data in the sockaddr structure.
- ///
- /// For fixed-size sockaddrs, this should be the size of the
- /// structure. But for variable-sized types like [`UnixAddr`] it
- /// may be less.
- fn len(&self) -> libc::socklen_t {
- // No robust default implementation is possible without an
- // sa_len field. Implementors with a variable size must
- // override this method.
- mem::size_of_val(self) as libc::socklen_t
- }
- }
- }
-
- /// Return the available space in the structure
- fn size() -> libc::socklen_t
- where
- Self: Sized,
- {
- mem::size_of::<Self>() as libc::socklen_t
- }
-}
-
-impl private::SockaddrLikePriv for () {
- fn as_mut_ptr(&mut self) -> *mut libc::sockaddr {
- ptr::null_mut()
- }
-}
-
-/// `()` can be used in place of a real Sockaddr when no address is expected,
-/// for example for a field of `Option<S> where S: SockaddrLike`.
-// If this RFC ever stabilizes, then ! will be a better choice.
-// https://github.com/rust-lang/rust/issues/35121
-impl SockaddrLike for () {
- fn as_ptr(&self) -> *const libc::sockaddr {
- ptr::null()
- }
-
- unsafe fn from_raw(
- _: *const libc::sockaddr,
- _: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- None
- }
-
- fn family(&self) -> Option<AddressFamily> {
- None
- }
-
- fn len(&self) -> libc::socklen_t {
- 0
- }
-}
-
-/// An IPv4 socket address
-// This is identical to net::SocketAddrV4. But the standard library
-// doesn't allow direct access to the libc fields, which we need. So we
-// reimplement it here.
-#[cfg(feature = "net")]
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct SockaddrIn(libc::sockaddr_in);
-
-#[cfg(feature = "net")]
-impl SockaddrIn {
- /// Returns the IP address associated with this socket address, in native
- /// endian.
- pub const fn ip(&self) -> libc::in_addr_t {
- u32::from_be(self.0.sin_addr.s_addr)
- }
-
- /// Creates a new socket address from IPv4 octets and a port number.
- pub fn new(a: u8, b: u8, c: u8, d: u8, port: u16) -> Self {
- Self(libc::sockaddr_in {
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
- ))]
- sin_len: Self::size() as u8,
- sin_family: AddressFamily::Inet as sa_family_t,
- sin_port: u16::to_be(port),
- sin_addr: libc::in_addr {
- s_addr: u32::from_ne_bytes([a, b, c, d]),
- },
- sin_zero: unsafe { mem::zeroed() },
- })
- }
-
- /// Returns the port number associated with this socket address, in native
- /// endian.
- pub const fn port(&self) -> u16 {
- u16::from_be(self.0.sin_port)
- }
-}
-
-#[cfg(feature = "net")]
-impl private::SockaddrLikePriv for SockaddrIn {}
-#[cfg(feature = "net")]
-impl SockaddrLike for SockaddrIn {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_in>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_INET {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
-}
-
-#[cfg(feature = "net")]
-impl AsRef<libc::sockaddr_in> for SockaddrIn {
- fn as_ref(&self) -> &libc::sockaddr_in {
- &self.0
- }
-}
-
-#[cfg(feature = "net")]
-impl fmt::Display for SockaddrIn {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let ne = u32::from_be(self.0.sin_addr.s_addr);
- let port = u16::from_be(self.0.sin_port);
- write!(
- f,
- "{}.{}.{}.{}:{}",
- ne >> 24,
- (ne >> 16) & 0xFF,
- (ne >> 8) & 0xFF,
- ne & 0xFF,
- port
- )
- }
-}
-
-#[cfg(feature = "net")]
-impl From<net::SocketAddrV4> for SockaddrIn {
- fn from(addr: net::SocketAddrV4) -> Self {
- Self(libc::sockaddr_in {
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "hermit",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
- sin_family: AddressFamily::Inet as sa_family_t,
- sin_port: addr.port().to_be(), // network byte order
- sin_addr: ipv4addr_to_libc(*addr.ip()),
- ..unsafe { mem::zeroed() }
- })
- }
-}
-
-#[cfg(feature = "net")]
-impl From<SockaddrIn> for net::SocketAddrV4 {
- fn from(addr: SockaddrIn) -> Self {
- net::SocketAddrV4::new(
- net::Ipv4Addr::from(addr.0.sin_addr.s_addr.to_ne_bytes()),
- u16::from_be(addr.0.sin_port),
- )
- }
-}
-
-#[cfg(feature = "net")]
-impl std::str::FromStr for SockaddrIn {
- type Err = net::AddrParseError;
-
- fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
- net::SocketAddrV4::from_str(s).map(SockaddrIn::from)
- }
-}
-
-/// An IPv6 socket address
-#[cfg(feature = "net")]
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct SockaddrIn6(libc::sockaddr_in6);
-
-#[cfg(feature = "net")]
-impl SockaddrIn6 {
- /// Returns the flow information associated with this address.
- pub const fn flowinfo(&self) -> u32 {
- self.0.sin6_flowinfo
- }
-
- /// Returns the IP address associated with this socket address.
- pub fn ip(&self) -> net::Ipv6Addr {
- net::Ipv6Addr::from(self.0.sin6_addr.s6_addr)
- }
-
- /// Returns the port number associated with this socket address, in native
- /// endian.
- pub const fn port(&self) -> u16 {
- u16::from_be(self.0.sin6_port)
- }
-
- /// Returns the scope ID associated with this address.
- pub const fn scope_id(&self) -> u32 {
- self.0.sin6_scope_id
- }
-}
-
-#[cfg(feature = "net")]
-impl private::SockaddrLikePriv for SockaddrIn6 {}
-#[cfg(feature = "net")]
-impl SockaddrLike for SockaddrIn6 {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_INET6 {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
-}
-
-#[cfg(feature = "net")]
-impl AsRef<libc::sockaddr_in6> for SockaddrIn6 {
- fn as_ref(&self) -> &libc::sockaddr_in6 {
- &self.0
- }
-}
-
-#[cfg(feature = "net")]
-impl fmt::Display for SockaddrIn6 {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // These things are really hard to display properly. Easier to let std
- // do it.
- let std = net::SocketAddrV6::new(
- self.ip(),
- self.port(),
- self.flowinfo(),
- self.scope_id(),
- );
- std.fmt(f)
- }
-}
-
-#[cfg(feature = "net")]
-impl From<net::SocketAddrV6> for SockaddrIn6 {
- fn from(addr: net::SocketAddrV6) -> Self {
- #[allow(clippy::needless_update)] // It isn't needless on Illumos
- Self(libc::sockaddr_in6 {
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "hermit",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8,
- sin6_family: AddressFamily::Inet6 as sa_family_t,
- sin6_port: addr.port().to_be(), // network byte order
- sin6_addr: ipv6addr_to_libc(addr.ip()),
- sin6_flowinfo: addr.flowinfo(), // host byte order
- sin6_scope_id: addr.scope_id(), // host byte order
- ..unsafe { mem::zeroed() }
- })
- }
-}
-
-#[cfg(feature = "net")]
-impl From<SockaddrIn6> for net::SocketAddrV6 {
- fn from(addr: SockaddrIn6) -> Self {
- net::SocketAddrV6::new(
- net::Ipv6Addr::from(addr.0.sin6_addr.s6_addr),
- u16::from_be(addr.0.sin6_port),
- addr.0.sin6_flowinfo,
- addr.0.sin6_scope_id,
- )
- }
-}
-
-#[cfg(feature = "net")]
-impl std::str::FromStr for SockaddrIn6 {
- type Err = net::AddrParseError;
-
- fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
- net::SocketAddrV6::from_str(s).map(SockaddrIn6::from)
- }
-}
-
-/// A container for any sockaddr type
-///
-/// Just like C's `sockaddr_storage`, this type is large enough to hold any type
-/// of sockaddr. It can be used as an argument with functions like
-/// [`bind`](super::bind) and [`getsockname`](super::getsockname). Though it is
-/// a union, it can be safely accessed through the `as_*` methods.
-///
-/// # Example
-/// ```
-/// # use nix::sys::socket::*;
-/// # use std::str::FromStr;
-/// let localhost = SockaddrIn::from_str("127.0.0.1:8081").unwrap();
-/// let fd = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(),
-/// None).unwrap();
-/// bind(fd, &localhost).expect("bind");
-/// let ss: SockaddrStorage = getsockname(fd).expect("getsockname");
-/// assert_eq!(&localhost, ss.as_sockaddr_in().unwrap());
-/// ```
-#[derive(Clone, Copy, Eq)]
-#[repr(C)]
-pub union SockaddrStorage {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- alg: AlgAddr,
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- dl: LinkAddr,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- nl: NetlinkAddr,
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
- sctl: SysControlAddr,
- #[cfg(feature = "net")]
- sin: SockaddrIn,
- #[cfg(feature = "net")]
- sin6: SockaddrIn6,
- ss: libc::sockaddr_storage,
- su: UnixAddr,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- vsock: VsockAddr,
-}
-impl private::SockaddrLikePriv for SockaddrStorage {}
-impl SockaddrLike for SockaddrStorage {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- l: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if addr.is_null() {
- return None;
- }
- if let Some(len) = l {
- let ulen = len as usize;
- if ulen < offset_of!(libc::sockaddr, sa_data)
- || ulen > mem::size_of::<libc::sockaddr_storage>()
- {
- None
- } else {
- let mut ss: libc::sockaddr_storage = mem::zeroed();
- let ssp = &mut ss as *mut libc::sockaddr_storage as *mut u8;
- ptr::copy(addr as *const u8, ssp, len as usize);
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- if i32::from(ss.ss_family) == libc::AF_UNIX {
- // Safe because we UnixAddr is strictly smaller than
- // SockaddrStorage, and we just initialized the structure.
- (*(&mut ss as *mut libc::sockaddr_storage as *mut UnixAddr)).sun_len = len as u8;
- }
- Some(Self { ss })
- }
- } else {
- // If length is not available and addr is of a fixed-length type,
- // copy it. If addr is of a variable length type and len is not
- // available, then there's nothing we can do.
- match (*addr).sa_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_ALG => {
- AlgAddr::from_raw(addr, l).map(|alg| Self { alg })
- }
- #[cfg(feature = "net")]
- libc::AF_INET => {
- SockaddrIn::from_raw(addr, l).map(|sin| Self { sin })
- }
- #[cfg(feature = "net")]
- libc::AF_INET6 => {
- SockaddrIn6::from_raw(addr, l).map(|sin6| Self { sin6 })
- }
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- libc::AF_LINK => {
- LinkAddr::from_raw(addr, l).map(|dl| Self { dl })
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => {
- NetlinkAddr::from_raw(addr, l).map(|nl| Self { nl })
- }
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg(feature = "net")]
- libc::AF_PACKET => {
- LinkAddr::from_raw(addr, l).map(|dl| Self { dl })
- }
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- libc::AF_SYSTEM => {
- SysControlAddr::from_raw(addr, l).map(|sctl| Self { sctl })
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_VSOCK => {
- VsockAddr::from_raw(addr, l).map(|vsock| Self { vsock })
- }
- _ => None,
- }
- }
- }
-
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- fn len(&self) -> libc::socklen_t {
- match self.as_unix_addr() {
- // The UnixAddr type knows its own length
- Some(ua) => ua.len(),
- // For all else, we're just a boring SockaddrStorage
- None => mem::size_of_val(self) as libc::socklen_t
- }
- }
-}
-
-macro_rules! accessors {
- (
- $fname:ident,
- $fname_mut:ident,
- $sockty:ty,
- $family:expr,
- $libc_ty:ty,
- $field:ident) => {
- /// Safely and falliably downcast to an immutable reference
- pub fn $fname(&self) -> Option<&$sockty> {
- if self.family() == Some($family)
- && self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t
- {
- // Safe because family and len are validated
- Some(unsafe { &self.$field })
- } else {
- None
- }
- }
-
- /// Safely and falliably downcast to a mutable reference
- pub fn $fname_mut(&mut self) -> Option<&mut $sockty> {
- if self.family() == Some($family)
- && self.len() >= mem::size_of::<$libc_ty>() as libc::socklen_t
- {
- // Safe because family and len are validated
- Some(unsafe { &mut self.$field })
- } else {
- None
- }
- }
- };
-}
-
-impl SockaddrStorage {
- /// Downcast to an immutable `[UnixAddr]` reference.
- pub fn as_unix_addr(&self) -> Option<&UnixAddr> {
- cfg_if! {
- if #[cfg(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- {
- let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
- // Safe because UnixAddr is strictly smaller than
- // sockaddr_storage, and we're fully initialized
- let len = unsafe {
- (*(p as *const UnixAddr )).sun_len as usize
- };
- } else {
- let len = self.len() as usize;
- }
- }
- // Sanity checks
- if self.family() != Some(AddressFamily::Unix) ||
- len < offset_of!(libc::sockaddr_un, sun_path) ||
- len > mem::size_of::<libc::sockaddr_un>() {
- None
- } else {
- Some(unsafe{&self.su})
- }
- }
-
- /// Downcast to a mutable `[UnixAddr]` reference.
- pub fn as_unix_addr_mut(&mut self) -> Option<&mut UnixAddr> {
- cfg_if! {
- if #[cfg(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux"
- ))]
- {
- let p = unsafe{ &self.ss as *const libc::sockaddr_storage };
- // Safe because UnixAddr is strictly smaller than
- // sockaddr_storage, and we're fully initialized
- let len = unsafe {
- (*(p as *const UnixAddr )).sun_len as usize
- };
- } else {
- let len = self.len() as usize;
- }
- }
- // Sanity checks
- if self.family() != Some(AddressFamily::Unix) ||
- len < offset_of!(libc::sockaddr_un, sun_path) ||
- len > mem::size_of::<libc::sockaddr_un>() {
- None
- } else {
- Some(unsafe{&mut self.su})
- }
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- accessors! {as_alg_addr, as_alg_addr_mut, AlgAddr,
- AddressFamily::Alg, libc::sockaddr_alg, alg}
-
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg(feature = "net")]
- accessors! {
- as_link_addr, as_link_addr_mut, LinkAddr,
- AddressFamily::Packet, libc::sockaddr_ll, dl}
-
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- accessors! {
- as_link_addr, as_link_addr_mut, LinkAddr,
- AddressFamily::Link, libc::sockaddr_dl, dl}
-
- #[cfg(feature = "net")]
- accessors! {
- as_sockaddr_in, as_sockaddr_in_mut, SockaddrIn,
- AddressFamily::Inet, libc::sockaddr_in, sin}
-
- #[cfg(feature = "net")]
- accessors! {
- as_sockaddr_in6, as_sockaddr_in6_mut, SockaddrIn6,
- AddressFamily::Inet6, libc::sockaddr_in6, sin6}
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- accessors! {as_netlink_addr, as_netlink_addr_mut, NetlinkAddr,
- AddressFamily::Netlink, libc::sockaddr_nl, nl}
-
- #[cfg(all(feature = "ioctl", any(target_os = "ios", target_os = "macos")))]
- #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
- accessors! {as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr,
- AddressFamily::System, libc::sockaddr_ctl, sctl}
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- accessors! {as_vsock_addr, as_vsock_addr_mut, VsockAddr,
- AddressFamily::Vsock, libc::sockaddr_vm, vsock}
-}
-
-impl fmt::Debug for SockaddrStorage {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("SockaddrStorage")
- // Safe because sockaddr_storage has the least specific
- // field types
- .field("ss", unsafe { &self.ss })
- .finish()
- }
-}
-
-impl fmt::Display for SockaddrStorage {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- unsafe {
- match self.ss.ss_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_ALG => self.alg.fmt(f),
- #[cfg(feature = "net")]
- libc::AF_INET => self.sin.fmt(f),
- #[cfg(feature = "net")]
- libc::AF_INET6 => self.sin6.fmt(f),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- libc::AF_LINK => self.dl.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => self.nl.fmt(f),
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "fuchsia"
- ))]
- #[cfg(feature = "net")]
- libc::AF_PACKET => self.dl.fmt(f),
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg(feature = "ioctl")]
- libc::AF_SYSTEM => self.sctl.fmt(f),
- libc::AF_UNIX => self.su.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_VSOCK => self.vsock.fmt(f),
- _ => "<Address family unspecified>".fmt(f),
- }
- }
- }
-}
-
-#[cfg(feature = "net")]
-impl From<net::SocketAddrV4> for SockaddrStorage {
- fn from(s: net::SocketAddrV4) -> Self {
- unsafe {
- let mut ss: Self = mem::zeroed();
- ss.sin = SockaddrIn::from(s);
- ss
- }
- }
-}
-
-#[cfg(feature = "net")]
-impl From<net::SocketAddrV6> for SockaddrStorage {
- fn from(s: net::SocketAddrV6) -> Self {
- unsafe {
- let mut ss: Self = mem::zeroed();
- ss.sin6 = SockaddrIn6::from(s);
- ss
- }
- }
-}
-
-#[cfg(feature = "net")]
-impl From<net::SocketAddr> for SockaddrStorage {
- fn from(s: net::SocketAddr) -> Self {
- match s {
- net::SocketAddr::V4(sa4) => Self::from(sa4),
- net::SocketAddr::V6(sa6) => Self::from(sa6),
- }
- }
-}
-
-impl Hash for SockaddrStorage {
- fn hash<H: Hasher>(&self, s: &mut H) {
- unsafe {
- match self.ss.ss_family as i32 {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_ALG => self.alg.hash(s),
- #[cfg(feature = "net")]
- libc::AF_INET => self.sin.hash(s),
- #[cfg(feature = "net")]
- libc::AF_INET6 => self.sin6.hash(s),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- libc::AF_LINK => self.dl.hash(s),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => self.nl.hash(s),
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "fuchsia"
- ))]
- #[cfg(feature = "net")]
- libc::AF_PACKET => self.dl.hash(s),
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg(feature = "ioctl")]
- libc::AF_SYSTEM => self.sctl.hash(s),
- libc::AF_UNIX => self.su.hash(s),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_VSOCK => self.vsock.hash(s),
- _ => self.ss.hash(s),
- }
- }
- }
-}
-
-impl PartialEq for SockaddrStorage {
- fn eq(&self, other: &Self) -> bool {
- unsafe {
- match (self.ss.ss_family as i32, other.ss.ss_family as i32) {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- (libc::AF_ALG, libc::AF_ALG) => self.alg == other.alg,
- #[cfg(feature = "net")]
- (libc::AF_INET, libc::AF_INET) => self.sin == other.sin,
- #[cfg(feature = "net")]
- (libc::AF_INET6, libc::AF_INET6) => self.sin6 == other.sin6,
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- (libc::AF_LINK, libc::AF_LINK) => self.dl == other.dl,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- (libc::AF_NETLINK, libc::AF_NETLINK) => self.nl == other.nl,
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg(feature = "net")]
- (libc::AF_PACKET, libc::AF_PACKET) => self.dl == other.dl,
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg(feature = "ioctl")]
- (libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl,
- (libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- (libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock,
- _ => false,
- }
- }
- }
-}
-
-mod private {
- pub trait SockaddrLikePriv {
- /// Returns a mutable raw pointer to the inner structure.
- ///
- /// # Safety
- ///
- /// This method is technically safe, but modifying the inner structure's
- /// `family` or `len` fields may result in violating Nix's invariants.
- /// It is best to use this method only with foreign functions that do
- /// not change the sockaddr type.
- fn as_mut_ptr(&mut self) -> *mut libc::sockaddr {
- self as *mut Self as *mut libc::sockaddr
- }
- }
-}
-
-/// Represents a socket address
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[deprecated(
- since = "0.24.0",
- note = "use SockaddrLike or SockaddrStorage instead"
-)]
-#[allow(missing_docs)] // Since they're all deprecated anyway
-#[allow(deprecated)]
-#[non_exhaustive]
-pub enum SockAddr {
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Inet(InetAddr),
- Unix(UnixAddr),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Netlink(NetlinkAddr),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Alg(AlgAddr),
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- #[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
- SysControl(SysControlAddr),
- /// Datalink address (MAC)
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Link(LinkAddr),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- Vsock(VsockAddr),
-}
-
-#[allow(missing_docs)] // Since they're all deprecated anyway
-#[allow(deprecated)]
-impl SockAddr {
- feature! {
- #![feature = "net"]
- pub fn new_inet(addr: InetAddr) -> SockAddr {
- SockAddr::Inet(addr)
- }
- }
-
- pub fn new_unix<P: ?Sized + NixPath>(path: &P) -> Result<SockAddr> {
- Ok(SockAddr::Unix(UnixAddr::new(path)?))
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn new_netlink(pid: u32, groups: u32) -> SockAddr {
- SockAddr::Netlink(NetlinkAddr::new(pid, groups))
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn new_alg(alg_type: &str, alg_name: &str) -> SockAddr {
- SockAddr::Alg(AlgAddr::new(alg_type, alg_name))
- }
-
- feature! {
- #![feature = "ioctl"]
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result<SockAddr> {
- SysControlAddr::from_name(sockfd, name, unit).map(SockAddr::SysControl)
- }
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn new_vsock(cid: u32, port: u32) -> SockAddr {
- SockAddr::Vsock(VsockAddr::new(cid, port))
- }
-
- pub fn family(&self) -> AddressFamily {
- match *self {
- #[cfg(feature = "net")]
- SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
- #[cfg(feature = "net")]
- SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6,
- SockAddr::Unix(..) => AddressFamily::Unix,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Netlink(..) => AddressFamily::Netlink,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Alg(..) => AddressFamily::Alg,
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- SockAddr::SysControl(..) => AddressFamily::System,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- SockAddr::Link(..) => AddressFamily::Packet,
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- SockAddr::Link(..) => AddressFamily::Link,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Vsock(..) => AddressFamily::Vsock,
- }
- }
-
- #[deprecated(since = "0.23.0", note = "use .to_string() instead")]
- pub fn to_str(&self) -> String {
- format!("{}", self)
- }
-
- /// Creates a `SockAddr` struct from libc's sockaddr.
- ///
- /// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System.
- /// Returns None for unsupported families.
- ///
- /// # Safety
- ///
- /// unsafe because it takes a raw pointer as argument. The caller must
- /// ensure that the pointer is valid.
- #[cfg(not(target_os = "fuchsia"))]
- #[cfg(feature = "net")]
- pub(crate) unsafe fn from_libc_sockaddr(
- addr: *const libc::sockaddr,
- ) -> Option<SockAddr> {
- if addr.is_null() {
- None
- } else {
- match AddressFamily::from_i32(i32::from((*addr).sa_family)) {
- Some(AddressFamily::Unix) => None,
- #[cfg(feature = "net")]
- Some(AddressFamily::Inet) => Some(SockAddr::Inet(
- InetAddr::V4(ptr::read_unaligned(addr as *const _)),
- )),
- #[cfg(feature = "net")]
- Some(AddressFamily::Inet6) => Some(SockAddr::Inet(
- InetAddr::V6(ptr::read_unaligned(addr as *const _)),
- )),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- Some(AddressFamily::Netlink) => Some(SockAddr::Netlink(
- NetlinkAddr(ptr::read_unaligned(addr as *const _)),
- )),
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- Some(AddressFamily::System) => Some(SockAddr::SysControl(
- SysControlAddr(ptr::read_unaligned(addr as *const _)),
- )),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- Some(AddressFamily::Packet) => Some(SockAddr::Link(LinkAddr(
- ptr::read_unaligned(addr as *const _),
- ))),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- Some(AddressFamily::Link) => {
- let ether_addr =
- LinkAddr(ptr::read_unaligned(addr as *const _));
- if ether_addr.is_empty() {
- None
- } else {
- Some(SockAddr::Link(ether_addr))
- }
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(VsockAddr(
- ptr::read_unaligned(addr as *const _),
- ))),
- // Other address families are currently not supported and simply yield a None
- // entry instead of a proper conversion to a `SockAddr`.
- Some(_) | None => None,
- }
- }
- }
-
- /// Conversion from nix's SockAddr type to the underlying libc sockaddr type.
- ///
- /// This is useful for interfacing with other libc functions that don't yet have nix wrappers.
- /// Returns a reference to the underlying data type (as a sockaddr reference) along
- /// with the size of the actual data type. sockaddr is commonly used as a proxy for
- /// a superclass as C doesn't support inheritance, so many functions that take
- /// a sockaddr * need to take the size of the underlying type as well and then internally cast it back.
- pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
- match *self {
- #[cfg(feature = "net")]
- SockAddr::Inet(InetAddr::V4(ref addr)) => (
- // This cast is always allowed in C
- unsafe {
- &*(addr as *const libc::sockaddr_in
- as *const libc::sockaddr)
- },
- mem::size_of_val(addr) as libc::socklen_t,
- ),
- #[cfg(feature = "net")]
- SockAddr::Inet(InetAddr::V6(ref addr)) => (
- // This cast is always allowed in C
- unsafe {
- &*(addr as *const libc::sockaddr_in6
- as *const libc::sockaddr)
- },
- mem::size_of_val(addr) as libc::socklen_t,
- ),
- SockAddr::Unix(ref unix_addr) => (
- // This cast is always allowed in C
- unsafe {
- &*(&unix_addr.sun as *const libc::sockaddr_un
- as *const libc::sockaddr)
- },
- unix_addr.sun_len() as libc::socklen_t,
- ),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Netlink(NetlinkAddr(ref sa)) => (
- // This cast is always allowed in C
- unsafe {
- &*(sa as *const libc::sockaddr_nl as *const libc::sockaddr)
- },
- mem::size_of_val(sa) as libc::socklen_t,
- ),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Alg(AlgAddr(ref sa)) => (
- // This cast is always allowed in C
- unsafe {
- &*(sa as *const libc::sockaddr_alg as *const libc::sockaddr)
- },
- mem::size_of_val(sa) as libc::socklen_t,
- ),
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- SockAddr::SysControl(SysControlAddr(ref sa)) => (
- // This cast is always allowed in C
- unsafe {
- &*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr)
- },
- mem::size_of_val(sa) as libc::socklen_t,
- ),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- SockAddr::Link(LinkAddr(ref addr)) => (
- // This cast is always allowed in C
- unsafe {
- &*(addr as *const libc::sockaddr_ll
- as *const libc::sockaddr)
- },
- mem::size_of_val(addr) as libc::socklen_t,
- ),
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- SockAddr::Link(LinkAddr(ref addr)) => (
- // This cast is always allowed in C
- unsafe {
- &*(addr as *const libc::sockaddr_dl
- as *const libc::sockaddr)
- },
- mem::size_of_val(addr) as libc::socklen_t,
- ),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Vsock(VsockAddr(ref sa)) => (
- // This cast is always allowed in C
- unsafe {
- &*(sa as *const libc::sockaddr_vm as *const libc::sockaddr)
- },
- mem::size_of_val(sa) as libc::socklen_t,
- ),
- }
- }
-}
-
-#[allow(deprecated)]
-impl fmt::Display for SockAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- #[cfg(feature = "net")]
- SockAddr::Inet(ref inet) => inet.fmt(f),
- SockAddr::Unix(ref unix) => unix.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Netlink(ref nl) => nl.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Alg(ref nl) => nl.fmt(f),
- #[cfg(all(
- feature = "ioctl",
- any(target_os = "ios", target_os = "macos")
- ))]
- SockAddr::SysControl(ref sc) => sc.fmt(f),
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"
- ))]
- #[cfg(feature = "net")]
- SockAddr::Link(ref ether_addr) => ether_addr.fmt(f),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- SockAddr::Vsock(ref svm) => svm.fmt(f),
- }
- }
-}
-
-#[cfg(not(target_os = "fuchsia"))]
-#[cfg(feature = "net")]
-#[allow(deprecated)]
-impl private::SockaddrLikePriv for SockAddr {}
-#[cfg(not(target_os = "fuchsia"))]
-#[cfg(feature = "net")]
-#[allow(deprecated)]
-impl SockaddrLike for SockAddr {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- _len: Option<libc::socklen_t>,
- ) -> Option<Self> {
- Self::from_libc_sockaddr(addr)
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub mod netlink {
- use super::*;
- use crate::sys::socket::addr::AddressFamily;
- use libc::{sa_family_t, sockaddr_nl};
- use std::{fmt, mem};
-
- /// Address for the Linux kernel user interface device.
- ///
- /// # References
- ///
- /// [netlink(7)](https://man7.org/linux/man-pages/man7/netlink.7.html)
- #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
- #[repr(transparent)]
- pub struct NetlinkAddr(pub(in super::super) sockaddr_nl);
-
- impl NetlinkAddr {
- /// Construct a new socket address from its port ID and multicast groups
- /// mask.
- pub fn new(pid: u32, groups: u32) -> NetlinkAddr {
- let mut addr: sockaddr_nl = unsafe { mem::zeroed() };
- addr.nl_family = AddressFamily::Netlink as sa_family_t;
- addr.nl_pid = pid;
- addr.nl_groups = groups;
-
- NetlinkAddr(addr)
- }
-
- /// Return the socket's port ID.
- pub const fn pid(&self) -> u32 {
- self.0.nl_pid
- }
-
- /// Return the socket's multicast groups mask
- pub const fn groups(&self) -> u32 {
- self.0.nl_groups
- }
- }
-
- impl private::SockaddrLikePriv for NetlinkAddr {}
- impl SockaddrLike for NetlinkAddr {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_nl>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_NETLINK {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
- }
-
- impl AsRef<libc::sockaddr_nl> for NetlinkAddr {
- fn as_ref(&self) -> &libc::sockaddr_nl {
- &self.0
- }
- }
-
- impl fmt::Display for NetlinkAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "pid: {} groups: {}", self.pid(), self.groups())
- }
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub mod alg {
- use super::*;
- use libc::{c_char, sockaddr_alg, AF_ALG};
- use std::ffi::CStr;
- use std::hash::{Hash, Hasher};
- use std::{fmt, mem, str};
-
- /// Socket address for the Linux kernel crypto API
- #[derive(Copy, Clone)]
- #[repr(transparent)]
- pub struct AlgAddr(pub(in super::super) sockaddr_alg);
-
- impl private::SockaddrLikePriv for AlgAddr {}
- impl SockaddrLike for AlgAddr {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- l: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if let Some(l) = l {
- if l != mem::size_of::<libc::sockaddr_alg>() as libc::socklen_t
- {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_ALG {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
- }
-
- impl AsRef<libc::sockaddr_alg> for AlgAddr {
- fn as_ref(&self) -> &libc::sockaddr_alg {
- &self.0
- }
- }
-
- // , PartialEq, Eq, Debug, Hash
- impl PartialEq for AlgAddr {
- fn eq(&self, other: &Self) -> bool {
- let (inner, other) = (self.0, other.0);
- (
- inner.salg_family,
- &inner.salg_type[..],
- inner.salg_feat,
- inner.salg_mask,
- &inner.salg_name[..],
- ) == (
- other.salg_family,
- &other.salg_type[..],
- other.salg_feat,
- other.salg_mask,
- &other.salg_name[..],
- )
- }
- }
-
- impl Eq for AlgAddr {}
-
- impl Hash for AlgAddr {
- fn hash<H: Hasher>(&self, s: &mut H) {
- let inner = self.0;
- (
- inner.salg_family,
- &inner.salg_type[..],
- inner.salg_feat,
- inner.salg_mask,
- &inner.salg_name[..],
- )
- .hash(s);
- }
- }
-
- impl AlgAddr {
- /// Construct an `AF_ALG` socket from its cipher name and type.
- pub fn new(alg_type: &str, alg_name: &str) -> AlgAddr {
- let mut addr: sockaddr_alg = unsafe { mem::zeroed() };
- addr.salg_family = AF_ALG as u16;
- addr.salg_type[..alg_type.len()]
- .copy_from_slice(alg_type.to_string().as_bytes());
- addr.salg_name[..alg_name.len()]
- .copy_from_slice(alg_name.to_string().as_bytes());
-
- AlgAddr(addr)
- }
-
- /// Return the socket's cipher type, for example `hash` or `aead`.
- pub fn alg_type(&self) -> &CStr {
- unsafe {
- CStr::from_ptr(self.0.salg_type.as_ptr() as *const c_char)
- }
- }
-
- /// Return the socket's cipher name, for example `sha1`.
- pub fn alg_name(&self) -> &CStr {
- unsafe {
- CStr::from_ptr(self.0.salg_name.as_ptr() as *const c_char)
- }
- }
- }
-
- impl fmt::Display for AlgAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(
- f,
- "type: {} alg: {}",
- self.alg_name().to_string_lossy(),
- self.alg_type().to_string_lossy()
- )
- }
- }
-
- impl fmt::Debug for AlgAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, f)
- }
- }
-}
-
-feature! {
-#![feature = "ioctl"]
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-pub mod sys_control {
- use crate::sys::socket::addr::AddressFamily;
- use libc::{self, c_uchar};
- use std::{fmt, mem, ptr};
- use std::os::unix::io::RawFd;
- use crate::{Errno, Result};
- use super::{private, SockaddrLike};
-
- // FIXME: Move type into `libc`
- #[repr(C)]
- #[derive(Clone, Copy)]
- #[allow(missing_debug_implementations)]
- pub struct ctl_ioc_info {
- pub ctl_id: u32,
- pub ctl_name: [c_uchar; MAX_KCTL_NAME],
- }
-
- const CTL_IOC_MAGIC: u8 = b'N';
- const CTL_IOC_INFO: u8 = 3;
- const MAX_KCTL_NAME: usize = 96;
-
- ioctl_readwrite!(ctl_info, CTL_IOC_MAGIC, CTL_IOC_INFO, ctl_ioc_info);
-
- /// Apple system control socket
- ///
- /// # References
- ///
- /// <https://developer.apple.com/documentation/kernel/sockaddr_ctl>
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- #[repr(transparent)]
- pub struct SysControlAddr(pub(in super::super) libc::sockaddr_ctl);
-
- impl private::SockaddrLikePriv for SysControlAddr {}
- impl SockaddrLike for SysControlAddr {
- unsafe fn from_raw(addr: *const libc::sockaddr, len: Option<libc::socklen_t>)
- -> Option<Self> where Self: Sized
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_ctl>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_SYSTEM {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
- }
-
- impl AsRef<libc::sockaddr_ctl> for SysControlAddr {
- fn as_ref(&self) -> &libc::sockaddr_ctl {
- &self.0
- }
- }
-
- impl SysControlAddr {
- /// Construct a new `SysControlAddr` from its kernel unique identifier
- /// and unit number.
- pub const fn new(id: u32, unit: u32) -> SysControlAddr {
- let addr = libc::sockaddr_ctl {
- sc_len: mem::size_of::<libc::sockaddr_ctl>() as c_uchar,
- sc_family: AddressFamily::System as c_uchar,
- ss_sysaddr: libc::AF_SYS_CONTROL as u16,
- sc_id: id,
- sc_unit: unit,
- sc_reserved: [0; 5]
- };
-
- SysControlAddr(addr)
- }
-
- /// Construct a new `SysControlAddr` from its human readable name and
- /// unit number.
- pub fn from_name(sockfd: RawFd, name: &str, unit: u32) -> Result<SysControlAddr> {
- if name.len() > MAX_KCTL_NAME {
- return Err(Errno::ENAMETOOLONG);
- }
-
- let mut ctl_name = [0; MAX_KCTL_NAME];
- ctl_name[..name.len()].clone_from_slice(name.as_bytes());
- let mut info = ctl_ioc_info { ctl_id: 0, ctl_name };
-
- unsafe { ctl_info(sockfd, &mut info)?; }
-
- Ok(SysControlAddr::new(info.ctl_id, unit))
- }
-
- /// Return the kernel unique identifier
- pub const fn id(&self) -> u32 {
- self.0.sc_id
- }
-
- /// Return the kernel controller private unit number.
- pub const fn unit(&self) -> u32 {
- self.0.sc_unit
- }
- }
-
- impl fmt::Display for SysControlAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(self, f)
- }
- }
-}
-}
-
-#[cfg(any(target_os = "android", target_os = "linux", target_os = "fuchsia"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod datalink {
- feature! {
- #![feature = "net"]
- use super::{fmt, mem, private, ptr, SockaddrLike};
-
- /// Hardware Address
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- #[repr(transparent)]
- pub struct LinkAddr(pub(in super::super) libc::sockaddr_ll);
-
- impl LinkAddr {
- /// Physical-layer protocol
- pub fn protocol(&self) -> u16 {
- self.0.sll_protocol
- }
-
- /// Interface number
- pub fn ifindex(&self) -> usize {
- self.0.sll_ifindex as usize
- }
-
- /// ARP hardware type
- pub fn hatype(&self) -> u16 {
- self.0.sll_hatype
- }
-
- /// Packet type
- pub fn pkttype(&self) -> u8 {
- self.0.sll_pkttype
- }
-
- /// Length of MAC address
- pub fn halen(&self) -> usize {
- self.0.sll_halen as usize
- }
-
- /// Physical-layer address (MAC)
- // Returns an Option just for cross-platform compatibility
- pub fn addr(&self) -> Option<[u8; 6]> {
- Some([
- self.0.sll_addr[0],
- self.0.sll_addr[1],
- self.0.sll_addr[2],
- self.0.sll_addr[3],
- self.0.sll_addr[4],
- self.0.sll_addr[5],
- ])
- }
- }
-
- impl fmt::Display for LinkAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if let Some(addr) = self.addr() {
- write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
- addr[0],
- addr[1],
- addr[2],
- addr[3],
- addr[4],
- addr[5])
- } else {
- Ok(())
- }
- }
- }
- impl private::SockaddrLikePriv for LinkAddr {}
- impl SockaddrLike for LinkAddr {
- unsafe fn from_raw(addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>)
- -> Option<Self> where Self: Sized
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_ll>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_PACKET {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
- }
-
- impl AsRef<libc::sockaddr_ll> for LinkAddr {
- fn as_ref(&self) -> &libc::sockaddr_ll {
- &self.0
- }
- }
-
- }
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos",
- target_os = "netbsd",
- target_os = "haiku",
- target_os = "openbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-mod datalink {
- feature! {
- #![feature = "net"]
- use super::{fmt, mem, private, ptr, SockaddrLike};
-
- /// Hardware Address
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- #[repr(transparent)]
- pub struct LinkAddr(pub(in super::super) libc::sockaddr_dl);
-
- impl LinkAddr {
- /// interface index, if != 0, system given index for interface
- #[cfg(not(target_os = "haiku"))]
- pub fn ifindex(&self) -> usize {
- self.0.sdl_index as usize
- }
-
- /// Datalink type
- #[cfg(not(target_os = "haiku"))]
- pub fn datalink_type(&self) -> u8 {
- self.0.sdl_type
- }
-
- /// MAC address start position
- pub fn nlen(&self) -> usize {
- self.0.sdl_nlen as usize
- }
-
- /// link level address length
- pub fn alen(&self) -> usize {
- self.0.sdl_alen as usize
- }
-
- /// link layer selector length
- #[cfg(not(target_os = "haiku"))]
- pub fn slen(&self) -> usize {
- self.0.sdl_slen as usize
- }
-
- /// if link level address length == 0,
- /// or `sdl_data` not be larger.
- pub fn is_empty(&self) -> bool {
- let nlen = self.nlen();
- let alen = self.alen();
- let data_len = self.0.sdl_data.len();
-
- alen == 0 || nlen + alen >= data_len
- }
-
- /// Physical-layer address (MAC)
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- pub fn addr(&self) -> Option<[u8; 6]> {
- let nlen = self.nlen();
- let data = self.0.sdl_data;
-
- if self.is_empty() {
- None
- } else {
- Some([
- data[nlen] as u8,
- data[nlen + 1] as u8,
- data[nlen + 2] as u8,
- data[nlen + 3] as u8,
- data[nlen + 4] as u8,
- data[nlen + 5] as u8,
- ])
- }
- }
- }
-
- impl fmt::Display for LinkAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if let Some(addr) = self.addr() {
- write!(f, "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
- addr[0],
- addr[1],
- addr[2],
- addr[3],
- addr[4],
- addr[5])
- } else {
- Ok(())
- }
- }
- }
- impl private::SockaddrLikePriv for LinkAddr {}
- impl SockaddrLike for LinkAddr {
- unsafe fn from_raw(addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>)
- -> Option<Self> where Self: Sized
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_dl>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_LINK {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
- }
-
- impl AsRef<libc::sockaddr_dl> for LinkAddr {
- fn as_ref(&self) -> &libc::sockaddr_dl {
- &self.0
- }
- }
-
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub mod vsock {
- use super::*;
- use crate::sys::socket::addr::AddressFamily;
- use libc::{sa_family_t, sockaddr_vm};
- use std::hash::{Hash, Hasher};
- use std::{fmt, mem};
-
- /// Socket address for VMWare VSockets protocol
- ///
- /// # References
- ///
- /// [vsock(7)](https://man7.org/linux/man-pages/man7/vsock.7.html)
- #[derive(Copy, Clone)]
- #[repr(transparent)]
- pub struct VsockAddr(pub(in super::super) sockaddr_vm);
-
- impl private::SockaddrLikePriv for VsockAddr {}
- impl SockaddrLike for VsockAddr {
- unsafe fn from_raw(
- addr: *const libc::sockaddr,
- len: Option<libc::socklen_t>,
- ) -> Option<Self>
- where
- Self: Sized,
- {
- if let Some(l) = len {
- if l != mem::size_of::<libc::sockaddr_vm>() as libc::socklen_t {
- return None;
- }
- }
- if (*addr).sa_family as i32 != libc::AF_VSOCK {
- return None;
- }
- Some(Self(ptr::read_unaligned(addr as *const _)))
- }
- }
-
- impl AsRef<libc::sockaddr_vm> for VsockAddr {
- fn as_ref(&self) -> &libc::sockaddr_vm {
- &self.0
- }
- }
-
- impl PartialEq for VsockAddr {
- fn eq(&self, other: &Self) -> bool {
- let (inner, other) = (self.0, other.0);
- (inner.svm_family, inner.svm_cid, inner.svm_port)
- == (other.svm_family, other.svm_cid, other.svm_port)
- }
- }
-
- impl Eq for VsockAddr {}
-
- impl Hash for VsockAddr {
- fn hash<H: Hasher>(&self, s: &mut H) {
- let inner = self.0;
- (inner.svm_family, inner.svm_cid, inner.svm_port).hash(s);
- }
- }
-
- /// VSOCK Address
- ///
- /// The address for AF_VSOCK socket is defined as a combination of a
- /// 32-bit Context Identifier (CID) and a 32-bit port number.
- impl VsockAddr {
- /// Construct a `VsockAddr` from its raw fields.
- pub fn new(cid: u32, port: u32) -> VsockAddr {
- let mut addr: sockaddr_vm = unsafe { mem::zeroed() };
- addr.svm_family = AddressFamily::Vsock as sa_family_t;
- addr.svm_cid = cid;
- addr.svm_port = port;
-
- VsockAddr(addr)
- }
-
- /// Context Identifier (CID)
- pub fn cid(&self) -> u32 {
- self.0.svm_cid
- }
-
- /// Port number
- pub fn port(&self) -> u32 {
- self.0.svm_port
- }
- }
-
- impl fmt::Display for VsockAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "cid: {} port: {}", self.cid(), self.port())
- }
- }
-
- impl fmt::Debug for VsockAddr {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, f)
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- mod types {
- use super::*;
-
- #[test]
- fn test_ipv4addr_to_libc() {
- let s = std::net::Ipv4Addr::new(1, 2, 3, 4);
- let l = ipv4addr_to_libc(s);
- assert_eq!(l.s_addr, u32::to_be(0x01020304));
- }
-
- #[test]
- fn test_ipv6addr_to_libc() {
- let s = std::net::Ipv6Addr::new(1, 2, 3, 4, 5, 6, 7, 8);
- let l = ipv6addr_to_libc(&s);
- assert_eq!(
- l.s6_addr,
- [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8]
- );
- }
- }
-
- mod link {
- #![allow(clippy::cast_ptr_alignment)]
-
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "illumos"
- ))]
- use super::super::super::socklen_t;
- use super::*;
-
- /// Don't panic when trying to display an empty datalink address
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ))]
- #[test]
- fn test_datalink_display() {
- use super::super::LinkAddr;
- use std::mem;
-
- let la = LinkAddr(libc::sockaddr_dl {
- sdl_len: 56,
- sdl_family: 18,
- sdl_index: 5,
- sdl_type: 24,
- sdl_nlen: 3,
- sdl_alen: 0,
- sdl_slen: 0,
- ..unsafe { mem::zeroed() }
- });
- format!("{}", la);
- }
-
- #[cfg(all(
- any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ),
- target_endian = "little"
- ))]
- #[test]
- fn linux_loopback() {
- #[repr(align(2))]
- struct Raw([u8; 20]);
-
- let bytes = Raw([
- 17u8, 0, 0, 0, 1, 0, 0, 0, 4, 3, 0, 6, 1, 2, 3, 4, 5, 6, 0, 0,
- ]);
- let sa = bytes.0.as_ptr() as *const libc::sockaddr;
- let len = None;
- let sock_addr =
- unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap();
- assert_eq!(sock_addr.family(), Some(AddressFamily::Packet));
- match sock_addr.as_link_addr() {
- Some(dl) => assert_eq!(dl.addr(), Some([1, 2, 3, 4, 5, 6])),
- None => panic!("Can't unwrap sockaddr storage"),
- }
- }
-
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[test]
- fn macos_loopback() {
- let bytes =
- [20i8, 18, 1, 0, 24, 3, 0, 0, 108, 111, 48, 0, 0, 0, 0, 0];
- let sa = bytes.as_ptr() as *const libc::sockaddr;
- let len = Some(bytes.len() as socklen_t);
- let sock_addr =
- unsafe { SockaddrStorage::from_raw(sa, len) }.unwrap();
- assert_eq!(sock_addr.family(), Some(AddressFamily::Link));
- match sock_addr.as_link_addr() {
- Some(dl) => {
- assert!(dl.addr().is_none());
- }
- None => panic!("Can't unwrap sockaddr storage"),
- }
- }
-
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[test]
- fn macos_tap() {
- let bytes = [
- 20i8, 18, 7, 0, 6, 3, 6, 0, 101, 110, 48, 24, 101, -112, -35,
- 76, -80,
- ];
- let ptr = bytes.as_ptr();
- let sa = ptr as *const libc::sockaddr;
- let len = Some(bytes.len() as socklen_t);
-
- let sock_addr =
- unsafe { SockaddrStorage::from_raw(sa, len).unwrap() };
- assert_eq!(sock_addr.family(), Some(AddressFamily::Link));
- match sock_addr.as_link_addr() {
- Some(dl) => {
- assert_eq!(dl.addr(), Some([24u8, 101, 144, 221, 76, 176]))
- }
- None => panic!("Can't unwrap sockaddr storage"),
- }
- }
-
- #[cfg(target_os = "illumos")]
- #[test]
- fn illumos_tap() {
- let bytes = [25u8, 0, 0, 0, 6, 0, 6, 0, 24, 101, 144, 221, 76, 176];
- let ptr = bytes.as_ptr();
- let sa = ptr as *const libc::sockaddr;
- let len = Some(bytes.len() as socklen_t);
- let _sock_addr = unsafe { SockaddrStorage::from_raw(sa, len) };
-
- assert!(_sock_addr.is_some());
-
- let sock_addr = _sock_addr.unwrap();
-
- assert_eq!(sock_addr.family().unwrap(), AddressFamily::Link);
-
- assert_eq!(
- sock_addr.as_link_addr().unwrap().addr(),
- Some([24u8, 101, 144, 221, 76, 176])
- );
- }
-
- #[test]
- fn size() {
- #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd",
- target_os = "haiku"
- ))]
- let l = mem::size_of::<libc::sockaddr_dl>();
- #[cfg(any(
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- let l = mem::size_of::<libc::sockaddr_ll>();
- assert_eq!(LinkAddr::size() as usize, l);
- }
- }
-
- mod sockaddr_in {
- use super::*;
- use std::str::FromStr;
-
- #[test]
- fn display() {
- let s = "127.0.0.1:8080";
- let addr = SockaddrIn::from_str(s).unwrap();
- assert_eq!(s, format!("{}", addr));
- }
-
- #[test]
- fn size() {
- assert_eq!(
- mem::size_of::<libc::sockaddr_in>(),
- SockaddrIn::size() as usize
- );
- }
- }
-
- mod sockaddr_in6 {
- use super::*;
- use std::str::FromStr;
-
- #[test]
- fn display() {
- let s = "[1234:5678:90ab:cdef::1111:2222]:8080";
- let addr = SockaddrIn6::from_str(s).unwrap();
- assert_eq!(s, format!("{}", addr));
- }
-
- #[test]
- fn size() {
- assert_eq!(
- mem::size_of::<libc::sockaddr_in6>(),
- SockaddrIn6::size() as usize
- );
- }
-
- #[test]
- // Ensure that we can convert to-and-from std::net variants without change.
- fn to_and_from() {
- let s = "[1234:5678:90ab:cdef::1111:2222]:8080";
- let mut nix_sin6 = SockaddrIn6::from_str(s).unwrap();
- nix_sin6.0.sin6_flowinfo = 0x12345678;
- nix_sin6.0.sin6_scope_id = 0x9abcdef0;
-
- let std_sin6 : std::net::SocketAddrV6 = nix_sin6.into();
- assert_eq!(nix_sin6, std_sin6.into());
- }
- }
-
- mod sockaddr_storage {
- use super::*;
-
- #[test]
- fn from_sockaddr_un_named() {
- let ua = UnixAddr::new("/var/run/mysock").unwrap();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
- let ss = unsafe {
- SockaddrStorage::from_raw(ptr, Some(ua.len()))
- }.unwrap();
- assert_eq!(ss.len(), ua.len());
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[test]
- fn from_sockaddr_un_abstract_named() {
- let name = String::from("nix\0abstract\0test");
- let ua = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
- let ss = unsafe {
- SockaddrStorage::from_raw(ptr, Some(ua.len()))
- }.unwrap();
- assert_eq!(ss.len(), ua.len());
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[test]
- fn from_sockaddr_un_abstract_unnamed() {
- let ua = UnixAddr::new_unnamed();
- let ptr = ua.as_ptr() as *const libc::sockaddr;
- let ss = unsafe {
- SockaddrStorage::from_raw(ptr, Some(ua.len()))
- }.unwrap();
- assert_eq!(ss.len(), ua.len());
- }
- }
-
- mod unixaddr {
- use super::*;
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[test]
- fn abstract_sun_path() {
- let name = String::from("nix\0abstract\0test");
- let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
-
- let sun_path1 =
- unsafe { &(*addr.as_ptr()).sun_path[..addr.path_len()] };
- let sun_path2 = [
- 0, 110, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0,
- 116, 101, 115, 116,
- ];
- assert_eq!(sun_path1, sun_path2);
- }
-
- #[test]
- fn size() {
- assert_eq!(
- mem::size_of::<libc::sockaddr_un>(),
- UnixAddr::size() as usize
- );
- }
- }
-}
diff --git a/vendor/nix/src/sys/socket/mod.rs b/vendor/nix/src/sys/socket/mod.rs
deleted file mode 100644
index 8513b6fbe..000000000
--- a/vendor/nix/src/sys/socket/mod.rs
+++ /dev/null
@@ -1,2487 +0,0 @@
-//! Socket interface functions
-//!
-//! [Further reading](https://man7.org/linux/man-pages/man7/socket.7.html)
-#[cfg(target_os = "linux")]
-#[cfg(feature = "uio")]
-use crate::sys::time::TimeSpec;
-#[cfg(feature = "uio")]
-use crate::sys::time::TimeVal;
-use crate::{errno::Errno, Result};
-use cfg_if::cfg_if;
-use libc::{
- self, c_int, c_void, iovec, size_t, socklen_t, CMSG_DATA, CMSG_FIRSTHDR,
- CMSG_LEN, CMSG_NXTHDR,
-};
-use std::convert::{TryFrom, TryInto};
-use std::io::{IoSlice, IoSliceMut};
-#[cfg(feature = "net")]
-use std::net;
-use std::os::unix::io::RawFd;
-use std::{mem, ptr, slice};
-
-#[deny(missing_docs)]
-mod addr;
-#[deny(missing_docs)]
-pub mod sockopt;
-
-/*
- *
- * ===== Re-exports =====
- *
- */
-
-pub use self::addr::{SockaddrLike, SockaddrStorage};
-
-#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
-#[allow(deprecated)]
-pub use self::addr::{AddressFamily, SockAddr, UnixAddr};
-#[cfg(any(target_os = "illumos", target_os = "solaris"))]
-#[allow(deprecated)]
-pub use self::addr::{AddressFamily, SockAddr, UnixAddr};
-#[allow(deprecated)]
-#[cfg(not(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
-)))]
-#[cfg(feature = "net")]
-pub use self::addr::{
- InetAddr, IpAddr, Ipv4Addr, Ipv6Addr, LinkAddr, SockaddrIn, SockaddrIn6,
-};
-#[allow(deprecated)]
-#[cfg(any(
- target_os = "illumos",
- target_os = "solaris",
- target_os = "haiku"
-))]
-#[cfg(feature = "net")]
-pub use self::addr::{
- InetAddr, IpAddr, Ipv4Addr, Ipv6Addr, SockaddrIn, SockaddrIn6,
-};
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use crate::sys::socket::addr::alg::AlgAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use crate::sys::socket::addr::netlink::NetlinkAddr;
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-#[cfg(feature = "ioctl")]
-pub use crate::sys::socket::addr::sys_control::SysControlAddr;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-pub use crate::sys::socket::addr::vsock::VsockAddr;
-
-#[cfg(feature = "uio")]
-pub use libc::{cmsghdr, msghdr};
-pub use libc::{sa_family_t, sockaddr, sockaddr_storage, sockaddr_un};
-#[cfg(feature = "net")]
-pub use libc::{sockaddr_in, sockaddr_in6};
-
-// Needed by the cmsg_space macro
-#[doc(hidden)]
-pub use libc::{c_uint, CMSG_SPACE};
-
-#[cfg(feature = "net")]
-use crate::sys::socket::addr::{ipv4addr_to_libc, ipv6addr_to_libc};
-
-/// These constants are used to specify the communication semantics
-/// when creating a socket with [`socket()`](fn.socket.html)
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-#[repr(i32)]
-#[non_exhaustive]
-pub enum SockType {
- /// Provides sequenced, reliable, two-way, connection-
- /// based byte streams. An out-of-band data transmission
- /// mechanism may be supported.
- Stream = libc::SOCK_STREAM,
- /// Supports datagrams (connectionless, unreliable
- /// messages of a fixed maximum length).
- Datagram = libc::SOCK_DGRAM,
- /// Provides a sequenced, reliable, two-way connection-
- /// based data transmission path for datagrams of fixed
- /// maximum length; a consumer is required to read an
- /// entire packet with each input system call.
- SeqPacket = libc::SOCK_SEQPACKET,
- /// Provides raw network protocol access.
- Raw = libc::SOCK_RAW,
- /// Provides a reliable datagram layer that does not
- /// guarantee ordering.
- #[cfg(not(any(target_os = "haiku")))]
- Rdm = libc::SOCK_RDM,
-}
-// The TryFrom impl could've been derived using libc_enum!. But for
-// backwards-compatibility with Nix-0.25.0 we manually implement it, so as to
-// keep the old variant names.
-impl TryFrom<i32> for SockType {
- type Error = crate::Error;
-
- fn try_from(x: i32) -> Result<Self> {
- match x {
- libc::SOCK_STREAM => Ok(Self::Stream),
- libc::SOCK_DGRAM => Ok(Self::Datagram),
- libc::SOCK_SEQPACKET => Ok(Self::SeqPacket),
- libc::SOCK_RAW => Ok(Self::Raw),
- #[cfg(not(any(target_os = "haiku")))]
- libc::SOCK_RDM => Ok(Self::Rdm),
- _ => Err(Errno::EINVAL)
- }
- }
-}
-
-/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
-/// to specify the protocol to use.
-#[repr(i32)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[non_exhaustive]
-pub enum SockProtocol {
- /// TCP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html))
- Tcp = libc::IPPROTO_TCP,
- /// UDP protocol ([ip(7)](https://man7.org/linux/man-pages/man7/ip.7.html))
- Udp = libc::IPPROTO_UDP,
- /// Raw sockets ([raw(7)](https://man7.org/linux/man-pages/man7/raw.7.html))
- Raw = libc::IPPROTO_RAW,
- /// Allows applications and other KEXTs to be notified when certain kernel events occur
- /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- KextEvent = libc::SYSPROTO_EVENT,
- /// Allows applications to configure and control a KEXT
- /// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- KextControl = libc::SYSPROTO_CONTROL,
- /// Receives routing and link updates and may be used to modify the routing tables (both IPv4 and IPv6), IP addresses, link
- // parameters, neighbor setups, queueing disciplines, traffic classes and packet classifiers
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkRoute = libc::NETLINK_ROUTE,
- /// Reserved for user-mode socket protocols
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkUserSock = libc::NETLINK_USERSOCK,
- /// Query information about sockets of various protocol families from the kernel
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkSockDiag = libc::NETLINK_SOCK_DIAG,
- /// SELinux event notifications.
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkSELinux = libc::NETLINK_SELINUX,
- /// Open-iSCSI
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkISCSI = libc::NETLINK_ISCSI,
- /// Auditing
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkAudit = libc::NETLINK_AUDIT,
- /// Access to FIB lookup from user space
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkFIBLookup = libc::NETLINK_FIB_LOOKUP,
- /// Netfilter subsystem
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkNetFilter = libc::NETLINK_NETFILTER,
- /// SCSI Transports
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkSCSITransport = libc::NETLINK_SCSITRANSPORT,
- /// Infiniband RDMA
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkRDMA = libc::NETLINK_RDMA,
- /// Transport IPv6 packets from netfilter to user space. Used by ip6_queue kernel module.
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkIPv6Firewall = libc::NETLINK_IP6_FW,
- /// DECnet routing messages
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkDECNetRoutingMessage = libc::NETLINK_DNRTMSG,
- /// Kernel messages to user space
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkKObjectUEvent = libc::NETLINK_KOBJECT_UEVENT,
- /// Netlink interface to request information about ciphers registered with the kernel crypto API as well as allow
- /// configuration of the kernel crypto API.
- /// ([ref](https://www.man7.org/linux/man-pages/man7/netlink.7.html))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NetlinkCrypto = libc::NETLINK_CRYPTO,
- /// Non-DIX type protocol number defined for the Ethernet IEEE 802.3 interface that allows packets of all protocols
- /// defined in the interface to be received.
- /// ([ref](https://man7.org/linux/man-pages/man7/packet.7.html))
- // The protocol number is fed into the socket syscall in network byte order.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- EthAll = libc::ETH_P_ALL.to_be(),
-}
-
-#[cfg(any(target_os = "linux"))]
-libc_bitflags! {
- /// Configuration flags for `SO_TIMESTAMPING` interface
- ///
- /// For use with [`Timestamping`][sockopt::Timestamping].
- /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
- pub struct TimestampingFlag: c_uint {
- /// Report any software timestamps when available.
- SOF_TIMESTAMPING_SOFTWARE;
- /// Report hardware timestamps as generated by SOF_TIMESTAMPING_TX_HARDWARE when available.
- SOF_TIMESTAMPING_RAW_HARDWARE;
- /// Collect transmiting timestamps as reported by hardware
- SOF_TIMESTAMPING_TX_HARDWARE;
- /// Collect transmiting timestamps as reported by software
- SOF_TIMESTAMPING_TX_SOFTWARE;
- /// Collect receiving timestamps as reported by hardware
- SOF_TIMESTAMPING_RX_HARDWARE;
- /// Collect receiving timestamps as reported by software
- SOF_TIMESTAMPING_RX_SOFTWARE;
- }
-}
-
-libc_bitflags! {
- /// Additional socket options
- pub struct SockFlag: c_int {
- /// Set non-blocking mode on the new socket
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SOCK_NONBLOCK;
- /// Set close-on-exec on the new descriptor
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SOCK_CLOEXEC;
- /// Return `EPIPE` instead of raising `SIGPIPE`
- #[cfg(target_os = "netbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SOCK_NOSIGPIPE;
- /// For domains `AF_INET(6)`, only allow `connect(2)`, `sendto(2)`, or `sendmsg(2)`
- /// to the DNS port (typically 53)
- #[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SOCK_DNS;
- }
-}
-
-libc_bitflags! {
- /// Flags for send/recv and their relatives
- pub struct MsgFlags: c_int {
- /// Sends or requests out-of-band data on sockets that support this notion
- /// (e.g., of type [`Stream`](enum.SockType.html)); the underlying protocol must also
- /// support out-of-band data.
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_OOB;
- /// Peeks at an incoming message. The data is treated as unread and the next
- /// [`recv()`](fn.recv.html)
- /// or similar function shall still return this data.
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_PEEK;
- /// Receive operation blocks until the full amount of data can be
- /// returned. The function may return smaller amount of data if a signal
- /// is caught, an error or disconnect occurs.
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_WAITALL;
- /// Enables nonblocking operation; if the operation would block,
- /// `EAGAIN` or `EWOULDBLOCK` is returned. This provides similar
- /// behavior to setting the `O_NONBLOCK` flag
- /// (via the [`fcntl`](../../fcntl/fn.fcntl.html)
- /// `F_SETFL` operation), but differs in that `MSG_DONTWAIT` is a per-
- /// call option, whereas `O_NONBLOCK` is a setting on the open file
- /// description (see [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)),
- /// which will affect all threads in
- /// the calling process and as well as other processes that hold
- /// file descriptors referring to the same open file description.
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_DONTWAIT;
- /// Receive flags: Control Data was discarded (buffer too small)
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_CTRUNC;
- /// For raw ([`Packet`](addr/enum.AddressFamily.html)), Internet datagram
- /// (since Linux 2.4.27/2.6.8),
- /// netlink (since Linux 2.6.22) and UNIX datagram (since Linux 3.4)
- /// sockets: return the real length of the packet or datagram, even
- /// when it was longer than the passed buffer. Not implemented for UNIX
- /// domain ([unix(7)](https://linux.die.net/man/7/unix)) sockets.
- ///
- /// For use with Internet stream sockets, see [tcp(7)](https://linux.die.net/man/7/tcp).
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_TRUNC;
- /// Terminates a record (when this notion is supported, as for
- /// sockets of type [`SeqPacket`](enum.SockType.html)).
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_EOR;
- /// This flag specifies that queued errors should be received from
- /// the socket error queue. (For more details, see
- /// [recvfrom(2)](https://linux.die.net/man/2/recvfrom))
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_ERRQUEUE;
- /// Set the `close-on-exec` flag for the file descriptor received via a UNIX domain
- /// file descriptor using the `SCM_RIGHTS` operation (described in
- /// [unix(7)](https://linux.die.net/man/7/unix)).
- /// This flag is useful for the same reasons as the `O_CLOEXEC` flag of
- /// [open(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html).
- ///
- /// Only used in [`recvmsg`](fn.recvmsg.html) function.
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_CMSG_CLOEXEC;
- /// Requests not to send `SIGPIPE` errors when the other end breaks the connection.
- /// (For more details, see [send(2)](https://linux.die.net/man/2/send)).
- #[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(deprecated)] // Suppress useless warnings from libc PR 2963
- MSG_NOSIGNAL;
- }
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- /// Unix credentials of the sending process.
- ///
- /// This struct is used with the `SO_PEERCRED` ancillary message
- /// and the `SCM_CREDENTIALS` control message for UNIX sockets.
- #[repr(transparent)]
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- pub struct UnixCredentials(libc::ucred);
-
- impl UnixCredentials {
- /// Creates a new instance with the credentials of the current process
- pub fn new() -> Self {
- // Safe because these FFI functions are inherently safe
- unsafe {
- UnixCredentials(libc::ucred {
- pid: libc::getpid(),
- uid: libc::getuid(),
- gid: libc::getgid()
- })
- }
- }
-
- /// Returns the process identifier
- pub fn pid(&self) -> libc::pid_t {
- self.0.pid
- }
-
- /// Returns the user identifier
- pub fn uid(&self) -> libc::uid_t {
- self.0.uid
- }
-
- /// Returns the group identifier
- pub fn gid(&self) -> libc::gid_t {
- self.0.gid
- }
- }
-
- impl Default for UnixCredentials {
- fn default() -> Self {
- Self::new()
- }
- }
-
- impl From<libc::ucred> for UnixCredentials {
- fn from(cred: libc::ucred) -> Self {
- UnixCredentials(cred)
- }
- }
-
- impl From<UnixCredentials> for libc::ucred {
- fn from(uc: UnixCredentials) -> Self {
- uc.0
- }
- }
- } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] {
- /// Unix credentials of the sending process.
- ///
- /// This struct is used with the `SCM_CREDS` ancillary message for UNIX sockets.
- #[repr(transparent)]
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- pub struct UnixCredentials(libc::cmsgcred);
-
- impl UnixCredentials {
- /// Returns the process identifier
- pub fn pid(&self) -> libc::pid_t {
- self.0.cmcred_pid
- }
-
- /// Returns the real user identifier
- pub fn uid(&self) -> libc::uid_t {
- self.0.cmcred_uid
- }
-
- /// Returns the effective user identifier
- pub fn euid(&self) -> libc::uid_t {
- self.0.cmcred_euid
- }
-
- /// Returns the real group identifier
- pub fn gid(&self) -> libc::gid_t {
- self.0.cmcred_gid
- }
-
- /// Returns a list group identifiers (the first one being the effective GID)
- pub fn groups(&self) -> &[libc::gid_t] {
- unsafe {
- slice::from_raw_parts(
- self.0.cmcred_groups.as_ptr() as *const libc::gid_t,
- self.0.cmcred_ngroups as _
- )
- }
- }
- }
-
- impl From<libc::cmsgcred> for UnixCredentials {
- fn from(cred: libc::cmsgcred) -> Self {
- UnixCredentials(cred)
- }
- }
- }
-}
-
-cfg_if! {
- if #[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
- ))] {
- /// Return type of [`LocalPeerCred`](crate::sys::socket::sockopt::LocalPeerCred)
- #[repr(transparent)]
- #[derive(Clone, Copy, Debug, Eq, PartialEq)]
- pub struct XuCred(libc::xucred);
-
- impl XuCred {
- /// Structure layout version
- pub fn version(&self) -> u32 {
- self.0.cr_version
- }
-
- /// Effective user ID
- pub fn uid(&self) -> libc::uid_t {
- self.0.cr_uid
- }
-
- /// Returns a list of group identifiers (the first one being the
- /// effective GID)
- pub fn groups(&self) -> &[libc::gid_t] {
- &self.0.cr_groups
- }
- }
- }
-}
-
-feature! {
-#![feature = "net"]
-/// Request for multicast socket operations
-///
-/// This is a wrapper type around `ip_mreq`.
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct IpMembershipRequest(libc::ip_mreq);
-
-impl IpMembershipRequest {
- /// Instantiate a new `IpMembershipRequest`
- ///
- /// If `interface` is `None`, then `Ipv4Addr::any()` will be used for the interface.
- pub fn new(group: net::Ipv4Addr, interface: Option<net::Ipv4Addr>)
- -> Self
- {
- let imr_addr = match interface {
- None => net::Ipv4Addr::UNSPECIFIED,
- Some(addr) => addr
- };
- IpMembershipRequest(libc::ip_mreq {
- imr_multiaddr: ipv4addr_to_libc(group),
- imr_interface: ipv4addr_to_libc(imr_addr)
- })
- }
-}
-
-/// Request for ipv6 multicast socket operations
-///
-/// This is a wrapper type around `ipv6_mreq`.
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct Ipv6MembershipRequest(libc::ipv6_mreq);
-
-impl Ipv6MembershipRequest {
- /// Instantiate a new `Ipv6MembershipRequest`
- pub const fn new(group: net::Ipv6Addr) -> Self {
- Ipv6MembershipRequest(libc::ipv6_mreq {
- ipv6mr_multiaddr: ipv6addr_to_libc(&group),
- ipv6mr_interface: 0,
- })
- }
-}
-}
-
-feature! {
-#![feature = "uio"]
-
-/// Create a buffer large enough for storing some control messages as returned
-/// by [`recvmsg`](fn.recvmsg.html).
-///
-/// # Examples
-///
-/// ```
-/// # #[macro_use] extern crate nix;
-/// # use nix::sys::time::TimeVal;
-/// # use std::os::unix::io::RawFd;
-/// # fn main() {
-/// // Create a buffer for a `ControlMessageOwned::ScmTimestamp` message
-/// let _ = cmsg_space!(TimeVal);
-/// // Create a buffer big enough for a `ControlMessageOwned::ScmRights` message
-/// // with two file descriptors
-/// let _ = cmsg_space!([RawFd; 2]);
-/// // Create a buffer big enough for a `ControlMessageOwned::ScmRights` message
-/// // and a `ControlMessageOwned::ScmTimestamp` message
-/// let _ = cmsg_space!(RawFd, TimeVal);
-/// # }
-/// ```
-// Unfortunately, CMSG_SPACE isn't a const_fn, or else we could return a
-// stack-allocated array.
-#[macro_export]
-macro_rules! cmsg_space {
- ( $( $x:ty ),* ) => {
- {
- let mut space = 0;
- $(
- // CMSG_SPACE is always safe
- space += unsafe {
- $crate::sys::socket::CMSG_SPACE(::std::mem::size_of::<$x>() as $crate::sys::socket::c_uint)
- } as usize;
- )*
- Vec::<u8>::with_capacity(space)
- }
- }
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-/// Contains outcome of sending or receiving a message
-///
-/// Use [`cmsgs`][RecvMsg::cmsgs] to access all the control messages present, and
-/// [`iovs`][RecvMsg::iovs`] to access underlying io slices.
-pub struct RecvMsg<'a, 's, S> {
- pub bytes: usize,
- cmsghdr: Option<&'a cmsghdr>,
- pub address: Option<S>,
- pub flags: MsgFlags,
- iobufs: std::marker::PhantomData<& 's()>,
- mhdr: msghdr,
-}
-
-impl<'a, S> RecvMsg<'a, '_, S> {
- /// Iterate over the valid control messages pointed to by this
- /// msghdr.
- pub fn cmsgs(&self) -> CmsgIterator {
- CmsgIterator {
- cmsghdr: self.cmsghdr,
- mhdr: &self.mhdr
- }
- }
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct CmsgIterator<'a> {
- /// Control message buffer to decode from. Must adhere to cmsg alignment.
- cmsghdr: Option<&'a cmsghdr>,
- mhdr: &'a msghdr
-}
-
-impl<'a> Iterator for CmsgIterator<'a> {
- type Item = ControlMessageOwned;
-
- fn next(&mut self) -> Option<ControlMessageOwned> {
- match self.cmsghdr {
- None => None, // No more messages
- Some(hdr) => {
- // Get the data.
- // Safe if cmsghdr points to valid data returned by recvmsg(2)
- let cm = unsafe { Some(ControlMessageOwned::decode_from(hdr))};
- // Advance the internal pointer. Safe if mhdr and cmsghdr point
- // to valid data returned by recvmsg(2)
- self.cmsghdr = unsafe {
- let p = CMSG_NXTHDR(self.mhdr as *const _, hdr as *const _);
- p.as_ref()
- };
- cm
- }
- }
- }
-}
-
-/// A type-safe wrapper around a single control message, as used with
-/// [`recvmsg`](#fn.recvmsg).
-///
-/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html)
-// Nix version 0.13.0 and earlier used ControlMessage for both recvmsg and
-// sendmsg. However, on some platforms the messages returned by recvmsg may be
-// unaligned. ControlMessageOwned takes those messages by copy, obviating any
-// alignment issues.
-//
-// See https://github.com/nix-rust/nix/issues/999
-#[derive(Clone, Debug, Eq, PartialEq)]
-#[non_exhaustive]
-pub enum ControlMessageOwned {
- /// Received version of [`ControlMessage::ScmRights`]
- ScmRights(Vec<RawFd>),
- /// Received version of [`ControlMessage::ScmCredentials`]
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ScmCredentials(UnixCredentials),
- /// Received version of [`ControlMessage::ScmCreds`]
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ScmCreds(UnixCredentials),
- /// A message of type `SCM_TIMESTAMP`, containing the time the
- /// packet was received by the kernel.
- ///
- /// See the kernel's explanation in "SO_TIMESTAMP" of
- /// [networking/timestamping](https://www.kernel.org/doc/Documentation/networking/timestamping.txt).
- ///
- /// # Examples
- ///
- /// ```
- /// # #[macro_use] extern crate nix;
- /// # use nix::sys::socket::*;
- /// # use nix::sys::time::*;
- /// # use std::io::{IoSlice, IoSliceMut};
- /// # use std::time::*;
- /// # use std::str::FromStr;
- /// # fn main() {
- /// // Set up
- /// let message = "Ohayō!".as_bytes();
- /// let in_socket = socket(
- /// AddressFamily::Inet,
- /// SockType::Datagram,
- /// SockFlag::empty(),
- /// None).unwrap();
- /// setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap();
- /// let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
- /// bind(in_socket, &localhost).unwrap();
- /// let address: SockaddrIn = getsockname(in_socket).unwrap();
- /// // Get initial time
- /// let time0 = SystemTime::now();
- /// // Send the message
- /// let iov = [IoSlice::new(message)];
- /// let flags = MsgFlags::empty();
- /// let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
- /// assert_eq!(message.len(), l);
- /// // Receive the message
- /// let mut buffer = vec![0u8; message.len()];
- /// let mut cmsgspace = cmsg_space!(TimeVal);
- /// let mut iov = [IoSliceMut::new(&mut buffer)];
- /// let r = recvmsg::<SockaddrIn>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
- /// .unwrap();
- /// let rtime = match r.cmsgs().next() {
- /// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
- /// Some(_) => panic!("Unexpected control message"),
- /// None => panic!("No control message")
- /// };
- /// // Check the final time
- /// let time1 = SystemTime::now();
- /// // the packet's received timestamp should lie in-between the two system
- /// // times, unless the system clock was adjusted in the meantime.
- /// let rduration = Duration::new(rtime.tv_sec() as u64,
- /// rtime.tv_usec() as u32 * 1000);
- /// assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
- /// assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
- /// // Close socket
- /// nix::unistd::close(in_socket).unwrap();
- /// # }
- /// ```
- ScmTimestamp(TimeVal),
- /// A set of nanosecond resolution timestamps
- ///
- /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
- #[cfg(all(target_os = "linux"))]
- ScmTimestampsns(Timestamps),
- /// Nanoseconds resolution timestamp
- ///
- /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
- #[cfg(all(target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ScmTimestampns(TimeSpec),
- #[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- ))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4PacketInfo(libc::in_pktinfo),
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "openbsd",
- target_os = "netbsd",
- ))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv6PacketInfo(libc::in6_pktinfo),
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4RecvIf(libc::sockaddr_dl),
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4RecvDstAddr(libc::in_addr),
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4OrigDstAddr(libc::sockaddr_in),
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv6OrigDstAddr(libc::sockaddr_in6),
-
- /// UDP Generic Receive Offload (GRO) allows receiving multiple UDP
- /// packets from a single sender.
- /// Fixed-size payloads are following one by one in a receive buffer.
- /// This Control Message indicates the size of all smaller packets,
- /// except, maybe, the last one.
- ///
- /// `UdpGroSegment` socket option should be enabled on a socket
- /// to allow receiving GRO packets.
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- UdpGroSegments(u16),
-
- /// SO_RXQ_OVFL indicates that an unsigned 32 bit value
- /// ancilliary msg (cmsg) should be attached to recieved
- /// skbs indicating the number of packets dropped by the
- /// socket between the last recieved packet and this
- /// received packet.
- ///
- /// `RxqOvfl` socket option should be enabled on a socket
- /// to allow receiving the drop counter.
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- RxqOvfl(u32),
-
- /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4RecvErr(libc::sock_extended_err, Option<sockaddr_in>),
- /// Socket error queue control messages read with the `MSG_ERRQUEUE` flag.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv6RecvErr(libc::sock_extended_err, Option<sockaddr_in6>),
-
- /// Catch-all variant for unimplemented cmsg types.
- #[doc(hidden)]
- Unknown(UnknownCmsg),
-}
-
-/// For representing packet timestamps via `SO_TIMESTAMPING` interface
-#[cfg(all(target_os = "linux"))]
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub struct Timestamps {
- /// software based timestamp, usually one containing data
- pub system: TimeSpec,
- /// legacy timestamp, usually empty
- pub hw_trans: TimeSpec,
- /// hardware based timestamp
- pub hw_raw: TimeSpec,
-}
-
-impl ControlMessageOwned {
- /// Decodes a `ControlMessageOwned` from raw bytes.
- ///
- /// This is only safe to call if the data is correct for the message type
- /// specified in the header. Normally, the kernel ensures that this is the
- /// case. "Correct" in this case includes correct length, alignment and
- /// actual content.
- // Clippy complains about the pointer alignment of `p`, not understanding
- // that it's being fed to a function that can handle that.
- #[allow(clippy::cast_ptr_alignment)]
- unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned
- {
- let p = CMSG_DATA(header);
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- let len = header as *const _ as usize + header.cmsg_len as usize
- - p as usize;
- match (header.cmsg_level, header.cmsg_type) {
- (libc::SOL_SOCKET, libc::SCM_RIGHTS) => {
- let n = len / mem::size_of::<RawFd>();
- let mut fds = Vec::with_capacity(n);
- for i in 0..n {
- let fdp = (p as *const RawFd).add(i);
- fds.push(ptr::read_unaligned(fdp));
- }
- ControlMessageOwned::ScmRights(fds)
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- (libc::SOL_SOCKET, libc::SCM_CREDENTIALS) => {
- let cred: libc::ucred = ptr::read_unaligned(p as *const _);
- ControlMessageOwned::ScmCredentials(cred.into())
- }
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- (libc::SOL_SOCKET, libc::SCM_CREDS) => {
- let cred: libc::cmsgcred = ptr::read_unaligned(p as *const _);
- ControlMessageOwned::ScmCreds(cred.into())
- }
- #[cfg(not(target_os = "haiku"))]
- (libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => {
- let tv: libc::timeval = ptr::read_unaligned(p as *const _);
- ControlMessageOwned::ScmTimestamp(TimeVal::from(tv))
- },
- #[cfg(all(target_os = "linux"))]
- (libc::SOL_SOCKET, libc::SCM_TIMESTAMPNS) => {
- let ts: libc::timespec = ptr::read_unaligned(p as *const _);
- ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts))
- }
- #[cfg(all(target_os = "linux"))]
- (libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => {
- let tp = p as *const libc::timespec;
- let ts: libc::timespec = ptr::read_unaligned(tp);
- let system = TimeSpec::from(ts);
- let ts: libc::timespec = ptr::read_unaligned(tp.add(1));
- let hw_trans = TimeSpec::from(ts);
- let ts: libc::timespec = ptr::read_unaligned(tp.add(2));
- let hw_raw = TimeSpec::from(ts);
- let timestamping = Timestamps { system, hw_trans, hw_raw };
- ControlMessageOwned::ScmTimestampsns(timestamping)
- }
- #[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"
- ))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IPV6, libc::IPV6_PKTINFO) => {
- let info = ptr::read_unaligned(p as *const libc::in6_pktinfo);
- ControlMessageOwned::Ipv6PacketInfo(info)
- }
- #[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- ))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IP, libc::IP_PKTINFO) => {
- let info = ptr::read_unaligned(p as *const libc::in_pktinfo);
- ControlMessageOwned::Ipv4PacketInfo(info)
- }
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IP, libc::IP_RECVIF) => {
- let dl = ptr::read_unaligned(p as *const libc::sockaddr_dl);
- ControlMessageOwned::Ipv4RecvIf(dl)
- },
- #[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IP, libc::IP_RECVDSTADDR) => {
- let dl = ptr::read_unaligned(p as *const libc::in_addr);
- ControlMessageOwned::Ipv4RecvDstAddr(dl)
- },
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {
- let dl = ptr::read_unaligned(p as *const libc::sockaddr_in);
- ControlMessageOwned::Ipv4OrigDstAddr(dl)
- },
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- (libc::SOL_UDP, libc::UDP_GRO) => {
- let gso_size: u16 = ptr::read_unaligned(p as *const _);
- ControlMessageOwned::UdpGroSegments(gso_size)
- },
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- (libc::SOL_SOCKET, libc::SO_RXQ_OVFL) => {
- let drop_counter = ptr::read_unaligned(p as *const u32);
- ControlMessageOwned::RxqOvfl(drop_counter)
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IP, libc::IP_RECVERR) => {
- let (err, addr) = Self::recv_err_helper::<sockaddr_in>(p, len);
- ControlMessageOwned::Ipv4RecvErr(err, addr)
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IPV6, libc::IPV6_RECVERR) => {
- let (err, addr) = Self::recv_err_helper::<sockaddr_in6>(p, len);
- ControlMessageOwned::Ipv6RecvErr(err, addr)
- },
- #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
- #[cfg(feature = "net")]
- (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {
- let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6);
- ControlMessageOwned::Ipv6OrigDstAddr(dl)
- },
- (_, _) => {
- let sl = slice::from_raw_parts(p, len);
- let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(sl));
- ControlMessageOwned::Unknown(ucmsg)
- }
- }
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- #[allow(clippy::cast_ptr_alignment)] // False positive
- unsafe fn recv_err_helper<T>(p: *mut libc::c_uchar, len: usize) -> (libc::sock_extended_err, Option<T>) {
- let ee = p as *const libc::sock_extended_err;
- let err = ptr::read_unaligned(ee);
-
- // For errors originating on the network, SO_EE_OFFENDER(ee) points inside the p[..len]
- // CMSG_DATA buffer. For local errors, there is no address included in the control
- // message, and SO_EE_OFFENDER(ee) points beyond the end of the buffer. So, we need to
- // validate that the address object is in-bounds before we attempt to copy it.
- let addrp = libc::SO_EE_OFFENDER(ee) as *const T;
-
- if addrp.offset(1) as usize - (p as usize) > len {
- (err, None)
- } else {
- (err, Some(ptr::read_unaligned(addrp)))
- }
- }
-}
-
-/// A type-safe zero-copy wrapper around a single control message, as used wih
-/// [`sendmsg`](#fn.sendmsg). More types may be added to this enum; do not
-/// exhaustively pattern-match it.
-///
-/// [Further reading](https://man7.org/linux/man-pages/man3/cmsg.3.html)
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-#[non_exhaustive]
-pub enum ControlMessage<'a> {
- /// A message of type `SCM_RIGHTS`, containing an array of file
- /// descriptors passed between processes.
- ///
- /// See the description in the "Ancillary messages" section of the
- /// [unix(7) man page](https://man7.org/linux/man-pages/man7/unix.7.html).
- ///
- /// Using multiple `ScmRights` messages for a single `sendmsg` call isn't
- /// recommended since it causes platform-dependent behaviour: It might
- /// swallow all but the first `ScmRights` message or fail with `EINVAL`.
- /// Instead, you can put all fds to be passed into a single `ScmRights`
- /// message.
- ScmRights(&'a [RawFd]),
- /// A message of type `SCM_CREDENTIALS`, containing the pid, uid and gid of
- /// a process connected to the socket.
- ///
- /// This is similar to the socket option `SO_PEERCRED`, but requires a
- /// process to explicitly send its credentials. A process running as root is
- /// allowed to specify any credentials, while credentials sent by other
- /// processes are verified by the kernel.
- ///
- /// For further information, please refer to the
- /// [`unix(7)`](https://man7.org/linux/man-pages/man7/unix.7.html) man page.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ScmCredentials(&'a UnixCredentials),
- /// A message of type `SCM_CREDS`, containing the pid, uid, euid, gid and groups of
- /// a process connected to the socket.
- ///
- /// This is similar to the socket options `LOCAL_CREDS` and `LOCAL_PEERCRED`, but
- /// requires a process to explicitly send its credentials.
- ///
- /// Credentials are always overwritten by the kernel, so this variant does have
- /// any data, unlike the receive-side
- /// [`ControlMessageOwned::ScmCreds`].
- ///
- /// For further information, please refer to the
- /// [`unix(4)`](https://www.freebsd.org/cgi/man.cgi?query=unix) man page.
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ScmCreds,
-
- /// Set IV for `AF_ALG` crypto API.
- ///
- /// For further information, please refer to the
- /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AlgSetIv(&'a [u8]),
- /// Set crypto operation for `AF_ALG` crypto API. It may be one of
- /// `ALG_OP_ENCRYPT` or `ALG_OP_DECRYPT`
- ///
- /// For further information, please refer to the
- /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AlgSetOp(&'a libc::c_int),
- /// Set the length of associated authentication data (AAD) (applicable only to AEAD algorithms)
- /// for `AF_ALG` crypto API.
- ///
- /// For further information, please refer to the
- /// [`documentation`](https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html)
- #[cfg(any(
- target_os = "android",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AlgSetAeadAssoclen(&'a u32),
-
- /// UDP GSO makes it possible for applications to generate network packets
- /// for a virtual MTU much greater than the real one.
- /// The length of the send data no longer matches the expected length on
- /// the wire.
- /// The size of the datagram payload as it should appear on the wire may be
- /// passed through this control message.
- /// Send buffer should consist of multiple fixed-size wire payloads
- /// following one by one, and the last, possibly smaller one.
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- UdpGsoSegments(&'a u16),
-
- /// Configure the sending addressing and interface for v4
- ///
- /// For further information, please refer to the
- /// [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html) man page.
- #[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "android",
- target_os = "ios",))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4PacketInfo(&'a libc::in_pktinfo),
-
- /// Configure the sending addressing and interface for v6
- ///
- /// For further information, please refer to the
- /// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page.
- #[cfg(any(target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "android",
- target_os = "ios",))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv6PacketInfo(&'a libc::in6_pktinfo),
-
- /// Configure the IPv4 source address with `IP_SENDSRCADDR`.
- #[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
- ))]
- #[cfg(feature = "net")]
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- Ipv4SendSrcAddr(&'a libc::in_addr),
-
- /// SO_RXQ_OVFL indicates that an unsigned 32 bit value
- /// ancilliary msg (cmsg) should be attached to recieved
- /// skbs indicating the number of packets dropped by the
- /// socket between the last recieved packet and this
- /// received packet.
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- RxqOvfl(&'a u32),
-
- /// Configure the transmission time of packets.
- ///
- /// For further information, please refer to the
- /// [`tc-etf(8)`](https://man7.org/linux/man-pages/man8/tc-etf.8.html) man
- /// page.
- #[cfg(target_os = "linux")]
- TxTime(&'a u64),
-}
-
-// An opaque structure used to prevent cmsghdr from being a public type
-#[doc(hidden)]
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct UnknownCmsg(cmsghdr, Vec<u8>);
-
-impl<'a> ControlMessage<'a> {
- /// The value of CMSG_SPACE on this message.
- /// Safe because CMSG_SPACE is always safe
- fn space(&self) -> usize {
- unsafe{CMSG_SPACE(self.len() as libc::c_uint) as usize}
- }
-
- /// The value of CMSG_LEN on this message.
- /// Safe because CMSG_LEN is always safe
- #[cfg(any(target_os = "android",
- all(target_os = "linux", not(target_env = "musl"))))]
- fn cmsg_len(&self) -> usize {
- unsafe{CMSG_LEN(self.len() as libc::c_uint) as usize}
- }
-
- #[cfg(not(any(target_os = "android",
- all(target_os = "linux", not(target_env = "musl")))))]
- fn cmsg_len(&self) -> libc::c_uint {
- unsafe{CMSG_LEN(self.len() as libc::c_uint)}
- }
-
- /// Return a reference to the payload data as a byte pointer
- fn copy_to_cmsg_data(&self, cmsg_data: *mut u8) {
- let data_ptr = match *self {
- ControlMessage::ScmRights(fds) => {
- fds as *const _ as *const u8
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::ScmCredentials(creds) => {
- &creds.0 as *const libc::ucred as *const u8
- }
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- ControlMessage::ScmCreds => {
- // The kernel overwrites the data, we just zero it
- // to make sure it's not uninitialized memory
- unsafe { ptr::write_bytes(cmsg_data, 0, self.len()) };
- return
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetIv(iv) => {
- #[allow(deprecated)] // https://github.com/rust-lang/libc/issues/1501
- let af_alg_iv = libc::af_alg_iv {
- ivlen: iv.len() as u32,
- iv: [0u8; 0],
- };
-
- let size = mem::size_of_val(&af_alg_iv);
-
- unsafe {
- ptr::copy_nonoverlapping(
- &af_alg_iv as *const _ as *const u8,
- cmsg_data,
- size,
- );
- ptr::copy_nonoverlapping(
- iv.as_ptr(),
- cmsg_data.add(size),
- iv.len()
- );
- };
-
- return
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetOp(op) => {
- op as *const _ as *const u8
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetAeadAssoclen(len) => {
- len as *const _ as *const u8
- },
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- ControlMessage::UdpGsoSegments(gso_size) => {
- gso_size as *const _ as *const u8
- },
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8,
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8,
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- ControlMessage::RxqOvfl(drop_count) => {
- drop_count as *const _ as *const u8
- },
- #[cfg(target_os = "linux")]
- ControlMessage::TxTime(tx_time) => {
- tx_time as *const _ as *const u8
- },
- };
- unsafe {
- ptr::copy_nonoverlapping(
- data_ptr,
- cmsg_data,
- self.len()
- )
- };
- }
-
- /// The size of the payload, excluding its cmsghdr
- fn len(&self) -> usize {
- match *self {
- ControlMessage::ScmRights(fds) => {
- mem::size_of_val(fds)
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::ScmCredentials(creds) => {
- mem::size_of_val(creds)
- }
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- ControlMessage::ScmCreds => {
- mem::size_of::<libc::cmsgcred>()
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetIv(iv) => {
- mem::size_of::<&[u8]>() + iv.len()
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetOp(op) => {
- mem::size_of_val(op)
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetAeadAssoclen(len) => {
- mem::size_of_val(len)
- },
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- ControlMessage::UdpGsoSegments(gso_size) => {
- mem::size_of_val(gso_size)
- },
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info),
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info),
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr),
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- ControlMessage::RxqOvfl(drop_count) => {
- mem::size_of_val(drop_count)
- },
- #[cfg(target_os = "linux")]
- ControlMessage::TxTime(tx_time) => {
- mem::size_of_val(tx_time)
- },
- }
- }
-
- /// Returns the value to put into the `cmsg_level` field of the header.
- fn cmsg_level(&self) -> libc::c_int {
- match *self {
- ControlMessage::ScmRights(_) => libc::SOL_SOCKET,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::ScmCredentials(_) => libc::SOL_SOCKET,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- ControlMessage::ScmCreds => libc::SOL_SOCKET,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) |
- ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG,
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6,
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP,
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET,
- #[cfg(target_os = "linux")]
- ControlMessage::TxTime(_) => libc::SOL_SOCKET,
- }
- }
-
- /// Returns the value to put into the `cmsg_type` field of the header.
- fn cmsg_type(&self) -> libc::c_int {
- match *self {
- ControlMessage::ScmRights(_) => libc::SCM_RIGHTS,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::ScmCredentials(_) => libc::SCM_CREDENTIALS,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- ControlMessage::ScmCreds => libc::SCM_CREDS,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetIv(_) => {
- libc::ALG_SET_IV
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetOp(_) => {
- libc::ALG_SET_OP
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessage::AlgSetAeadAssoclen(_) => {
- libc::ALG_SET_AEAD_ASSOCLEN
- },
- #[cfg(target_os = "linux")]
- #[cfg(feature = "net")]
- ControlMessage::UdpGsoSegments(_) => {
- libc::UDP_SEGMENT
- },
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "android",
- target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO,
- #[cfg(any(target_os = "linux", target_os = "macos",
- target_os = "netbsd", target_os = "freebsd",
- target_os = "android", target_os = "ios",))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO,
- #[cfg(any(target_os = "netbsd", target_os = "freebsd",
- target_os = "openbsd", target_os = "dragonfly"))]
- #[cfg(feature = "net")]
- ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR,
- #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
- ControlMessage::RxqOvfl(_) => {
- libc::SO_RXQ_OVFL
- },
- #[cfg(target_os = "linux")]
- ControlMessage::TxTime(_) => {
- libc::SCM_TXTIME
- },
- }
- }
-
- // Unsafe: cmsg must point to a valid cmsghdr with enough space to
- // encode self.
- unsafe fn encode_into(&self, cmsg: *mut cmsghdr) {
- (*cmsg).cmsg_level = self.cmsg_level();
- (*cmsg).cmsg_type = self.cmsg_type();
- (*cmsg).cmsg_len = self.cmsg_len();
- self.copy_to_cmsg_data(CMSG_DATA(cmsg));
- }
-}
-
-
-/// Send data in scatter-gather vectors to a socket, possibly accompanied
-/// by ancillary data. Optionally direct the message at the given address,
-/// as with sendto.
-///
-/// Allocates if cmsgs is nonempty.
-///
-/// # Examples
-/// When not directing to any specific address, use `()` for the generic type
-/// ```
-/// # use nix::sys::socket::*;
-/// # use nix::unistd::pipe;
-/// # use std::io::IoSlice;
-/// let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None,
-/// SockFlag::empty())
-/// .unwrap();
-/// let (r, w) = pipe().unwrap();
-///
-/// let iov = [IoSlice::new(b"hello")];
-/// let fds = [r];
-/// let cmsg = ControlMessage::ScmRights(&fds);
-/// sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap();
-/// ```
-/// When directing to a specific address, the generic type will be inferred.
-/// ```
-/// # use nix::sys::socket::*;
-/// # use nix::unistd::pipe;
-/// # use std::io::IoSlice;
-/// # use std::str::FromStr;
-/// let localhost = SockaddrIn::from_str("1.2.3.4:8080").unwrap();
-/// let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(),
-/// None).unwrap();
-/// let (r, w) = pipe().unwrap();
-///
-/// let iov = [IoSlice::new(b"hello")];
-/// let fds = [r];
-/// let cmsg = ControlMessage::ScmRights(&fds);
-/// sendmsg(fd, &iov, &[cmsg], MsgFlags::empty(), Some(&localhost)).unwrap();
-/// ```
-pub fn sendmsg<S>(fd: RawFd, iov: &[IoSlice<'_>], cmsgs: &[ControlMessage],
- flags: MsgFlags, addr: Option<&S>) -> Result<usize>
- where S: SockaddrLike
-{
- let capacity = cmsgs.iter().map(|c| c.space()).sum();
-
- // First size the buffer needed to hold the cmsgs. It must be zeroed,
- // because subsequent code will not clear the padding bytes.
- let mut cmsg_buffer = vec![0u8; capacity];
-
- let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr);
-
- let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) };
-
- Errno::result(ret).map(|r| r as usize)
-}
-
-
-/// An extension of `sendmsg` that allows the caller to transmit multiple
-/// messages on a socket using a single system call. This has performance
-/// benefits for some applications.
-///
-/// Allocations are performed for cmsgs and to build `msghdr` buffer
-///
-/// # Arguments
-///
-/// * `fd`: Socket file descriptor
-/// * `data`: Struct that implements `IntoIterator` with `SendMmsgData` items
-/// * `flags`: Optional flags passed directly to the operating system.
-///
-/// # Returns
-/// `Vec` with numbers of sent bytes on each sent message.
-///
-/// # References
-/// [`sendmsg`](fn.sendmsg.html)
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-pub fn sendmmsg<'a, XS, AS, C, I, S>(
- fd: RawFd,
- data: &'a mut MultiHeaders<S>,
- slices: XS,
- // one address per group of slices
- addrs: AS,
- // shared across all the messages
- cmsgs: C,
- flags: MsgFlags
-) -> crate::Result<MultiResults<'a, S>>
- where
- XS: IntoIterator<Item = &'a I>,
- AS: AsRef<[Option<S>]>,
- I: AsRef<[IoSlice<'a>]> + 'a,
- C: AsRef<[ControlMessage<'a>]> + 'a,
- S: SockaddrLike + 'a
-{
-
- let mut count = 0;
-
-
- for (i, ((slice, addr), mmsghdr)) in slices.into_iter().zip(addrs.as_ref()).zip(data.items.iter_mut() ).enumerate() {
- let mut p = &mut mmsghdr.msg_hdr;
- p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec;
- p.msg_iovlen = slice.as_ref().len() as _;
-
- p.msg_namelen = addr.as_ref().map_or(0, S::len);
- p.msg_name = addr.as_ref().map_or(ptr::null(), S::as_ptr) as _;
-
- // Encode each cmsg. This must happen after initializing the header because
- // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields.
- // CMSG_FIRSTHDR is always safe
- let mut pmhdr: *mut cmsghdr = unsafe { CMSG_FIRSTHDR(p) };
- for cmsg in cmsgs.as_ref() {
- assert_ne!(pmhdr, ptr::null_mut());
- // Safe because we know that pmhdr is valid, and we initialized it with
- // sufficient space
- unsafe { cmsg.encode_into(pmhdr) };
- // Safe because mhdr is valid
- pmhdr = unsafe { CMSG_NXTHDR(p, pmhdr) };
- }
-
- count = i+1;
- }
-
- let sent = Errno::result(unsafe {
- libc::sendmmsg(
- fd,
- data.items.as_mut_ptr(),
- count as _,
- flags.bits() as _
- )
- })? as usize;
-
- Ok(MultiResults {
- rmm: data,
- current_index: 0,
- received: sent
- })
-
-}
-
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-#[derive(Debug)]
-/// Preallocated structures needed for [`recvmmsg`] and [`sendmmsg`] functions
-pub struct MultiHeaders<S> {
- // preallocated boxed slice of mmsghdr
- items: Box<[libc::mmsghdr]>,
- addresses: Box<[mem::MaybeUninit<S>]>,
- // while we are not using it directly - this is used to store control messages
- // and we retain pointers to them inside items array
- #[allow(dead_code)]
- cmsg_buffers: Option<Box<[u8]>>,
- msg_controllen: usize,
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-impl<S> MultiHeaders<S> {
- /// Preallocate structure used by [`recvmmsg`] and [`sendmmsg`] takes number of headers to preallocate
- ///
- /// `cmsg_buffer` should be created with [`cmsg_space!`] if needed
- pub fn preallocate(num_slices: usize, cmsg_buffer: Option<Vec<u8>>) -> Self
- where
- S: Copy + SockaddrLike,
- {
- // we will be storing pointers to addresses inside mhdr - convert it into boxed
- // slice so it can'be changed later by pushing anything into self.addresses
- let mut addresses = vec![std::mem::MaybeUninit::uninit(); num_slices].into_boxed_slice();
-
- let msg_controllen = cmsg_buffer.as_ref().map_or(0, |v| v.capacity());
-
- // we'll need a cmsg_buffer for each slice, we preallocate a vector and split
- // it into "slices" parts
- let cmsg_buffers =
- cmsg_buffer.map(|v| vec![0u8; v.capacity() * num_slices].into_boxed_slice());
-
- let items = addresses
- .iter_mut()
- .enumerate()
- .map(|(ix, address)| {
- let (ptr, cap) = match &cmsg_buffers {
- Some(v) => ((&v[ix * msg_controllen] as *const u8), msg_controllen),
- None => (std::ptr::null(), 0),
- };
- let msg_hdr = unsafe { pack_mhdr_to_receive(std::ptr::null(), 0, ptr, cap, address.as_mut_ptr()) };
- libc::mmsghdr {
- msg_hdr,
- msg_len: 0,
- }
- })
- .collect::<Vec<_>>();
-
- Self {
- items: items.into_boxed_slice(),
- addresses,
- cmsg_buffers,
- msg_controllen,
- }
- }
-}
-
-/// An extension of recvmsg that allows the caller to receive multiple messages from a socket using a single system call.
-///
-/// This has performance benefits for some applications.
-///
-/// This method performs no allocations.
-///
-/// Returns an iterator producing [`RecvMsg`], one per received messages. Each `RecvMsg` can produce
-/// iterators over [`IoSlice`] with [`iovs`][RecvMsg::iovs`] and
-/// `ControlMessageOwned` with [`cmsgs`][RecvMsg::cmsgs].
-///
-/// # Bugs (in underlying implementation, at least in Linux)
-/// The timeout argument does not work as intended. The timeout is checked only after the receipt
-/// of each datagram, so that if up to `vlen`-1 datagrams are received before the timeout expires,
-/// but then no further datagrams are received, the call will block forever.
-///
-/// If an error occurs after at least one message has been received, the call succeeds, and returns
-/// the number of messages received. The error code is expected to be returned on a subsequent
-/// call to recvmmsg(). In the current implementation, however, the error code can be
-/// overwritten in the meantime by an unrelated network event on a socket, for example an
-/// incoming ICMP packet.
-
-// On aarch64 linux using recvmmsg and trying to get hardware/kernel timestamps might not
-// always produce the desired results - see https://github.com/nix-rust/nix/pull/1744 for more
-// details
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-pub fn recvmmsg<'a, XS, S, I>(
- fd: RawFd,
- data: &'a mut MultiHeaders<S>,
- slices: XS,
- flags: MsgFlags,
- mut timeout: Option<crate::sys::time::TimeSpec>,
-) -> crate::Result<MultiResults<'a, S>>
-where
- XS: IntoIterator<Item = &'a I>,
- I: AsRef<[IoSliceMut<'a>]> + 'a,
-{
- let mut count = 0;
- for (i, (slice, mmsghdr)) in slices.into_iter().zip(data.items.iter_mut()).enumerate() {
- let mut p = &mut mmsghdr.msg_hdr;
- p.msg_iov = slice.as_ref().as_ptr() as *mut libc::iovec;
- p.msg_iovlen = slice.as_ref().len() as _;
- count = i + 1;
- }
-
- let timeout_ptr = timeout
- .as_mut()
- .map_or_else(std::ptr::null_mut, |t| t as *mut _ as *mut libc::timespec);
-
- let received = Errno::result(unsafe {
- libc::recvmmsg(
- fd,
- data.items.as_mut_ptr(),
- count as _,
- flags.bits() as _,
- timeout_ptr,
- )
- })? as usize;
-
- Ok(MultiResults {
- rmm: data,
- current_index: 0,
- received,
- })
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-#[derive(Debug)]
-/// Iterator over results of [`recvmmsg`]/[`sendmmsg`]
-///
-///
-pub struct MultiResults<'a, S> {
- // preallocated structures
- rmm: &'a MultiHeaders<S>,
- current_index: usize,
- received: usize,
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
-))]
-impl<'a, S> Iterator for MultiResults<'a, S>
-where
- S: Copy + SockaddrLike,
-{
- type Item = RecvMsg<'a, 'a, S>;
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn next(&mut self) -> Option<Self::Item> {
- if self.current_index >= self.received {
- return None;
- }
- let mmsghdr = self.rmm.items[self.current_index];
-
- // as long as we are not reading past the index writen by recvmmsg - address
- // will be initialized
- let address = unsafe { self.rmm.addresses[self.current_index].assume_init() };
-
- self.current_index += 1;
- Some(unsafe {
- read_mhdr(
- mmsghdr.msg_hdr,
- mmsghdr.msg_len as isize,
- self.rmm.msg_controllen,
- address,
- )
- })
- }
-}
-
-impl<'a, S> RecvMsg<'_, 'a, S> {
- /// Iterate over the filled io slices pointed by this msghdr
- pub fn iovs(&self) -> IoSliceIterator<'a> {
- IoSliceIterator {
- index: 0,
- remaining: self.bytes,
- slices: unsafe {
- // safe for as long as mgdr is properly initialized and references are valid.
- // for multi messages API we initialize it with an empty
- // slice and replace with a concrete buffer
- // for single message API we hold a lifetime reference to ioslices
- std::slice::from_raw_parts(self.mhdr.msg_iov as *const _, self.mhdr.msg_iovlen as _)
- },
- }
- }
-}
-
-#[derive(Debug)]
-pub struct IoSliceIterator<'a> {
- index: usize,
- remaining: usize,
- slices: &'a [IoSlice<'a>],
-}
-
-impl<'a> Iterator for IoSliceIterator<'a> {
- type Item = &'a [u8];
-
- fn next(&mut self) -> Option<Self::Item> {
- if self.index >= self.slices.len() {
- return None;
- }
- let slice = &self.slices[self.index][..self.remaining.min(self.slices[self.index].len())];
- self.remaining -= slice.len();
- self.index += 1;
- if slice.is_empty() {
- return None;
- }
-
- Some(slice)
- }
-}
-
-// test contains both recvmmsg and timestaping which is linux only
-// there are existing tests for recvmmsg only in tests/
-#[cfg(target_os = "linux")]
-#[cfg(test)]
-mod test {
- use crate::sys::socket::{AddressFamily, ControlMessageOwned};
- use crate::*;
- use std::str::FromStr;
-
- #[cfg_attr(qemu, ignore)]
- #[test]
- fn test_recvmm2() -> crate::Result<()> {
- use crate::sys::socket::{
- sendmsg, setsockopt, socket, sockopt::Timestamping, MsgFlags, SockFlag, SockType,
- SockaddrIn, TimestampingFlag,
- };
- use std::io::{IoSlice, IoSliceMut};
-
- let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap();
-
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )?;
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::SOCK_NONBLOCK,
- None,
- )?;
-
- crate::sys::socket::bind(rsock, &sock_addr)?;
-
- setsockopt(rsock, Timestamping, &TimestampingFlag::all())?;
-
- let sbuf = (0..400).map(|i| i as u8).collect::<Vec<_>>();
-
- let mut recv_buf = vec![0; 1024];
-
- let mut recv_iovs = Vec::new();
- let mut pkt_iovs = Vec::new();
-
- for (ix, chunk) in recv_buf.chunks_mut(256).enumerate() {
- pkt_iovs.push(IoSliceMut::new(chunk));
- if ix % 2 == 1 {
- recv_iovs.push(pkt_iovs);
- pkt_iovs = Vec::new();
- }
- }
- drop(pkt_iovs);
-
- let flags = MsgFlags::empty();
- let iov1 = [IoSlice::new(&sbuf)];
-
- let cmsg = cmsg_space!(crate::sys::socket::Timestamps);
- sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap();
-
- let mut data = super::MultiHeaders::<()>::preallocate(recv_iovs.len(), Some(cmsg));
-
- let t = sys::time::TimeSpec::from_duration(std::time::Duration::from_secs(10));
-
- let recv = super::recvmmsg(rsock, &mut data, recv_iovs.iter(), flags, Some(t))?;
-
- for rmsg in recv {
- #[cfg(not(any(qemu, target_arch = "aarch64")))]
- let mut saw_time = false;
- let mut recvd = 0;
- for cmsg in rmsg.cmsgs() {
- if let ControlMessageOwned::ScmTimestampsns(timestamps) = cmsg {
- let ts = timestamps.system;
-
- let sys_time =
- crate::time::clock_gettime(crate::time::ClockId::CLOCK_REALTIME)?;
- let diff = if ts > sys_time {
- ts - sys_time
- } else {
- sys_time - ts
- };
- assert!(std::time::Duration::from(diff).as_secs() < 60);
- #[cfg(not(any(qemu, target_arch = "aarch64")))]
- {
- saw_time = true;
- }
- }
- }
-
- #[cfg(not(any(qemu, target_arch = "aarch64")))]
- assert!(saw_time);
-
- for iov in rmsg.iovs() {
- recvd += iov.len();
- }
- assert_eq!(recvd, 400);
- }
-
- Ok(())
- }
-}
-unsafe fn read_mhdr<'a, 'i, S>(
- mhdr: msghdr,
- r: isize,
- msg_controllen: usize,
- address: S,
-) -> RecvMsg<'a, 'i, S>
- where S: SockaddrLike
-{
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- let cmsghdr = {
- if mhdr.msg_controllen > 0 {
- debug_assert!(!mhdr.msg_control.is_null());
- debug_assert!(msg_controllen >= mhdr.msg_controllen as usize);
- CMSG_FIRSTHDR(&mhdr as *const msghdr)
- } else {
- ptr::null()
- }.as_ref()
- };
-
- RecvMsg {
- bytes: r as usize,
- cmsghdr,
- address: Some(address),
- flags: MsgFlags::from_bits_truncate(mhdr.msg_flags),
- mhdr,
- iobufs: std::marker::PhantomData,
- }
-}
-
-/// Pack pointers to various structures into into msghdr
-///
-/// # Safety
-/// `iov_buffer` and `iov_buffer_len` must point to a slice
-/// of `IoSliceMut` and number of available elements or be a null pointer and 0
-///
-/// `cmsg_buffer` and `cmsg_capacity` must point to a byte buffer used
-/// to store control headers later or be a null pointer and 0 if control
-/// headers are not used
-///
-/// Buffers must remain valid for the whole lifetime of msghdr
-unsafe fn pack_mhdr_to_receive<S>(
- iov_buffer: *const IoSliceMut,
- iov_buffer_len: usize,
- cmsg_buffer: *const u8,
- cmsg_capacity: usize,
- address: *mut S,
-) -> msghdr
- where
- S: SockaddrLike
-{
- // Musl's msghdr has private fields, so this is the only way to
- // initialize it.
- let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
- let p = mhdr.as_mut_ptr();
- (*p).msg_name = (*address).as_mut_ptr() as *mut c_void;
- (*p).msg_namelen = S::size();
- (*p).msg_iov = iov_buffer as *mut iovec;
- (*p).msg_iovlen = iov_buffer_len as _;
- (*p).msg_control = cmsg_buffer as *mut c_void;
- (*p).msg_controllen = cmsg_capacity as _;
- (*p).msg_flags = 0;
- mhdr.assume_init()
-}
-
-fn pack_mhdr_to_send<'a, I, C, S>(
- cmsg_buffer: &mut [u8],
- iov: I,
- cmsgs: C,
- addr: Option<&S>
-) -> msghdr
- where
- I: AsRef<[IoSlice<'a>]>,
- C: AsRef<[ControlMessage<'a>]>,
- S: SockaddrLike + 'a
-{
- let capacity = cmsg_buffer.len();
-
- // The message header must be initialized before the individual cmsgs.
- let cmsg_ptr = if capacity > 0 {
- cmsg_buffer.as_ptr() as *mut c_void
- } else {
- ptr::null_mut()
- };
-
- let mhdr = unsafe {
- // Musl's msghdr has private fields, so this is the only way to
- // initialize it.
- let mut mhdr = mem::MaybeUninit::<msghdr>::zeroed();
- let p = mhdr.as_mut_ptr();
- (*p).msg_name = addr.map(S::as_ptr).unwrap_or(ptr::null()) as *mut _;
- (*p).msg_namelen = addr.map(S::len).unwrap_or(0);
- // transmute iov into a mutable pointer. sendmsg doesn't really mutate
- // the buffer, but the standard says that it takes a mutable pointer
- (*p).msg_iov = iov.as_ref().as_ptr() as *mut _;
- (*p).msg_iovlen = iov.as_ref().len() as _;
- (*p).msg_control = cmsg_ptr;
- (*p).msg_controllen = capacity as _;
- (*p).msg_flags = 0;
- mhdr.assume_init()
- };
-
- // Encode each cmsg. This must happen after initializing the header because
- // CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields.
- // CMSG_FIRSTHDR is always safe
- let mut pmhdr: *mut cmsghdr = unsafe { CMSG_FIRSTHDR(&mhdr as *const msghdr) };
- for cmsg in cmsgs.as_ref() {
- assert_ne!(pmhdr, ptr::null_mut());
- // Safe because we know that pmhdr is valid, and we initialized it with
- // sufficient space
- unsafe { cmsg.encode_into(pmhdr) };
- // Safe because mhdr is valid
- pmhdr = unsafe { CMSG_NXTHDR(&mhdr as *const msghdr, pmhdr) };
- }
-
- mhdr
-}
-
-/// Receive message in scatter-gather vectors from a socket, and
-/// optionally receive ancillary data into the provided buffer.
-/// If no ancillary data is desired, use () as the type parameter.
-///
-/// # Arguments
-///
-/// * `fd`: Socket file descriptor
-/// * `iov`: Scatter-gather list of buffers to receive the message
-/// * `cmsg_buffer`: Space to receive ancillary data. Should be created by
-/// [`cmsg_space!`](../../macro.cmsg_space.html)
-/// * `flags`: Optional flags passed directly to the operating system.
-///
-/// # References
-/// [recvmsg(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvmsg.html)
-pub fn recvmsg<'a, 'outer, 'inner, S>(fd: RawFd, iov: &'outer mut [IoSliceMut<'inner>],
- mut cmsg_buffer: Option<&'a mut Vec<u8>>,
- flags: MsgFlags) -> Result<RecvMsg<'a, 'inner, S>>
- where S: SockaddrLike + 'a,
- 'inner: 'outer
-{
- let mut address = mem::MaybeUninit::uninit();
-
- let (msg_control, msg_controllen) = cmsg_buffer.as_mut()
- .map(|v| (v.as_mut_ptr(), v.capacity()))
- .unwrap_or((ptr::null_mut(), 0));
- let mut mhdr = unsafe {
- pack_mhdr_to_receive(iov.as_ref().as_ptr(), iov.len(), msg_control, msg_controllen, address.as_mut_ptr())
- };
-
- let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) };
-
- let r = Errno::result(ret)?;
-
- Ok(unsafe { read_mhdr(mhdr, r, msg_controllen, address.assume_init()) })
-}
-}
-
-/// Create an endpoint for communication
-///
-/// The `protocol` specifies a particular protocol to be used with the
-/// socket. Normally only a single protocol exists to support a
-/// particular socket type within a given protocol family, in which case
-/// protocol can be specified as `None`. However, it is possible that many
-/// protocols may exist, in which case a particular protocol must be
-/// specified in this manner.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html)
-pub fn socket<T: Into<Option<SockProtocol>>>(
- domain: AddressFamily,
- ty: SockType,
- flags: SockFlag,
- protocol: T,
-) -> Result<RawFd> {
- let protocol = match protocol.into() {
- None => 0,
- Some(p) => p as c_int,
- };
-
- // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a
- // little easier to understand by separating it out. So we have to merge these bitfields
- // here.
- let mut ty = ty as c_int;
- ty |= flags.bits();
-
- let res = unsafe { libc::socket(domain as c_int, ty, protocol) };
-
- Errno::result(res)
-}
-
-/// Create a pair of connected sockets
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html)
-pub fn socketpair<T: Into<Option<SockProtocol>>>(
- domain: AddressFamily,
- ty: SockType,
- protocol: T,
- flags: SockFlag,
-) -> Result<(RawFd, RawFd)> {
- let protocol = match protocol.into() {
- None => 0,
- Some(p) => p as c_int,
- };
-
- // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a
- // little easier to understand by separating it out. So we have to merge these bitfields
- // here.
- let mut ty = ty as c_int;
- ty |= flags.bits();
-
- let mut fds = [-1, -1];
-
- let res = unsafe {
- libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr())
- };
- Errno::result(res)?;
-
- Ok((fds[0], fds[1]))
-}
-
-/// Listen for connections on a socket
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
-pub fn listen(sockfd: RawFd, backlog: usize) -> Result<()> {
- let res = unsafe { libc::listen(sockfd, backlog as c_int) };
-
- Errno::result(res).map(drop)
-}
-
-/// Bind a name to a socket
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html)
-pub fn bind(fd: RawFd, addr: &dyn SockaddrLike) -> Result<()> {
- let res = unsafe { libc::bind(fd, addr.as_ptr(), addr.len()) };
-
- Errno::result(res).map(drop)
-}
-
-/// Accept a connection on a socket
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html)
-pub fn accept(sockfd: RawFd) -> Result<RawFd> {
- let res = unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) };
-
- Errno::result(res)
-}
-
-/// Accept a connection on a socket
-///
-/// [Further reading](https://man7.org/linux/man-pages/man2/accept.2.html)
-#[cfg(any(
- all(
- target_os = "android",
- any(
- target_arch = "aarch64",
- target_arch = "x86",
- target_arch = "x86_64"
- )
- ),
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> {
- let res = unsafe {
- libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits())
- };
-
- Errno::result(res)
-}
-
-/// Initiate a connection on a socket
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html)
-pub fn connect(fd: RawFd, addr: &dyn SockaddrLike) -> Result<()> {
- let res = unsafe { libc::connect(fd, addr.as_ptr(), addr.len()) };
-
- Errno::result(res).map(drop)
-}
-
-/// Receive data from a connection-oriented socket. Returns the number of
-/// bytes read
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html)
-pub fn recv(sockfd: RawFd, buf: &mut [u8], flags: MsgFlags) -> Result<usize> {
- unsafe {
- let ret = libc::recv(
- sockfd,
- buf.as_ptr() as *mut c_void,
- buf.len() as size_t,
- flags.bits(),
- );
-
- Errno::result(ret).map(|r| r as usize)
- }
-}
-
-/// Receive data from a connectionless or connection-oriented socket. Returns
-/// the number of bytes read and, for connectionless sockets, the socket
-/// address of the sender.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/recvfrom.html)
-pub fn recvfrom<T: SockaddrLike>(
- sockfd: RawFd,
- buf: &mut [u8],
-) -> Result<(usize, Option<T>)> {
- unsafe {
- let mut addr = mem::MaybeUninit::<T>::uninit();
- let mut len = mem::size_of_val(&addr) as socklen_t;
-
- let ret = Errno::result(libc::recvfrom(
- sockfd,
- buf.as_ptr() as *mut c_void,
- buf.len() as size_t,
- 0,
- addr.as_mut_ptr() as *mut libc::sockaddr,
- &mut len as *mut socklen_t,
- ))? as usize;
-
- Ok((
- ret,
- T::from_raw(
- addr.assume_init().as_ptr() as *const libc::sockaddr,
- Some(len),
- ),
- ))
- }
-}
-
-/// Send a message to a socket
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sendto.html)
-pub fn sendto(
- fd: RawFd,
- buf: &[u8],
- addr: &dyn SockaddrLike,
- flags: MsgFlags,
-) -> Result<usize> {
- let ret = unsafe {
- libc::sendto(
- fd,
- buf.as_ptr() as *const c_void,
- buf.len() as size_t,
- flags.bits(),
- addr.as_ptr(),
- addr.len(),
- )
- };
-
- Errno::result(ret).map(|r| r as usize)
-}
-
-/// Send data to a connection-oriented socket. Returns the number of bytes read
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html)
-pub fn send(fd: RawFd, buf: &[u8], flags: MsgFlags) -> Result<usize> {
- let ret = unsafe {
- libc::send(
- fd,
- buf.as_ptr() as *const c_void,
- buf.len() as size_t,
- flags.bits(),
- )
- };
-
- Errno::result(ret).map(|r| r as usize)
-}
-
-/*
- *
- * ===== Socket Options =====
- *
- */
-
-/// Represents a socket option that can be retrieved.
-pub trait GetSockOpt: Copy {
- type Val;
-
- /// Look up the value of this socket option on the given socket.
- fn get(&self, fd: RawFd) -> Result<Self::Val>;
-}
-
-/// Represents a socket option that can be set.
-pub trait SetSockOpt: Clone {
- type Val;
-
- /// Set the value of this socket option on the given socket.
- fn set(&self, fd: RawFd, val: &Self::Val) -> Result<()>;
-}
-
-/// Get the current value for the requested socket option
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html)
-pub fn getsockopt<O: GetSockOpt>(fd: RawFd, opt: O) -> Result<O::Val> {
- opt.get(fd)
-}
-
-/// Sets the value for the requested socket option
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html)
-///
-/// # Examples
-///
-/// ```
-/// use nix::sys::socket::setsockopt;
-/// use nix::sys::socket::sockopt::KeepAlive;
-/// use std::net::TcpListener;
-/// use std::os::unix::io::AsRawFd;
-///
-/// let listener = TcpListener::bind("0.0.0.0:0").unwrap();
-/// let fd = listener.as_raw_fd();
-/// let res = setsockopt(fd, KeepAlive, &true);
-/// assert!(res.is_ok());
-/// ```
-pub fn setsockopt<O: SetSockOpt>(
- fd: RawFd,
- opt: O,
- val: &O::Val,
-) -> Result<()> {
- opt.set(fd, val)
-}
-
-/// Get the address of the peer connected to the socket `fd`.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html)
-pub fn getpeername<T: SockaddrLike>(fd: RawFd) -> Result<T> {
- unsafe {
- let mut addr = mem::MaybeUninit::<T>::uninit();
- let mut len = T::size();
-
- let ret = libc::getpeername(
- fd,
- addr.as_mut_ptr() as *mut libc::sockaddr,
- &mut len,
- );
-
- Errno::result(ret)?;
-
- T::from_raw(addr.assume_init().as_ptr(), Some(len)).ok_or(Errno::EINVAL)
- }
-}
-
-/// Get the current address to which the socket `fd` is bound.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html)
-pub fn getsockname<T: SockaddrLike>(fd: RawFd) -> Result<T> {
- unsafe {
- let mut addr = mem::MaybeUninit::<T>::uninit();
- let mut len = T::size();
-
- let ret = libc::getsockname(
- fd,
- addr.as_mut_ptr() as *mut libc::sockaddr,
- &mut len,
- );
-
- Errno::result(ret)?;
-
- T::from_raw(addr.assume_init().as_ptr(), Some(len)).ok_or(Errno::EINVAL)
- }
-}
-
-/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a
-/// certain size.
-///
-/// In C this would usually be done by casting. The `len` argument
-/// should be the number of bytes in the `sockaddr_storage` that are actually
-/// allocated and valid. It must be at least as large as all the useful parts
-/// of the structure. Note that in the case of a `sockaddr_un`, `len` need not
-/// include the terminating null.
-#[deprecated(
- since = "0.24.0",
- note = "use SockaddrLike or SockaddrStorage instead"
-)]
-#[allow(deprecated)]
-pub fn sockaddr_storage_to_addr(
- addr: &sockaddr_storage,
- len: usize,
-) -> Result<SockAddr> {
- assert!(len <= mem::size_of::<sockaddr_storage>());
- if len < mem::size_of_val(&addr.ss_family) {
- return Err(Errno::ENOTCONN);
- }
-
- match c_int::from(addr.ss_family) {
- #[cfg(feature = "net")]
- libc::AF_INET => {
- assert!(len >= mem::size_of::<sockaddr_in>());
- let sin = unsafe {
- *(addr as *const sockaddr_storage as *const sockaddr_in)
- };
- Ok(SockAddr::Inet(InetAddr::V4(sin)))
- }
- #[cfg(feature = "net")]
- libc::AF_INET6 => {
- assert!(len >= mem::size_of::<sockaddr_in6>());
- let sin6 = unsafe { *(addr as *const _ as *const sockaddr_in6) };
- Ok(SockAddr::Inet(InetAddr::V6(sin6)))
- }
- libc::AF_UNIX => unsafe {
- let sun = *(addr as *const _ as *const sockaddr_un);
- let sun_len = len.try_into().unwrap();
- Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, sun_len)))
- },
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg(feature = "net")]
- libc::AF_PACKET => {
- use libc::sockaddr_ll;
- // Don't assert anything about the size.
- // Apparently the Linux kernel can return smaller sizes when
- // the value in the last element of sockaddr_ll (`sll_addr`) is
- // smaller than the declared size of that field
- let sll = unsafe { *(addr as *const _ as *const sockaddr_ll) };
- Ok(SockAddr::Link(LinkAddr(sll)))
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_NETLINK => {
- use libc::sockaddr_nl;
- let snl = unsafe { *(addr as *const _ as *const sockaddr_nl) };
- Ok(SockAddr::Netlink(NetlinkAddr(snl)))
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_ALG => {
- use libc::sockaddr_alg;
- let salg = unsafe { *(addr as *const _ as *const sockaddr_alg) };
- Ok(SockAddr::Alg(AlgAddr(salg)))
- }
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::AF_VSOCK => {
- use libc::sockaddr_vm;
- let svm = unsafe { *(addr as *const _ as *const sockaddr_vm) };
- Ok(SockAddr::Vsock(VsockAddr(svm)))
- }
- af => panic!("unexpected address family {}", af),
- }
-}
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum Shutdown {
- /// Further receptions will be disallowed.
- Read,
- /// Further transmissions will be disallowed.
- Write,
- /// Further receptions and transmissions will be disallowed.
- Both,
-}
-
-/// Shut down part of a full-duplex connection.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html)
-pub fn shutdown(df: RawFd, how: Shutdown) -> Result<()> {
- unsafe {
- use libc::shutdown;
-
- let how = match how {
- Shutdown::Read => libc::SHUT_RD,
- Shutdown::Write => libc::SHUT_WR,
- Shutdown::Both => libc::SHUT_RDWR,
- };
-
- Errno::result(shutdown(df, how)).map(drop)
- }
-}
-
-#[cfg(test)]
-mod tests {
- #[test]
- fn can_use_cmsg_space() {
- let _ = cmsg_space!(u8);
- }
-}
diff --git a/vendor/nix/src/sys/socket/sockopt.rs b/vendor/nix/src/sys/socket/sockopt.rs
deleted file mode 100644
index 06e9ee456..000000000
--- a/vendor/nix/src/sys/socket/sockopt.rs
+++ /dev/null
@@ -1,1422 +0,0 @@
-//! Socket options as used by `setsockopt` and `getsockopt`.
-use super::{GetSockOpt, SetSockOpt};
-use crate::errno::Errno;
-use crate::sys::time::TimeVal;
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{self, c_int, c_void, socklen_t};
-use std::ffi::{OsStr, OsString};
-use std::{
- convert::TryFrom,
- mem::{self, MaybeUninit}
-};
-#[cfg(target_family = "unix")]
-use std::os::unix::ffi::OsStrExt;
-use std::os::unix::io::RawFd;
-
-// Constants
-// TCP_CA_NAME_MAX isn't defined in user space include files
-#[cfg(any(target_os = "freebsd", target_os = "linux"))]
-#[cfg(feature = "net")]
-const TCP_CA_NAME_MAX: usize = 16;
-
-/// Helper for implementing `SetSockOpt` for a given socket option. See
-/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
-///
-/// This macro aims to help implementing `SetSockOpt` for different socket options that accept
-/// different kinds of data to be used with `setsockopt`.
-///
-/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option
-/// you are implementing represents a simple type.
-///
-/// # Arguments
-///
-/// * `$name:ident`: name of the type you want to implement `SetSockOpt` for.
-/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets*
-/// (`libc::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
-/// and more. Please refer to your system manual for more options. Will be passed as the second
-/// argument (`level`) to the `setsockopt` call.
-/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
-/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`)
-/// to the `setsockopt` call.
-/// * Type of the value that you are going to set.
-/// * Type that implements the `Set` trait for the type from the previous item (like `SetBool` for
-/// `bool`, `SetUsize` for `usize`, etc.).
-macro_rules! setsockopt_impl {
- ($name:ident, $level:expr, $flag:path, $ty:ty, $setter:ty) => {
- impl SetSockOpt for $name {
- type Val = $ty;
-
- fn set(&self, fd: RawFd, val: &$ty) -> Result<()> {
- unsafe {
- let setter: $setter = Set::new(val);
-
- let res = libc::setsockopt(
- fd,
- $level,
- $flag,
- setter.ffi_ptr(),
- setter.ffi_len(),
- );
- Errno::result(res).map(drop)
- }
- }
- }
- };
-}
-
-/// Helper for implementing `GetSockOpt` for a given socket option. See
-/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html).
-///
-/// This macro aims to help implementing `GetSockOpt` for different socket options that accept
-/// different kinds of data to be use with `getsockopt`.
-///
-/// Instead of using this macro directly consider using `sockopt_impl!`, especially if the option
-/// you are implementing represents a simple type.
-///
-/// # Arguments
-///
-/// * Name of the type you want to implement `GetSockOpt` for.
-/// * Socket layer, or a `protocol level`: could be *raw sockets* (`lic::SOL_SOCKET`), *ip
-/// protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`), and more. Please refer
-/// to your system manual for more options. Will be passed as the second argument (`level`) to
-/// the `getsockopt` call.
-/// * A flag to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
-/// `libc::SO_ORIGINAL_DST` and others. Will be passed as the third argument (`option_name`) to
-/// the `getsockopt` call.
-/// * Type of the value that you are going to get.
-/// * Type that implements the `Get` trait for the type from the previous item (`GetBool` for
-/// `bool`, `GetUsize` for `usize`, etc.).
-macro_rules! getsockopt_impl {
- ($name:ident, $level:expr, $flag:path, $ty:ty, $getter:ty) => {
- impl GetSockOpt for $name {
- type Val = $ty;
-
- fn get(&self, fd: RawFd) -> Result<$ty> {
- unsafe {
- let mut getter: $getter = Get::uninit();
-
- let res = libc::getsockopt(
- fd,
- $level,
- $flag,
- getter.ffi_ptr(),
- getter.ffi_len(),
- );
- Errno::result(res)?;
-
- match <$ty>::try_from(getter.assume_init()) {
- Err(_) => Err(Errno::EINVAL),
- Ok(r) => Ok(r)
- }
- }
- }
- }
- };
-}
-
-/// Helper to generate the sockopt accessors. See
-/// [`::sys::socket::GetSockOpt`](sys/socket/trait.GetSockOpt.html) and
-/// [`::sys::socket::SetSockOpt`](sys/socket/trait.SetSockOpt.html).
-///
-/// This macro aims to help implementing `GetSockOpt` and `SetSockOpt` for different socket options
-/// that accept different kinds of data to be use with `getsockopt` and `setsockopt` respectively.
-///
-/// Basically this macro wraps up the [`getsockopt_impl!`](macro.getsockopt_impl.html) and
-/// [`setsockopt_impl!`](macro.setsockopt_impl.html) macros.
-///
-/// # Arguments
-///
-/// * `GetOnly`, `SetOnly` or `Both`: whether you want to implement only getter, only setter or
-/// both of them.
-/// * `$name:ident`: name of type `GetSockOpt`/`SetSockOpt` will be implemented for.
-/// * `$level:expr` : socket layer, or a `protocol level`: could be *raw sockets*
-/// (`lic::SOL_SOCKET`), *ip protocol* (libc::IPPROTO_IP), *tcp protocol* (`libc::IPPROTO_TCP`),
-/// and more. Please refer to your system manual for more options. Will be passed as the second
-/// argument (`level`) to the `getsockopt`/`setsockopt` call.
-/// * `$flag:path`: a flag name to set. Some examples: `libc::SO_REUSEADDR`, `libc::TCP_NODELAY`,
-/// `libc::IP_ADD_MEMBERSHIP` and others. Will be passed as the third argument (`option_name`)
-/// to the `setsockopt`/`getsockopt` call.
-/// * `$ty:ty`: type of the value that will be get/set.
-/// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`.
-/// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`.
-// Some targets don't use all rules.
-#[allow(unknown_lints)]
-#[allow(unused_macro_rules)]
-macro_rules! sockopt_impl {
- ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, bool) => {
- sockopt_impl!($(#[$attr])*
- $name, GetOnly, $level, $flag, bool, GetBool);
- };
-
- ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, u8) => {
- sockopt_impl!($(#[$attr])* $name, GetOnly, $level, $flag, u8, GetU8);
- };
-
- ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, usize) =>
- {
- sockopt_impl!($(#[$attr])*
- $name, GetOnly, $level, $flag, usize, GetUsize);
- };
-
- ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, bool) => {
- sockopt_impl!($(#[$attr])*
- $name, SetOnly, $level, $flag, bool, SetBool);
- };
-
- ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, u8) => {
- sockopt_impl!($(#[$attr])* $name, SetOnly, $level, $flag, u8, SetU8);
- };
-
- ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, usize) =>
- {
- sockopt_impl!($(#[$attr])*
- $name, SetOnly, $level, $flag, usize, SetUsize);
- };
-
- ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, bool) => {
- sockopt_impl!($(#[$attr])*
- $name, Both, $level, $flag, bool, GetBool, SetBool);
- };
-
- ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, u8) => {
- sockopt_impl!($(#[$attr])*
- $name, Both, $level, $flag, u8, GetU8, SetU8);
- };
-
- ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, usize) => {
- sockopt_impl!($(#[$attr])*
- $name, Both, $level, $flag, usize, GetUsize, SetUsize);
- };
-
- ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path,
- OsString<$array:ty>) =>
- {
- sockopt_impl!($(#[$attr])*
- $name, Both, $level, $flag, OsString, GetOsString<$array>,
- SetOsString);
- };
-
- /*
- * Matchers with generic getter types must be placed at the end, so
- * they'll only match _after_ specialized matchers fail
- */
- ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, $ty:ty) =>
- {
- sockopt_impl!($(#[$attr])*
- $name, GetOnly, $level, $flag, $ty, GetStruct<$ty>);
- };
-
- ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, $ty:ty,
- $getter:ty) =>
- {
- $(#[$attr])*
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- pub struct $name;
-
- getsockopt_impl!($name, $level, $flag, $ty, $getter);
- };
-
- ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, $ty:ty) =>
- {
- sockopt_impl!($(#[$attr])*
- $name, SetOnly, $level, $flag, $ty, SetStruct<$ty>);
- };
-
- ($(#[$attr:meta])* $name:ident, SetOnly, $level:expr, $flag:path, $ty:ty,
- $setter:ty) =>
- {
- $(#[$attr])*
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- pub struct $name;
-
- setsockopt_impl!($name, $level, $flag, $ty, $setter);
- };
-
- ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, $ty:ty,
- $getter:ty, $setter:ty) =>
- {
- $(#[$attr])*
- #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
- pub struct $name;
-
- setsockopt_impl!($name, $level, $flag, $ty, $setter);
- getsockopt_impl!($name, $level, $flag, $ty, $getter);
- };
-
- ($(#[$attr:meta])* $name:ident, Both, $level:expr, $flag:path, $ty:ty) => {
- sockopt_impl!($(#[$attr])*
- $name, Both, $level, $flag, $ty, GetStruct<$ty>,
- SetStruct<$ty>);
- };
-}
-
-/*
- *
- * ===== Define sockopts =====
- *
- */
-
-sockopt_impl!(
- /// Enables local address reuse
- ReuseAddr,
- Both,
- libc::SOL_SOCKET,
- libc::SO_REUSEADDR,
- bool
-);
-#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
-sockopt_impl!(
- /// Permits multiple AF_INET or AF_INET6 sockets to be bound to an
- /// identical socket address.
- ReusePort,
- Both,
- libc::SOL_SOCKET,
- libc::SO_REUSEPORT,
- bool
-);
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Under most circumstances, TCP sends data when it is presented; when
- /// outstanding data has not yet been acknowledged, it gathers small amounts
- /// of output to be sent in a single packet once an acknowledgement is
- /// received. For a small number of clients, such as window systems that
- /// send a stream of mouse events which receive no replies, this
- /// packetization may cause significant delays. The boolean option
- /// TCP_NODELAY defeats this algorithm.
- TcpNoDelay,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_NODELAY,
- bool
-);
-sockopt_impl!(
- /// When enabled, a close(2) or shutdown(2) will not return until all
- /// queued messages for the socket have been successfully sent or the
- /// linger timeout has been reached.
- Linger,
- Both,
- libc::SOL_SOCKET,
- libc::SO_LINGER,
- libc::linger
-);
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Join a multicast group
- IpAddMembership,
- SetOnly,
- libc::IPPROTO_IP,
- libc::IP_ADD_MEMBERSHIP,
- super::IpMembershipRequest
-);
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Leave a multicast group.
- IpDropMembership,
- SetOnly,
- libc::IPPROTO_IP,
- libc::IP_DROP_MEMBERSHIP,
- super::IpMembershipRequest
-);
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- #[cfg(feature = "net")]
- sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Join an IPv6 multicast group.
- Ipv6AddMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest);
- #[cfg(feature = "net")]
- sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Leave an IPv6 multicast group.
- Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest);
- } else if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))] {
- #[cfg(feature = "net")]
- sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Join an IPv6 multicast group.
- Ipv6AddMembership, SetOnly, libc::IPPROTO_IPV6,
- libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest);
- #[cfg(feature = "net")]
- sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Leave an IPv6 multicast group.
- Ipv6DropMembership, SetOnly, libc::IPPROTO_IPV6,
- libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest);
- }
-}
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Set or read the time-to-live value of outgoing multicast packets for
- /// this socket.
- IpMulticastTtl,
- Both,
- libc::IPPROTO_IP,
- libc::IP_MULTICAST_TTL,
- u8
-);
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Set or read a boolean integer argument that determines whether sent
- /// multicast packets should be looped back to the local sockets.
- IpMulticastLoop,
- Both,
- libc::IPPROTO_IP,
- libc::IP_MULTICAST_LOOP,
- bool
-);
-#[cfg(target_os = "linux")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Set the protocol-defined priority for all packets to be
- /// sent on this socket
- Priority,
- Both,
- libc::SOL_SOCKET,
- libc::SO_PRIORITY,
- libc::c_int
-);
-#[cfg(target_os = "linux")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Set or receive the Type-Of-Service (TOS) field that is
- /// sent with every IP packet originating from this socket
- IpTos,
- Both,
- libc::IPPROTO_IP,
- libc::IP_TOS,
- libc::c_int
-);
-#[cfg(target_os = "linux")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Traffic class associated with outgoing packets
- Ipv6TClass,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_TCLASS,
- libc::c_int
-);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// If enabled, this boolean option allows binding to an IP address that
- /// is nonlocal or does not (yet) exist.
- IpFreebind,
- Both,
- libc::IPPROTO_IP,
- libc::IP_FREEBIND,
- bool
-);
-sockopt_impl!(
- /// Specify the receiving timeout until reporting an error.
- ReceiveTimeout,
- Both,
- libc::SOL_SOCKET,
- libc::SO_RCVTIMEO,
- TimeVal
-);
-sockopt_impl!(
- /// Specify the sending timeout until reporting an error.
- SendTimeout,
- Both,
- libc::SOL_SOCKET,
- libc::SO_SNDTIMEO,
- TimeVal
-);
-sockopt_impl!(
- /// Set or get the broadcast flag.
- Broadcast,
- Both,
- libc::SOL_SOCKET,
- libc::SO_BROADCAST,
- bool
-);
-sockopt_impl!(
- /// If this option is enabled, out-of-band data is directly placed into
- /// the receive data stream.
- OobInline,
- Both,
- libc::SOL_SOCKET,
- libc::SO_OOBINLINE,
- bool
-);
-sockopt_impl!(
- /// Get and clear the pending socket error.
- SocketError,
- GetOnly,
- libc::SOL_SOCKET,
- libc::SO_ERROR,
- i32
-);
-sockopt_impl!(
- /// Set or get the don't route flag.
- DontRoute,
- Both,
- libc::SOL_SOCKET,
- libc::SO_DONTROUTE,
- bool
-);
-sockopt_impl!(
- /// Enable sending of keep-alive messages on connection-oriented sockets.
- KeepAlive,
- Both,
- libc::SOL_SOCKET,
- libc::SO_KEEPALIVE,
- bool
-);
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
-))]
-sockopt_impl!(
- /// Get the credentials of the peer process of a connected unix domain
- /// socket.
- LocalPeerCred,
- GetOnly,
- 0,
- libc::LOCAL_PEERCRED,
- super::XuCred
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Return the credentials of the foreign process connected to this socket.
- PeerCredentials,
- GetOnly,
- libc::SOL_SOCKET,
- libc::SO_PEERCRED,
- super::UnixCredentials
-);
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Specify the amount of time, in seconds, that the connection must be idle
- /// before keepalive probes (if enabled) are sent.
- TcpKeepAlive,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_KEEPALIVE,
- u32
-);
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
-))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The time (in seconds) the connection needs to remain idle before TCP
- /// starts sending keepalive probes
- TcpKeepIdle,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_KEEPIDLE,
- u32
-);
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- sockopt_impl!(
- /// The maximum segment size for outgoing TCP packets.
- TcpMaxSeg, Both, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
- } else {
- sockopt_impl!(
- /// The maximum segment size for outgoing TCP packets.
- TcpMaxSeg, GetOnly, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
- }
-}
-#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The maximum number of keepalive probes TCP should send before
- /// dropping the connection.
- TcpKeepCount,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_KEEPCNT,
- u32
-);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
-sockopt_impl!(
- #[allow(missing_docs)]
- // Not documented by Linux!
- TcpRepair,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_REPAIR,
- u32
-);
-#[cfg(not(any(target_os = "openbsd", target_os = "haiku")))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The time (in seconds) between individual keepalive probes.
- TcpKeepInterval,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_KEEPINTVL,
- u32
-);
-#[cfg(any(target_os = "fuchsia", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Specifies the maximum amount of time in milliseconds that transmitted
- /// data may remain unacknowledged before TCP will forcibly close the
- /// corresponding connection
- TcpUserTimeout,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_USER_TIMEOUT,
- u32
-);
-sockopt_impl!(
- /// Sets or gets the maximum socket receive buffer in bytes.
- RcvBuf,
- Both,
- libc::SOL_SOCKET,
- libc::SO_RCVBUF,
- usize
-);
-sockopt_impl!(
- /// Sets or gets the maximum socket send buffer in bytes.
- SndBuf,
- Both,
- libc::SOL_SOCKET,
- libc::SO_SNDBUF,
- usize
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
- /// perform the same task as `SO_RCVBUF`, but the `rmem_max limit` can be
- /// overridden.
- RcvBufForce,
- SetOnly,
- libc::SOL_SOCKET,
- libc::SO_RCVBUFFORCE,
- usize
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Using this socket option, a privileged (`CAP_NET_ADMIN`) process can
- /// perform the same task as `SO_SNDBUF`, but the `wmem_max` limit can be
- /// overridden.
- SndBufForce,
- SetOnly,
- libc::SOL_SOCKET,
- libc::SO_SNDBUFFORCE,
- usize
-);
-sockopt_impl!(
- /// Gets the socket type as an integer.
- SockType,
- GetOnly,
- libc::SOL_SOCKET,
- libc::SO_TYPE,
- super::SockType,
- GetStruct<i32>
-);
-sockopt_impl!(
- /// Returns a value indicating whether or not this socket has been marked to
- /// accept connections with `listen(2)`.
- AcceptConn,
- GetOnly,
- libc::SOL_SOCKET,
- libc::SO_ACCEPTCONN,
- bool
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Bind this socket to a particular device like “eth0”.
- BindToDevice,
- Both,
- libc::SOL_SOCKET,
- libc::SO_BINDTODEVICE,
- OsString<[u8; libc::IFNAMSIZ]>
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- #[allow(missing_docs)]
- // Not documented by Linux!
- OriginalDst,
- GetOnly,
- libc::SOL_IP,
- libc::SO_ORIGINAL_DST,
- libc::sockaddr_in
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- #[allow(missing_docs)]
- // Not documented by Linux!
- Ip6tOriginalDst,
- GetOnly,
- libc::SOL_IPV6,
- libc::IP6T_SO_ORIGINAL_DST,
- libc::sockaddr_in6
-);
-#[cfg(any(target_os = "linux"))]
-sockopt_impl!(
- /// Specifies exact type of timestamping information collected by the kernel
- /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html)
- Timestamping,
- Both,
- libc::SOL_SOCKET,
- libc::SO_TIMESTAMPING,
- super::TimestampingFlag
-);
-#[cfg(not(target_os = "haiku"))]
-sockopt_impl!(
- /// Enable or disable the receiving of the `SO_TIMESTAMP` control message.
- ReceiveTimestamp,
- Both,
- libc::SOL_SOCKET,
- libc::SO_TIMESTAMP,
- bool
-);
-#[cfg(all(target_os = "linux"))]
-sockopt_impl!(
- /// Enable or disable the receiving of the `SO_TIMESTAMPNS` control message.
- ReceiveTimestampns,
- Both,
- libc::SOL_SOCKET,
- libc::SO_TIMESTAMPNS,
- bool
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Setting this boolean option enables transparent proxying on this socket.
- IpTransparent,
- Both,
- libc::SOL_IP,
- libc::IP_TRANSPARENT,
- bool
-);
-#[cfg(target_os = "openbsd")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Allows the socket to be bound to addresses which are not local to the
- /// machine, so it can be used to make a transparent proxy.
- BindAny,
- Both,
- libc::SOL_SOCKET,
- libc::SO_BINDANY,
- bool
-);
-#[cfg(target_os = "freebsd")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Can `bind(2)` to any address, even one not bound to any available
- /// network interface in the system.
- BindAny,
- Both,
- libc::IPPROTO_IP,
- libc::IP_BINDANY,
- bool
-);
-#[cfg(target_os = "linux")]
-sockopt_impl!(
- /// Set the mark for each packet sent through this socket (similar to the
- /// netfilter MARK target but socket-based).
- Mark,
- Both,
- libc::SOL_SOCKET,
- libc::SO_MARK,
- u32
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Enable or disable the receiving of the `SCM_CREDENTIALS` control
- /// message.
- PassCred,
- Both,
- libc::SOL_SOCKET,
- libc::SO_PASSCRED,
- bool
-);
-#[cfg(any(target_os = "freebsd", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// This option allows the caller to set the TCP congestion control
- /// algorithm to be used, on a per-socket basis.
- TcpCongestion,
- Both,
- libc::IPPROTO_TCP,
- libc::TCP_CONGESTION,
- OsString<[u8; TCP_CA_NAME_MAX]>
-);
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
-))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Pass an `IP_PKTINFO` ancillary message that contains a pktinfo
- /// structure that supplies some information about the incoming packet.
- Ipv4PacketInfo,
- Both,
- libc::IPPROTO_IP,
- libc::IP_PKTINFO,
- bool
-);
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// Set delivery of the `IPV6_PKTINFO` control message on incoming
- /// datagrams.
- Ipv6RecvPacketInfo,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_RECVPKTINFO,
- bool
-);
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The `recvmsg(2)` call returns a `struct sockaddr_dl` corresponding to
- /// the interface on which the packet was received.
- Ipv4RecvIf,
- Both,
- libc::IPPROTO_IP,
- libc::IP_RECVIF,
- bool
-);
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The `recvmsg(2)` call will return the destination IP address for a UDP
- /// datagram.
- Ipv4RecvDstAddr,
- Both,
- libc::IPPROTO_IP,
- libc::IP_RECVDSTADDR,
- bool
-);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The `recvmsg(2)` call will return the destination IP address for a UDP
- /// datagram.
- Ipv4OrigDstAddr,
- Both,
- libc::IPPROTO_IP,
- libc::IP_ORIGDSTADDR,
- bool
-);
-#[cfg(target_os = "linux")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- #[allow(missing_docs)]
- // Not documented by Linux!
- UdpGsoSegment,
- Both,
- libc::SOL_UDP,
- libc::UDP_SEGMENT,
- libc::c_int
-);
-#[cfg(target_os = "linux")]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- #[allow(missing_docs)]
- // Not documented by Linux!
- UdpGroSegment,
- Both,
- libc::IPPROTO_UDP,
- libc::UDP_GRO,
- bool
-);
-#[cfg(target_os = "linux")]
-sockopt_impl!(
- /// Configures the behavior of time-based transmission of packets, for use
- /// with the `TxTime` control message.
- TxTime,
- Both,
- libc::SOL_SOCKET,
- libc::SO_TXTIME,
- libc::sock_txtime
-);
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
-sockopt_impl!(
- /// Indicates that an unsigned 32-bit value ancillary message (cmsg) should
- /// be attached to received skbs indicating the number of packets dropped by
- /// the socket since its creation.
- RxqOvfl,
- Both,
- libc::SOL_SOCKET,
- libc::SO_RXQ_OVFL,
- libc::c_int
-);
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The socket is restricted to sending and receiving IPv6 packets only.
- Ipv6V6Only,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_V6ONLY,
- bool
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Enable extended reliable error message passing.
- Ipv4RecvErr,
- Both,
- libc::IPPROTO_IP,
- libc::IP_RECVERR,
- bool
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Control receiving of asynchronous error options.
- Ipv6RecvErr,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_RECVERR,
- bool
-);
-#[cfg(any(target_os = "android", target_os = "linux"))]
-sockopt_impl!(
- /// Fetch the current system-estimated Path MTU.
- IpMtu,
- GetOnly,
- libc::IPPROTO_IP,
- libc::IP_MTU,
- libc::c_int
-);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-sockopt_impl!(
- /// Set or retrieve the current time-to-live field that is used in every
- /// packet sent from this socket.
- Ipv4Ttl,
- Both,
- libc::IPPROTO_IP,
- libc::IP_TTL,
- libc::c_int
-);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-sockopt_impl!(
- /// Set the unicast hop limit for the socket.
- Ipv6Ttl,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_UNICAST_HOPS,
- libc::c_int
-);
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-#[cfg(feature = "net")]
-sockopt_impl!(
- #[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- /// The `recvmsg(2)` call will return the destination IP address for a UDP
- /// datagram.
- Ipv6OrigDstAddr,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_ORIGDSTADDR,
- bool
-);
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-sockopt_impl!(
- /// Set "don't fragment packet" flag on the IP packet.
- IpDontFrag,
- Both,
- libc::IPPROTO_IP,
- libc::IP_DONTFRAG,
- bool
-);
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
-))]
-sockopt_impl!(
- /// Set "don't fragment packet" flag on the IPv6 packet.
- Ipv6DontFrag,
- Both,
- libc::IPPROTO_IPV6,
- libc::IPV6_DONTFRAG,
- bool
-);
-
-#[allow(missing_docs)]
-// Not documented by Linux!
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[derive(Copy, Clone, Debug)]
-pub struct AlgSetAeadAuthSize;
-
-// ALG_SET_AEAD_AUTH_SIZE read the length from passed `option_len`
-// See https://elixir.bootlin.com/linux/v4.4/source/crypto/af_alg.c#L222
-#[cfg(any(target_os = "android", target_os = "linux"))]
-impl SetSockOpt for AlgSetAeadAuthSize {
- type Val = usize;
-
- fn set(&self, fd: RawFd, val: &usize) -> Result<()> {
- unsafe {
- let res = libc::setsockopt(
- fd,
- libc::SOL_ALG,
- libc::ALG_SET_AEAD_AUTHSIZE,
- ::std::ptr::null(),
- *val as libc::socklen_t,
- );
- Errno::result(res).map(drop)
- }
- }
-}
-
-#[allow(missing_docs)]
-// Not documented by Linux!
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[derive(Clone, Debug)]
-pub struct AlgSetKey<T>(::std::marker::PhantomData<T>);
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-impl<T> Default for AlgSetKey<T> {
- fn default() -> Self {
- AlgSetKey(Default::default())
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-impl<T> SetSockOpt for AlgSetKey<T>
-where
- T: AsRef<[u8]> + Clone,
-{
- type Val = T;
-
- fn set(&self, fd: RawFd, val: &T) -> Result<()> {
- unsafe {
- let res = libc::setsockopt(
- fd,
- libc::SOL_ALG,
- libc::ALG_SET_KEY,
- val.as_ref().as_ptr() as *const _,
- val.as_ref().len() as libc::socklen_t,
- );
- Errno::result(res).map(drop)
- }
- }
-}
-
-/*
- *
- * ===== Accessor helpers =====
- *
- */
-
-/// Helper trait that describes what is expected from a `GetSockOpt` getter.
-trait Get<T> {
- /// Returns an uninitialized value.
- fn uninit() -> Self;
- /// Returns a pointer to the stored value. This pointer will be passed to the system's
- /// `getsockopt` call (`man 3p getsockopt`, argument `option_value`).
- fn ffi_ptr(&mut self) -> *mut c_void;
- /// Returns length of the stored value. This pointer will be passed to the system's
- /// `getsockopt` call (`man 3p getsockopt`, argument `option_len`).
- fn ffi_len(&mut self) -> *mut socklen_t;
- /// Returns the hopefully initialized inner value.
- unsafe fn assume_init(self) -> T;
-}
-
-/// Helper trait that describes what is expected from a `SetSockOpt` setter.
-trait Set<'a, T> {
- /// Initialize the setter with a given value.
- fn new(val: &'a T) -> Self;
- /// Returns a pointer to the stored value. This pointer will be passed to the system's
- /// `setsockopt` call (`man 3p setsockopt`, argument `option_value`).
- fn ffi_ptr(&self) -> *const c_void;
- /// Returns length of the stored value. This pointer will be passed to the system's
- /// `setsockopt` call (`man 3p setsockopt`, argument `option_len`).
- fn ffi_len(&self) -> socklen_t;
-}
-
-/// Getter for an arbitrary `struct`.
-struct GetStruct<T> {
- len: socklen_t,
- val: MaybeUninit<T>,
-}
-
-impl<T> Get<T> for GetStruct<T> {
- fn uninit() -> Self {
- GetStruct {
- len: mem::size_of::<T>() as socklen_t,
- val: MaybeUninit::uninit(),
- }
- }
-
- fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
- }
-
- fn ffi_len(&mut self) -> *mut socklen_t {
- &mut self.len
- }
-
- unsafe fn assume_init(self) -> T {
- assert_eq!(
- self.len as usize,
- mem::size_of::<T>(),
- "invalid getsockopt implementation"
- );
- self.val.assume_init()
- }
-}
-
-/// Setter for an arbitrary `struct`.
-struct SetStruct<'a, T: 'static> {
- ptr: &'a T,
-}
-
-impl<'a, T> Set<'a, T> for SetStruct<'a, T> {
- fn new(ptr: &'a T) -> SetStruct<'a, T> {
- SetStruct { ptr }
- }
-
- fn ffi_ptr(&self) -> *const c_void {
- self.ptr as *const T as *const c_void
- }
-
- fn ffi_len(&self) -> socklen_t {
- mem::size_of::<T>() as socklen_t
- }
-}
-
-/// Getter for a boolean value.
-struct GetBool {
- len: socklen_t,
- val: MaybeUninit<c_int>,
-}
-
-impl Get<bool> for GetBool {
- fn uninit() -> Self {
- GetBool {
- len: mem::size_of::<c_int>() as socklen_t,
- val: MaybeUninit::uninit(),
- }
- }
-
- fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
- }
-
- fn ffi_len(&mut self) -> *mut socklen_t {
- &mut self.len
- }
-
- unsafe fn assume_init(self) -> bool {
- assert_eq!(
- self.len as usize,
- mem::size_of::<c_int>(),
- "invalid getsockopt implementation"
- );
- self.val.assume_init() != 0
- }
-}
-
-/// Setter for a boolean value.
-struct SetBool {
- val: c_int,
-}
-
-impl<'a> Set<'a, bool> for SetBool {
- fn new(val: &'a bool) -> SetBool {
- SetBool {
- val: i32::from(*val),
- }
- }
-
- fn ffi_ptr(&self) -> *const c_void {
- &self.val as *const c_int as *const c_void
- }
-
- fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
- }
-}
-
-/// Getter for an `u8` value.
-struct GetU8 {
- len: socklen_t,
- val: MaybeUninit<u8>,
-}
-
-impl Get<u8> for GetU8 {
- fn uninit() -> Self {
- GetU8 {
- len: mem::size_of::<u8>() as socklen_t,
- val: MaybeUninit::uninit(),
- }
- }
-
- fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
- }
-
- fn ffi_len(&mut self) -> *mut socklen_t {
- &mut self.len
- }
-
- unsafe fn assume_init(self) -> u8 {
- assert_eq!(
- self.len as usize,
- mem::size_of::<u8>(),
- "invalid getsockopt implementation"
- );
- self.val.assume_init()
- }
-}
-
-/// Setter for an `u8` value.
-struct SetU8 {
- val: u8,
-}
-
-impl<'a> Set<'a, u8> for SetU8 {
- fn new(val: &'a u8) -> SetU8 {
- SetU8 { val: *val }
- }
-
- fn ffi_ptr(&self) -> *const c_void {
- &self.val as *const u8 as *const c_void
- }
-
- fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
- }
-}
-
-/// Getter for an `usize` value.
-struct GetUsize {
- len: socklen_t,
- val: MaybeUninit<c_int>,
-}
-
-impl Get<usize> for GetUsize {
- fn uninit() -> Self {
- GetUsize {
- len: mem::size_of::<c_int>() as socklen_t,
- val: MaybeUninit::uninit(),
- }
- }
-
- fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
- }
-
- fn ffi_len(&mut self) -> *mut socklen_t {
- &mut self.len
- }
-
- unsafe fn assume_init(self) -> usize {
- assert_eq!(
- self.len as usize,
- mem::size_of::<c_int>(),
- "invalid getsockopt implementation"
- );
- self.val.assume_init() as usize
- }
-}
-
-/// Setter for an `usize` value.
-struct SetUsize {
- val: c_int,
-}
-
-impl<'a> Set<'a, usize> for SetUsize {
- fn new(val: &'a usize) -> SetUsize {
- SetUsize { val: *val as c_int }
- }
-
- fn ffi_ptr(&self) -> *const c_void {
- &self.val as *const c_int as *const c_void
- }
-
- fn ffi_len(&self) -> socklen_t {
- mem::size_of::<c_int>() as socklen_t
- }
-}
-
-/// Getter for a `OsString` value.
-struct GetOsString<T: AsMut<[u8]>> {
- len: socklen_t,
- val: MaybeUninit<T>,
-}
-
-impl<T: AsMut<[u8]>> Get<OsString> for GetOsString<T> {
- fn uninit() -> Self {
- GetOsString {
- len: mem::size_of::<T>() as socklen_t,
- val: MaybeUninit::uninit(),
- }
- }
-
- fn ffi_ptr(&mut self) -> *mut c_void {
- self.val.as_mut_ptr() as *mut c_void
- }
-
- fn ffi_len(&mut self) -> *mut socklen_t {
- &mut self.len
- }
-
- unsafe fn assume_init(self) -> OsString {
- let len = self.len as usize;
- let mut v = self.val.assume_init();
- OsStr::from_bytes(&v.as_mut()[0..len]).to_owned()
- }
-}
-
-/// Setter for a `OsString` value.
-struct SetOsString<'a> {
- val: &'a OsStr,
-}
-
-impl<'a> Set<'a, OsString> for SetOsString<'a> {
- fn new(val: &'a OsString) -> SetOsString {
- SetOsString {
- val: val.as_os_str(),
- }
- }
-
- fn ffi_ptr(&self) -> *const c_void {
- self.val.as_bytes().as_ptr() as *const c_void
- }
-
- fn ffi_len(&self) -> socklen_t {
- self.val.len() as socklen_t
- }
-}
-
-#[cfg(test)]
-mod test {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[test]
- fn can_get_peercred_on_unix_socket() {
- use super::super::*;
-
- let (a, b) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
- let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
- assert_eq!(a_cred, b_cred);
- assert_ne!(a_cred.pid(), 0);
- }
-
- #[test]
- fn is_socket_type_unix() {
- use super::super::*;
- use crate::unistd::close;
-
- let (a, b) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let a_type = getsockopt(a, super::SockType).unwrap();
- assert_eq!(a_type, SockType::Stream);
- close(a).unwrap();
- close(b).unwrap();
- }
-
- #[test]
- fn is_socket_type_dgram() {
- use super::super::*;
- use crate::unistd::close;
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let s_type = getsockopt(s, super::SockType).unwrap();
- assert_eq!(s_type, SockType::Datagram);
- close(s).unwrap();
- }
-
- #[cfg(any(target_os = "freebsd", target_os = "linux"))]
- #[test]
- fn can_get_listen_on_tcp_socket() {
- use super::super::*;
- use crate::unistd::close;
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let s_listening = getsockopt(s, super::AcceptConn).unwrap();
- assert!(!s_listening);
- listen(s, 10).unwrap();
- let s_listening2 = getsockopt(s, super::AcceptConn).unwrap();
- assert!(s_listening2);
- close(s).unwrap();
- }
-}
diff --git a/vendor/nix/src/sys/stat.rs b/vendor/nix/src/sys/stat.rs
deleted file mode 100644
index 78203bfbe..000000000
--- a/vendor/nix/src/sys/stat.rs
+++ /dev/null
@@ -1,480 +0,0 @@
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))]
-pub use libc::c_uint;
-#[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
-pub use libc::c_ulong;
-pub use libc::stat as FileStat;
-pub use libc::{dev_t, mode_t};
-
-#[cfg(not(target_os = "redox"))]
-use crate::fcntl::{at_rawfd, AtFlags};
-use crate::sys::time::{TimeSpec, TimeVal};
-use crate::{errno::Errno, NixPath, Result};
-use std::mem;
-use std::os::unix::io::RawFd;
-
-libc_bitflags!(
- /// "File type" flags for `mknod` and related functions.
- pub struct SFlag: mode_t {
- S_IFIFO;
- S_IFCHR;
- S_IFDIR;
- S_IFBLK;
- S_IFREG;
- S_IFLNK;
- S_IFSOCK;
- S_IFMT;
- }
-);
-
-libc_bitflags! {
- /// "File mode / permissions" flags.
- pub struct Mode: mode_t {
- /// Read, write and execute for owner.
- S_IRWXU;
- /// Read for owner.
- S_IRUSR;
- /// Write for owner.
- S_IWUSR;
- /// Execute for owner.
- S_IXUSR;
- /// Read write and execute for group.
- S_IRWXG;
- /// Read fr group.
- S_IRGRP;
- /// Write for group.
- S_IWGRP;
- /// Execute for group.
- S_IXGRP;
- /// Read, write and execute for other.
- S_IRWXO;
- /// Read for other.
- S_IROTH;
- /// Write for other.
- S_IWOTH;
- /// Execute for other.
- S_IXOTH;
- /// Set user id on execution.
- S_ISUID as mode_t;
- /// Set group id on execution.
- S_ISGID as mode_t;
- S_ISVTX as mode_t;
- }
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "openbsd"))]
-pub type type_of_file_flag = c_uint;
-#[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
-pub type type_of_file_flag = c_ulong;
-
-#[cfg(any(
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "macos",
- target_os = "ios"
-))]
-libc_bitflags! {
- /// File flags.
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub struct FileFlag: type_of_file_flag {
- /// The file may only be appended to.
- SF_APPEND;
- /// The file has been archived.
- SF_ARCHIVED;
- #[cfg(any(target_os = "dragonfly"))]
- SF_CACHE;
- /// The file may not be changed.
- SF_IMMUTABLE;
- /// Indicates a WAPBL journal file.
- #[cfg(any(target_os = "netbsd"))]
- SF_LOG;
- /// Do not retain history for file
- #[cfg(any(target_os = "dragonfly"))]
- SF_NOHISTORY;
- /// The file may not be renamed or deleted.
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- SF_NOUNLINK;
- /// Mask of superuser changeable flags
- SF_SETTABLE;
- /// Snapshot is invalid.
- #[cfg(any(target_os = "netbsd"))]
- SF_SNAPINVAL;
- /// The file is a snapshot file.
- #[cfg(any(target_os = "netbsd", target_os = "freebsd"))]
- SF_SNAPSHOT;
- #[cfg(any(target_os = "dragonfly"))]
- SF_XLINK;
- /// The file may only be appended to.
- UF_APPEND;
- /// The file needs to be archived.
- #[cfg(any(target_os = "freebsd"))]
- UF_ARCHIVE;
- #[cfg(any(target_os = "dragonfly"))]
- UF_CACHE;
- /// File is compressed at the file system level.
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- UF_COMPRESSED;
- /// The file may be hidden from directory listings at the application's
- /// discretion.
- #[cfg(any(
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios",
- ))]
- UF_HIDDEN;
- /// The file may not be changed.
- UF_IMMUTABLE;
- /// Do not dump the file.
- UF_NODUMP;
- #[cfg(any(target_os = "dragonfly"))]
- UF_NOHISTORY;
- /// The file may not be renamed or deleted.
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- UF_NOUNLINK;
- /// The file is offline, or has the Windows and CIFS
- /// `FILE_ATTRIBUTE_OFFLINE` attribute.
- #[cfg(any(target_os = "freebsd"))]
- UF_OFFLINE;
- /// The directory is opaque when viewed through a union stack.
- UF_OPAQUE;
- /// The file is read only, and may not be written or appended.
- #[cfg(any(target_os = "freebsd"))]
- UF_READONLY;
- /// The file contains a Windows reparse point.
- #[cfg(any(target_os = "freebsd"))]
- UF_REPARSE;
- /// Mask of owner changeable flags.
- UF_SETTABLE;
- /// The file has the Windows `FILE_ATTRIBUTE_SPARSE_FILE` attribute.
- #[cfg(any(target_os = "freebsd"))]
- UF_SPARSE;
- /// The file has the DOS, Windows and CIFS `FILE_ATTRIBUTE_SYSTEM`
- /// attribute.
- #[cfg(any(target_os = "freebsd"))]
- UF_SYSTEM;
- /// File renames and deletes are tracked.
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- UF_TRACKED;
- #[cfg(any(target_os = "dragonfly"))]
- UF_XLINK;
- }
-}
-
-/// Create a special or ordinary file, by pathname.
-pub fn mknod<P: ?Sized + NixPath>(
- path: &P,
- kind: SFlag,
- perm: Mode,
- dev: dev_t,
-) -> Result<()> {
- let res = path.with_nix_path(|cstr| unsafe {
- libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev)
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Create a special or ordinary file, relative to a given directory.
-#[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "redox",
- target_os = "haiku"
-)))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn mknodat<P: ?Sized + NixPath>(
- dirfd: RawFd,
- path: &P,
- kind: SFlag,
- perm: Mode,
- dev: dev_t,
-) -> Result<()> {
- let res = path.with_nix_path(|cstr| unsafe {
- libc::mknodat(
- dirfd,
- cstr.as_ptr(),
- kind.bits | perm.bits() as mode_t,
- dev,
- )
- })?;
-
- Errno::result(res).map(drop)
-}
-
-#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub const fn major(dev: dev_t) -> u64 {
- ((dev >> 32) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)
-}
-
-#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub const fn minor(dev: dev_t) -> u64 {
- ((dev >> 12) & 0xffff_ff00) | ((dev) & 0x0000_00ff)
-}
-
-#[cfg(target_os = "linux")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub const fn makedev(major: u64, minor: u64) -> dev_t {
- ((major & 0xffff_f000) << 32)
- | ((major & 0x0000_0fff) << 8)
- | ((minor & 0xffff_ff00) << 12)
- | (minor & 0x0000_00ff)
-}
-
-pub fn umask(mode: Mode) -> Mode {
- let prev = unsafe { libc::umask(mode.bits() as mode_t) };
- Mode::from_bits(prev).expect("[BUG] umask returned invalid Mode")
-}
-
-pub fn stat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
- let mut dst = mem::MaybeUninit::uninit();
- let res = path.with_nix_path(|cstr| unsafe {
- libc::stat(cstr.as_ptr(), dst.as_mut_ptr())
- })?;
-
- Errno::result(res)?;
-
- Ok(unsafe { dst.assume_init() })
-}
-
-pub fn lstat<P: ?Sized + NixPath>(path: &P) -> Result<FileStat> {
- let mut dst = mem::MaybeUninit::uninit();
- let res = path.with_nix_path(|cstr| unsafe {
- libc::lstat(cstr.as_ptr(), dst.as_mut_ptr())
- })?;
-
- Errno::result(res)?;
-
- Ok(unsafe { dst.assume_init() })
-}
-
-pub fn fstat(fd: RawFd) -> Result<FileStat> {
- let mut dst = mem::MaybeUninit::uninit();
- let res = unsafe { libc::fstat(fd, dst.as_mut_ptr()) };
-
- Errno::result(res)?;
-
- Ok(unsafe { dst.assume_init() })
-}
-
-#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn fstatat<P: ?Sized + NixPath>(
- dirfd: RawFd,
- pathname: &P,
- f: AtFlags,
-) -> Result<FileStat> {
- let mut dst = mem::MaybeUninit::uninit();
- let res = pathname.with_nix_path(|cstr| unsafe {
- libc::fstatat(
- dirfd,
- cstr.as_ptr(),
- dst.as_mut_ptr(),
- f.bits() as libc::c_int,
- )
- })?;
-
- Errno::result(res)?;
-
- Ok(unsafe { dst.assume_init() })
-}
-
-/// Change the file permission bits of the file specified by a file descriptor.
-///
-/// # References
-///
-/// [fchmod(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html).
-pub fn fchmod(fd: RawFd, mode: Mode) -> Result<()> {
- let res = unsafe { libc::fchmod(fd, mode.bits() as mode_t) };
-
- Errno::result(res).map(drop)
-}
-
-/// Flags for `fchmodat` function.
-#[derive(Clone, Copy, Debug)]
-pub enum FchmodatFlags {
- FollowSymlink,
- NoFollowSymlink,
-}
-
-/// Change the file permission bits.
-///
-/// The file to be changed is determined relative to the directory associated
-/// with the file descriptor `dirfd` or the current working directory
-/// if `dirfd` is `None`.
-///
-/// If `flag` is `FchmodatFlags::NoFollowSymlink` and `path` names a symbolic link,
-/// then the mode of the symbolic link is changed.
-///
-/// `fchmodat(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to
-/// a call `libc::chmod(path, mode)`. That's why `chmod` is unimplemented
-/// in the `nix` crate.
-///
-/// # References
-///
-/// [fchmodat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html).
-#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn fchmodat<P: ?Sized + NixPath>(
- dirfd: Option<RawFd>,
- path: &P,
- mode: Mode,
- flag: FchmodatFlags,
-) -> Result<()> {
- let atflag = match flag {
- FchmodatFlags::FollowSymlink => AtFlags::empty(),
- FchmodatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
- };
- let res = path.with_nix_path(|cstr| unsafe {
- libc::fchmodat(
- at_rawfd(dirfd),
- cstr.as_ptr(),
- mode.bits() as mode_t,
- atflag.bits() as libc::c_int,
- )
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Change the access and modification times of a file.
-///
-/// `utimes(path, times)` is identical to
-/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)`. The former
-/// is a deprecated API so prefer using the latter if the platforms you care
-/// about support it.
-///
-/// # References
-///
-/// [utimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimes.html).
-pub fn utimes<P: ?Sized + NixPath>(
- path: &P,
- atime: &TimeVal,
- mtime: &TimeVal,
-) -> Result<()> {
- let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
- let res = path.with_nix_path(|cstr| unsafe {
- libc::utimes(cstr.as_ptr(), &times[0])
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Change the access and modification times of a file without following symlinks.
-///
-/// `lutimes(path, times)` is identical to
-/// `utimensat(None, path, times, UtimensatFlags::NoFollowSymlink)`. The former
-/// is a deprecated API so prefer using the latter if the platforms you care
-/// about support it.
-///
-/// # References
-///
-/// [lutimes(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lutimes.html).
-#[cfg(any(
- target_os = "linux",
- target_os = "haiku",
- target_os = "ios",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "netbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn lutimes<P: ?Sized + NixPath>(
- path: &P,
- atime: &TimeVal,
- mtime: &TimeVal,
-) -> Result<()> {
- let times: [libc::timeval; 2] = [*atime.as_ref(), *mtime.as_ref()];
- let res = path.with_nix_path(|cstr| unsafe {
- libc::lutimes(cstr.as_ptr(), &times[0])
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Change the access and modification times of the file specified by a file descriptor.
-///
-/// # References
-///
-/// [futimens(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html).
-#[inline]
-pub fn futimens(fd: RawFd, atime: &TimeSpec, mtime: &TimeSpec) -> Result<()> {
- let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()];
- let res = unsafe { libc::futimens(fd, &times[0]) };
-
- Errno::result(res).map(drop)
-}
-
-/// Flags for `utimensat` function.
-// TODO: replace with fcntl::AtFlags
-#[derive(Clone, Copy, Debug)]
-pub enum UtimensatFlags {
- FollowSymlink,
- NoFollowSymlink,
-}
-
-/// Change the access and modification times of a file.
-///
-/// The file to be changed is determined relative to the directory associated
-/// with the file descriptor `dirfd` or the current working directory
-/// if `dirfd` is `None`.
-///
-/// If `flag` is `UtimensatFlags::NoFollowSymlink` and `path` names a symbolic link,
-/// then the mode of the symbolic link is changed.
-///
-/// `utimensat(None, path, times, UtimensatFlags::FollowSymlink)` is identical to
-/// `utimes(path, times)`. The latter is a deprecated API so prefer using the
-/// former if the platforms you care about support it.
-///
-/// # References
-///
-/// [utimensat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/utimens.html).
-#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn utimensat<P: ?Sized + NixPath>(
- dirfd: Option<RawFd>,
- path: &P,
- atime: &TimeSpec,
- mtime: &TimeSpec,
- flag: UtimensatFlags,
-) -> Result<()> {
- let atflag = match flag {
- UtimensatFlags::FollowSymlink => AtFlags::empty(),
- UtimensatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
- };
- let times: [libc::timespec; 2] = [*atime.as_ref(), *mtime.as_ref()];
- let res = path.with_nix_path(|cstr| unsafe {
- libc::utimensat(
- at_rawfd(dirfd),
- cstr.as_ptr(),
- &times[0],
- atflag.bits() as libc::c_int,
- )
- })?;
-
- Errno::result(res).map(drop)
-}
-
-#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn mkdirat<P: ?Sized + NixPath>(
- fd: RawFd,
- path: &P,
- mode: Mode,
-) -> Result<()> {
- let res = path.with_nix_path(|cstr| unsafe {
- libc::mkdirat(fd, cstr.as_ptr(), mode.bits() as mode_t)
- })?;
-
- Errno::result(res).map(drop)
-}
diff --git a/vendor/nix/src/sys/statfs.rs b/vendor/nix/src/sys/statfs.rs
deleted file mode 100644
index 9be8ca666..000000000
--- a/vendor/nix/src/sys/statfs.rs
+++ /dev/null
@@ -1,853 +0,0 @@
-//! Get filesystem statistics, non-portably
-//!
-//! See [`statvfs`](crate::sys::statvfs) for a portable alternative.
-#[cfg(not(any(target_os = "linux", target_os = "android")))]
-use std::ffi::CStr;
-use std::fmt::{self, Debug};
-use std::mem;
-use std::os::unix::io::AsRawFd;
-
-use cfg_if::cfg_if;
-
-#[cfg(all(
- feature = "mount",
- any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )
-))]
-use crate::mount::MntFlags;
-#[cfg(target_os = "linux")]
-use crate::sys::statvfs::FsFlags;
-use crate::{errno::Errno, NixPath, Result};
-
-/// Identifies a mounted file system
-#[cfg(target_os = "android")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub type fsid_t = libc::__fsid_t;
-/// Identifies a mounted file system
-#[cfg(not(target_os = "android"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub type fsid_t = libc::fsid_t;
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] {
- type type_of_statfs = libc::statfs64;
- const LIBC_FSTATFS: unsafe extern fn
- (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
- = libc::fstatfs64;
- const LIBC_STATFS: unsafe extern fn
- (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int
- = libc::statfs64;
- } else {
- type type_of_statfs = libc::statfs;
- const LIBC_FSTATFS: unsafe extern fn
- (fd: libc::c_int, buf: *mut type_of_statfs) -> libc::c_int
- = libc::fstatfs;
- const LIBC_STATFS: unsafe extern fn
- (path: *const libc::c_char, buf: *mut type_of_statfs) -> libc::c_int
- = libc::statfs;
- }
-}
-
-/// Describes a mounted file system
-#[derive(Clone, Copy)]
-#[repr(transparent)]
-pub struct Statfs(type_of_statfs);
-
-#[cfg(target_os = "freebsd")]
-type fs_type_t = u32;
-#[cfg(target_os = "android")]
-type fs_type_t = libc::c_ulong;
-#[cfg(all(target_os = "linux", target_arch = "s390x"))]
-type fs_type_t = libc::c_uint;
-#[cfg(all(target_os = "linux", target_env = "musl"))]
-type fs_type_t = libc::c_ulong;
-#[cfg(all(target_os = "linux", target_env = "uclibc"))]
-type fs_type_t = libc::c_int;
-#[cfg(all(
- target_os = "linux",
- not(any(
- target_arch = "s390x",
- target_env = "musl",
- target_env = "uclibc"
- ))
-))]
-type fs_type_t = libc::__fsword_t;
-
-/// Describes the file system type as known by the operating system.
-#[cfg(any(
- target_os = "freebsd",
- target_os = "android",
- all(target_os = "linux", target_arch = "s390x"),
- all(target_os = "linux", target_env = "musl"),
- all(
- target_os = "linux",
- not(any(target_arch = "s390x", target_env = "musl"))
- ),
-))]
-#[derive(Eq, Copy, Clone, PartialEq, Debug)]
-pub struct FsType(pub fs_type_t);
-
-// These constants are defined without documentation in the Linux headers, so we
-// can't very well document them here.
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const ADFS_SUPER_MAGIC: FsType =
- FsType(libc::ADFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const AFFS_SUPER_MAGIC: FsType =
- FsType(libc::AFFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const AFS_SUPER_MAGIC: FsType = FsType(libc::AFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const AUTOFS_SUPER_MAGIC: FsType =
- FsType(libc::AUTOFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const BPF_FS_MAGIC: FsType = FsType(libc::BPF_FS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const BTRFS_SUPER_MAGIC: FsType =
- FsType(libc::BTRFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const CGROUP2_SUPER_MAGIC: FsType =
- FsType(libc::CGROUP2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const CGROUP_SUPER_MAGIC: FsType =
- FsType(libc::CGROUP_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const CODA_SUPER_MAGIC: FsType =
- FsType(libc::CODA_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const CRAMFS_MAGIC: FsType = FsType(libc::CRAMFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const DEBUGFS_MAGIC: FsType = FsType(libc::DEBUGFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const DEVPTS_SUPER_MAGIC: FsType =
- FsType(libc::DEVPTS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const ECRYPTFS_SUPER_MAGIC: FsType =
- FsType(libc::ECRYPTFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const EFS_SUPER_MAGIC: FsType = FsType(libc::EFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const EXT2_SUPER_MAGIC: FsType =
- FsType(libc::EXT2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const EXT3_SUPER_MAGIC: FsType =
- FsType(libc::EXT3_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const EXT4_SUPER_MAGIC: FsType =
- FsType(libc::EXT4_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const F2FS_SUPER_MAGIC: FsType =
- FsType(libc::F2FS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const FUSE_SUPER_MAGIC: FsType =
- FsType(libc::FUSE_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const FUTEXFS_SUPER_MAGIC: FsType =
- FsType(libc::FUTEXFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const HOSTFS_SUPER_MAGIC: FsType =
- FsType(libc::HOSTFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const HPFS_SUPER_MAGIC: FsType =
- FsType(libc::HPFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const HUGETLBFS_MAGIC: FsType = FsType(libc::HUGETLBFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const ISOFS_SUPER_MAGIC: FsType =
- FsType(libc::ISOFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const JFFS2_SUPER_MAGIC: FsType =
- FsType(libc::JFFS2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const MINIX2_SUPER_MAGIC2: FsType =
- FsType(libc::MINIX2_SUPER_MAGIC2 as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const MINIX2_SUPER_MAGIC: FsType =
- FsType(libc::MINIX2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const MINIX3_SUPER_MAGIC: FsType =
- FsType(libc::MINIX3_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const MINIX_SUPER_MAGIC2: FsType =
- FsType(libc::MINIX_SUPER_MAGIC2 as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const MINIX_SUPER_MAGIC: FsType =
- FsType(libc::MINIX_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const MSDOS_SUPER_MAGIC: FsType =
- FsType(libc::MSDOS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const NCP_SUPER_MAGIC: FsType = FsType(libc::NCP_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const NFS_SUPER_MAGIC: FsType = FsType(libc::NFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const NILFS_SUPER_MAGIC: FsType =
- FsType(libc::NILFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const OCFS2_SUPER_MAGIC: FsType =
- FsType(libc::OCFS2_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const OPENPROM_SUPER_MAGIC: FsType =
- FsType(libc::OPENPROM_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const OVERLAYFS_SUPER_MAGIC: FsType =
- FsType(libc::OVERLAYFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const PROC_SUPER_MAGIC: FsType =
- FsType(libc::PROC_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const QNX4_SUPER_MAGIC: FsType =
- FsType(libc::QNX4_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const QNX6_SUPER_MAGIC: FsType =
- FsType(libc::QNX6_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const RDTGROUP_SUPER_MAGIC: FsType =
- FsType(libc::RDTGROUP_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const REISERFS_SUPER_MAGIC: FsType =
- FsType(libc::REISERFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const SECURITYFS_MAGIC: FsType =
- FsType(libc::SECURITYFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const SELINUX_MAGIC: FsType = FsType(libc::SELINUX_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const SMACK_MAGIC: FsType = FsType(libc::SMACK_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const SMB_SUPER_MAGIC: FsType = FsType(libc::SMB_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const SYSFS_MAGIC: FsType = FsType(libc::SYSFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const TMPFS_MAGIC: FsType = FsType(libc::TMPFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const TRACEFS_MAGIC: FsType = FsType(libc::TRACEFS_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const UDF_SUPER_MAGIC: FsType = FsType(libc::UDF_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const USBDEVICE_SUPER_MAGIC: FsType =
- FsType(libc::USBDEVICE_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const XENFS_SUPER_MAGIC: FsType =
- FsType(libc::XENFS_SUPER_MAGIC as fs_type_t);
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[allow(missing_docs)]
-pub const NSFS_MAGIC: FsType = FsType(libc::NSFS_MAGIC as fs_type_t);
-#[cfg(all(
- any(target_os = "linux", target_os = "android"),
- not(target_env = "musl")
-))]
-#[allow(missing_docs)]
-pub const XFS_SUPER_MAGIC: FsType = FsType(libc::XFS_SUPER_MAGIC as fs_type_t);
-
-impl Statfs {
- /// Magic code defining system type
- #[cfg(not(any(
- target_os = "openbsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos"
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn filesystem_type(&self) -> FsType {
- FsType(self.0.f_type)
- }
-
- /// Magic code defining system type
- #[cfg(not(any(target_os = "linux", target_os = "android")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn filesystem_type_name(&self) -> &str {
- let c_str = unsafe { CStr::from_ptr(self.0.f_fstypename.as_ptr()) };
- c_str.to_str().unwrap()
- }
-
- /// Optimal transfer block size
- #[cfg(any(target_os = "ios", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> i32 {
- self.0.f_iosize
- }
-
- /// Optimal transfer block size
- #[cfg(target_os = "openbsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> u32 {
- self.0.f_iosize
- }
-
- /// Optimal transfer block size
- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> u32 {
- self.0.f_bsize
- }
-
- /// Optimal transfer block size
- #[cfg(any(
- target_os = "android",
- all(target_os = "linux", target_env = "musl")
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> libc::c_ulong {
- self.0.f_bsize
- }
-
- /// Optimal transfer block size
- #[cfg(all(
- target_os = "linux",
- not(any(
- target_arch = "s390x",
- target_env = "musl",
- target_env = "uclibc"
- ))
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> libc::__fsword_t {
- self.0.f_bsize
- }
-
- /// Optimal transfer block size
- #[cfg(all(target_os = "linux", target_env = "uclibc"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> libc::c_int {
- self.0.f_bsize
- }
-
- /// Optimal transfer block size
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> libc::c_long {
- self.0.f_iosize
- }
-
- /// Optimal transfer block size
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn optimal_transfer_size(&self) -> u64 {
- self.0.f_iosize
- }
-
- /// Size of a block
- #[cfg(any(target_os = "ios", target_os = "macos", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> u32 {
- self.0.f_bsize
- }
-
- /// Size of a block
- // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> u32 {
- self.0.f_bsize
- }
-
- /// Size of a block
- // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
- #[cfg(all(target_os = "linux", target_env = "musl"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> libc::c_ulong {
- self.0.f_bsize
- }
-
- /// Size of a block
- // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
- #[cfg(all(target_os = "linux", target_env = "uclibc"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> libc::c_int {
- self.0.f_bsize
- }
-
- /// Size of a block
- // f_bsize on linux: https://github.com/torvalds/linux/blob/master/fs/nfs/super.c#L471
- #[cfg(all(
- target_os = "linux",
- not(any(
- target_arch = "s390x",
- target_env = "musl",
- target_env = "uclibc"
- ))
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> libc::__fsword_t {
- self.0.f_bsize
- }
-
- /// Size of a block
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> u64 {
- self.0.f_bsize
- }
-
- /// Size of a block
- #[cfg(target_os = "android")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> libc::c_ulong {
- self.0.f_bsize
- }
-
- /// Size of a block
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn block_size(&self) -> libc::c_long {
- self.0.f_bsize
- }
-
- /// Get the mount flags
- #[cfg(all(
- feature = "mount",
- any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- #[allow(clippy::unnecessary_cast)] // Not unnecessary on all arches
- pub fn flags(&self) -> MntFlags {
- MntFlags::from_bits_truncate(self.0.f_flags as i32)
- }
-
- /// Get the mount flags
- // The f_flags field exists on Android and Fuchsia too, but without man
- // pages I can't tell if it can be cast to FsFlags.
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn flags(&self) -> FsFlags {
- FsFlags::from_bits_truncate(self.0.f_flags as libc::c_ulong)
- }
-
- /// Maximum length of filenames
- #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn maximum_name_length(&self) -> u32 {
- self.0.f_namemax
- }
-
- /// Maximum length of filenames
- #[cfg(all(target_os = "linux", target_arch = "s390x"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn maximum_name_length(&self) -> u32 {
- self.0.f_namelen
- }
-
- /// Maximum length of filenames
- #[cfg(all(target_os = "linux", target_env = "musl"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn maximum_name_length(&self) -> libc::c_ulong {
- self.0.f_namelen
- }
-
- /// Maximum length of filenames
- #[cfg(all(target_os = "linux", target_env = "uclibc"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn maximum_name_length(&self) -> libc::c_int {
- self.0.f_namelen
- }
-
- /// Maximum length of filenames
- #[cfg(all(
- target_os = "linux",
- not(any(
- target_arch = "s390x",
- target_env = "musl",
- target_env = "uclibc"
- ))
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn maximum_name_length(&self) -> libc::__fsword_t {
- self.0.f_namelen
- }
-
- /// Maximum length of filenames
- #[cfg(target_os = "android")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn maximum_name_length(&self) -> libc::c_ulong {
- self.0.f_namelen
- }
-
- /// Total data blocks in filesystem
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "openbsd",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks(&self) -> u64 {
- self.0.f_blocks
- }
-
- /// Total data blocks in filesystem
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks(&self) -> libc::c_long {
- self.0.f_blocks
- }
-
- /// Total data blocks in filesystem
- #[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks(&self) -> u32 {
- self.0.f_blocks
- }
-
- /// Free blocks in filesystem
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "openbsd",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_free(&self) -> u64 {
- self.0.f_bfree
- }
-
- /// Free blocks in filesystem
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_free(&self) -> libc::c_long {
- self.0.f_bfree
- }
-
- /// Free blocks in filesystem
- #[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_free(&self) -> u32 {
- self.0.f_bfree
- }
-
- /// Free blocks available to unprivileged user
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_available(&self) -> u64 {
- self.0.f_bavail
- }
-
- /// Free blocks available to unprivileged user
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_available(&self) -> libc::c_long {
- self.0.f_bavail
- }
-
- /// Free blocks available to unprivileged user
- #[cfg(any(target_os = "freebsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_available(&self) -> i64 {
- self.0.f_bavail
- }
-
- /// Free blocks available to unprivileged user
- #[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn blocks_available(&self) -> u32 {
- self.0.f_bavail
- }
-
- /// Total file nodes in filesystem
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "openbsd",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files(&self) -> u64 {
- self.0.f_files
- }
-
- /// Total file nodes in filesystem
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files(&self) -> libc::c_long {
- self.0.f_files
- }
-
- /// Total file nodes in filesystem
- #[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files(&self) -> u32 {
- self.0.f_files
- }
-
- /// Free file nodes in filesystem
- #[cfg(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "android",
- target_os = "fuchsia",
- target_os = "openbsd",
- target_os = "linux",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files_free(&self) -> u64 {
- self.0.f_ffree
- }
-
- /// Free file nodes in filesystem
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files_free(&self) -> libc::c_long {
- self.0.f_ffree
- }
-
- /// Free file nodes in filesystem
- #[cfg(target_os = "freebsd")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files_free(&self) -> i64 {
- self.0.f_ffree
- }
-
- /// Free file nodes in filesystem
- #[cfg(target_os = "emscripten")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn files_free(&self) -> u32 {
- self.0.f_ffree
- }
-
- /// Filesystem ID
- pub fn filesystem_id(&self) -> fsid_t {
- self.0.f_fsid
- }
-}
-
-impl Debug for Statfs {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let mut ds = f.debug_struct("Statfs");
- ds.field("optimal_transfer_size", &self.optimal_transfer_size());
- ds.field("block_size", &self.block_size());
- ds.field("blocks", &self.blocks());
- ds.field("blocks_free", &self.blocks_free());
- ds.field("blocks_available", &self.blocks_available());
- ds.field("files", &self.files());
- ds.field("files_free", &self.files_free());
- ds.field("filesystem_id", &self.filesystem_id());
- #[cfg(all(
- feature = "mount",
- any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )
- ))]
- ds.field("flags", &self.flags());
- ds.finish()
- }
-}
-
-/// Describes a mounted file system.
-///
-/// The result is OS-dependent. For a portable alternative, see
-/// [`statvfs`](crate::sys::statvfs::statvfs).
-///
-/// # Arguments
-///
-/// `path` - Path to any file within the file system to describe
-pub fn statfs<P: ?Sized + NixPath>(path: &P) -> Result<Statfs> {
- unsafe {
- let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
- let res = path.with_nix_path(|path| {
- LIBC_STATFS(path.as_ptr(), stat.as_mut_ptr())
- })?;
- Errno::result(res).map(|_| Statfs(stat.assume_init()))
- }
-}
-
-/// Describes a mounted file system.
-///
-/// The result is OS-dependent. For a portable alternative, see
-/// [`fstatvfs`](crate::sys::statvfs::fstatvfs).
-///
-/// # Arguments
-///
-/// `fd` - File descriptor of any open file within the file system to describe
-pub fn fstatfs<T: AsRawFd>(fd: &T) -> Result<Statfs> {
- unsafe {
- let mut stat = mem::MaybeUninit::<type_of_statfs>::uninit();
- Errno::result(LIBC_FSTATFS(fd.as_raw_fd(), stat.as_mut_ptr()))
- .map(|_| Statfs(stat.assume_init()))
- }
-}
-
-#[cfg(test)]
-mod test {
- use std::fs::File;
-
- use crate::sys::statfs::*;
- use crate::sys::statvfs::*;
- use std::path::Path;
-
- #[test]
- fn statfs_call() {
- check_statfs("/tmp");
- check_statfs("/dev");
- check_statfs("/run");
- check_statfs("/");
- }
-
- #[test]
- fn fstatfs_call() {
- check_fstatfs("/tmp");
- check_fstatfs("/dev");
- check_fstatfs("/run");
- check_fstatfs("/");
- }
-
- fn check_fstatfs(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes()).unwrap();
- let file = File::open(path).unwrap();
- let fs = fstatfs(&file).unwrap();
- assert_fs_equals(fs, vfs);
- }
-
- fn check_statfs(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes()).unwrap();
- let fs = statfs(path.as_bytes()).unwrap();
- assert_fs_equals(fs, vfs);
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn assert_fs_equals(fs: Statfs, vfs: Statvfs) {
- assert_eq!(fs.files() as u64, vfs.files() as u64);
- assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
- assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
- }
-
- // This test is ignored because files_free/blocks_free can change after statvfs call and before
- // statfs call.
- #[test]
- #[ignore]
- fn statfs_call_strict() {
- check_statfs_strict("/tmp");
- check_statfs_strict("/dev");
- check_statfs_strict("/run");
- check_statfs_strict("/");
- }
-
- // This test is ignored because files_free/blocks_free can change after statvfs call and before
- // fstatfs call.
- #[test]
- #[ignore]
- fn fstatfs_call_strict() {
- check_fstatfs_strict("/tmp");
- check_fstatfs_strict("/dev");
- check_fstatfs_strict("/run");
- check_fstatfs_strict("/");
- }
-
- fn check_fstatfs_strict(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes());
- let file = File::open(path).unwrap();
- let fs = fstatfs(&file);
- assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
- }
-
- fn check_statfs_strict(path: &str) {
- if !Path::new(path).exists() {
- return;
- }
- let vfs = statvfs(path.as_bytes());
- let fs = statfs(path.as_bytes());
- assert_fs_equals_strict(fs.unwrap(), vfs.unwrap())
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) {
- assert_eq!(fs.files_free() as u64, vfs.files_free() as u64);
- assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64);
- assert_eq!(fs.blocks_available() as u64, vfs.blocks_available() as u64);
- assert_eq!(fs.files() as u64, vfs.files() as u64);
- assert_eq!(fs.blocks() as u64, vfs.blocks() as u64);
- assert_eq!(fs.block_size() as u64, vfs.fragment_size() as u64);
- }
-}
diff --git a/vendor/nix/src/sys/statvfs.rs b/vendor/nix/src/sys/statvfs.rs
deleted file mode 100644
index 8de369f42..000000000
--- a/vendor/nix/src/sys/statvfs.rs
+++ /dev/null
@@ -1,173 +0,0 @@
-//! Get filesystem statistics
-//!
-//! See [the man pages](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html)
-//! for more details.
-use std::mem;
-use std::os::unix::io::AsRawFd;
-
-use libc::{self, c_ulong};
-
-use crate::{errno::Errno, NixPath, Result};
-
-#[cfg(not(target_os = "redox"))]
-libc_bitflags!(
- /// File system mount Flags
- #[repr(C)]
- #[derive(Default)]
- pub struct FsFlags: c_ulong {
- /// Read Only
- #[cfg(not(target_os = "haiku"))]
- ST_RDONLY;
- /// Do not allow the set-uid bits to have an effect
- #[cfg(not(target_os = "haiku"))]
- ST_NOSUID;
- /// Do not interpret character or block-special devices
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_NODEV;
- /// Do not allow execution of binaries on the filesystem
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_NOEXEC;
- /// All IO should be done synchronously
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_SYNCHRONOUS;
- /// Allow mandatory locks on the filesystem
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_MANDLOCK;
- /// Write on file/directory/symlink
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_WRITE;
- /// Append-only file
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_APPEND;
- /// Immutable file
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_IMMUTABLE;
- /// Do not update access times on files
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_NOATIME;
- /// Do not update access times on files
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_NODIRATIME;
- /// Update access time relative to modify/change time
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_env = "musl"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ST_RELATIME;
- }
-);
-
-/// Wrapper around the POSIX `statvfs` struct
-///
-/// For more information see the [`statvfs(3)` man pages](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_statvfs.h.html).
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct Statvfs(libc::statvfs);
-
-impl Statvfs {
- /// get the file system block size
- pub fn block_size(&self) -> c_ulong {
- self.0.f_bsize
- }
-
- /// Get the fundamental file system block size
- pub fn fragment_size(&self) -> c_ulong {
- self.0.f_frsize
- }
-
- /// Get the number of blocks.
- ///
- /// Units are in units of `fragment_size()`
- pub fn blocks(&self) -> libc::fsblkcnt_t {
- self.0.f_blocks
- }
-
- /// Get the number of free blocks in the file system
- pub fn blocks_free(&self) -> libc::fsblkcnt_t {
- self.0.f_bfree
- }
-
- /// Get the number of free blocks for unprivileged users
- pub fn blocks_available(&self) -> libc::fsblkcnt_t {
- self.0.f_bavail
- }
-
- /// Get the total number of file inodes
- pub fn files(&self) -> libc::fsfilcnt_t {
- self.0.f_files
- }
-
- /// Get the number of free file inodes
- pub fn files_free(&self) -> libc::fsfilcnt_t {
- self.0.f_ffree
- }
-
- /// Get the number of free file inodes for unprivileged users
- pub fn files_available(&self) -> libc::fsfilcnt_t {
- self.0.f_favail
- }
-
- /// Get the file system id
- pub fn filesystem_id(&self) -> c_ulong {
- self.0.f_fsid
- }
-
- /// Get the mount flags
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn flags(&self) -> FsFlags {
- FsFlags::from_bits_truncate(self.0.f_flag)
- }
-
- /// Get the maximum filename length
- pub fn name_max(&self) -> c_ulong {
- self.0.f_namemax
- }
-}
-
-/// Return a `Statvfs` object with information about the `path`
-pub fn statvfs<P: ?Sized + NixPath>(path: &P) -> Result<Statvfs> {
- unsafe {
- Errno::clear();
- let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
- let res = path.with_nix_path(|path| {
- libc::statvfs(path.as_ptr(), stat.as_mut_ptr())
- })?;
-
- Errno::result(res).map(|_| Statvfs(stat.assume_init()))
- }
-}
-
-/// Return a `Statvfs` object with information about `fd`
-pub fn fstatvfs<T: AsRawFd>(fd: &T) -> Result<Statvfs> {
- unsafe {
- Errno::clear();
- let mut stat = mem::MaybeUninit::<libc::statvfs>::uninit();
- Errno::result(libc::fstatvfs(fd.as_raw_fd(), stat.as_mut_ptr()))
- .map(|_| Statvfs(stat.assume_init()))
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::sys::statvfs::*;
- use std::fs::File;
-
- #[test]
- fn statvfs_call() {
- statvfs(&b"/"[..]).unwrap();
- }
-
- #[test]
- fn fstatvfs_call() {
- let root = File::open("/").unwrap();
- fstatvfs(&root).unwrap();
- }
-}
diff --git a/vendor/nix/src/sys/sysinfo.rs b/vendor/nix/src/sys/sysinfo.rs
deleted file mode 100644
index e8aa00b00..000000000
--- a/vendor/nix/src/sys/sysinfo.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-use libc::{self, SI_LOAD_SHIFT};
-use std::time::Duration;
-use std::{cmp, mem};
-
-use crate::errno::Errno;
-use crate::Result;
-
-/// System info structure returned by `sysinfo`.
-#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
-#[repr(transparent)]
-pub struct SysInfo(libc::sysinfo);
-
-// The fields are c_ulong on 32-bit linux, u64 on 64-bit linux; x32's ulong is u32
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
-type mem_blocks_t = u64;
-#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
-type mem_blocks_t = libc::c_ulong;
-
-impl SysInfo {
- /// Returns the load average tuple.
- ///
- /// The returned values represent the load average over time intervals of
- /// 1, 5, and 15 minutes, respectively.
- pub fn load_average(&self) -> (f64, f64, f64) {
- (
- self.0.loads[0] as f64 / (1 << SI_LOAD_SHIFT) as f64,
- self.0.loads[1] as f64 / (1 << SI_LOAD_SHIFT) as f64,
- self.0.loads[2] as f64 / (1 << SI_LOAD_SHIFT) as f64,
- )
- }
-
- /// Returns the time since system boot.
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- pub fn uptime(&self) -> Duration {
- // Truncate negative values to 0
- Duration::from_secs(cmp::max(self.0.uptime, 0) as u64)
- }
-
- /// Current number of processes.
- pub fn process_count(&self) -> u16 {
- self.0.procs
- }
-
- /// Returns the amount of swap memory in Bytes.
- pub fn swap_total(&self) -> u64 {
- self.scale_mem(self.0.totalswap)
- }
-
- /// Returns the amount of unused swap memory in Bytes.
- pub fn swap_free(&self) -> u64 {
- self.scale_mem(self.0.freeswap)
- }
-
- /// Returns the total amount of installed RAM in Bytes.
- pub fn ram_total(&self) -> u64 {
- self.scale_mem(self.0.totalram)
- }
-
- /// Returns the amount of completely unused RAM in Bytes.
- ///
- /// "Unused" in this context means that the RAM in neither actively used by
- /// programs, nor by the operating system as disk cache or buffer. It is
- /// "wasted" RAM since it currently serves no purpose.
- pub fn ram_unused(&self) -> u64 {
- self.scale_mem(self.0.freeram)
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn scale_mem(&self, units: mem_blocks_t) -> u64 {
- units as u64 * self.0.mem_unit as u64
- }
-}
-
-/// Returns system information.
-///
-/// [See `sysinfo(2)`](https://man7.org/linux/man-pages/man2/sysinfo.2.html).
-pub fn sysinfo() -> Result<SysInfo> {
- let mut info = mem::MaybeUninit::uninit();
- let res = unsafe { libc::sysinfo(info.as_mut_ptr()) };
- Errno::result(res).map(|_| unsafe { SysInfo(info.assume_init()) })
-}
diff --git a/vendor/nix/src/sys/termios.rs b/vendor/nix/src/sys/termios.rs
deleted file mode 100644
index fba2cd826..000000000
--- a/vendor/nix/src/sys/termios.rs
+++ /dev/null
@@ -1,1227 +0,0 @@
-//! An interface for controlling asynchronous communication ports
-//!
-//! This interface provides a safe wrapper around the termios subsystem defined by POSIX. The
-//! underlying types are all implemented in libc for most platforms and either wrapped in safer
-//! types here or exported directly.
-//!
-//! If you are unfamiliar with the `termios` API, you should first read the
-//! [API documentation](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html) and
-//! then come back to understand how `nix` safely wraps it.
-//!
-//! It should be noted that this API incurs some runtime overhead above the base `libc` definitions.
-//! As this interface is not used with high-bandwidth information, this should be fine in most
-//! cases. The primary cost when using this API is that the `Termios` datatype here duplicates the
-//! standard fields of the underlying `termios` struct and uses safe type wrappers for those fields.
-//! This means that when crossing the FFI interface to the underlying C library, data is first
-//! copied into the underlying `termios` struct, then the operation is done, and the data is copied
-//! back (with additional sanity checking) into the safe wrapper types. The `termios` struct is
-//! relatively small across all platforms (on the order of 32-64 bytes).
-//!
-//! The following examples highlight some of the API use cases such that users coming from using C
-//! or reading the standard documentation will understand how to use the safe API exposed here.
-//!
-//! Example disabling processing of the end-of-file control character:
-//!
-//! ```
-//! # use self::nix::sys::termios::SpecialCharacterIndices::VEOF;
-//! # use self::nix::sys::termios::{_POSIX_VDISABLE, Termios};
-//! # let mut termios: Termios = unsafe { std::mem::zeroed() };
-//! termios.control_chars[VEOF as usize] = _POSIX_VDISABLE;
-//! ```
-//!
-//! The flags within `Termios` are defined as bitfields using the `bitflags` crate. This provides
-//! an interface for working with bitfields that is similar to working with the raw unsigned
-//! integer types but offers type safety because of the internal checking that values will always
-//! be a valid combination of the defined flags.
-//!
-//! An example showing some of the basic operations for interacting with the control flags:
-//!
-//! ```
-//! # use self::nix::sys::termios::{ControlFlags, Termios};
-//! # let mut termios: Termios = unsafe { std::mem::zeroed() };
-//! termios.control_flags & ControlFlags::CSIZE == ControlFlags::CS5;
-//! termios.control_flags |= ControlFlags::CS5;
-//! ```
-//!
-//! # Baud rates
-//!
-//! This API is not consistent across platforms when it comes to `BaudRate`: Android and Linux both
-//! only support the rates specified by the `BaudRate` enum through their termios API while the BSDs
-//! support arbitrary baud rates as the values of the `BaudRate` enum constants are the same integer
-//! value of the constant (`B9600` == `9600`). Therefore the `nix::termios` API uses the following
-//! conventions:
-//!
-//! * `cfgetispeed()` - Returns `u32` on BSDs, `BaudRate` on Android/Linux
-//! * `cfgetospeed()` - Returns `u32` on BSDs, `BaudRate` on Android/Linux
-//! * `cfsetispeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux
-//! * `cfsetospeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux
-//! * `cfsetspeed()` - Takes `u32` or `BaudRate` on BSDs, `BaudRate` on Android/Linux
-//!
-//! The most common use case of specifying a baud rate using the enum will work the same across
-//! platforms:
-//!
-//! ```rust
-//! # use nix::sys::termios::{BaudRate, cfsetispeed, cfsetospeed, cfsetspeed, Termios};
-//! # fn main() {
-//! # let mut t: Termios = unsafe { std::mem::zeroed() };
-//! cfsetispeed(&mut t, BaudRate::B9600).unwrap();
-//! cfsetospeed(&mut t, BaudRate::B9600).unwrap();
-//! cfsetspeed(&mut t, BaudRate::B9600).unwrap();
-//! # }
-//! ```
-//!
-//! Additionally round-tripping baud rates is consistent across platforms:
-//!
-//! ```rust
-//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetispeed, cfsetspeed, Termios};
-//! # fn main() {
-//! # let mut t: Termios = unsafe { std::mem::zeroed() };
-//! # cfsetspeed(&mut t, BaudRate::B9600).unwrap();
-//! let speed = cfgetispeed(&t);
-//! assert_eq!(speed, cfgetospeed(&t));
-//! cfsetispeed(&mut t, speed).unwrap();
-//! # }
-//! ```
-//!
-//! On non-BSDs, `cfgetispeed()` and `cfgetospeed()` both return a `BaudRate`:
-//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust,ignore"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust"
-)]
-//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
-//! # fn main() {
-//! # let mut t: Termios = unsafe { std::mem::zeroed() };
-//! # cfsetspeed(&mut t, BaudRate::B9600);
-//! assert_eq!(cfgetispeed(&t), BaudRate::B9600);
-//! assert_eq!(cfgetospeed(&t), BaudRate::B9600);
-//! # }
-//! ```
-//!
-//! But on the BSDs, `cfgetispeed()` and `cfgetospeed()` both return `u32`s:
-//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust,ignore"
-)]
-//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfgetospeed, cfsetspeed, Termios};
-//! # fn main() {
-//! # let mut t: Termios = unsafe { std::mem::zeroed() };
-//! # cfsetspeed(&mut t, 9600u32);
-//! assert_eq!(cfgetispeed(&t), 9600u32);
-//! assert_eq!(cfgetospeed(&t), 9600u32);
-//! # }
-//! ```
-//!
-//! It's trivial to convert from a `BaudRate` to a `u32` on BSDs:
-//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust,ignore"
-)]
-//! # use nix::sys::termios::{BaudRate, cfgetispeed, cfsetspeed, Termios};
-//! # fn main() {
-//! # let mut t: Termios = unsafe { std::mem::zeroed() };
-//! # cfsetspeed(&mut t, 9600u32);
-//! assert_eq!(cfgetispeed(&t), BaudRate::B9600.into());
-//! assert_eq!(u32::from(BaudRate::B9600), 9600u32);
-//! # }
-//! ```
-//!
-//! And on BSDs you can specify arbitrary baud rates (**note** this depends on hardware support)
-//! by specifying baud rates directly using `u32`s:
-//!
-#![cfg_attr(
- any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- ),
- doc = " ```rust"
-)]
-#![cfg_attr(
- not(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
- )),
- doc = " ```rust,ignore"
-)]
-//! # use nix::sys::termios::{cfsetispeed, cfsetospeed, cfsetspeed, Termios};
-//! # fn main() {
-//! # let mut t: Termios = unsafe { std::mem::zeroed() };
-//! cfsetispeed(&mut t, 9600u32);
-//! cfsetospeed(&mut t, 9600u32);
-//! cfsetspeed(&mut t, 9600u32);
-//! # }
-//! ```
-use crate::errno::Errno;
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{self, c_int, tcflag_t};
-use std::cell::{Ref, RefCell};
-use std::convert::From;
-use std::mem;
-use std::os::unix::io::RawFd;
-
-#[cfg(feature = "process")]
-use crate::unistd::Pid;
-
-/// Stores settings for the termios API
-///
-/// This is a wrapper around the `libc::termios` struct that provides a safe interface for the
-/// standard fields. The only safe way to obtain an instance of this struct is to extract it from
-/// an open port using `tcgetattr()`.
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Termios {
- inner: RefCell<libc::termios>,
- /// Input mode flags (see `termios.c_iflag` documentation)
- pub input_flags: InputFlags,
- /// Output mode flags (see `termios.c_oflag` documentation)
- pub output_flags: OutputFlags,
- /// Control mode flags (see `termios.c_cflag` documentation)
- pub control_flags: ControlFlags,
- /// Local mode flags (see `termios.c_lflag` documentation)
- pub local_flags: LocalFlags,
- /// Control characters (see `termios.c_cc` documentation)
- pub control_chars: [libc::cc_t; NCCS],
- /// Line discipline (see `termios.c_line` documentation)
- #[cfg(any(target_os = "linux", target_os = "android",))]
- pub line_discipline: libc::cc_t,
- /// Line discipline (see `termios.c_line` documentation)
- #[cfg(target_os = "haiku")]
- pub line_discipline: libc::c_char,
-}
-
-impl Termios {
- /// Exposes an immutable reference to the underlying `libc::termios` data structure.
- ///
- /// This is not part of `nix`'s public API because it requires additional work to maintain type
- /// safety.
- pub(crate) fn get_libc_termios(&self) -> Ref<libc::termios> {
- {
- let mut termios = self.inner.borrow_mut();
- termios.c_iflag = self.input_flags.bits();
- termios.c_oflag = self.output_flags.bits();
- termios.c_cflag = self.control_flags.bits();
- termios.c_lflag = self.local_flags.bits();
- termios.c_cc = self.control_chars;
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
- {
- termios.c_line = self.line_discipline;
- }
- }
- self.inner.borrow()
- }
-
- /// Exposes the inner `libc::termios` datastore within `Termios`.
- ///
- /// This is unsafe because if this is used to modify the inner `libc::termios` struct, it will
- /// not automatically update the safe wrapper type around it. In this case it should also be
- /// paired with a call to `update_wrapper()` so that the wrapper-type and internal
- /// representation stay consistent.
- pub(crate) unsafe fn get_libc_termios_mut(&mut self) -> *mut libc::termios {
- {
- let mut termios = self.inner.borrow_mut();
- termios.c_iflag = self.input_flags.bits();
- termios.c_oflag = self.output_flags.bits();
- termios.c_cflag = self.control_flags.bits();
- termios.c_lflag = self.local_flags.bits();
- termios.c_cc = self.control_chars;
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
- {
- termios.c_line = self.line_discipline;
- }
- }
- self.inner.as_ptr()
- }
-
- /// Updates the wrapper values from the internal `libc::termios` data structure.
- pub(crate) fn update_wrapper(&mut self) {
- let termios = *self.inner.borrow_mut();
- self.input_flags = InputFlags::from_bits_truncate(termios.c_iflag);
- self.output_flags = OutputFlags::from_bits_truncate(termios.c_oflag);
- self.control_flags = ControlFlags::from_bits_truncate(termios.c_cflag);
- self.local_flags = LocalFlags::from_bits_truncate(termios.c_lflag);
- self.control_chars = termios.c_cc;
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
- {
- self.line_discipline = termios.c_line;
- }
- }
-}
-
-impl From<libc::termios> for Termios {
- fn from(termios: libc::termios) -> Self {
- Termios {
- inner: RefCell::new(termios),
- input_flags: InputFlags::from_bits_truncate(termios.c_iflag),
- output_flags: OutputFlags::from_bits_truncate(termios.c_oflag),
- control_flags: ControlFlags::from_bits_truncate(termios.c_cflag),
- local_flags: LocalFlags::from_bits_truncate(termios.c_lflag),
- control_chars: termios.c_cc,
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "haiku",
- ))]
- line_discipline: termios.c_line,
- }
- }
-}
-
-impl From<Termios> for libc::termios {
- fn from(termios: Termios) -> Self {
- termios.inner.into_inner()
- }
-}
-
-libc_enum! {
- /// Baud rates supported by the system.
- ///
- /// For the BSDs, arbitrary baud rates can be specified by using `u32`s directly instead of this
- /// enum.
- ///
- /// B0 is special and will disable the port.
- #[cfg_attr(all(any(target_os = "haiku"), target_pointer_width = "64"), repr(u8))]
- #[cfg_attr(all(any(target_os = "ios", target_os = "macos"), target_pointer_width = "64"), repr(u64))]
- #[cfg_attr(not(all(any(target_os = "ios", target_os = "macos", target_os = "haiku"), target_pointer_width = "64")), repr(u32))]
- #[non_exhaustive]
- pub enum BaudRate {
- B0,
- B50,
- B75,
- B110,
- B134,
- B150,
- B200,
- B300,
- B600,
- B1200,
- B1800,
- B2400,
- B4800,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B7200,
- B9600,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B14400,
- B19200,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B28800,
- B38400,
- B57600,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B76800,
- B115200,
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B153600,
- B230400,
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B307200,
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B460800,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B500000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B576000,
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B921600,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B1000000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B1152000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B1500000,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B2000000,
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B2500000,
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B3000000,
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B3500000,
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- B4000000,
- }
- impl TryFrom<libc::speed_t>
-}
-
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-impl From<BaudRate> for u32 {
- fn from(b: BaudRate) -> u32 {
- b as u32
- }
-}
-
-#[cfg(target_os = "haiku")]
-impl From<BaudRate> for u8 {
- fn from(b: BaudRate) -> u8 {
- b as u8
- }
-}
-
-// TODO: Add TCSASOFT, which will require treating this as a bitfield.
-libc_enum! {
- /// Specify when a port configuration change should occur.
- ///
- /// Used as an argument to `tcsetattr()`
- #[repr(i32)]
- #[non_exhaustive]
- pub enum SetArg {
- /// The change will occur immediately
- TCSANOW,
- /// The change occurs after all output has been written
- TCSADRAIN,
- /// Same as `TCSADRAIN`, but will also flush the input buffer
- TCSAFLUSH,
- }
-}
-
-libc_enum! {
- /// Specify a combination of the input and output buffers to flush
- ///
- /// Used as an argument to `tcflush()`.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum FlushArg {
- /// Flush data that was received but not read
- TCIFLUSH,
- /// Flush data written but not transmitted
- TCOFLUSH,
- /// Flush both received data not read and written data not transmitted
- TCIOFLUSH,
- }
-}
-
-libc_enum! {
- /// Specify how transmission flow should be altered
- ///
- /// Used as an argument to `tcflow()`.
- #[repr(i32)]
- #[non_exhaustive]
- pub enum FlowArg {
- /// Suspend transmission
- TCOOFF,
- /// Resume transmission
- TCOON,
- /// Transmit a STOP character, which should disable a connected terminal device
- TCIOFF,
- /// Transmit a START character, which should re-enable a connected terminal device
- TCION,
- }
-}
-
-// TODO: Make this usable directly as a slice index.
-#[cfg(not(target_os = "haiku"))]
-libc_enum! {
- /// Indices into the `termios.c_cc` array for special characters.
- #[repr(usize)]
- #[non_exhaustive]
- pub enum SpecialCharacterIndices {
- VDISCARD,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VDSUSP,
- VEOF,
- VEOL,
- VEOL2,
- VERASE,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VERASE2,
- VINTR,
- VKILL,
- VLNEXT,
- #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"),
- target_os = "illumos", target_os = "solaris")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VMIN,
- VQUIT,
- VREPRINT,
- VSTART,
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VSTATUS,
- VSTOP,
- VSUSP,
- #[cfg(target_os = "linux")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VSWTC,
- #[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VSWTCH,
- #[cfg(not(any(all(target_os = "linux", target_arch = "sparc64"),
- target_os = "illumos", target_os = "solaris")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VTIME,
- VWERASE,
- #[cfg(target_os = "dragonfly")]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VCHECKPT,
- }
-}
-
-#[cfg(any(
- all(target_os = "linux", target_arch = "sparc64"),
- target_os = "illumos",
- target_os = "solaris"
-))]
-impl SpecialCharacterIndices {
- pub const VMIN: SpecialCharacterIndices = SpecialCharacterIndices::VEOF;
- pub const VTIME: SpecialCharacterIndices = SpecialCharacterIndices::VEOL;
-}
-
-pub use libc::NCCS;
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub use libc::_POSIX_VDISABLE;
-
-libc_bitflags! {
- /// Flags for configuring the input mode of a terminal
- pub struct InputFlags: tcflag_t {
- IGNBRK;
- BRKINT;
- IGNPAR;
- PARMRK;
- INPCK;
- ISTRIP;
- INLCR;
- IGNCR;
- ICRNL;
- IXON;
- IXOFF;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IXANY;
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IMAXBEL;
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IUTF8;
- }
-}
-
-libc_bitflags! {
- /// Flags for configuring the output mode of a terminal
- pub struct OutputFlags: tcflag_t {
- OPOST;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "linux",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- OLCUC;
- ONLCR;
- OCRNL as tcflag_t;
- ONOCR as tcflag_t;
- ONLRET as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- OFILL as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- OFDEL as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NL0 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NL1 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CR0 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CR1 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CR2 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CR3 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- TAB0 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- TAB1 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- TAB2 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- TAB3 as tcflag_t;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- XTABS;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BS0 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BS1 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VT0 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VT1 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- FF0 as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- FF1 as tcflag_t;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- OXTABS;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ONOEOT as tcflag_t;
-
- // Bitmasks for use with OutputFlags to select specific settings
- // These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110
- // is resolved.
-
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NLDLY as tcflag_t; // FIXME: Datatype needs to be corrected in libc for mac
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CRDLY as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- TABDLY as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BSDLY as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- VTDLY as tcflag_t;
- #[cfg(any(target_os = "android",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- FFDLY as tcflag_t;
- }
-}
-
-libc_bitflags! {
- /// Flags for setting the control mode of a terminal
- pub struct ControlFlags: tcflag_t {
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CIGNORE;
- CS5;
- CS6;
- CS7;
- CS8;
- CSTOPB;
- CREAD;
- PARENB;
- PARODD;
- HUPCL;
- CLOCAL;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CRTSCTS;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CBAUD;
- #[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "mips"))))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CMSPAR;
- #[cfg(any(target_os = "android",
- all(target_os = "linux",
- not(any(target_arch = "powerpc", target_arch = "powerpc64")))))]
- CIBAUD;
- #[cfg(any(target_os = "android", target_os = "linux"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CBAUDEX;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MDMBUF;
- #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CHWFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CCTS_OFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CRTS_IFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CDTR_IFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CDSR_OFLOW;
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- CCAR_OFLOW;
-
- // Bitmasks for use with ControlFlags to select specific settings
- // These should be moved to be a mask once https://github.com/rust-lang-nursery/bitflags/issues/110
- // is resolved.
-
- CSIZE;
- }
-}
-
-libc_bitflags! {
- /// Flags for setting any local modes
- pub struct LocalFlags: tcflag_t {
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ECHOKE;
- ECHOE;
- ECHOK;
- ECHO;
- ECHONL;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ECHOPRT;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ECHOCTL;
- ISIG;
- ICANON;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ALTWERASE;
- IEXTEN;
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- EXTPROC;
- TOSTOP;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- FLUSHO;
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- NOKERNINFO;
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PENDIN;
- NOFLSH;
- }
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"))] {
- /// Get input baud rate (see
- /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
- ///
- /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure.
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- pub fn cfgetispeed(termios: &Termios) -> u32 {
- let inner_termios = termios.get_libc_termios();
- unsafe { libc::cfgetispeed(&*inner_termios) as u32 }
- }
-
- /// Get output baud rate (see
- /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)).
- ///
- /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure.
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- pub fn cfgetospeed(termios: &Termios) -> u32 {
- let inner_termios = termios.get_libc_termios();
- unsafe { libc::cfgetospeed(&*inner_termios) as u32 }
- }
-
- /// Set input baud rate (see
- /// [cfsetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)).
- ///
- /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure.
- pub fn cfsetispeed<T: Into<u32>>(termios: &mut Termios, baud: T) -> Result<()> {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- let res = unsafe { libc::cfsetispeed(inner_termios, baud.into() as libc::speed_t) };
- termios.update_wrapper();
- Errno::result(res).map(drop)
- }
-
- /// Set output baud rate (see
- /// [cfsetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)).
- ///
- /// `cfsetospeed()` sets the output baud rate in the given termios structure.
- pub fn cfsetospeed<T: Into<u32>>(termios: &mut Termios, baud: T) -> Result<()> {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- let res = unsafe { libc::cfsetospeed(inner_termios, baud.into() as libc::speed_t) };
- termios.update_wrapper();
- Errno::result(res).map(drop)
- }
-
- /// Set both the input and output baud rates (see
- /// [termios(3)](https://www.freebsd.org/cgi/man.cgi?query=cfsetspeed)).
- ///
- /// `cfsetspeed()` sets the input and output baud rate in the given termios structure. Note that
- /// this is part of the 4.4BSD standard and not part of POSIX.
- pub fn cfsetspeed<T: Into<u32>>(termios: &mut Termios, baud: T) -> Result<()> {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- let res = unsafe { libc::cfsetspeed(inner_termios, baud.into() as libc::speed_t) };
- termios.update_wrapper();
- Errno::result(res).map(drop)
- }
- } else {
- use std::convert::TryInto;
-
- /// Get input baud rate (see
- /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
- ///
- /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure.
- pub fn cfgetispeed(termios: &Termios) -> BaudRate {
- let inner_termios = termios.get_libc_termios();
- unsafe { libc::cfgetispeed(&*inner_termios) }.try_into().unwrap()
- }
-
- /// Get output baud rate (see
- /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)).
- ///
- /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure.
- pub fn cfgetospeed(termios: &Termios) -> BaudRate {
- let inner_termios = termios.get_libc_termios();
- unsafe { libc::cfgetospeed(&*inner_termios) }.try_into().unwrap()
- }
-
- /// Set input baud rate (see
- /// [cfsetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetispeed.html)).
- ///
- /// `cfsetispeed()` sets the intput baud rate in the given `Termios` structure.
- pub fn cfsetispeed(termios: &mut Termios, baud: BaudRate) -> Result<()> {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- let res = unsafe { libc::cfsetispeed(inner_termios, baud as libc::speed_t) };
- termios.update_wrapper();
- Errno::result(res).map(drop)
- }
-
- /// Set output baud rate (see
- /// [cfsetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfsetospeed.html)).
- ///
- /// `cfsetospeed()` sets the output baud rate in the given `Termios` structure.
- pub fn cfsetospeed(termios: &mut Termios, baud: BaudRate) -> Result<()> {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- let res = unsafe { libc::cfsetospeed(inner_termios, baud as libc::speed_t) };
- termios.update_wrapper();
- Errno::result(res).map(drop)
- }
-
- /// Set both the input and output baud rates (see
- /// [termios(3)](https://www.freebsd.org/cgi/man.cgi?query=cfsetspeed)).
- ///
- /// `cfsetspeed()` sets the input and output baud rate in the given `Termios` structure. Note that
- /// this is part of the 4.4BSD standard and not part of POSIX.
- #[cfg(not(target_os = "haiku"))]
- pub fn cfsetspeed(termios: &mut Termios, baud: BaudRate) -> Result<()> {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- let res = unsafe { libc::cfsetspeed(inner_termios, baud as libc::speed_t) };
- termios.update_wrapper();
- Errno::result(res).map(drop)
- }
- }
-}
-
-/// Configures the port to something like the "raw" mode of the old Version 7 terminal driver (see
-/// [termios(3)](https://man7.org/linux/man-pages/man3/termios.3.html)).
-///
-/// `cfmakeraw()` configures the termios structure such that input is available character-by-
-/// character, echoing is disabled, and all special input and output processing is disabled. Note
-/// that this is a non-standard function, but is available on Linux and BSDs.
-pub fn cfmakeraw(termios: &mut Termios) {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- unsafe {
- libc::cfmakeraw(inner_termios);
- }
- termios.update_wrapper();
-}
-
-/// Configures the port to "sane" mode (like the configuration of a newly created terminal) (see
-/// [tcsetattr(3)](https://www.freebsd.org/cgi/man.cgi?query=tcsetattr)).
-///
-/// Note that this is a non-standard function, available on FreeBSD.
-#[cfg(target_os = "freebsd")]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn cfmakesane(termios: &mut Termios) {
- let inner_termios = unsafe { termios.get_libc_termios_mut() };
- unsafe {
- libc::cfmakesane(inner_termios);
- }
- termios.update_wrapper();
-}
-
-/// Return the configuration of a port
-/// [tcgetattr(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetattr.html)).
-///
-/// `tcgetattr()` returns a `Termios` structure with the current configuration for a port. Modifying
-/// this structure *will not* reconfigure the port, instead the modifications should be done to
-/// the `Termios` structure and then the port should be reconfigured using `tcsetattr()`.
-pub fn tcgetattr(fd: RawFd) -> Result<Termios> {
- let mut termios = mem::MaybeUninit::uninit();
-
- let res = unsafe { libc::tcgetattr(fd, termios.as_mut_ptr()) };
-
- Errno::result(res)?;
-
- unsafe { Ok(termios.assume_init().into()) }
-}
-
-/// Set the configuration for a terminal (see
-/// [tcsetattr(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetattr.html)).
-///
-/// `tcsetattr()` reconfigures the given port based on a given `Termios` structure. This change
-/// takes affect at a time specified by `actions`. Note that this function may return success if
-/// *any* of the parameters were successfully set, not only if all were set successfully.
-pub fn tcsetattr(fd: RawFd, actions: SetArg, termios: &Termios) -> Result<()> {
- let inner_termios = termios.get_libc_termios();
- Errno::result(unsafe {
- libc::tcsetattr(fd, actions as c_int, &*inner_termios)
- })
- .map(drop)
-}
-
-/// Block until all output data is written (see
-/// [tcdrain(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcdrain.html)).
-pub fn tcdrain(fd: RawFd) -> Result<()> {
- Errno::result(unsafe { libc::tcdrain(fd) }).map(drop)
-}
-
-/// Suspend or resume the transmission or reception of data (see
-/// [tcflow(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflow.html)).
-///
-/// `tcflow()` suspends of resumes the transmission or reception of data for the given port
-/// depending on the value of `action`.
-pub fn tcflow(fd: RawFd, action: FlowArg) -> Result<()> {
- Errno::result(unsafe { libc::tcflow(fd, action as c_int) }).map(drop)
-}
-
-/// Discard data in the output or input queue (see
-/// [tcflush(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcflush.html)).
-///
-/// `tcflush()` will discard data for a terminal port in the input queue, output queue, or both
-/// depending on the value of `action`.
-pub fn tcflush(fd: RawFd, action: FlushArg) -> Result<()> {
- Errno::result(unsafe { libc::tcflush(fd, action as c_int) }).map(drop)
-}
-
-/// Send a break for a specific duration (see
-/// [tcsendbreak(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsendbreak.html)).
-///
-/// When using asynchronous data transmission `tcsendbreak()` will transmit a continuous stream
-/// of zero-valued bits for an implementation-defined duration.
-pub fn tcsendbreak(fd: RawFd, duration: c_int) -> Result<()> {
- Errno::result(unsafe { libc::tcsendbreak(fd, duration) }).map(drop)
-}
-
-feature! {
-#![feature = "process"]
-/// Get the session controlled by the given terminal (see
-/// [tcgetsid(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetsid.html)).
-pub fn tcgetsid(fd: RawFd) -> Result<Pid> {
- let res = unsafe { libc::tcgetsid(fd) };
-
- Errno::result(res).map(Pid::from_raw)
-}
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use std::convert::TryFrom;
-
- #[test]
- fn try_from() {
- assert_eq!(Ok(BaudRate::B0), BaudRate::try_from(libc::B0));
- #[cfg(not(target_os = "haiku"))]
- BaudRate::try_from(999999999).expect_err("assertion failed");
- #[cfg(target_os = "haiku")]
- BaudRate::try_from(99).expect_err("assertion failed");
- }
-}
diff --git a/vendor/nix/src/sys/time.rs b/vendor/nix/src/sys/time.rs
deleted file mode 100644
index 0042c4508..000000000
--- a/vendor/nix/src/sys/time.rs
+++ /dev/null
@@ -1,811 +0,0 @@
-#[cfg_attr(target_env = "musl", allow(deprecated))]
-// https://github.com/rust-lang/libc/issues/1848
-pub use libc::{suseconds_t, time_t};
-use libc::{timespec, timeval};
-use std::convert::From;
-use std::time::Duration;
-use std::{cmp, fmt, ops};
-
-const fn zero_init_timespec() -> timespec {
- // `std::mem::MaybeUninit::zeroed()` is not yet a const fn
- // (https://github.com/rust-lang/rust/issues/91850) so we will instead initialize an array of
- // the appropriate size to zero and then transmute it to a timespec value.
- unsafe { std::mem::transmute([0u8; std::mem::size_of::<timespec>()]) }
-}
-
-#[cfg(any(
- all(feature = "time", any(target_os = "android", target_os = "linux")),
- all(
- any(
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd"
- ),
- feature = "time",
- feature = "signal"
- )
-))]
-pub(crate) mod timer {
- use crate::sys::time::{zero_init_timespec, TimeSpec};
- use bitflags::bitflags;
-
- #[derive(Debug, Clone, Copy)]
- pub(crate) struct TimerSpec(libc::itimerspec);
-
- impl TimerSpec {
- pub const fn none() -> Self {
- Self(libc::itimerspec {
- it_interval: zero_init_timespec(),
- it_value: zero_init_timespec(),
- })
- }
- }
-
- impl AsMut<libc::itimerspec> for TimerSpec {
- fn as_mut(&mut self) -> &mut libc::itimerspec {
- &mut self.0
- }
- }
-
- impl AsRef<libc::itimerspec> for TimerSpec {
- fn as_ref(&self) -> &libc::itimerspec {
- &self.0
- }
- }
-
- impl From<Expiration> for TimerSpec {
- fn from(expiration: Expiration) -> TimerSpec {
- match expiration {
- Expiration::OneShot(t) => TimerSpec(libc::itimerspec {
- it_interval: zero_init_timespec(),
- it_value: *t.as_ref(),
- }),
- Expiration::IntervalDelayed(start, interval) => {
- TimerSpec(libc::itimerspec {
- it_interval: *interval.as_ref(),
- it_value: *start.as_ref(),
- })
- }
- Expiration::Interval(t) => TimerSpec(libc::itimerspec {
- it_interval: *t.as_ref(),
- it_value: *t.as_ref(),
- }),
- }
- }
- }
-
- /// An enumeration allowing the definition of the expiration time of an alarm,
- /// recurring or not.
- #[derive(Debug, Clone, Copy, Eq, PartialEq)]
- pub enum Expiration {
- /// Alarm will trigger once after the time given in `TimeSpec`
- OneShot(TimeSpec),
- /// Alarm will trigger after a specified delay and then every interval of
- /// time.
- IntervalDelayed(TimeSpec, TimeSpec),
- /// Alarm will trigger every specified interval of time.
- Interval(TimeSpec),
- }
-
- #[cfg(any(target_os = "android", target_os = "linux"))]
- bitflags! {
- /// Flags that are used for arming the timer.
- pub struct TimerSetTimeFlags: libc::c_int {
- const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME;
- }
- }
- #[cfg(any(
- target_os = "freebsd",
- target_os = "netbsd",
- target_os = "dragonfly",
- target_os = "illumos"
- ))]
- bitflags! {
- /// Flags that are used for arming the timer.
- pub struct TimerSetTimeFlags: libc::c_int {
- const TFD_TIMER_ABSTIME = libc::TIMER_ABSTIME;
- }
- }
-
- impl From<TimerSpec> for Expiration {
- fn from(timerspec: TimerSpec) -> Expiration {
- match timerspec {
- TimerSpec(libc::itimerspec {
- it_interval:
- libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- ..
- },
- it_value: ts,
- }) => Expiration::OneShot(ts.into()),
- TimerSpec(libc::itimerspec {
- it_interval: int_ts,
- it_value: val_ts,
- }) => {
- if (int_ts.tv_sec == val_ts.tv_sec)
- && (int_ts.tv_nsec == val_ts.tv_nsec)
- {
- Expiration::Interval(int_ts.into())
- } else {
- Expiration::IntervalDelayed(
- val_ts.into(),
- int_ts.into(),
- )
- }
- }
- }
- }
- }
-}
-
-pub trait TimeValLike: Sized {
- #[inline]
- fn zero() -> Self {
- Self::seconds(0)
- }
-
- #[inline]
- fn hours(hours: i64) -> Self {
- let secs = hours
- .checked_mul(SECS_PER_HOUR)
- .expect("TimeValLike::hours ouf of bounds");
- Self::seconds(secs)
- }
-
- #[inline]
- fn minutes(minutes: i64) -> Self {
- let secs = minutes
- .checked_mul(SECS_PER_MINUTE)
- .expect("TimeValLike::minutes out of bounds");
- Self::seconds(secs)
- }
-
- fn seconds(seconds: i64) -> Self;
- fn milliseconds(milliseconds: i64) -> Self;
- fn microseconds(microseconds: i64) -> Self;
- fn nanoseconds(nanoseconds: i64) -> Self;
-
- #[inline]
- fn num_hours(&self) -> i64 {
- self.num_seconds() / 3600
- }
-
- #[inline]
- fn num_minutes(&self) -> i64 {
- self.num_seconds() / 60
- }
-
- fn num_seconds(&self) -> i64;
- fn num_milliseconds(&self) -> i64;
- fn num_microseconds(&self) -> i64;
- fn num_nanoseconds(&self) -> i64;
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct TimeSpec(timespec);
-
-const NANOS_PER_SEC: i64 = 1_000_000_000;
-const SECS_PER_MINUTE: i64 = 60;
-const SECS_PER_HOUR: i64 = 3600;
-
-#[cfg(target_pointer_width = "64")]
-const TS_MAX_SECONDS: i64 = (i64::MAX / NANOS_PER_SEC) - 1;
-
-#[cfg(target_pointer_width = "32")]
-const TS_MAX_SECONDS: i64 = isize::MAX as i64;
-
-const TS_MIN_SECONDS: i64 = -TS_MAX_SECONDS;
-
-// x32 compatibility
-// See https://sourceware.org/bugzilla/show_bug.cgi?id=16437
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))]
-type timespec_tv_nsec_t = i64;
-#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
-type timespec_tv_nsec_t = libc::c_long;
-
-impl From<timespec> for TimeSpec {
- fn from(ts: timespec) -> Self {
- Self(ts)
- }
-}
-
-impl From<Duration> for TimeSpec {
- fn from(duration: Duration) -> Self {
- Self::from_duration(duration)
- }
-}
-
-impl From<TimeSpec> for Duration {
- fn from(timespec: TimeSpec) -> Self {
- Duration::new(timespec.0.tv_sec as u64, timespec.0.tv_nsec as u32)
- }
-}
-
-impl AsRef<timespec> for TimeSpec {
- fn as_ref(&self) -> &timespec {
- &self.0
- }
-}
-
-impl AsMut<timespec> for TimeSpec {
- fn as_mut(&mut self) -> &mut timespec {
- &mut self.0
- }
-}
-
-impl Ord for TimeSpec {
- // The implementation of cmp is simplified by assuming that the struct is
- // normalized. That is, tv_nsec must always be within [0, 1_000_000_000)
- fn cmp(&self, other: &TimeSpec) -> cmp::Ordering {
- if self.tv_sec() == other.tv_sec() {
- self.tv_nsec().cmp(&other.tv_nsec())
- } else {
- self.tv_sec().cmp(&other.tv_sec())
- }
- }
-}
-
-impl PartialOrd for TimeSpec {
- fn partial_cmp(&self, other: &TimeSpec) -> Option<cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl TimeValLike for TimeSpec {
- #[inline]
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- fn seconds(seconds: i64) -> TimeSpec {
- assert!(
- (TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&seconds),
- "TimeSpec out of bounds; seconds={}",
- seconds
- );
- let mut ts = zero_init_timespec();
- ts.tv_sec = seconds as time_t;
- TimeSpec(ts)
- }
-
- #[inline]
- fn milliseconds(milliseconds: i64) -> TimeSpec {
- let nanoseconds = milliseconds
- .checked_mul(1_000_000)
- .expect("TimeSpec::milliseconds out of bounds");
-
- TimeSpec::nanoseconds(nanoseconds)
- }
-
- /// Makes a new `TimeSpec` with given number of microseconds.
- #[inline]
- fn microseconds(microseconds: i64) -> TimeSpec {
- let nanoseconds = microseconds
- .checked_mul(1_000)
- .expect("TimeSpec::milliseconds out of bounds");
-
- TimeSpec::nanoseconds(nanoseconds)
- }
-
- /// Makes a new `TimeSpec` with given number of nanoseconds.
- #[inline]
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- fn nanoseconds(nanoseconds: i64) -> TimeSpec {
- let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC);
- assert!(
- (TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs),
- "TimeSpec out of bounds"
- );
- let mut ts = zero_init_timespec();
- ts.tv_sec = secs as time_t;
- ts.tv_nsec = nanos as timespec_tv_nsec_t;
- TimeSpec(ts)
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn num_seconds(&self) -> i64 {
- if self.tv_sec() < 0 && self.tv_nsec() > 0 {
- (self.tv_sec() + 1) as i64
- } else {
- self.tv_sec() as i64
- }
- }
-
- fn num_milliseconds(&self) -> i64 {
- self.num_nanoseconds() / 1_000_000
- }
-
- fn num_microseconds(&self) -> i64 {
- self.num_nanoseconds() / 1_000
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn num_nanoseconds(&self) -> i64 {
- let secs = self.num_seconds() * 1_000_000_000;
- let nsec = self.nanos_mod_sec();
- secs + nsec as i64
- }
-}
-
-impl TimeSpec {
- /// Construct a new `TimeSpec` from its components
- #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
- pub const fn new(seconds: time_t, nanoseconds: timespec_tv_nsec_t) -> Self {
- let mut ts = zero_init_timespec();
- ts.tv_sec = seconds;
- ts.tv_nsec = nanoseconds;
- Self(ts)
- }
-
- fn nanos_mod_sec(&self) -> timespec_tv_nsec_t {
- if self.tv_sec() < 0 && self.tv_nsec() > 0 {
- self.tv_nsec() - NANOS_PER_SEC as timespec_tv_nsec_t
- } else {
- self.tv_nsec()
- }
- }
-
- #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
- pub const fn tv_sec(&self) -> time_t {
- self.0.tv_sec
- }
-
- pub const fn tv_nsec(&self) -> timespec_tv_nsec_t {
- self.0.tv_nsec
- }
-
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- pub const fn from_duration(duration: Duration) -> Self {
- let mut ts = zero_init_timespec();
- ts.tv_sec = duration.as_secs() as time_t;
- ts.tv_nsec = duration.subsec_nanos() as timespec_tv_nsec_t;
- TimeSpec(ts)
- }
-
- pub const fn from_timespec(timespec: timespec) -> Self {
- Self(timespec)
- }
-}
-
-impl ops::Neg for TimeSpec {
- type Output = TimeSpec;
-
- fn neg(self) -> TimeSpec {
- TimeSpec::nanoseconds(-self.num_nanoseconds())
- }
-}
-
-impl ops::Add for TimeSpec {
- type Output = TimeSpec;
-
- fn add(self, rhs: TimeSpec) -> TimeSpec {
- TimeSpec::nanoseconds(self.num_nanoseconds() + rhs.num_nanoseconds())
- }
-}
-
-impl ops::Sub for TimeSpec {
- type Output = TimeSpec;
-
- fn sub(self, rhs: TimeSpec) -> TimeSpec {
- TimeSpec::nanoseconds(self.num_nanoseconds() - rhs.num_nanoseconds())
- }
-}
-
-impl ops::Mul<i32> for TimeSpec {
- type Output = TimeSpec;
-
- fn mul(self, rhs: i32) -> TimeSpec {
- let usec = self
- .num_nanoseconds()
- .checked_mul(i64::from(rhs))
- .expect("TimeSpec multiply out of bounds");
-
- TimeSpec::nanoseconds(usec)
- }
-}
-
-impl ops::Div<i32> for TimeSpec {
- type Output = TimeSpec;
-
- fn div(self, rhs: i32) -> TimeSpec {
- let usec = self.num_nanoseconds() / i64::from(rhs);
- TimeSpec::nanoseconds(usec)
- }
-}
-
-impl fmt::Display for TimeSpec {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let (abs, sign) = if self.tv_sec() < 0 {
- (-*self, "-")
- } else {
- (*self, "")
- };
-
- let sec = abs.tv_sec();
-
- write!(f, "{}", sign)?;
-
- if abs.tv_nsec() == 0 {
- if abs.tv_sec() == 1 {
- write!(f, "{} second", sec)?;
- } else {
- write!(f, "{} seconds", sec)?;
- }
- } else if abs.tv_nsec() % 1_000_000 == 0 {
- write!(f, "{}.{:03} seconds", sec, abs.tv_nsec() / 1_000_000)?;
- } else if abs.tv_nsec() % 1_000 == 0 {
- write!(f, "{}.{:06} seconds", sec, abs.tv_nsec() / 1_000)?;
- } else {
- write!(f, "{}.{:09} seconds", sec, abs.tv_nsec())?;
- }
-
- Ok(())
- }
-}
-
-#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct TimeVal(timeval);
-
-const MICROS_PER_SEC: i64 = 1_000_000;
-
-#[cfg(target_pointer_width = "64")]
-const TV_MAX_SECONDS: i64 = (i64::MAX / MICROS_PER_SEC) - 1;
-
-#[cfg(target_pointer_width = "32")]
-const TV_MAX_SECONDS: i64 = isize::MAX as i64;
-
-const TV_MIN_SECONDS: i64 = -TV_MAX_SECONDS;
-
-impl AsRef<timeval> for TimeVal {
- fn as_ref(&self) -> &timeval {
- &self.0
- }
-}
-
-impl AsMut<timeval> for TimeVal {
- fn as_mut(&mut self) -> &mut timeval {
- &mut self.0
- }
-}
-
-impl Ord for TimeVal {
- // The implementation of cmp is simplified by assuming that the struct is
- // normalized. That is, tv_usec must always be within [0, 1_000_000)
- fn cmp(&self, other: &TimeVal) -> cmp::Ordering {
- if self.tv_sec() == other.tv_sec() {
- self.tv_usec().cmp(&other.tv_usec())
- } else {
- self.tv_sec().cmp(&other.tv_sec())
- }
- }
-}
-
-impl PartialOrd for TimeVal {
- fn partial_cmp(&self, other: &TimeVal) -> Option<cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl TimeValLike for TimeVal {
- #[inline]
- fn seconds(seconds: i64) -> TimeVal {
- assert!(
- (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&seconds),
- "TimeVal out of bounds; seconds={}",
- seconds
- );
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- TimeVal(timeval {
- tv_sec: seconds as time_t,
- tv_usec: 0,
- })
- }
-
- #[inline]
- fn milliseconds(milliseconds: i64) -> TimeVal {
- let microseconds = milliseconds
- .checked_mul(1_000)
- .expect("TimeVal::milliseconds out of bounds");
-
- TimeVal::microseconds(microseconds)
- }
-
- /// Makes a new `TimeVal` with given number of microseconds.
- #[inline]
- fn microseconds(microseconds: i64) -> TimeVal {
- let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
- assert!(
- (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs),
- "TimeVal out of bounds"
- );
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- TimeVal(timeval {
- tv_sec: secs as time_t,
- tv_usec: micros as suseconds_t,
- })
- }
-
- /// Makes a new `TimeVal` with given number of nanoseconds. Some precision
- /// will be lost
- #[inline]
- fn nanoseconds(nanoseconds: i64) -> TimeVal {
- let microseconds = nanoseconds / 1000;
- let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC);
- assert!(
- (TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs),
- "TimeVal out of bounds"
- );
- #[cfg_attr(target_env = "musl", allow(deprecated))]
- // https://github.com/rust-lang/libc/issues/1848
- TimeVal(timeval {
- tv_sec: secs as time_t,
- tv_usec: micros as suseconds_t,
- })
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn num_seconds(&self) -> i64 {
- if self.tv_sec() < 0 && self.tv_usec() > 0 {
- (self.tv_sec() + 1) as i64
- } else {
- self.tv_sec() as i64
- }
- }
-
- fn num_milliseconds(&self) -> i64 {
- self.num_microseconds() / 1_000
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- fn num_microseconds(&self) -> i64 {
- let secs = self.num_seconds() * 1_000_000;
- let usec = self.micros_mod_sec();
- secs + usec as i64
- }
-
- fn num_nanoseconds(&self) -> i64 {
- self.num_microseconds() * 1_000
- }
-}
-
-impl TimeVal {
- /// Construct a new `TimeVal` from its components
- #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
- pub const fn new(seconds: time_t, microseconds: suseconds_t) -> Self {
- Self(timeval {
- tv_sec: seconds,
- tv_usec: microseconds,
- })
- }
-
- fn micros_mod_sec(&self) -> suseconds_t {
- if self.tv_sec() < 0 && self.tv_usec() > 0 {
- self.tv_usec() - MICROS_PER_SEC as suseconds_t
- } else {
- self.tv_usec()
- }
- }
-
- #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848
- pub const fn tv_sec(&self) -> time_t {
- self.0.tv_sec
- }
-
- pub const fn tv_usec(&self) -> suseconds_t {
- self.0.tv_usec
- }
-}
-
-impl ops::Neg for TimeVal {
- type Output = TimeVal;
-
- fn neg(self) -> TimeVal {
- TimeVal::microseconds(-self.num_microseconds())
- }
-}
-
-impl ops::Add for TimeVal {
- type Output = TimeVal;
-
- fn add(self, rhs: TimeVal) -> TimeVal {
- TimeVal::microseconds(self.num_microseconds() + rhs.num_microseconds())
- }
-}
-
-impl ops::Sub for TimeVal {
- type Output = TimeVal;
-
- fn sub(self, rhs: TimeVal) -> TimeVal {
- TimeVal::microseconds(self.num_microseconds() - rhs.num_microseconds())
- }
-}
-
-impl ops::Mul<i32> for TimeVal {
- type Output = TimeVal;
-
- fn mul(self, rhs: i32) -> TimeVal {
- let usec = self
- .num_microseconds()
- .checked_mul(i64::from(rhs))
- .expect("TimeVal multiply out of bounds");
-
- TimeVal::microseconds(usec)
- }
-}
-
-impl ops::Div<i32> for TimeVal {
- type Output = TimeVal;
-
- fn div(self, rhs: i32) -> TimeVal {
- let usec = self.num_microseconds() / i64::from(rhs);
- TimeVal::microseconds(usec)
- }
-}
-
-impl fmt::Display for TimeVal {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let (abs, sign) = if self.tv_sec() < 0 {
- (-*self, "-")
- } else {
- (*self, "")
- };
-
- let sec = abs.tv_sec();
-
- write!(f, "{}", sign)?;
-
- if abs.tv_usec() == 0 {
- if abs.tv_sec() == 1 {
- write!(f, "{} second", sec)?;
- } else {
- write!(f, "{} seconds", sec)?;
- }
- } else if abs.tv_usec() % 1000 == 0 {
- write!(f, "{}.{:03} seconds", sec, abs.tv_usec() / 1000)?;
- } else {
- write!(f, "{}.{:06} seconds", sec, abs.tv_usec())?;
- }
-
- Ok(())
- }
-}
-
-impl From<timeval> for TimeVal {
- fn from(tv: timeval) -> Self {
- TimeVal(tv)
- }
-}
-
-#[inline]
-fn div_mod_floor_64(this: i64, other: i64) -> (i64, i64) {
- (div_floor_64(this, other), mod_floor_64(this, other))
-}
-
-#[inline]
-fn div_floor_64(this: i64, other: i64) -> i64 {
- match div_rem_64(this, other) {
- (d, r) if (r > 0 && other < 0) || (r < 0 && other > 0) => d - 1,
- (d, _) => d,
- }
-}
-
-#[inline]
-fn mod_floor_64(this: i64, other: i64) -> i64 {
- match this % other {
- r if (r > 0 && other < 0) || (r < 0 && other > 0) => r + other,
- r => r,
- }
-}
-
-#[inline]
-fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
- (this / other, this % other)
-}
-
-#[cfg(test)]
-mod test {
- use super::{TimeSpec, TimeVal, TimeValLike};
- use std::time::Duration;
-
- #[test]
- pub fn test_timespec() {
- assert_ne!(TimeSpec::seconds(1), TimeSpec::zero());
- assert_eq!(
- TimeSpec::seconds(1) + TimeSpec::seconds(2),
- TimeSpec::seconds(3)
- );
- assert_eq!(
- TimeSpec::minutes(3) + TimeSpec::seconds(2),
- TimeSpec::seconds(182)
- );
- }
-
- #[test]
- pub fn test_timespec_from() {
- let duration = Duration::new(123, 123_456_789);
- let timespec = TimeSpec::nanoseconds(123_123_456_789);
-
- assert_eq!(TimeSpec::from(duration), timespec);
- assert_eq!(Duration::from(timespec), duration);
- }
-
- #[test]
- pub fn test_timespec_neg() {
- let a = TimeSpec::seconds(1) + TimeSpec::nanoseconds(123);
- let b = TimeSpec::seconds(-1) + TimeSpec::nanoseconds(-123);
-
- assert_eq!(a, -b);
- }
-
- #[test]
- pub fn test_timespec_ord() {
- assert_eq!(TimeSpec::seconds(1), TimeSpec::nanoseconds(1_000_000_000));
- assert!(TimeSpec::seconds(1) < TimeSpec::nanoseconds(1_000_000_001));
- assert!(TimeSpec::seconds(1) > TimeSpec::nanoseconds(999_999_999));
- assert!(TimeSpec::seconds(-1) < TimeSpec::nanoseconds(-999_999_999));
- assert!(TimeSpec::seconds(-1) > TimeSpec::nanoseconds(-1_000_000_001));
- }
-
- #[test]
- pub fn test_timespec_fmt() {
- assert_eq!(TimeSpec::zero().to_string(), "0 seconds");
- assert_eq!(TimeSpec::seconds(42).to_string(), "42 seconds");
- assert_eq!(TimeSpec::milliseconds(42).to_string(), "0.042 seconds");
- assert_eq!(TimeSpec::microseconds(42).to_string(), "0.000042 seconds");
- assert_eq!(
- TimeSpec::nanoseconds(42).to_string(),
- "0.000000042 seconds"
- );
- assert_eq!(TimeSpec::seconds(-86401).to_string(), "-86401 seconds");
- }
-
- #[test]
- pub fn test_timeval() {
- assert_ne!(TimeVal::seconds(1), TimeVal::zero());
- assert_eq!(
- TimeVal::seconds(1) + TimeVal::seconds(2),
- TimeVal::seconds(3)
- );
- assert_eq!(
- TimeVal::minutes(3) + TimeVal::seconds(2),
- TimeVal::seconds(182)
- );
- }
-
- #[test]
- pub fn test_timeval_ord() {
- assert_eq!(TimeVal::seconds(1), TimeVal::microseconds(1_000_000));
- assert!(TimeVal::seconds(1) < TimeVal::microseconds(1_000_001));
- assert!(TimeVal::seconds(1) > TimeVal::microseconds(999_999));
- assert!(TimeVal::seconds(-1) < TimeVal::microseconds(-999_999));
- assert!(TimeVal::seconds(-1) > TimeVal::microseconds(-1_000_001));
- }
-
- #[test]
- pub fn test_timeval_neg() {
- let a = TimeVal::seconds(1) + TimeVal::microseconds(123);
- let b = TimeVal::seconds(-1) + TimeVal::microseconds(-123);
-
- assert_eq!(a, -b);
- }
-
- #[test]
- pub fn test_timeval_fmt() {
- assert_eq!(TimeVal::zero().to_string(), "0 seconds");
- assert_eq!(TimeVal::seconds(42).to_string(), "42 seconds");
- assert_eq!(TimeVal::milliseconds(42).to_string(), "0.042 seconds");
- assert_eq!(TimeVal::microseconds(42).to_string(), "0.000042 seconds");
- assert_eq!(TimeVal::nanoseconds(1402).to_string(), "0.000001 seconds");
- assert_eq!(TimeVal::seconds(-86401).to_string(), "-86401 seconds");
- }
-}
diff --git a/vendor/nix/src/sys/timer.rs b/vendor/nix/src/sys/timer.rs
deleted file mode 100644
index e1a34051e..000000000
--- a/vendor/nix/src/sys/timer.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-//! Timer API via signals.
-//!
-//! Timer is a POSIX API to create timers and get expiration notifications
-//! through queued Unix signals, for the current process. This is similar to
-//! Linux's timerfd mechanism, except that API is specific to Linux and makes
-//! use of file polling.
-//!
-//! For more documentation, please read [timer_create](https://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_create.html).
-//!
-//! # Examples
-//!
-//! Create an interval timer that signals SIGALARM every 250 milliseconds.
-//!
-//! ```no_run
-//! use nix::sys::signal::{self, SigEvent, SigHandler, SigevNotify, Signal};
-//! use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags};
-//! use nix::time::ClockId;
-//! use std::convert::TryFrom;
-//! use std::sync::atomic::{AtomicU64, Ordering};
-//! use std::thread::yield_now;
-//! use std::time::Duration;
-//!
-//! const SIG: Signal = Signal::SIGALRM;
-//! static ALARMS: AtomicU64 = AtomicU64::new(0);
-//!
-//! extern "C" fn handle_alarm(signal: libc::c_int) {
-//! let signal = Signal::try_from(signal).unwrap();
-//! if signal == SIG {
-//! ALARMS.fetch_add(1, Ordering::Relaxed);
-//! }
-//! }
-//!
-//! fn main() {
-//! let clockid = ClockId::CLOCK_MONOTONIC;
-//! let sigevent = SigEvent::new(SigevNotify::SigevSignal {
-//! signal: SIG,
-//! si_value: 0,
-//! });
-//!
-//! let mut timer = Timer::new(clockid, sigevent).unwrap();
-//! let expiration = Expiration::Interval(Duration::from_millis(250).into());
-//! let flags = TimerSetTimeFlags::empty();
-//! timer.set(expiration, flags).expect("could not set timer");
-//!
-//! let handler = SigHandler::Handler(handle_alarm);
-//! unsafe { signal::signal(SIG, handler) }.unwrap();
-//!
-//! loop {
-//! let alarms = ALARMS.load(Ordering::Relaxed);
-//! if alarms >= 10 {
-//! println!("total alarms handled: {}", alarms);
-//! break;
-//! }
-//! yield_now()
-//! }
-//! }
-//! ```
-use crate::sys::signal::SigEvent;
-use crate::sys::time::timer::TimerSpec;
-pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags};
-use crate::time::ClockId;
-use crate::{errno::Errno, Result};
-use core::mem;
-
-/// A Unix signal per-process timer.
-#[derive(Debug)]
-#[repr(transparent)]
-pub struct Timer(libc::timer_t);
-
-impl Timer {
- /// Creates a new timer based on the clock defined by `clockid`. The details
- /// of the signal and its handler are defined by the passed `sigevent`.
- #[doc(alias("timer_create"))]
- pub fn new(clockid: ClockId, mut sigevent: SigEvent) -> Result<Self> {
- let mut timer_id: mem::MaybeUninit<libc::timer_t> =
- mem::MaybeUninit::uninit();
- Errno::result(unsafe {
- libc::timer_create(
- clockid.as_raw(),
- sigevent.as_mut_ptr(),
- timer_id.as_mut_ptr(),
- )
- })
- .map(|_| {
- // SAFETY: libc::timer_create is responsible for initializing
- // timer_id.
- unsafe { Self(timer_id.assume_init()) }
- })
- }
-
- /// Set a new alarm on the timer.
- ///
- /// # Types of alarm
- ///
- /// There are 3 types of alarms you can set:
- ///
- /// - one shot: the alarm will trigger once after the specified amount of
- /// time.
- /// Example: I want an alarm to go off in 60s and then disable itself.
- ///
- /// - interval: the alarm will trigger every specified interval of time.
- /// Example: I want an alarm to go off every 60s. The alarm will first
- /// go off 60s after I set it and every 60s after that. The alarm will
- /// not disable itself.
- ///
- /// - interval delayed: the alarm will trigger after a certain amount of
- /// time and then trigger at a specified interval.
- /// Example: I want an alarm to go off every 60s but only start in 1h.
- /// The alarm will first trigger 1h after I set it and then every 60s
- /// after that. The alarm will not disable itself.
- ///
- /// # Relative vs absolute alarm
- ///
- /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass
- /// to the `Expiration` you want is relative. If however you want an alarm
- /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`.
- /// Then the one shot TimeSpec and the delay TimeSpec of the delayed
- /// interval are going to be interpreted as absolute.
- ///
- /// # Disabling alarms
- ///
- /// Note: Only one alarm can be set for any given timer. Setting a new alarm
- /// actually removes the previous one.
- ///
- /// Note: Setting a one shot alarm with a 0s TimeSpec disable the alarm
- /// altogether.
- #[doc(alias("timer_settime"))]
- pub fn set(
- &mut self,
- expiration: Expiration,
- flags: TimerSetTimeFlags,
- ) -> Result<()> {
- let timerspec: TimerSpec = expiration.into();
- Errno::result(unsafe {
- libc::timer_settime(
- self.0,
- flags.bits(),
- timerspec.as_ref(),
- core::ptr::null_mut(),
- )
- })
- .map(drop)
- }
-
- /// Get the parameters for the alarm currently set, if any.
- #[doc(alias("timer_gettime"))]
- pub fn get(&self) -> Result<Option<Expiration>> {
- let mut timerspec = TimerSpec::none();
- Errno::result(unsafe {
- libc::timer_gettime(self.0, timerspec.as_mut())
- })
- .map(|_| {
- if timerspec.as_ref().it_interval.tv_sec == 0
- && timerspec.as_ref().it_interval.tv_nsec == 0
- && timerspec.as_ref().it_value.tv_sec == 0
- && timerspec.as_ref().it_value.tv_nsec == 0
- {
- None
- } else {
- Some(timerspec.into())
- }
- })
- }
-
- /// Return the number of timers that have overrun
- ///
- /// Each timer is able to queue one signal to the process at a time, meaning
- /// if the signal is not handled before the next expiration the timer has
- /// 'overrun'. This function returns how many times that has happened to
- /// this timer, up to `libc::DELAYTIMER_MAX`. If more than the maximum
- /// number of overruns have happened the return is capped to the maximum.
- #[doc(alias("timer_getoverrun"))]
- pub fn overruns(&self) -> i32 {
- unsafe { libc::timer_getoverrun(self.0) }
- }
-}
-
-impl Drop for Timer {
- fn drop(&mut self) {
- if !std::thread::panicking() {
- let result = Errno::result(unsafe { libc::timer_delete(self.0) });
- if let Err(Errno::EINVAL) = result {
- panic!("close of Timer encountered EINVAL");
- }
- }
- }
-}
diff --git a/vendor/nix/src/sys/timerfd.rs b/vendor/nix/src/sys/timerfd.rs
deleted file mode 100644
index a35fc927f..000000000
--- a/vendor/nix/src/sys/timerfd.rs
+++ /dev/null
@@ -1,214 +0,0 @@
-//! Timer API via file descriptors.
-//!
-//! Timer FD is a Linux-only API to create timers and get expiration
-//! notifications through file descriptors.
-//!
-//! For more documentation, please read [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html).
-//!
-//! # Examples
-//!
-//! Create a new one-shot timer that expires after 1 second.
-//! ```
-//! # use std::os::unix::io::AsRawFd;
-//! # use nix::sys::timerfd::{TimerFd, ClockId, TimerFlags, TimerSetTimeFlags,
-//! # Expiration};
-//! # use nix::sys::time::{TimeSpec, TimeValLike};
-//! # use nix::unistd::read;
-//! #
-//! // We create a new monotonic timer.
-//! let timer = TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty())
-//! .unwrap();
-//!
-//! // We set a new one-shot timer in 1 seconds.
-//! timer.set(
-//! Expiration::OneShot(TimeSpec::seconds(1)),
-//! TimerSetTimeFlags::empty()
-//! ).unwrap();
-//!
-//! // We wait for the timer to expire.
-//! timer.wait().unwrap();
-//! ```
-use crate::sys::time::timer::TimerSpec;
-pub use crate::sys::time::timer::{Expiration, TimerSetTimeFlags};
-use crate::unistd::read;
-use crate::{errno::Errno, Result};
-use libc::c_int;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
-
-/// A timerfd instance. This is also a file descriptor, you can feed it to
-/// other interfaces consuming file descriptors, epoll for example.
-#[derive(Debug)]
-pub struct TimerFd {
- fd: RawFd,
-}
-
-impl AsRawFd for TimerFd {
- fn as_raw_fd(&self) -> RawFd {
- self.fd
- }
-}
-
-impl FromRawFd for TimerFd {
- unsafe fn from_raw_fd(fd: RawFd) -> Self {
- TimerFd { fd }
- }
-}
-
-libc_enum! {
- /// The type of the clock used to mark the progress of the timer. For more
- /// details on each kind of clock, please refer to [timerfd_create(2)](https://man7.org/linux/man-pages/man2/timerfd_create.2.html).
- #[repr(i32)]
- #[non_exhaustive]
- pub enum ClockId {
- /// A settable system-wide real-time clock.
- CLOCK_REALTIME,
- /// A non-settable monotonically increasing clock.
- ///
- /// Does not change after system startup.
- /// Does not measure time while the system is suspended.
- CLOCK_MONOTONIC,
- /// Like `CLOCK_MONOTONIC`, except that `CLOCK_BOOTTIME` includes the time
- /// that the system was suspended.
- CLOCK_BOOTTIME,
- /// Like `CLOCK_REALTIME`, but will wake the system if it is suspended.
- CLOCK_REALTIME_ALARM,
- /// Like `CLOCK_BOOTTIME`, but will wake the system if it is suspended.
- CLOCK_BOOTTIME_ALARM,
- }
-}
-
-libc_bitflags! {
- /// Additional flags to change the behaviour of the file descriptor at the
- /// time of creation.
- pub struct TimerFlags: c_int {
- /// Set the `O_NONBLOCK` flag on the open file description referred to by the new file descriptor.
- TFD_NONBLOCK;
- /// Set the `FD_CLOEXEC` flag on the file descriptor.
- TFD_CLOEXEC;
- }
-}
-
-impl TimerFd {
- /// Creates a new timer based on the clock defined by `clockid`. The
- /// underlying fd can be assigned specific flags with `flags` (CLOEXEC,
- /// NONBLOCK). The underlying fd will be closed on drop.
- #[doc(alias("timerfd_create"))]
- pub fn new(clockid: ClockId, flags: TimerFlags) -> Result<Self> {
- Errno::result(unsafe {
- libc::timerfd_create(clockid as i32, flags.bits())
- })
- .map(|fd| Self { fd })
- }
-
- /// Sets a new alarm on the timer.
- ///
- /// # Types of alarm
- ///
- /// There are 3 types of alarms you can set:
- ///
- /// - one shot: the alarm will trigger once after the specified amount of
- /// time.
- /// Example: I want an alarm to go off in 60s and then disable itself.
- ///
- /// - interval: the alarm will trigger every specified interval of time.
- /// Example: I want an alarm to go off every 60s. The alarm will first
- /// go off 60s after I set it and every 60s after that. The alarm will
- /// not disable itself.
- ///
- /// - interval delayed: the alarm will trigger after a certain amount of
- /// time and then trigger at a specified interval.
- /// Example: I want an alarm to go off every 60s but only start in 1h.
- /// The alarm will first trigger 1h after I set it and then every 60s
- /// after that. The alarm will not disable itself.
- ///
- /// # Relative vs absolute alarm
- ///
- /// If you do not set any `TimerSetTimeFlags`, then the `TimeSpec` you pass
- /// to the `Expiration` you want is relative. If however you want an alarm
- /// to go off at a certain point in time, you can set `TFD_TIMER_ABSTIME`.
- /// Then the one shot TimeSpec and the delay TimeSpec of the delayed
- /// interval are going to be interpreted as absolute.
- ///
- /// # Disabling alarms
- ///
- /// Note: Only one alarm can be set for any given timer. Setting a new alarm
- /// actually removes the previous one.
- ///
- /// Note: Setting a one shot alarm with a 0s TimeSpec disables the alarm
- /// altogether.
- #[doc(alias("timerfd_settime"))]
- pub fn set(
- &self,
- expiration: Expiration,
- flags: TimerSetTimeFlags,
- ) -> Result<()> {
- let timerspec: TimerSpec = expiration.into();
- Errno::result(unsafe {
- libc::timerfd_settime(
- self.fd,
- flags.bits(),
- timerspec.as_ref(),
- std::ptr::null_mut(),
- )
- })
- .map(drop)
- }
-
- /// Get the parameters for the alarm currently set, if any.
- #[doc(alias("timerfd_gettime"))]
- pub fn get(&self) -> Result<Option<Expiration>> {
- let mut timerspec = TimerSpec::none();
- Errno::result(unsafe {
- libc::timerfd_gettime(self.fd, timerspec.as_mut())
- })
- .map(|_| {
- if timerspec.as_ref().it_interval.tv_sec == 0
- && timerspec.as_ref().it_interval.tv_nsec == 0
- && timerspec.as_ref().it_value.tv_sec == 0
- && timerspec.as_ref().it_value.tv_nsec == 0
- {
- None
- } else {
- Some(timerspec.into())
- }
- })
- }
-
- /// Remove the alarm if any is set.
- #[doc(alias("timerfd_settime"))]
- pub fn unset(&self) -> Result<()> {
- Errno::result(unsafe {
- libc::timerfd_settime(
- self.fd,
- TimerSetTimeFlags::empty().bits(),
- TimerSpec::none().as_ref(),
- std::ptr::null_mut(),
- )
- })
- .map(drop)
- }
-
- /// Wait for the configured alarm to expire.
- ///
- /// Note: If the alarm is unset, then you will wait forever.
- pub fn wait(&self) -> Result<()> {
- while let Err(e) = read(self.fd, &mut [0u8; 8]) {
- if e != Errno::EINTR {
- return Err(e);
- }
- }
-
- Ok(())
- }
-}
-
-impl Drop for TimerFd {
- fn drop(&mut self) {
- if !std::thread::panicking() {
- let result = Errno::result(unsafe { libc::close(self.fd) });
- if let Err(Errno::EBADF) = result {
- panic!("close of TimerFd encountered EBADF");
- }
- }
- }
-}
diff --git a/vendor/nix/src/sys/uio.rs b/vendor/nix/src/sys/uio.rs
deleted file mode 100644
index b31c3068a..000000000
--- a/vendor/nix/src/sys/uio.rs
+++ /dev/null
@@ -1,291 +0,0 @@
-//! Vectored I/O
-
-use crate::errno::Errno;
-use crate::Result;
-use libc::{self, c_int, c_void, off_t, size_t};
-use std::io::{IoSlice, IoSliceMut};
-use std::marker::PhantomData;
-use std::os::unix::io::RawFd;
-
-/// Low-level vectored write to a raw file descriptor
-///
-/// See also [writev(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html)
-pub fn writev(fd: RawFd, iov: &[IoSlice<'_>]) -> Result<usize> {
- // SAFETY: to quote the documentation for `IoSlice`:
- //
- // [IoSlice] is semantically a wrapper around a &[u8], but is
- // guaranteed to be ABI compatible with the iovec type on Unix
- // platforms.
- //
- // Because it is ABI compatible, a pointer cast here is valid
- let res = unsafe {
- libc::writev(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Low-level vectored read from a raw file descriptor
-///
-/// See also [readv(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html)
-pub fn readv(fd: RawFd, iov: &mut [IoSliceMut<'_>]) -> Result<usize> {
- // SAFETY: same as in writev(), IoSliceMut is ABI-compatible with iovec
- let res = unsafe {
- libc::readv(fd, iov.as_ptr() as *const libc::iovec, iov.len() as c_int)
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Write to `fd` at `offset` from buffers in `iov`.
-///
-/// Buffers in `iov` will be written in order until all buffers have been written
-/// or an error occurs. The file offset is not changed.
-///
-/// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html)
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn pwritev(fd: RawFd, iov: &[IoSlice<'_>], offset: off_t) -> Result<usize> {
- #[cfg(target_env = "uclibc")]
- let offset = offset as libc::off64_t; // uclibc doesn't use off_t
-
- // SAFETY: same as in writev()
- let res = unsafe {
- libc::pwritev(
- fd,
- iov.as_ptr() as *const libc::iovec,
- iov.len() as c_int,
- offset,
- )
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Read from `fd` at `offset` filling buffers in `iov`.
-///
-/// Buffers in `iov` will be filled in order until all buffers have been filled,
-/// no more bytes are available, or an error occurs. The file offset is not
-/// changed.
-///
-/// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html)
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn preadv(
- fd: RawFd,
- iov: &mut [IoSliceMut<'_>],
- offset: off_t,
-) -> Result<usize> {
- #[cfg(target_env = "uclibc")]
- let offset = offset as libc::off64_t; // uclibc doesn't use off_t
-
- // SAFETY: same as in readv()
- let res = unsafe {
- libc::preadv(
- fd,
- iov.as_ptr() as *const libc::iovec,
- iov.len() as c_int,
- offset,
- )
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Low-level write to a file, with specified offset.
-///
-/// See also [pwrite(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html)
-// TODO: move to unistd
-pub fn pwrite(fd: RawFd, buf: &[u8], offset: off_t) -> Result<usize> {
- let res = unsafe {
- libc::pwrite(
- fd,
- buf.as_ptr() as *const c_void,
- buf.len() as size_t,
- offset,
- )
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Low-level read from a file, with specified offset.
-///
-/// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html)
-// TODO: move to unistd
-pub fn pread(fd: RawFd, buf: &mut [u8], offset: off_t) -> Result<usize> {
- let res = unsafe {
- libc::pread(
- fd,
- buf.as_mut_ptr() as *mut c_void,
- buf.len() as size_t,
- offset,
- )
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// A slice of memory in a remote process, starting at address `base`
-/// and consisting of `len` bytes.
-///
-/// This is the same underlying C structure as `IoSlice`,
-/// except that it refers to memory in some other process, and is
-/// therefore not represented in Rust by an actual slice as `IoSlice` is. It
-/// is used with [`process_vm_readv`](fn.process_vm_readv.html)
-/// and [`process_vm_writev`](fn.process_vm_writev.html).
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-#[repr(C)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct RemoteIoVec {
- /// The starting address of this slice (`iov_base`).
- pub base: usize,
- /// The number of bytes in this slice (`iov_len`).
- pub len: usize,
-}
-
-/// A vector of buffers.
-///
-/// Vectored I/O methods like [`writev`] and [`readv`] use this structure for
-/// both reading and writing. Each `IoVec` specifies the base address and
-/// length of an area in memory.
-#[deprecated(
- since = "0.24.0",
- note = "`IoVec` is no longer used in the public interface, use `IoSlice` or `IoSliceMut` instead"
-)]
-#[repr(transparent)]
-#[allow(renamed_and_removed_lints)]
-#[allow(clippy::unknown_clippy_lints)]
-// Clippy false positive: https://github.com/rust-lang/rust-clippy/issues/8867
-#[allow(clippy::derive_partial_eq_without_eq)]
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct IoVec<T>(pub(crate) libc::iovec, PhantomData<T>);
-
-#[allow(deprecated)]
-impl<T> IoVec<T> {
- /// View the `IoVec` as a Rust slice.
- #[deprecated(
- since = "0.24.0",
- note = "Use the `Deref` impl of `IoSlice` or `IoSliceMut` instead"
- )]
- #[inline]
- pub fn as_slice(&self) -> &[u8] {
- use std::slice;
-
- unsafe {
- slice::from_raw_parts(self.0.iov_base as *const u8, self.0.iov_len)
- }
- }
-}
-
-#[allow(deprecated)]
-impl<'a> IoVec<&'a [u8]> {
- /// Create an `IoVec` from a Rust slice.
- #[deprecated(since = "0.24.0", note = "Use `IoSlice::new` instead")]
- pub fn from_slice(buf: &'a [u8]) -> IoVec<&'a [u8]> {
- IoVec(
- libc::iovec {
- iov_base: buf.as_ptr() as *mut c_void,
- iov_len: buf.len() as size_t,
- },
- PhantomData,
- )
- }
-}
-
-#[allow(deprecated)]
-impl<'a> IoVec<&'a mut [u8]> {
- /// Create an `IoVec` from a mutable Rust slice.
- #[deprecated(since = "0.24.0", note = "Use `IoSliceMut::new` instead")]
- pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> {
- IoVec(
- libc::iovec {
- iov_base: buf.as_ptr() as *mut c_void,
- iov_len: buf.len() as size_t,
- },
- PhantomData,
- )
- }
-}
-
-// The only reason IoVec isn't automatically Send+Sync is because libc::iovec
-// contains raw pointers.
-#[allow(deprecated)]
-unsafe impl<T> Send for IoVec<T> where T: Send {}
-#[allow(deprecated)]
-unsafe impl<T> Sync for IoVec<T> where T: Sync {}
-
-feature! {
-#![feature = "process"]
-
-/// Write data directly to another process's virtual memory
-/// (see [`process_vm_writev`(2)]).
-///
-/// `local_iov` is a list of [`IoSlice`]s containing the data to be written,
-/// and `remote_iov` is a list of [`RemoteIoVec`]s identifying where the
-/// data should be written in the target process. On success, returns the
-/// number of bytes written, which will always be a whole
-/// number of `remote_iov` chunks.
-///
-/// This requires the same permissions as debugging the process using
-/// [ptrace]: you must either be a privileged process (with
-/// `CAP_SYS_PTRACE`), or you must be running as the same user as the
-/// target process and the OS must have unprivileged debugging enabled.
-///
-/// This function is only available on Linux and Android(SDK23+).
-///
-/// [`process_vm_writev`(2)]: https://man7.org/linux/man-pages/man2/process_vm_writev.2.html
-/// [ptrace]: ../ptrace/index.html
-/// [`IoSlice`]: https://doc.rust-lang.org/std/io/struct.IoSlice.html
-/// [`RemoteIoVec`]: struct.RemoteIoVec.html
-#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
-pub fn process_vm_writev(
- pid: crate::unistd::Pid,
- local_iov: &[IoSlice<'_>],
- remote_iov: &[RemoteIoVec]) -> Result<usize>
-{
- let res = unsafe {
- libc::process_vm_writev(pid.into(),
- local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
- remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Read data directly from another process's virtual memory
-/// (see [`process_vm_readv`(2)]).
-///
-/// `local_iov` is a list of [`IoSliceMut`]s containing the buffer to copy
-/// data into, and `remote_iov` is a list of [`RemoteIoVec`]s identifying
-/// where the source data is in the target process. On success,
-/// returns the number of bytes written, which will always be a whole
-/// number of `remote_iov` chunks.
-///
-/// This requires the same permissions as debugging the process using
-/// [`ptrace`]: you must either be a privileged process (with
-/// `CAP_SYS_PTRACE`), or you must be running as the same user as the
-/// target process and the OS must have unprivileged debugging enabled.
-///
-/// This function is only available on Linux and Android(SDK23+).
-///
-/// [`process_vm_readv`(2)]: https://man7.org/linux/man-pages/man2/process_vm_readv.2.html
-/// [`ptrace`]: ../ptrace/index.html
-/// [`IoSliceMut`]: https://doc.rust-lang.org/std/io/struct.IoSliceMut.html
-/// [`RemoteIoVec`]: struct.RemoteIoVec.html
-#[cfg(all(any(target_os = "linux", target_os = "android"), not(target_env = "uclibc")))]
-pub fn process_vm_readv(
- pid: crate::unistd::Pid,
- local_iov: &mut [IoSliceMut<'_>],
- remote_iov: &[RemoteIoVec]) -> Result<usize>
-{
- let res = unsafe {
- libc::process_vm_readv(pid.into(),
- local_iov.as_ptr() as *const libc::iovec, local_iov.len() as libc::c_ulong,
- remote_iov.as_ptr() as *const libc::iovec, remote_iov.len() as libc::c_ulong, 0)
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-}
diff --git a/vendor/nix/src/sys/utsname.rs b/vendor/nix/src/sys/utsname.rs
deleted file mode 100644
index b48ed9f45..000000000
--- a/vendor/nix/src/sys/utsname.rs
+++ /dev/null
@@ -1,85 +0,0 @@
-//! Get system identification
-use crate::{Errno, Result};
-use libc::c_char;
-use std::ffi::OsStr;
-use std::mem;
-use std::os::unix::ffi::OsStrExt;
-
-/// Describes the running system. Return type of [`uname`].
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(transparent)]
-pub struct UtsName(libc::utsname);
-
-impl UtsName {
- /// Name of the operating system implementation.
- pub fn sysname(&self) -> &OsStr {
- cast_and_trim(&self.0.sysname)
- }
-
- /// Network name of this machine.
- pub fn nodename(&self) -> &OsStr {
- cast_and_trim(&self.0.nodename)
- }
-
- /// Release level of the operating system.
- pub fn release(&self) -> &OsStr {
- cast_and_trim(&self.0.release)
- }
-
- /// Version level of the operating system.
- pub fn version(&self) -> &OsStr {
- cast_and_trim(&self.0.version)
- }
-
- /// Machine hardware platform.
- pub fn machine(&self) -> &OsStr {
- cast_and_trim(&self.0.machine)
- }
-
- /// NIS or YP domain name of this machine.
- #[cfg(any(target_os = "android", target_os = "linux"))]
- pub fn domainname(&self) -> &OsStr {
- cast_and_trim(&self.0.domainname)
- }
-}
-
-/// Get system identification
-pub fn uname() -> Result<UtsName> {
- unsafe {
- let mut ret = mem::MaybeUninit::zeroed();
- Errno::result(libc::uname(ret.as_mut_ptr()))?;
- Ok(UtsName(ret.assume_init()))
- }
-}
-
-fn cast_and_trim(slice: &[c_char]) -> &OsStr {
- let length = slice
- .iter()
- .position(|&byte| byte == 0)
- .unwrap_or(slice.len());
- let bytes =
- unsafe { std::slice::from_raw_parts(slice.as_ptr().cast(), length) };
-
- OsStr::from_bytes(bytes)
-}
-
-#[cfg(test)]
-mod test {
- #[cfg(target_os = "linux")]
- #[test]
- pub fn test_uname_linux() {
- assert_eq!(super::uname().unwrap().sysname(), "Linux");
- }
-
- #[cfg(any(target_os = "macos", target_os = "ios"))]
- #[test]
- pub fn test_uname_darwin() {
- assert_eq!(super::uname().unwrap().sysname(), "Darwin");
- }
-
- #[cfg(target_os = "freebsd")]
- #[test]
- pub fn test_uname_freebsd() {
- assert_eq!(super::uname().unwrap().sysname(), "FreeBSD");
- }
-}
diff --git a/vendor/nix/src/sys/wait.rs b/vendor/nix/src/sys/wait.rs
deleted file mode 100644
index b6524e866..000000000
--- a/vendor/nix/src/sys/wait.rs
+++ /dev/null
@@ -1,388 +0,0 @@
-//! Wait for a process to change status
-use crate::errno::Errno;
-use crate::sys::signal::Signal;
-use crate::unistd::Pid;
-use crate::Result;
-use cfg_if::cfg_if;
-use libc::{self, c_int};
-use std::convert::TryFrom;
-#[cfg(any(
- target_os = "android",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-use std::os::unix::io::RawFd;
-
-libc_bitflags!(
- /// Controls the behavior of [`waitpid`].
- pub struct WaitPidFlag: c_int {
- /// Do not block when there are no processes wishing to report status.
- WNOHANG;
- /// Report the status of selected processes which are stopped due to a
- /// [`SIGTTIN`](crate::sys::signal::Signal::SIGTTIN),
- /// [`SIGTTOU`](crate::sys::signal::Signal::SIGTTOU),
- /// [`SIGTSTP`](crate::sys::signal::Signal::SIGTSTP), or
- /// [`SIGSTOP`](crate::sys::signal::Signal::SIGSTOP) signal.
- WUNTRACED;
- /// Report the status of selected processes which have terminated.
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "redox",
- target_os = "macos",
- target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- WEXITED;
- /// Report the status of selected processes that have continued from a
- /// job control stop by receiving a
- /// [`SIGCONT`](crate::sys::signal::Signal::SIGCONT) signal.
- WCONTINUED;
- /// An alias for WUNTRACED.
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "redox",
- target_os = "macos",
- target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- WSTOPPED;
- /// Don't reap, just poll status.
- #[cfg(any(target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- target_os = "ios",
- target_os = "linux",
- target_os = "redox",
- target_os = "macos",
- target_os = "netbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- WNOWAIT;
- /// Don't wait on children of other threads in this group
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- __WNOTHREAD;
- /// Wait on all children, regardless of type
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- __WALL;
- /// Wait for "clone" children only.
- #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- __WCLONE;
- }
-);
-
-/// Possible return values from `wait()` or `waitpid()`.
-///
-/// Each status (other than `StillAlive`) describes a state transition
-/// in a child process `Pid`, such as the process exiting or stopping,
-/// plus additional data about the transition if any.
-///
-/// Note that there are two Linux-specific enum variants, `PtraceEvent`
-/// and `PtraceSyscall`. Portable code should avoid exhaustively
-/// matching on `WaitStatus`.
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub enum WaitStatus {
- /// The process exited normally (as with `exit()` or returning from
- /// `main`) with the given exit code. This case matches the C macro
- /// `WIFEXITED(status)`; the second field is `WEXITSTATUS(status)`.
- Exited(Pid, i32),
- /// The process was killed by the given signal. The third field
- /// indicates whether the signal generated a core dump. This case
- /// matches the C macro `WIFSIGNALED(status)`; the last two fields
- /// correspond to `WTERMSIG(status)` and `WCOREDUMP(status)`.
- Signaled(Pid, Signal, bool),
- /// The process is alive, but was stopped by the given signal. This
- /// is only reported if `WaitPidFlag::WUNTRACED` was passed. This
- /// case matches the C macro `WIFSTOPPED(status)`; the second field
- /// is `WSTOPSIG(status)`.
- Stopped(Pid, Signal),
- /// The traced process was stopped by a `PTRACE_EVENT_*` event. See
- /// [`nix::sys::ptrace`] and [`ptrace`(2)] for more information. All
- /// currently-defined events use `SIGTRAP` as the signal; the third
- /// field is the `PTRACE_EVENT_*` value of the event.
- ///
- /// [`nix::sys::ptrace`]: ../ptrace/index.html
- /// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html
- #[cfg(any(target_os = "linux", target_os = "android"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PtraceEvent(Pid, Signal, c_int),
- /// The traced process was stopped by execution of a system call,
- /// and `PTRACE_O_TRACESYSGOOD` is in effect. See [`ptrace`(2)] for
- /// more information.
- ///
- /// [`ptrace`(2)]: https://man7.org/linux/man-pages/man2/ptrace.2.html
- #[cfg(any(target_os = "linux", target_os = "android"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PtraceSyscall(Pid),
- /// The process was previously stopped but has resumed execution
- /// after receiving a `SIGCONT` signal. This is only reported if
- /// `WaitPidFlag::WCONTINUED` was passed. This case matches the C
- /// macro `WIFCONTINUED(status)`.
- Continued(Pid),
- /// There are currently no state changes to report in any awaited
- /// child process. This is only returned if `WaitPidFlag::WNOHANG`
- /// was used (otherwise `wait()` or `waitpid()` would block until
- /// there was something to report).
- StillAlive,
-}
-
-impl WaitStatus {
- /// Extracts the PID from the WaitStatus unless it equals StillAlive.
- pub fn pid(&self) -> Option<Pid> {
- use self::WaitStatus::*;
- match *self {
- Exited(p, _) | Signaled(p, _, _) | Stopped(p, _) | Continued(p) => {
- Some(p)
- }
- StillAlive => None,
- #[cfg(any(target_os = "android", target_os = "linux"))]
- PtraceEvent(p, _, _) | PtraceSyscall(p) => Some(p),
- }
- }
-}
-
-fn exited(status: i32) -> bool {
- libc::WIFEXITED(status)
-}
-
-fn exit_status(status: i32) -> i32 {
- libc::WEXITSTATUS(status)
-}
-
-fn signaled(status: i32) -> bool {
- libc::WIFSIGNALED(status)
-}
-
-fn term_signal(status: i32) -> Result<Signal> {
- Signal::try_from(libc::WTERMSIG(status))
-}
-
-fn dumped_core(status: i32) -> bool {
- libc::WCOREDUMP(status)
-}
-
-fn stopped(status: i32) -> bool {
- libc::WIFSTOPPED(status)
-}
-
-fn stop_signal(status: i32) -> Result<Signal> {
- Signal::try_from(libc::WSTOPSIG(status))
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn syscall_stop(status: i32) -> bool {
- // From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect
- // of delivering SIGTRAP | 0x80 as the signal number for syscall
- // stops. This allows easily distinguishing syscall stops from
- // genuine SIGTRAP signals.
- libc::WSTOPSIG(status) == libc::SIGTRAP | 0x80
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn stop_additional(status: i32) -> c_int {
- (status >> 16) as c_int
-}
-
-fn continued(status: i32) -> bool {
- libc::WIFCONTINUED(status)
-}
-
-impl WaitStatus {
- /// Convert a raw `wstatus` as returned by `waitpid`/`wait` into a `WaitStatus`
- ///
- /// # Errors
- ///
- /// Returns an `Error` corresponding to `EINVAL` for invalid status values.
- ///
- /// # Examples
- ///
- /// Convert a `wstatus` obtained from `libc::waitpid` into a `WaitStatus`:
- ///
- /// ```
- /// use nix::sys::wait::WaitStatus;
- /// use nix::sys::signal::Signal;
- /// let pid = nix::unistd::Pid::from_raw(1);
- /// let status = WaitStatus::from_raw(pid, 0x0002);
- /// assert_eq!(status, Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false)));
- /// ```
- pub fn from_raw(pid: Pid, status: i32) -> Result<WaitStatus> {
- Ok(if exited(status) {
- WaitStatus::Exited(pid, exit_status(status))
- } else if signaled(status) {
- WaitStatus::Signaled(pid, term_signal(status)?, dumped_core(status))
- } else if stopped(status) {
- cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- fn decode_stopped(pid: Pid, status: i32) -> Result<WaitStatus> {
- let status_additional = stop_additional(status);
- Ok(if syscall_stop(status) {
- WaitStatus::PtraceSyscall(pid)
- } else if status_additional == 0 {
- WaitStatus::Stopped(pid, stop_signal(status)?)
- } else {
- WaitStatus::PtraceEvent(pid, stop_signal(status)?,
- stop_additional(status))
- })
- }
- } else {
- fn decode_stopped(pid: Pid, status: i32) -> Result<WaitStatus> {
- Ok(WaitStatus::Stopped(pid, stop_signal(status)?))
- }
- }
- }
- return decode_stopped(pid, status);
- } else {
- assert!(continued(status));
- WaitStatus::Continued(pid)
- })
- }
-
- /// Convert a `siginfo_t` as returned by `waitid` to a `WaitStatus`
- ///
- /// # Errors
- ///
- /// Returns an `Error` corresponding to `EINVAL` for invalid values.
- ///
- /// # Safety
- ///
- /// siginfo_t is actually a union, not all fields may be initialized.
- /// The functions si_pid() and si_status() must be valid to call on
- /// the passed siginfo_t.
- #[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
- ))]
- unsafe fn from_siginfo(siginfo: &libc::siginfo_t) -> Result<WaitStatus> {
- let si_pid = siginfo.si_pid();
- if si_pid == 0 {
- return Ok(WaitStatus::StillAlive);
- }
-
- assert_eq!(siginfo.si_signo, libc::SIGCHLD);
-
- let pid = Pid::from_raw(si_pid);
- let si_status = siginfo.si_status();
-
- let status = match siginfo.si_code {
- libc::CLD_EXITED => WaitStatus::Exited(pid, si_status),
- libc::CLD_KILLED | libc::CLD_DUMPED => WaitStatus::Signaled(
- pid,
- Signal::try_from(si_status)?,
- siginfo.si_code == libc::CLD_DUMPED,
- ),
- libc::CLD_STOPPED => {
- WaitStatus::Stopped(pid, Signal::try_from(si_status)?)
- }
- libc::CLD_CONTINUED => WaitStatus::Continued(pid),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- libc::CLD_TRAPPED => {
- if si_status == libc::SIGTRAP | 0x80 {
- WaitStatus::PtraceSyscall(pid)
- } else {
- WaitStatus::PtraceEvent(
- pid,
- Signal::try_from(si_status & 0xff)?,
- (si_status >> 8) as c_int,
- )
- }
- }
- _ => return Err(Errno::EINVAL),
- };
-
- Ok(status)
- }
-}
-
-/// Wait for a process to change status
-///
-/// See also [waitpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html)
-pub fn waitpid<P: Into<Option<Pid>>>(
- pid: P,
- options: Option<WaitPidFlag>,
-) -> Result<WaitStatus> {
- use self::WaitStatus::*;
-
- let mut status: i32 = 0;
-
- let option_bits = match options {
- Some(bits) => bits.bits(),
- None => 0,
- };
-
- let res = unsafe {
- libc::waitpid(
- pid.into().unwrap_or_else(|| Pid::from_raw(-1)).into(),
- &mut status as *mut c_int,
- option_bits,
- )
- };
-
- match Errno::result(res)? {
- 0 => Ok(StillAlive),
- res => WaitStatus::from_raw(Pid::from_raw(res), status),
- }
-}
-
-/// Wait for any child process to change status or a signal is received.
-///
-/// See also [wait(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html)
-pub fn wait() -> Result<WaitStatus> {
- waitpid(None, None)
-}
-
-/// The ID argument for `waitid`
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub enum Id {
- /// Wait for any child
- All,
- /// Wait for the child whose process ID matches the given PID
- Pid(Pid),
- /// Wait for the child whose process group ID matches the given PID
- ///
- /// If the PID is zero, the caller's process group is used since Linux 5.4.
- PGid(Pid),
- /// Wait for the child referred to by the given PID file descriptor
- #[cfg(any(target_os = "android", target_os = "linux"))]
- PIDFd(RawFd),
-}
-
-/// Wait for a process to change status
-///
-/// See also [waitid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/waitid.html)
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-pub fn waitid(id: Id, flags: WaitPidFlag) -> Result<WaitStatus> {
- let (idtype, idval) = match id {
- Id::All => (libc::P_ALL, 0),
- Id::Pid(pid) => (libc::P_PID, pid.as_raw() as libc::id_t),
- Id::PGid(pid) => (libc::P_PGID, pid.as_raw() as libc::id_t),
- #[cfg(any(target_os = "android", target_os = "linux"))]
- Id::PIDFd(fd) => (libc::P_PIDFD, fd as libc::id_t),
- };
-
- let siginfo = unsafe {
- // Memory is zeroed rather than uninitialized, as not all platforms
- // initialize the memory in the StillAlive case
- let mut siginfo: libc::siginfo_t = std::mem::zeroed();
- Errno::result(libc::waitid(idtype, idval, &mut siginfo, flags.bits()))?;
- siginfo
- };
-
- unsafe { WaitStatus::from_siginfo(&siginfo) }
-}
diff --git a/vendor/nix/src/time.rs b/vendor/nix/src/time.rs
deleted file mode 100644
index 2e03c46cf..000000000
--- a/vendor/nix/src/time.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-use crate::sys::time::TimeSpec;
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
-))]
-#[cfg(feature = "process")]
-use crate::unistd::Pid;
-use crate::{Errno, Result};
-use libc::{self, clockid_t};
-use std::mem::MaybeUninit;
-
-/// Clock identifier
-///
-/// Newtype pattern around `clockid_t` (which is just alias). It prevents bugs caused by
-/// accidentally passing wrong value.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-pub struct ClockId(clockid_t);
-
-impl ClockId {
- /// Creates `ClockId` from raw `clockid_t`
- pub const fn from_raw(clk_id: clockid_t) -> Self {
- ClockId(clk_id)
- }
-
- feature! {
- #![feature = "process"]
- /// Returns `ClockId` of a `pid` CPU-time clock
- #[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn pid_cpu_clock_id(pid: Pid) -> Result<Self> {
- clock_getcpuclockid(pid)
- }
- }
-
- /// Returns resolution of the clock id
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn res(self) -> Result<TimeSpec> {
- clock_getres(self)
- }
-
- /// Returns the current time on the clock id
- pub fn now(self) -> Result<TimeSpec> {
- clock_gettime(self)
- }
-
- /// Sets time to `timespec` on the clock id
- #[cfg(not(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "redox",
- target_os = "hermit",
- )))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub fn set_time(self, timespec: TimeSpec) -> Result<()> {
- clock_settime(self, timespec)
- }
-
- /// Gets the raw `clockid_t` wrapped by `self`
- pub const fn as_raw(self) -> clockid_t {
- self.0
- }
-
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_BOOTTIME: ClockId = ClockId(libc::CLOCK_BOOTTIME);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_BOOTTIME_ALARM: ClockId =
- ClockId(libc::CLOCK_BOOTTIME_ALARM);
- pub const CLOCK_MONOTONIC: ClockId = ClockId(libc::CLOCK_MONOTONIC);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_MONOTONIC_COARSE: ClockId =
- ClockId(libc::CLOCK_MONOTONIC_COARSE);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_MONOTONIC_FAST: ClockId =
- ClockId(libc::CLOCK_MONOTONIC_FAST);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_MONOTONIC_PRECISE: ClockId =
- ClockId(libc::CLOCK_MONOTONIC_PRECISE);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_MONOTONIC_RAW: ClockId = ClockId(libc::CLOCK_MONOTONIC_RAW);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "redox",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_PROCESS_CPUTIME_ID: ClockId =
- ClockId(libc::CLOCK_PROCESS_CPUTIME_ID);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_PROF: ClockId = ClockId(libc::CLOCK_PROF);
- pub const CLOCK_REALTIME: ClockId = ClockId(libc::CLOCK_REALTIME);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_REALTIME_ALARM: ClockId =
- ClockId(libc::CLOCK_REALTIME_ALARM);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_REALTIME_COARSE: ClockId =
- ClockId(libc::CLOCK_REALTIME_COARSE);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_REALTIME_FAST: ClockId = ClockId(libc::CLOCK_REALTIME_FAST);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_REALTIME_PRECISE: ClockId =
- ClockId(libc::CLOCK_REALTIME_PRECISE);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_SECOND: ClockId = ClockId(libc::CLOCK_SECOND);
- #[cfg(any(
- target_os = "emscripten",
- target_os = "fuchsia",
- all(target_os = "linux", target_env = "musl")
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_SGI_CYCLE: ClockId = ClockId(libc::CLOCK_SGI_CYCLE);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_TAI: ClockId = ClockId(libc::CLOCK_TAI);
- #[cfg(any(
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "ios",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux"
- ))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_THREAD_CPUTIME_ID: ClockId =
- ClockId(libc::CLOCK_THREAD_CPUTIME_ID);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_UPTIME: ClockId = ClockId(libc::CLOCK_UPTIME);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_UPTIME_FAST: ClockId = ClockId(libc::CLOCK_UPTIME_FAST);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_UPTIME_PRECISE: ClockId =
- ClockId(libc::CLOCK_UPTIME_PRECISE);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub const CLOCK_VIRTUAL: ClockId = ClockId(libc::CLOCK_VIRTUAL);
-}
-
-impl From<ClockId> for clockid_t {
- fn from(clock_id: ClockId) -> Self {
- clock_id.as_raw()
- }
-}
-
-impl From<clockid_t> for ClockId {
- fn from(clk_id: clockid_t) -> Self {
- ClockId::from_raw(clk_id)
- }
-}
-
-impl std::fmt::Display for ClockId {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- std::fmt::Display::fmt(&self.0, f)
- }
-}
-
-/// Get the resolution of the specified clock, (see
-/// [clock_getres(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_getres.html)).
-#[cfg(not(target_os = "redox"))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn clock_getres(clock_id: ClockId) -> Result<TimeSpec> {
- let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
- let ret =
- unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) };
- Errno::result(ret)?;
- let res = unsafe { c_time.assume_init() };
- Ok(TimeSpec::from(res))
-}
-
-/// Get the time of the specified clock, (see
-/// [clock_gettime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_gettime.html)).
-pub fn clock_gettime(clock_id: ClockId) -> Result<TimeSpec> {
- let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
- let ret =
- unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) };
- Errno::result(ret)?;
- let res = unsafe { c_time.assume_init() };
- Ok(TimeSpec::from(res))
-}
-
-/// Set the time of the specified clock, (see
-/// [clock_settime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_settime.html)).
-#[cfg(not(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "redox",
- target_os = "hermit",
-)))]
-#[cfg_attr(docsrs, doc(cfg(all())))]
-pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> {
- let ret =
- unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) };
- Errno::result(ret).map(drop)
-}
-
-/// Get the clock id of the specified process id, (see
-/// [clock_getcpuclockid(3)](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_getcpuclockid.html)).
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
-))]
-#[cfg(feature = "process")]
-#[cfg_attr(docsrs, doc(cfg(feature = "process")))]
-pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> {
- let mut clk_id: MaybeUninit<libc::clockid_t> = MaybeUninit::uninit();
- let ret =
- unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) };
- if ret == 0 {
- let res = unsafe { clk_id.assume_init() };
- Ok(ClockId::from(res))
- } else {
- Err(Errno::from_i32(ret))
- }
-}
diff --git a/vendor/nix/src/ucontext.rs b/vendor/nix/src/ucontext.rs
deleted file mode 100644
index b2a39f769..000000000
--- a/vendor/nix/src/ucontext.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-#[cfg(not(target_env = "musl"))]
-use crate::errno::Errno;
-use crate::sys::signal::SigSet;
-#[cfg(not(target_env = "musl"))]
-use crate::Result;
-#[cfg(not(target_env = "musl"))]
-use std::mem;
-
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-pub struct UContext {
- context: libc::ucontext_t,
-}
-
-impl UContext {
- #[cfg(not(target_env = "musl"))]
- pub fn get() -> Result<UContext> {
- let mut context = mem::MaybeUninit::<libc::ucontext_t>::uninit();
- let res = unsafe { libc::getcontext(context.as_mut_ptr()) };
- Errno::result(res).map(|_| unsafe {
- UContext {
- context: context.assume_init(),
- }
- })
- }
-
- #[cfg(not(target_env = "musl"))]
- pub fn set(&self) -> Result<()> {
- let res = unsafe {
- libc::setcontext(&self.context as *const libc::ucontext_t)
- };
- Errno::result(res).map(drop)
- }
-
- pub fn sigmask_mut(&mut self) -> &mut SigSet {
- unsafe {
- &mut *(&mut self.context.uc_sigmask as *mut libc::sigset_t
- as *mut SigSet)
- }
- }
-
- pub fn sigmask(&self) -> &SigSet {
- unsafe {
- &*(&self.context.uc_sigmask as *const libc::sigset_t
- as *const SigSet)
- }
- }
-}
diff --git a/vendor/nix/src/unistd.rs b/vendor/nix/src/unistd.rs
deleted file mode 100644
index ca07b34a2..000000000
--- a/vendor/nix/src/unistd.rs
+++ /dev/null
@@ -1,3383 +0,0 @@
-//! Safe wrappers around functions found in libc "unistd.h" header
-
-use crate::errno::{self, Errno};
-#[cfg(not(target_os = "redox"))]
-#[cfg(feature = "fs")]
-use crate::fcntl::{at_rawfd, AtFlags};
-#[cfg(feature = "fs")]
-use crate::fcntl::{fcntl, FcntlArg::F_SETFD, FdFlag, OFlag};
-#[cfg(all(
- feature = "fs",
- any(
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "macos",
- target_os = "ios"
- )
-))]
-use crate::sys::stat::FileFlag;
-#[cfg(feature = "fs")]
-use crate::sys::stat::Mode;
-use crate::{Error, NixPath, Result};
-#[cfg(not(target_os = "redox"))]
-use cfg_if::cfg_if;
-use libc::{
- self, c_char, c_int, c_long, c_uint, c_void, gid_t, mode_t, off_t, pid_t,
- size_t, uid_t, PATH_MAX,
-};
-use std::convert::Infallible;
-use std::ffi::{CStr, OsString};
-#[cfg(not(target_os = "redox"))]
-use std::ffi::{CString, OsStr};
-#[cfg(not(target_os = "redox"))]
-use std::os::unix::ffi::OsStrExt;
-use std::os::unix::ffi::OsStringExt;
-use std::os::unix::io::RawFd;
-use std::path::PathBuf;
-use std::{fmt, mem, ptr};
-
-feature! {
- #![feature = "fs"]
- #[cfg(any(target_os = "android", target_os = "linux"))]
- pub use self::pivot_root::*;
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "openbsd"
-))]
-pub use self::setres::*;
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "openbsd"
-))]
-pub use self::getres::*;
-
-feature! {
-#![feature = "user"]
-
-/// User identifier
-///
-/// Newtype pattern around `uid_t` (which is just alias). It prevents bugs caused by accidentally
-/// passing wrong value.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub struct Uid(uid_t);
-
-impl Uid {
- /// Creates `Uid` from raw `uid_t`.
- pub const fn from_raw(uid: uid_t) -> Self {
- Uid(uid)
- }
-
- /// Returns Uid of calling process. This is practically a more Rusty alias for `getuid`.
- #[doc(alias("getuid"))]
- pub fn current() -> Self {
- getuid()
- }
-
- /// Returns effective Uid of calling process. This is practically a more Rusty alias for `geteuid`.
- #[doc(alias("geteuid"))]
- pub fn effective() -> Self {
- geteuid()
- }
-
- /// Returns true if the `Uid` represents privileged user - root. (If it equals zero.)
- pub const fn is_root(self) -> bool {
- self.0 == ROOT.0
- }
-
- /// Get the raw `uid_t` wrapped by `self`.
- pub const fn as_raw(self) -> uid_t {
- self.0
- }
-}
-
-impl From<Uid> for uid_t {
- fn from(uid: Uid) -> Self {
- uid.0
- }
-}
-
-impl From<uid_t> for Uid {
- fn from(uid: uid_t) -> Self {
- Uid(uid)
- }
-}
-
-impl fmt::Display for Uid {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.0, f)
- }
-}
-
-/// Constant for UID = 0
-pub const ROOT: Uid = Uid(0);
-
-/// Group identifier
-///
-/// Newtype pattern around `gid_t` (which is just alias). It prevents bugs caused by accidentally
-/// passing wrong value.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub struct Gid(gid_t);
-
-impl Gid {
- /// Creates `Gid` from raw `gid_t`.
- pub const fn from_raw(gid: gid_t) -> Self {
- Gid(gid)
- }
-
- /// Returns Gid of calling process. This is practically a more Rusty alias for `getgid`.
- #[doc(alias("getgid"))]
- pub fn current() -> Self {
- getgid()
- }
-
- /// Returns effective Gid of calling process. This is practically a more Rusty alias for `getegid`.
- #[doc(alias("getegid"))]
- pub fn effective() -> Self {
- getegid()
- }
-
- /// Get the raw `gid_t` wrapped by `self`.
- pub const fn as_raw(self) -> gid_t {
- self.0
- }
-}
-
-impl From<Gid> for gid_t {
- fn from(gid: Gid) -> Self {
- gid.0
- }
-}
-
-impl From<gid_t> for Gid {
- fn from(gid: gid_t) -> Self {
- Gid(gid)
- }
-}
-
-impl fmt::Display for Gid {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.0, f)
- }
-}
-}
-
-feature! {
-#![feature = "process"]
-/// Process identifier
-///
-/// Newtype pattern around `pid_t` (which is just alias). It prevents bugs caused by accidentally
-/// passing wrong value.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-pub struct Pid(pid_t);
-
-impl Pid {
- /// Creates `Pid` from raw `pid_t`.
- pub const fn from_raw(pid: pid_t) -> Self {
- Pid(pid)
- }
-
- /// Returns PID of calling process
- #[doc(alias("getpid"))]
- pub fn this() -> Self {
- getpid()
- }
-
- /// Returns PID of parent of calling process
- #[doc(alias("getppid"))]
- pub fn parent() -> Self {
- getppid()
- }
-
- /// Get the raw `pid_t` wrapped by `self`.
- pub const fn as_raw(self) -> pid_t {
- self.0
- }
-}
-
-impl From<Pid> for pid_t {
- fn from(pid: Pid) -> Self {
- pid.0
- }
-}
-
-impl fmt::Display for Pid {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.0, f)
- }
-}
-
-
-/// Represents the successful result of calling `fork`
-///
-/// When `fork` is called, the process continues execution in the parent process
-/// and in the new child. This return type can be examined to determine whether
-/// you are now executing in the parent process or in the child.
-#[derive(Clone, Copy, Debug)]
-pub enum ForkResult {
- Parent { child: Pid },
- Child,
-}
-
-impl ForkResult {
-
- /// Return `true` if this is the child process of the `fork()`
- #[inline]
- pub fn is_child(self) -> bool {
- matches!(self, ForkResult::Child)
- }
-
- /// Returns `true` if this is the parent process of the `fork()`
- #[inline]
- pub fn is_parent(self) -> bool {
- !self.is_child()
- }
-}
-
-/// Create a new child process duplicating the parent process ([see
-/// fork(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)).
-///
-/// After successfully calling the fork system call, a second process will
-/// be created which is identical to the original except for the pid and the
-/// return value of this function. As an example:
-///
-/// ```
-/// use nix::{sys::wait::waitpid,unistd::{fork, ForkResult, write}};
-///
-/// match unsafe{fork()} {
-/// Ok(ForkResult::Parent { child, .. }) => {
-/// println!("Continuing execution in parent process, new child has pid: {}", child);
-/// waitpid(child, None).unwrap();
-/// }
-/// Ok(ForkResult::Child) => {
-/// // Unsafe to use `println!` (or `unwrap`) here. See Safety.
-/// write(libc::STDOUT_FILENO, "I'm a new child process\n".as_bytes()).ok();
-/// unsafe { libc::_exit(0) };
-/// }
-/// Err(_) => println!("Fork failed"),
-/// }
-/// ```
-///
-/// This will print something like the following (order nondeterministic). The
-/// thing to note is that you end up with two processes continuing execution
-/// immediately after the fork call but with different match arms.
-///
-/// ```text
-/// Continuing execution in parent process, new child has pid: 1234
-/// I'm a new child process
-/// ```
-///
-/// # Safety
-///
-/// In a multithreaded program, only [async-signal-safe] functions like `pause`
-/// and `_exit` may be called by the child (the parent isn't restricted). Note
-/// that memory allocation may **not** be async-signal-safe and thus must be
-/// prevented.
-///
-/// Those functions are only a small subset of your operating system's API, so
-/// special care must be taken to only invoke code you can control and audit.
-///
-/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html
-#[inline]
-pub unsafe fn fork() -> Result<ForkResult> {
- use self::ForkResult::*;
- let res = libc::fork();
-
- Errno::result(res).map(|res| match res {
- 0 => Child,
- res => Parent { child: Pid(res) },
- })
-}
-
-/// Get the pid of this process (see
-/// [getpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html)).
-///
-/// Since you are running code, there is always a pid to return, so there
-/// is no error case that needs to be handled.
-#[inline]
-pub fn getpid() -> Pid {
- Pid(unsafe { libc::getpid() })
-}
-
-/// Get the pid of this processes' parent (see
-/// [getpid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html)).
-///
-/// There is always a parent pid to return, so there is no error case that needs
-/// to be handled.
-#[inline]
-pub fn getppid() -> Pid {
- Pid(unsafe { libc::getppid() }) // no error handling, according to man page: "These functions are always successful."
-}
-
-/// Set a process group ID (see
-/// [setpgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html)).
-///
-/// Set the process group id (PGID) of a particular process. If a pid of zero
-/// is specified, then the pid of the calling process is used. Process groups
-/// may be used to group together a set of processes in order for the OS to
-/// apply some operations across the group.
-///
-/// `setsid()` may be used to create a new process group.
-#[inline]
-pub fn setpgid(pid: Pid, pgid: Pid) -> Result<()> {
- let res = unsafe { libc::setpgid(pid.into(), pgid.into()) };
- Errno::result(res).map(drop)
-}
-#[inline]
-pub fn getpgid(pid: Option<Pid>) -> Result<Pid> {
- let res = unsafe { libc::getpgid(pid.unwrap_or(Pid(0)).into()) };
- Errno::result(res).map(Pid)
-}
-
-/// Create new session and set process group id (see
-/// [setsid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html)).
-#[inline]
-pub fn setsid() -> Result<Pid> {
- Errno::result(unsafe { libc::setsid() }).map(Pid)
-}
-
-/// Get the process group ID of a session leader
-/// [getsid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html).
-///
-/// Obtain the process group ID of the process that is the session leader of the process specified
-/// by pid. If pid is zero, it specifies the calling process.
-#[inline]
-#[cfg(not(target_os = "redox"))]
-pub fn getsid(pid: Option<Pid>) -> Result<Pid> {
- let res = unsafe { libc::getsid(pid.unwrap_or(Pid(0)).into()) };
- Errno::result(res).map(Pid)
-}
-}
-
-feature! {
-#![all(feature = "process", feature = "term")]
-/// Get the terminal foreground process group (see
-/// [tcgetpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcgetpgrp.html)).
-///
-/// Get the group process id (GPID) of the foreground process group on the
-/// terminal associated to file descriptor (FD).
-#[inline]
-pub fn tcgetpgrp(fd: c_int) -> Result<Pid> {
- let res = unsafe { libc::tcgetpgrp(fd) };
- Errno::result(res).map(Pid)
-}
-/// Set the terminal foreground process group (see
-/// [tcgetpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html)).
-///
-/// Get the group process id (PGID) to the foreground process group on the
-/// terminal associated to file descriptor (FD).
-#[inline]
-pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> {
- let res = unsafe { libc::tcsetpgrp(fd, pgrp.into()) };
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![feature = "process"]
-/// Get the group id of the calling process (see
-///[getpgrp(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html)).
-///
-/// Get the process group id (PGID) of the calling process.
-/// According to the man page it is always successful.
-#[inline]
-pub fn getpgrp() -> Pid {
- Pid(unsafe { libc::getpgrp() })
-}
-
-/// Get the caller's thread ID (see
-/// [gettid(2)](https://man7.org/linux/man-pages/man2/gettid.2.html).
-///
-/// This function is only available on Linux based systems. In a single
-/// threaded process, the main thread will have the same ID as the process. In
-/// a multithreaded process, each thread will have a unique thread id but the
-/// same process ID.
-///
-/// No error handling is required as a thread id should always exist for any
-/// process, even if threads are not being used.
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[inline]
-pub fn gettid() -> Pid {
- Pid(unsafe { libc::syscall(libc::SYS_gettid) as pid_t })
-}
-}
-
-feature! {
-#![feature = "fs"]
-/// Create a copy of the specified file descriptor (see
-/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)).
-///
-/// The new file descriptor will have a new index but refer to the same
-/// resource as the old file descriptor and the old and new file descriptors may
-/// be used interchangeably. The new and old file descriptor share the same
-/// underlying resource, offset, and file status flags. The actual index used
-/// for the file descriptor will be the lowest fd index that is available.
-///
-/// The two file descriptors do not share file descriptor flags (e.g. `OFlag::FD_CLOEXEC`).
-#[inline]
-pub fn dup(oldfd: RawFd) -> Result<RawFd> {
- let res = unsafe { libc::dup(oldfd) };
-
- Errno::result(res)
-}
-
-/// Create a copy of the specified file descriptor using the specified fd (see
-/// [dup(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html)).
-///
-/// This function behaves similar to `dup()` except that it will try to use the
-/// specified fd instead of allocating a new one. See the man pages for more
-/// detail on the exact behavior of this function.
-#[inline]
-pub fn dup2(oldfd: RawFd, newfd: RawFd) -> Result<RawFd> {
- let res = unsafe { libc::dup2(oldfd, newfd) };
-
- Errno::result(res)
-}
-
-/// Create a new copy of the specified file descriptor using the specified fd
-/// and flags (see [dup(2)](https://man7.org/linux/man-pages/man2/dup.2.html)).
-///
-/// This function behaves similar to `dup2()` but allows for flags to be
-/// specified.
-pub fn dup3(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
- dup3_polyfill(oldfd, newfd, flags)
-}
-
-#[inline]
-fn dup3_polyfill(oldfd: RawFd, newfd: RawFd, flags: OFlag) -> Result<RawFd> {
- if oldfd == newfd {
- return Err(Errno::EINVAL);
- }
-
- let fd = dup2(oldfd, newfd)?;
-
- if flags.contains(OFlag::O_CLOEXEC) {
- if let Err(e) = fcntl(fd, F_SETFD(FdFlag::FD_CLOEXEC)) {
- let _ = close(fd);
- return Err(e);
- }
- }
-
- Ok(fd)
-}
-
-/// Change the current working directory of the calling process (see
-/// [chdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html)).
-///
-/// This function may fail in a number of different scenarios. See the man
-/// pages for additional details on possible failure cases.
-#[inline]
-pub fn chdir<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::chdir(cstr.as_ptr()) }
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Change the current working directory of the process to the one
-/// given as an open file descriptor (see
-/// [fchdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html)).
-///
-/// This function may fail in a number of different scenarios. See the man
-/// pages for additional details on possible failure cases.
-#[inline]
-#[cfg(not(target_os = "fuchsia"))]
-pub fn fchdir(dirfd: RawFd) -> Result<()> {
- let res = unsafe { libc::fchdir(dirfd) };
-
- Errno::result(res).map(drop)
-}
-
-/// Creates new directory `path` with access rights `mode`. (see [mkdir(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html))
-///
-/// # Errors
-///
-/// There are several situations where mkdir might fail:
-///
-/// - current user has insufficient rights in the parent directory
-/// - the path already exists
-/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X)
-///
-/// # Example
-///
-/// ```rust
-/// use nix::unistd;
-/// use nix::sys::stat;
-/// use tempfile::tempdir;
-///
-/// let tmp_dir1 = tempdir().unwrap();
-/// let tmp_dir2 = tmp_dir1.path().join("new_dir");
-///
-/// // create new directory and give read, write and execute rights to the owner
-/// match unistd::mkdir(&tmp_dir2, stat::Mode::S_IRWXU) {
-/// Ok(_) => println!("created {:?}", tmp_dir2),
-/// Err(err) => println!("Error creating directory: {}", err),
-/// }
-/// ```
-#[inline]
-pub fn mkdir<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::mkdir(cstr.as_ptr(), mode.bits() as mode_t) }
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
-///
-/// # Errors
-///
-/// There are several situations where mkfifo might fail:
-///
-/// - current user has insufficient rights in the parent directory
-/// - the path already exists
-/// - the path name is too long (longer than `PATH_MAX`, usually 4096 on linux, 1024 on OS X)
-///
-/// For a full list consult
-/// [posix specification](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html)
-///
-/// # Example
-///
-/// ```rust
-/// use nix::unistd;
-/// use nix::sys::stat;
-/// use tempfile::tempdir;
-///
-/// let tmp_dir = tempdir().unwrap();
-/// let fifo_path = tmp_dir.path().join("foo.pipe");
-///
-/// // create new fifo and give read, write and execute rights to the owner
-/// match unistd::mkfifo(&fifo_path, stat::Mode::S_IRWXU) {
-/// Ok(_) => println!("created {:?}", fifo_path),
-/// Err(err) => println!("Error creating fifo: {}", err),
-/// }
-/// ```
-#[inline]
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support fifo yet
-pub fn mkfifo<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::mkfifo(cstr.as_ptr(), mode.bits() as mode_t) }
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Creates new fifo special file (named pipe) with path `path` and access rights `mode`.
-///
-/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
-///
-/// If `dirfd` is `None`, then `path` is relative to the current working directory.
-///
-/// # References
-///
-/// [mkfifoat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifoat.html).
-// mkfifoat is not implemented in OSX or android
-#[inline]
-#[cfg(not(any(
- target_os = "macos", target_os = "ios", target_os = "haiku",
- target_os = "android", target_os = "redox")))]
-pub fn mkfifoat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: Mode) -> Result<()> {
- let res = path.with_nix_path(|cstr| unsafe {
- libc::mkfifoat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits() as mode_t)
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Creates a symbolic link at `path2` which points to `path1`.
-///
-/// If `dirfd` has a value, then `path2` is relative to directory associated
-/// with the file descriptor.
-///
-/// If `dirfd` is `None`, then `path2` is relative to the current working
-/// directory. This is identical to `libc::symlink(path1, path2)`.
-///
-/// See also [symlinkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlinkat.html).
-#[cfg(not(target_os = "redox"))]
-pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
- path1: &P1,
- dirfd: Option<RawFd>,
- path2: &P2) -> Result<()> {
- let res =
- path1.with_nix_path(|path1| {
- path2.with_nix_path(|path2| {
- unsafe {
- libc::symlinkat(
- path1.as_ptr(),
- dirfd.unwrap_or(libc::AT_FDCWD),
- path2.as_ptr()
- )
- }
- })
- })??;
- Errno::result(res).map(drop)
-}
-}
-
-// Double the buffer capacity up to limit. In case it already has
-// reached the limit, return Errno::ERANGE.
-#[cfg(any(feature = "fs", feature = "user"))]
-fn reserve_double_buffer_size<T>(buf: &mut Vec<T>, limit: usize) -> Result<()> {
- use std::cmp::min;
-
- if buf.capacity() >= limit {
- return Err(Errno::ERANGE);
- }
-
- let capacity = min(buf.capacity() * 2, limit);
- buf.reserve(capacity);
-
- Ok(())
-}
-
-feature! {
-#![feature = "fs"]
-
-/// Returns the current directory as a `PathBuf`
-///
-/// Err is returned if the current user doesn't have the permission to read or search a component
-/// of the current path.
-///
-/// # Example
-///
-/// ```rust
-/// use nix::unistd;
-///
-/// // assume that we are allowed to get current directory
-/// let dir = unistd::getcwd().unwrap();
-/// println!("The current directory is {:?}", dir);
-/// ```
-#[inline]
-pub fn getcwd() -> Result<PathBuf> {
- let mut buf = Vec::with_capacity(512);
- loop {
- unsafe {
- let ptr = buf.as_mut_ptr() as *mut c_char;
-
- // The buffer must be large enough to store the absolute pathname plus
- // a terminating null byte, or else null is returned.
- // To safely handle this we start with a reasonable size (512 bytes)
- // and double the buffer size upon every error
- if !libc::getcwd(ptr, buf.capacity()).is_null() {
- let len = CStr::from_ptr(buf.as_ptr() as *const c_char).to_bytes().len();
- buf.set_len(len);
- buf.shrink_to_fit();
- return Ok(PathBuf::from(OsString::from_vec(buf)));
- } else {
- let error = Errno::last();
- // ERANGE means buffer was too small to store directory name
- if error != Errno::ERANGE {
- return Err(error);
- }
- }
-
- // Trigger the internal buffer resizing logic.
- reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?;
- }
- }
-}
-}
-
-feature! {
-#![all(feature = "user", feature = "fs")]
-
-/// Computes the raw UID and GID values to pass to a `*chown` call.
-// The cast is not unnecessary on all platforms.
-#[allow(clippy::unnecessary_cast)]
-fn chown_raw_ids(owner: Option<Uid>, group: Option<Gid>) -> (libc::uid_t, libc::gid_t) {
- // According to the POSIX specification, -1 is used to indicate that owner and group
- // are not to be changed. Since uid_t and gid_t are unsigned types, we have to wrap
- // around to get -1.
- let uid = owner.map(Into::into)
- .unwrap_or_else(|| (0 as uid_t).wrapping_sub(1));
- let gid = group.map(Into::into)
- .unwrap_or_else(|| (0 as gid_t).wrapping_sub(1));
- (uid, gid)
-}
-
-/// Change the ownership of the file at `path` to be owned by the specified
-/// `owner` (user) and `group` (see
-/// [chown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html)).
-///
-/// The owner/group for the provided path name will not be modified if `None` is
-/// provided for that argument. Ownership change will be attempted for the path
-/// only if `Some` owner/group is provided.
-#[inline]
-pub fn chown<P: ?Sized + NixPath>(path: &P, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- let (uid, gid) = chown_raw_ids(owner, group);
- unsafe { libc::chown(cstr.as_ptr(), uid, gid) }
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Change the ownership of the file referred to by the open file descriptor `fd` to be owned by
-/// the specified `owner` (user) and `group` (see
-/// [fchown(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html)).
-///
-/// The owner/group for the provided file will not be modified if `None` is
-/// provided for that argument. Ownership change will be attempted for the path
-/// only if `Some` owner/group is provided.
-#[inline]
-pub fn fchown(fd: RawFd, owner: Option<Uid>, group: Option<Gid>) -> Result<()> {
- let (uid, gid) = chown_raw_ids(owner, group);
- let res = unsafe { libc::fchown(fd, uid, gid) };
- Errno::result(res).map(drop)
-}
-
-/// Flags for `fchownat` function.
-#[derive(Clone, Copy, Debug)]
-pub enum FchownatFlags {
- FollowSymlink,
- NoFollowSymlink,
-}
-
-/// Change the ownership of the file at `path` to be owned by the specified
-/// `owner` (user) and `group`.
-///
-/// The owner/group for the provided path name will not be modified if `None` is
-/// provided for that argument. Ownership change will be attempted for the path
-/// only if `Some` owner/group is provided.
-///
-/// The file to be changed is determined relative to the directory associated
-/// with the file descriptor `dirfd` or the current working directory
-/// if `dirfd` is `None`.
-///
-/// If `flag` is `FchownatFlags::NoFollowSymlink` and `path` names a symbolic link,
-/// then the mode of the symbolic link is changed.
-///
-/// `fchownat(None, path, owner, group, FchownatFlags::NoFollowSymlink)` is identical to
-/// a call `libc::lchown(path, owner, group)`. That's why `lchown` is unimplemented in
-/// the `nix` crate.
-///
-/// # References
-///
-/// [fchownat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchownat.html).
-#[cfg(not(target_os = "redox"))]
-pub fn fchownat<P: ?Sized + NixPath>(
- dirfd: Option<RawFd>,
- path: &P,
- owner: Option<Uid>,
- group: Option<Gid>,
- flag: FchownatFlags,
-) -> Result<()> {
- let atflag =
- match flag {
- FchownatFlags::FollowSymlink => AtFlags::empty(),
- FchownatFlags::NoFollowSymlink => AtFlags::AT_SYMLINK_NOFOLLOW,
- };
- let res = path.with_nix_path(|cstr| unsafe {
- let (uid, gid) = chown_raw_ids(owner, group);
- libc::fchownat(at_rawfd(dirfd), cstr.as_ptr(), uid, gid,
- atflag.bits() as libc::c_int)
- })?;
-
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![feature = "process"]
-fn to_exec_array<S: AsRef<CStr>>(args: &[S]) -> Vec<*const c_char> {
- use std::iter::once;
- args.iter()
- .map(|s| s.as_ref().as_ptr())
- .chain(once(ptr::null()))
- .collect()
-}
-
-/// Replace the current process image with a new one (see
-/// [exec(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
-///
-/// See the `::nix::unistd::execve` system call for additional details. `execv`
-/// performs the same action but does not allow for customization of the
-/// environment for the new process.
-#[inline]
-pub fn execv<S: AsRef<CStr>>(path: &CStr, argv: &[S]) -> Result<Infallible> {
- let args_p = to_exec_array(argv);
-
- unsafe {
- libc::execv(path.as_ptr(), args_p.as_ptr())
- };
-
- Err(Errno::last())
-}
-
-
-/// Replace the current process image with a new one (see
-/// [execve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
-///
-/// The execve system call allows for another process to be "called" which will
-/// replace the current process image. That is, this process becomes the new
-/// command that is run. On success, this function will not return. Instead,
-/// the new program will run until it exits.
-///
-/// `::nix::unistd::execv` and `::nix::unistd::execve` take as arguments a slice
-/// of `::std::ffi::CString`s for `args` and `env` (for `execve`). Each element
-/// in the `args` list is an argument to the new process. Each element in the
-/// `env` list should be a string in the form "key=value".
-#[inline]
-pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(path: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
- let args_p = to_exec_array(args);
- let env_p = to_exec_array(env);
-
- unsafe {
- libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
- };
-
- Err(Errno::last())
-}
-
-/// Replace the current process image with a new one and replicate shell `PATH`
-/// searching behavior (see
-/// [exec(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html)).
-///
-/// See `::nix::unistd::execve` for additional details. `execvp` behaves the
-/// same as execv except that it will examine the `PATH` environment variables
-/// for file names not specified with a leading slash. For example, `execv`
-/// would not work if "bash" was specified for the path argument, but `execvp`
-/// would assuming that a bash executable was on the system `PATH`.
-#[inline]
-pub fn execvp<S: AsRef<CStr>>(filename: &CStr, args: &[S]) -> Result<Infallible> {
- let args_p = to_exec_array(args);
-
- unsafe {
- libc::execvp(filename.as_ptr(), args_p.as_ptr())
- };
-
- Err(Errno::last())
-}
-
-/// Replace the current process image with a new one and replicate shell `PATH`
-/// searching behavior (see
-/// [`execvpe(3)`](https://man7.org/linux/man-pages/man3/exec.3.html)).
-///
-/// This functions like a combination of `execvp(2)` and `execve(2)` to pass an
-/// environment and have a search path. See these two for additional
-/// information.
-#[cfg(any(target_os = "haiku",
- target_os = "linux",
- target_os = "openbsd"))]
-pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(filename: &CStr, args: &[SA], env: &[SE]) -> Result<Infallible> {
- let args_p = to_exec_array(args);
- let env_p = to_exec_array(env);
-
- unsafe {
- libc::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr())
- };
-
- Err(Errno::last())
-}
-
-/// Replace the current process image with a new one (see
-/// [fexecve(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html)).
-///
-/// The `fexecve` function allows for another process to be "called" which will
-/// replace the current process image. That is, this process becomes the new
-/// command that is run. On success, this function will not return. Instead,
-/// the new program will run until it exits.
-///
-/// This function is similar to `execve`, except that the program to be executed
-/// is referenced as a file descriptor instead of a path.
-#[cfg(any(target_os = "android",
- target_os = "linux",
- target_os = "dragonfly",
- target_os = "freebsd"))]
-#[inline]
-pub fn fexecve<SA: AsRef<CStr> ,SE: AsRef<CStr>>(fd: RawFd, args: &[SA], env: &[SE]) -> Result<Infallible> {
- let args_p = to_exec_array(args);
- let env_p = to_exec_array(env);
-
- unsafe {
- libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr())
- };
-
- Err(Errno::last())
-}
-
-/// Execute program relative to a directory file descriptor (see
-/// [execveat(2)](https://man7.org/linux/man-pages/man2/execveat.2.html)).
-///
-/// The `execveat` function allows for another process to be "called" which will
-/// replace the current process image. That is, this process becomes the new
-/// command that is run. On success, this function will not return. Instead,
-/// the new program will run until it exits.
-///
-/// This function is similar to `execve`, except that the program to be executed
-/// is referenced as a file descriptor to the base directory plus a path.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[inline]
-pub fn execveat<SA: AsRef<CStr>,SE: AsRef<CStr>>(dirfd: RawFd, pathname: &CStr, args: &[SA],
- env: &[SE], flags: super::fcntl::AtFlags) -> Result<Infallible> {
- let args_p = to_exec_array(args);
- let env_p = to_exec_array(env);
-
- unsafe {
- libc::syscall(libc::SYS_execveat, dirfd, pathname.as_ptr(),
- args_p.as_ptr(), env_p.as_ptr(), flags);
- };
-
- Err(Errno::last())
-}
-
-/// Daemonize this process by detaching from the controlling terminal (see
-/// [daemon(3)](https://man7.org/linux/man-pages/man3/daemon.3.html)).
-///
-/// When a process is launched it is typically associated with a parent and it,
-/// in turn, by its controlling terminal/process. In order for a process to run
-/// in the "background" it must daemonize itself by detaching itself. Under
-/// posix, this is done by doing the following:
-///
-/// 1. Parent process (this one) forks
-/// 2. Parent process exits
-/// 3. Child process continues to run.
-///
-/// `nochdir`:
-///
-/// * `nochdir = true`: The current working directory after daemonizing will
-/// be the current working directory.
-/// * `nochdir = false`: The current working directory after daemonizing will
-/// be the root direcory, `/`.
-///
-/// `noclose`:
-///
-/// * `noclose = true`: The process' current stdin, stdout, and stderr file
-/// descriptors will remain identical after daemonizing.
-/// * `noclose = false`: The process' stdin, stdout, and stderr will point to
-/// `/dev/null` after daemonizing.
-#[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
-pub fn daemon(nochdir: bool, noclose: bool) -> Result<()> {
- let res = unsafe { libc::daemon(nochdir as c_int, noclose as c_int) };
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![feature = "hostname"]
-
-/// Set the system host name (see
-/// [sethostname(2)](https://man7.org/linux/man-pages/man2/gethostname.2.html)).
-///
-/// Given a name, attempt to update the system host name to the given string.
-/// On some systems, the host name is limited to as few as 64 bytes. An error
-/// will be returned if the name is not valid or the current process does not
-/// have permissions to update the host name.
-#[cfg(not(target_os = "redox"))]
-pub fn sethostname<S: AsRef<OsStr>>(name: S) -> Result<()> {
- // Handle some differences in type of the len arg across platforms.
- cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "solaris", ))] {
- type sethostname_len_t = c_int;
- } else {
- type sethostname_len_t = size_t;
- }
- }
- let ptr = name.as_ref().as_bytes().as_ptr() as *const c_char;
- let len = name.as_ref().len() as sethostname_len_t;
-
- let res = unsafe { libc::sethostname(ptr, len) };
- Errno::result(res).map(drop)
-}
-
-/// Get the host name and store it in an internally allocated buffer, returning an
-/// `OsString` on success (see
-/// [gethostname(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html)).
-///
-/// This function call attempts to get the host name for the running system and
-/// store it in an internal buffer, returning it as an `OsString` if successful.
-///
-/// ```no_run
-/// use nix::unistd;
-///
-/// let hostname = unistd::gethostname().expect("Failed getting hostname");
-/// let hostname = hostname.into_string().expect("Hostname wasn't valid UTF-8");
-/// println!("Hostname: {}", hostname);
-/// ```
-pub fn gethostname() -> Result<OsString> {
- // The capacity is the max length of a hostname plus the NUL terminator.
- let mut buffer: Vec<u8> = Vec::with_capacity(256);
- let ptr = buffer.as_mut_ptr() as *mut c_char;
- let len = buffer.capacity() as size_t;
-
- let res = unsafe { libc::gethostname(ptr, len) };
- Errno::result(res).map(|_| {
- unsafe {
- buffer.as_mut_ptr().wrapping_add(len - 1).write(0); // ensure always null-terminated
- let len = CStr::from_ptr(buffer.as_ptr() as *const c_char).len();
- buffer.set_len(len);
- }
- OsString::from_vec(buffer)
- })
-}
-}
-
-/// Close a raw file descriptor
-///
-/// Be aware that many Rust types implicitly close-on-drop, including
-/// `std::fs::File`. Explicitly closing them with this method too can result in
-/// a double-close condition, which can cause confusing `EBADF` errors in
-/// seemingly unrelated code. Caveat programmer. See also
-/// [close(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html).
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::unix::io::AsRawFd;
-/// use nix::unistd::close;
-///
-/// let f = tempfile::tempfile().unwrap();
-/// close(f.as_raw_fd()).unwrap(); // Bad! f will also close on drop!
-/// ```
-///
-/// ```rust
-/// use std::os::unix::io::IntoRawFd;
-/// use nix::unistd::close;
-///
-/// let f = tempfile::tempfile().unwrap();
-/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f
-/// ```
-pub fn close(fd: RawFd) -> Result<()> {
- let res = unsafe { libc::close(fd) };
- Errno::result(res).map(drop)
-}
-
-/// Read from a raw file descriptor.
-///
-/// See also [read(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html)
-pub fn read(fd: RawFd, buf: &mut [u8]) -> Result<usize> {
- let res = unsafe {
- libc::read(fd, buf.as_mut_ptr() as *mut c_void, buf.len() as size_t)
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-/// Write to a raw file descriptor.
-///
-/// See also [write(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html)
-pub fn write(fd: RawFd, buf: &[u8]) -> Result<usize> {
- let res = unsafe {
- libc::write(fd, buf.as_ptr() as *const c_void, buf.len() as size_t)
- };
-
- Errno::result(res).map(|r| r as usize)
-}
-
-feature! {
-#![feature = "fs"]
-
-/// Directive that tells [`lseek`] and [`lseek64`] what the offset is relative to.
-///
-/// [`lseek`]: ./fn.lseek.html
-/// [`lseek64`]: ./fn.lseek64.html
-#[repr(i32)]
-#[derive(Clone, Copy, Debug)]
-pub enum Whence {
- /// Specify an offset relative to the start of the file.
- SeekSet = libc::SEEK_SET,
- /// Specify an offset relative to the current file location.
- SeekCur = libc::SEEK_CUR,
- /// Specify an offset relative to the end of the file.
- SeekEnd = libc::SEEK_END,
- /// Specify an offset relative to the next location in the file greater than or
- /// equal to offset that contains some data. If offset points to
- /// some data, then the file offset is set to offset.
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris"))]
- SeekData = libc::SEEK_DATA,
- /// Specify an offset relative to the next hole in the file greater than
- /// or equal to offset. If offset points into the middle of a hole, then
- /// the file offset should be set to offset. If there is no hole past offset,
- /// then the file offset should be adjusted to the end of the file (i.e., there
- /// is an implicit hole at the end of any file).
- #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris"))]
- SeekHole = libc::SEEK_HOLE
-}
-
-/// Move the read/write file offset.
-///
-/// See also [lseek(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html)
-pub fn lseek(fd: RawFd, offset: off_t, whence: Whence) -> Result<off_t> {
- let res = unsafe { libc::lseek(fd, offset, whence as i32) };
-
- Errno::result(res).map(|r| r as off_t)
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn lseek64(fd: RawFd, offset: libc::off64_t, whence: Whence) -> Result<libc::off64_t> {
- let res = unsafe { libc::lseek64(fd, offset, whence as i32) };
-
- Errno::result(res).map(|r| r as libc::off64_t)
-}
-}
-
-/// Create an interprocess channel.
-///
-/// See also [pipe(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html)
-pub fn pipe() -> std::result::Result<(RawFd, RawFd), Error> {
- let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
-
- let res = unsafe { libc::pipe(fds.as_mut_ptr() as *mut c_int) };
-
- Error::result(res)?;
-
- unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) }
-}
-
-feature! {
-#![feature = "fs"]
-/// Like `pipe`, but allows setting certain file descriptor flags.
-///
-/// The following flags are supported, and will be set atomically as the pipe is
-/// created:
-///
-/// - `O_CLOEXEC`: Set the close-on-exec flag for the new file descriptors.
-#[cfg_attr(target_os = "linux", doc = "- `O_DIRECT`: Create a pipe that performs I/O in \"packet\" mode.")]
-#[cfg_attr(target_os = "netbsd", doc = "- `O_NOSIGPIPE`: Return `EPIPE` instead of raising `SIGPIPE`.")]
-/// - `O_NONBLOCK`: Set the non-blocking flag for the ends of the pipe.
-///
-/// See also [pipe(2)](https://man7.org/linux/man-pages/man2/pipe.2.html)
-#[cfg(any(target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "redox",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))]
-pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> {
- let mut fds = mem::MaybeUninit::<[c_int; 2]>::uninit();
-
- let res = unsafe {
- libc::pipe2(fds.as_mut_ptr() as *mut c_int, flags.bits())
- };
-
- Errno::result(res)?;
-
- unsafe { Ok((fds.assume_init()[0], fds.assume_init()[1])) }
-}
-
-/// Truncate a file to a specified length
-///
-/// See also
-/// [truncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html)
-#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
-pub fn truncate<P: ?Sized + NixPath>(path: &P, len: off_t) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::truncate(cstr.as_ptr(), len)
- }
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Truncate a file to a specified length
-///
-/// See also
-/// [ftruncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html)
-pub fn ftruncate(fd: RawFd, len: off_t) -> Result<()> {
- Errno::result(unsafe { libc::ftruncate(fd, len) }).map(drop)
-}
-
-pub fn isatty(fd: RawFd) -> Result<bool> {
- unsafe {
- // ENOTTY means `fd` is a valid file descriptor, but not a TTY, so
- // we return `Ok(false)`
- if libc::isatty(fd) == 1 {
- Ok(true)
- } else {
- match Errno::last() {
- Errno::ENOTTY => Ok(false),
- err => Err(err),
- }
- }
- }
-}
-
-/// Flags for `linkat` function.
-#[derive(Clone, Copy, Debug)]
-pub enum LinkatFlags {
- SymlinkFollow,
- NoSymlinkFollow,
-}
-
-/// Link one file to another file
-///
-/// Creates a new link (directory entry) at `newpath` for the existing file at `oldpath`. In the
-/// case of a relative `oldpath`, the path is interpreted relative to the directory associated
-/// with file descriptor `olddirfd` instead of the current working directory and similiarly for
-/// `newpath` and file descriptor `newdirfd`. In case `flag` is LinkatFlags::SymlinkFollow and
-/// `oldpath` names a symoblic link, a new link for the target of the symbolic link is created.
-/// If either `olddirfd` or `newdirfd` is `None`, `AT_FDCWD` is used respectively where `oldpath`
-/// and/or `newpath` is then interpreted relative to the current working directory of the calling
-/// process. If either `oldpath` or `newpath` is absolute, then `dirfd` is ignored.
-///
-/// # References
-/// See also [linkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html)
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support symlinks yet
-pub fn linkat<P: ?Sized + NixPath>(
- olddirfd: Option<RawFd>,
- oldpath: &P,
- newdirfd: Option<RawFd>,
- newpath: &P,
- flag: LinkatFlags,
-) -> Result<()> {
-
- let atflag =
- match flag {
- LinkatFlags::SymlinkFollow => AtFlags::AT_SYMLINK_FOLLOW,
- LinkatFlags::NoSymlinkFollow => AtFlags::empty(),
- };
-
- let res =
- oldpath.with_nix_path(|oldcstr| {
- newpath.with_nix_path(|newcstr| {
- unsafe {
- libc::linkat(
- at_rawfd(olddirfd),
- oldcstr.as_ptr(),
- at_rawfd(newdirfd),
- newcstr.as_ptr(),
- atflag.bits() as libc::c_int
- )
- }
- })
- })??;
- Errno::result(res).map(drop)
-}
-
-
-/// Remove a directory entry
-///
-/// See also [unlink(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html)
-pub fn unlink<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::unlink(cstr.as_ptr())
- }
- })?;
- Errno::result(res).map(drop)
-}
-
-/// Flags for `unlinkat` function.
-#[derive(Clone, Copy, Debug)]
-pub enum UnlinkatFlags {
- RemoveDir,
- NoRemoveDir,
-}
-
-/// Remove a directory entry
-///
-/// In the case of a relative path, the directory entry to be removed is determined relative to
-/// the directory associated with the file descriptor `dirfd` or the current working directory
-/// if `dirfd` is `None`. In the case of an absolute `path` `dirfd` is ignored. If `flag` is
-/// `UnlinkatFlags::RemoveDir` then removal of the directory entry specified by `dirfd` and `path`
-/// is performed.
-///
-/// # References
-/// See also [unlinkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlinkat.html)
-#[cfg(not(target_os = "redox"))]
-pub fn unlinkat<P: ?Sized + NixPath>(
- dirfd: Option<RawFd>,
- path: &P,
- flag: UnlinkatFlags,
-) -> Result<()> {
- let atflag =
- match flag {
- UnlinkatFlags::RemoveDir => AtFlags::AT_REMOVEDIR,
- UnlinkatFlags::NoRemoveDir => AtFlags::empty(),
- };
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::unlinkat(at_rawfd(dirfd), cstr.as_ptr(), atflag.bits() as libc::c_int)
- }
- })?;
- Errno::result(res).map(drop)
-}
-
-
-#[inline]
-#[cfg(not(target_os = "fuchsia"))]
-pub fn chroot<P: ?Sized + NixPath>(path: &P) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe { libc::chroot(cstr.as_ptr()) }
- })?;
-
- Errno::result(res).map(drop)
-}
-
-/// Commit filesystem caches to disk
-///
-/// See also [sync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html)
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-pub fn sync() {
- unsafe { libc::sync() };
-}
-
-/// Commit filesystem caches containing file referred to by the open file
-/// descriptor `fd` to disk
-///
-/// See also [syncfs(2)](https://man7.org/linux/man-pages/man2/sync.2.html)
-#[cfg(target_os = "linux")]
-pub fn syncfs(fd: RawFd) -> Result<()> {
- let res = unsafe { libc::syncfs(fd) };
-
- Errno::result(res).map(drop)
-}
-
-/// Synchronize changes to a file
-///
-/// See also [fsync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html)
-#[inline]
-pub fn fsync(fd: RawFd) -> Result<()> {
- let res = unsafe { libc::fsync(fd) };
-
- Errno::result(res).map(drop)
-}
-
-/// Synchronize the data of a file
-///
-/// See also
-/// [fdatasync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html)
-#[cfg(any(target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "fuchsia",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "illumos",
- target_os = "solaris"))]
-#[inline]
-pub fn fdatasync(fd: RawFd) -> Result<()> {
- let res = unsafe { libc::fdatasync(fd) };
-
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![feature = "user"]
-
-/// Get a real user ID
-///
-/// See also [getuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html)
-// POSIX requires that getuid is always successful, so no need to check return
-// value or errno.
-#[inline]
-pub fn getuid() -> Uid {
- Uid(unsafe { libc::getuid() })
-}
-
-/// Get the effective user ID
-///
-/// See also [geteuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html)
-// POSIX requires that geteuid is always successful, so no need to check return
-// value or errno.
-#[inline]
-pub fn geteuid() -> Uid {
- Uid(unsafe { libc::geteuid() })
-}
-
-/// Get the real group ID
-///
-/// See also [getgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html)
-// POSIX requires that getgid is always successful, so no need to check return
-// value or errno.
-#[inline]
-pub fn getgid() -> Gid {
- Gid(unsafe { libc::getgid() })
-}
-
-/// Get the effective group ID
-///
-/// See also [getegid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html)
-// POSIX requires that getegid is always successful, so no need to check return
-// value or errno.
-#[inline]
-pub fn getegid() -> Gid {
- Gid(unsafe { libc::getegid() })
-}
-
-/// Set the effective user ID
-///
-/// See also [seteuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/seteuid.html)
-#[inline]
-pub fn seteuid(euid: Uid) -> Result<()> {
- let res = unsafe { libc::seteuid(euid.into()) };
-
- Errno::result(res).map(drop)
-}
-
-/// Set the effective group ID
-///
-/// See also [setegid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setegid.html)
-#[inline]
-pub fn setegid(egid: Gid) -> Result<()> {
- let res = unsafe { libc::setegid(egid.into()) };
-
- Errno::result(res).map(drop)
-}
-
-/// Set the user ID
-///
-/// See also [setuid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html)
-#[inline]
-pub fn setuid(uid: Uid) -> Result<()> {
- let res = unsafe { libc::setuid(uid.into()) };
-
- Errno::result(res).map(drop)
-}
-
-/// Set the group ID
-///
-/// See also [setgid(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html)
-#[inline]
-pub fn setgid(gid: Gid) -> Result<()> {
- let res = unsafe { libc::setgid(gid.into()) };
-
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![all(feature = "fs", feature = "user")]
-/// Set the user identity used for filesystem checks per-thread.
-/// On both success and failure, this call returns the previous filesystem user
-/// ID of the caller.
-///
-/// See also [setfsuid(2)](https://man7.org/linux/man-pages/man2/setfsuid.2.html)
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn setfsuid(uid: Uid) -> Uid {
- let prev_fsuid = unsafe { libc::setfsuid(uid.into()) };
- Uid::from_raw(prev_fsuid as uid_t)
-}
-
-/// Set the group identity used for filesystem checks per-thread.
-/// On both success and failure, this call returns the previous filesystem group
-/// ID of the caller.
-///
-/// See also [setfsgid(2)](https://man7.org/linux/man-pages/man2/setfsgid.2.html)
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn setfsgid(gid: Gid) -> Gid {
- let prev_fsgid = unsafe { libc::setfsgid(gid.into()) };
- Gid::from_raw(prev_fsgid as gid_t)
-}
-}
-
-feature! {
-#![feature = "user"]
-
-/// Get the list of supplementary group IDs of the calling process.
-///
-/// [Further reading](https://pubs.opengroup.org/onlinepubs/009695399/functions/getgroups.html)
-///
-/// **Note:** This function is not available for Apple platforms. On those
-/// platforms, checking group membership should be achieved via communication
-/// with the `opendirectoryd` service.
-#[cfg(not(any(target_os = "ios", target_os = "macos")))]
-pub fn getgroups() -> Result<Vec<Gid>> {
- // First get the maximum number of groups. The value returned
- // shall always be greater than or equal to one and less than or
- // equal to the value of {NGROUPS_MAX} + 1.
- let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
- Ok(Some(n)) => (n + 1) as usize,
- Ok(None) | Err(_) => <usize>::max_value(),
- };
-
- // Next, get the number of groups so we can size our Vec
- let ngroups = unsafe { libc::getgroups(0, ptr::null_mut()) };
-
- // If there are no supplementary groups, return early.
- // This prevents a potential buffer over-read if the number of groups
- // increases from zero before the next call. It would return the total
- // number of groups beyond the capacity of the buffer.
- if ngroups == 0 {
- return Ok(Vec::new());
- }
-
- // Now actually get the groups. We try multiple times in case the number of
- // groups has changed since the first call to getgroups() and the buffer is
- // now too small.
- let mut groups = Vec::<Gid>::with_capacity(Errno::result(ngroups)? as usize);
- loop {
- // FIXME: On the platforms we currently support, the `Gid` struct has
- // the same representation in memory as a bare `gid_t`. This is not
- // necessarily the case on all Rust platforms, though. See RFC 1785.
- let ngroups = unsafe {
- libc::getgroups(groups.capacity() as c_int, groups.as_mut_ptr() as *mut gid_t)
- };
-
- match Errno::result(ngroups) {
- Ok(s) => {
- unsafe { groups.set_len(s as usize) };
- return Ok(groups);
- },
- Err(Errno::EINVAL) => {
- // EINVAL indicates that the buffer size was too
- // small, resize it up to ngroups_max as limit.
- reserve_double_buffer_size(&mut groups, ngroups_max)
- .or(Err(Errno::EINVAL))?;
- },
- Err(e) => return Err(e)
- }
- }
-}
-
-/// Set the list of supplementary group IDs for the calling process.
-///
-/// [Further reading](https://man7.org/linux/man-pages/man2/getgroups.2.html)
-///
-/// **Note:** This function is not available for Apple platforms. On those
-/// platforms, group membership management should be achieved via communication
-/// with the `opendirectoryd` service.
-///
-/// # Examples
-///
-/// `setgroups` can be used when dropping privileges from the root user to a
-/// specific user and group. For example, given the user `www-data` with UID
-/// `33` and the group `backup` with the GID `34`, one could switch the user as
-/// follows:
-///
-/// ```rust,no_run
-/// # use std::error::Error;
-/// # use nix::unistd::*;
-/// #
-/// # fn try_main() -> Result<(), Box<dyn Error>> {
-/// let uid = Uid::from_raw(33);
-/// let gid = Gid::from_raw(34);
-/// setgroups(&[gid])?;
-/// setgid(gid)?;
-/// setuid(uid)?;
-/// #
-/// # Ok(())
-/// # }
-/// #
-/// # try_main().unwrap();
-/// ```
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
-pub fn setgroups(groups: &[Gid]) -> Result<()> {
- cfg_if! {
- if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "illumos",
- target_os = "openbsd"))] {
- type setgroups_ngroups_t = c_int;
- } else {
- type setgroups_ngroups_t = size_t;
- }
- }
- // FIXME: On the platforms we currently support, the `Gid` struct has the
- // same representation in memory as a bare `gid_t`. This is not necessarily
- // the case on all Rust platforms, though. See RFC 1785.
- let res = unsafe {
- libc::setgroups(groups.len() as setgroups_ngroups_t, groups.as_ptr() as *const gid_t)
- };
-
- Errno::result(res).map(drop)
-}
-
-/// Calculate the supplementary group access list.
-///
-/// Gets the group IDs of all groups that `user` is a member of. The additional
-/// group `group` is also added to the list.
-///
-/// [Further reading](https://man7.org/linux/man-pages/man3/getgrouplist.3.html)
-///
-/// **Note:** This function is not available for Apple platforms. On those
-/// platforms, checking group membership should be achieved via communication
-/// with the `opendirectoryd` service.
-///
-/// # Errors
-///
-/// Although the `getgrouplist()` call does not return any specific
-/// errors on any known platforms, this implementation will return a system
-/// error of `EINVAL` if the number of groups to be fetched exceeds the
-/// `NGROUPS_MAX` sysconf value. This mimics the behaviour of `getgroups()`
-/// and `setgroups()`. Additionally, while some implementations will return a
-/// partial list of groups when `NGROUPS_MAX` is exceeded, this implementation
-/// will only ever return the complete list or else an error.
-#[cfg(not(any(target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "redox")))]
-pub fn getgrouplist(user: &CStr, group: Gid) -> Result<Vec<Gid>> {
- let ngroups_max = match sysconf(SysconfVar::NGROUPS_MAX) {
- Ok(Some(n)) => n as c_int,
- Ok(None) | Err(_) => <c_int>::max_value(),
- };
- use std::cmp::min;
- let mut groups = Vec::<Gid>::with_capacity(min(ngroups_max, 8) as usize);
- cfg_if! {
- if #[cfg(any(target_os = "ios", target_os = "macos"))] {
- type getgrouplist_group_t = c_int;
- } else {
- type getgrouplist_group_t = gid_t;
- }
- }
- let gid: gid_t = group.into();
- loop {
- let mut ngroups = groups.capacity() as i32;
- let ret = unsafe {
- libc::getgrouplist(user.as_ptr(),
- gid as getgrouplist_group_t,
- groups.as_mut_ptr() as *mut getgrouplist_group_t,
- &mut ngroups)
- };
-
- // BSD systems only return 0 or -1, Linux returns ngroups on success.
- if ret >= 0 {
- unsafe { groups.set_len(ngroups as usize) };
- return Ok(groups);
- } else if ret == -1 {
- // Returns -1 if ngroups is too small, but does not set errno.
- // BSD systems will still fill the groups buffer with as many
- // groups as possible, but Linux manpages do not mention this
- // behavior.
- reserve_double_buffer_size(&mut groups, ngroups_max as usize)
- .map_err(|_| Errno::EINVAL)?;
- }
- }
-}
-
-/// Initialize the supplementary group access list.
-///
-/// Sets the supplementary group IDs for the calling process using all groups
-/// that `user` is a member of. The additional group `group` is also added to
-/// the list.
-///
-/// [Further reading](https://man7.org/linux/man-pages/man3/initgroups.3.html)
-///
-/// **Note:** This function is not available for Apple platforms. On those
-/// platforms, group membership management should be achieved via communication
-/// with the `opendirectoryd` service.
-///
-/// # Examples
-///
-/// `initgroups` can be used when dropping privileges from the root user to
-/// another user. For example, given the user `www-data`, we could look up the
-/// UID and GID for the user in the system's password database (usually found
-/// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`,
-/// respectively, one could switch the user as follows:
-///
-/// ```rust,no_run
-/// # use std::error::Error;
-/// # use std::ffi::CString;
-/// # use nix::unistd::*;
-/// #
-/// # fn try_main() -> Result<(), Box<dyn Error>> {
-/// let user = CString::new("www-data").unwrap();
-/// let uid = Uid::from_raw(33);
-/// let gid = Gid::from_raw(33);
-/// initgroups(&user, gid)?;
-/// setgid(gid)?;
-/// setuid(uid)?;
-/// #
-/// # Ok(())
-/// # }
-/// #
-/// # try_main().unwrap();
-/// ```
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox", target_os = "haiku")))]
-pub fn initgroups(user: &CStr, group: Gid) -> Result<()> {
- cfg_if! {
- if #[cfg(any(target_os = "ios", target_os = "macos"))] {
- type initgroups_group_t = c_int;
- } else {
- type initgroups_group_t = gid_t;
- }
- }
- let gid: gid_t = group.into();
- let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
-
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![feature = "signal"]
-
-/// Suspend the thread until a signal is received.
-///
-/// See also [pause(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html).
-#[inline]
-#[cfg(not(target_os = "redox"))]
-pub fn pause() {
- unsafe { libc::pause() };
-}
-
-pub mod alarm {
- //! Alarm signal scheduling.
- //!
- //! Scheduling an alarm will trigger a `SIGALRM` signal when the time has
- //! elapsed, which has to be caught, because the default action for the
- //! signal is to terminate the program. This signal also can't be ignored
- //! because the system calls like `pause` will not be interrupted, see the
- //! second example below.
- //!
- //! # Examples
- //!
- //! Canceling an alarm:
- //!
- //! ```
- //! use nix::unistd::alarm;
- //!
- //! // Set an alarm for 60 seconds from now.
- //! alarm::set(60);
- //!
- //! // Cancel the above set alarm, which returns the number of seconds left
- //! // of the previously set alarm.
- //! assert_eq!(alarm::cancel(), Some(60));
- //! ```
- //!
- //! Scheduling an alarm and waiting for the signal:
- //!
-#![cfg_attr(target_os = "redox", doc = " ```rust,ignore")]
-#![cfg_attr(not(target_os = "redox"), doc = " ```rust")]
- //! use std::time::{Duration, Instant};
- //!
- //! use nix::unistd::{alarm, pause};
- //! use nix::sys::signal::*;
- //!
- //! // We need to setup an empty signal handler to catch the alarm signal,
- //! // otherwise the program will be terminated once the signal is delivered.
- //! extern fn signal_handler(_: nix::libc::c_int) { }
- //! let sa = SigAction::new(
- //! SigHandler::Handler(signal_handler),
- //! SaFlags::SA_RESTART,
- //! SigSet::empty()
- //! );
- //! unsafe {
- //! sigaction(Signal::SIGALRM, &sa);
- //! }
- //!
- //! let start = Instant::now();
- //!
- //! // Set an alarm for 1 second from now.
- //! alarm::set(1);
- //!
- //! // Pause the process until the alarm signal is received.
- //! let mut sigset = SigSet::empty();
- //! sigset.add(Signal::SIGALRM);
- //! sigset.wait();
- //!
- //! assert!(start.elapsed() >= Duration::from_secs(1));
- //! ```
- //!
- //! # References
- //!
- //! See also [alarm(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/alarm.html).
-
- /// Schedule an alarm signal.
- ///
- /// This will cause the system to generate a `SIGALRM` signal for the
- /// process after the specified number of seconds have elapsed.
- ///
- /// Returns the leftover time of a previously set alarm if there was one.
- pub fn set(secs: libc::c_uint) -> Option<libc::c_uint> {
- assert!(secs != 0, "passing 0 to `alarm::set` is not allowed, to cancel an alarm use `alarm::cancel`");
- alarm(secs)
- }
-
- /// Cancel an previously set alarm signal.
- ///
- /// Returns the leftover time of a previously set alarm if there was one.
- pub fn cancel() -> Option<libc::c_uint> {
- alarm(0)
- }
-
- fn alarm(secs: libc::c_uint) -> Option<libc::c_uint> {
- match unsafe { libc::alarm(secs) } {
- 0 => None,
- secs => Some(secs),
- }
- }
-}
-}
-
-/// Suspend execution for an interval of time
-///
-/// See also [sleep(2)](https://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html#tag_03_705_05)
-// Per POSIX, does not fail
-#[inline]
-pub fn sleep(seconds: c_uint) -> c_uint {
- unsafe { libc::sleep(seconds) }
-}
-
-feature! {
-#![feature = "acct"]
-
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-pub mod acct {
- use crate::{Result, NixPath};
- use crate::errno::Errno;
- use std::ptr;
-
- /// Enable process accounting
- ///
- /// See also [acct(2)](https://linux.die.net/man/2/acct)
- pub fn enable<P: ?Sized + NixPath>(filename: &P) -> Result<()> {
- let res = filename.with_nix_path(|cstr| {
- unsafe { libc::acct(cstr.as_ptr()) }
- })?;
-
- Errno::result(res).map(drop)
- }
-
- /// Disable process accounting
- pub fn disable() -> Result<()> {
- let res = unsafe { libc::acct(ptr::null()) };
-
- Errno::result(res).map(drop)
- }
-}
-}
-
-feature! {
-#![feature = "fs"]
-/// Creates a regular file which persists even after process termination
-///
-/// * `template`: a path whose 6 rightmost characters must be X, e.g. `/tmp/tmpfile_XXXXXX`
-/// * returns: tuple of file descriptor and filename
-///
-/// Err is returned either if no temporary filename could be created or the template doesn't
-/// end with XXXXXX
-///
-/// See also [mkstemp(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkstemp.html)
-///
-/// # Example
-///
-/// ```rust
-/// use nix::unistd;
-///
-/// let _ = match unistd::mkstemp("/tmp/tempfile_XXXXXX") {
-/// Ok((fd, path)) => {
-/// unistd::unlink(path.as_path()).unwrap(); // flag file to be deleted at app termination
-/// fd
-/// }
-/// Err(e) => panic!("mkstemp failed: {}", e)
-/// };
-/// // do something with fd
-/// ```
-#[inline]
-pub fn mkstemp<P: ?Sized + NixPath>(template: &P) -> Result<(RawFd, PathBuf)> {
- let mut path = template.with_nix_path(|path| {path.to_bytes_with_nul().to_owned()})?;
- let p = path.as_mut_ptr() as *mut _;
- let fd = unsafe { libc::mkstemp(p) };
- let last = path.pop(); // drop the trailing nul
- debug_assert!(last == Some(b'\0'));
- let pathname = OsString::from_vec(path);
- Errno::result(fd)?;
- Ok((fd, PathBuf::from(pathname)))
-}
-}
-
-feature! {
-#![all(feature = "fs", feature = "feature")]
-
-/// Variable names for `pathconf`
-///
-/// Nix uses the same naming convention for these variables as the
-/// [getconf(1)](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility.
-/// That is, `PathconfVar` variables have the same name as the abstract
-/// variables shown in the `pathconf(2)` man page. Usually, it's the same as
-/// the C variable name without the leading `_PC_`.
-///
-/// POSIX 1003.1-2008 standardizes all of these variables, but some OSes choose
-/// not to implement variables that cannot change at runtime.
-///
-/// # References
-///
-/// - [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html)
-/// - [limits.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
-/// - [unistd.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html)
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(i32)]
-#[non_exhaustive]
-pub enum PathconfVar {
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux",
- target_os = "netbsd", target_os = "openbsd", target_os = "redox"))]
- /// Minimum number of bits needed to represent, as a signed integer value,
- /// the maximum size of a regular file allowed in the specified directory.
- #[cfg_attr(docsrs, doc(cfg(all())))]
- FILESIZEBITS = libc::_PC_FILESIZEBITS,
- /// Maximum number of links to a single file.
- LINK_MAX = libc::_PC_LINK_MAX,
- /// Maximum number of bytes in a terminal canonical input line.
- MAX_CANON = libc::_PC_MAX_CANON,
- /// Minimum number of bytes for which space is available in a terminal input
- /// queue; therefore, the maximum number of bytes a conforming application
- /// may require to be typed as input before reading them.
- MAX_INPUT = libc::_PC_MAX_INPUT,
- /// Maximum number of bytes in a filename (not including the terminating
- /// null of a filename string).
- NAME_MAX = libc::_PC_NAME_MAX,
- /// Maximum number of bytes the implementation will store as a pathname in a
- /// user-supplied buffer of unspecified size, including the terminating null
- /// character. Minimum number the implementation will accept as the maximum
- /// number of bytes in a pathname.
- PATH_MAX = libc::_PC_PATH_MAX,
- /// Maximum number of bytes that is guaranteed to be atomic when writing to
- /// a pipe.
- PIPE_BUF = libc::_PC_PIPE_BUF,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "illumos",
- target_os = "linux", target_os = "netbsd", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Symbolic links can be created.
- POSIX2_SYMLINKS = libc::_PC_2_SYMLINKS,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Minimum number of bytes of storage actually allocated for any portion of
- /// a file.
- POSIX_ALLOC_SIZE_MIN = libc::_PC_ALLOC_SIZE_MIN,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Recommended increment for file transfer sizes between the
- /// `POSIX_REC_MIN_XFER_SIZE` and `POSIX_REC_MAX_XFER_SIZE` values.
- POSIX_REC_INCR_XFER_SIZE = libc::_PC_REC_INCR_XFER_SIZE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Maximum recommended file transfer size.
- POSIX_REC_MAX_XFER_SIZE = libc::_PC_REC_MAX_XFER_SIZE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Minimum recommended file transfer size.
- POSIX_REC_MIN_XFER_SIZE = libc::_PC_REC_MIN_XFER_SIZE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "linux", target_os = "openbsd", target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Recommended file transfer buffer alignment.
- POSIX_REC_XFER_ALIGN = libc::_PC_REC_XFER_ALIGN,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "netbsd",
- target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Maximum number of bytes in a symbolic link.
- SYMLINK_MAX = libc::_PC_SYMLINK_MAX,
- /// The use of `chown` and `fchown` is restricted to a process with
- /// appropriate privileges, and to changing the group ID of a file only to
- /// the effective group ID of the process or to one of its supplementary
- /// group IDs.
- _POSIX_CHOWN_RESTRICTED = libc::_PC_CHOWN_RESTRICTED,
- /// Pathname components longer than {NAME_MAX} generate an error.
- _POSIX_NO_TRUNC = libc::_PC_NO_TRUNC,
- /// This symbol shall be defined to be the value of a character that shall
- /// disable terminal special character handling.
- _POSIX_VDISABLE = libc::_PC_VDISABLE,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Asynchronous input or output operations may be performed for the
- /// associated file.
- _POSIX_ASYNC_IO = libc::_PC_ASYNC_IO,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "openbsd",
- target_os = "redox", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Prioritized input or output operations may be performed for the
- /// associated file.
- _POSIX_PRIO_IO = libc::_PC_PRIO_IO,
- #[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
- target_os = "illumos", target_os = "linux", target_os = "netbsd",
- target_os = "openbsd", target_os = "redox", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Synchronized input or output operations may be performed for the
- /// associated file.
- _POSIX_SYNC_IO = libc::_PC_SYNC_IO,
- #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The resolution in nanoseconds for all file timestamps.
- _POSIX_TIMESTAMP_RESOLUTION = libc::_PC_TIMESTAMP_RESOLUTION
-}
-
-/// Like `pathconf`, but works with file descriptors instead of paths (see
-/// [fpathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html))
-///
-/// # Parameters
-///
-/// - `fd`: The file descriptor whose variable should be interrogated
-/// - `var`: The pathconf variable to lookup
-///
-/// # Returns
-///
-/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its
-/// implementation level (for option variables). Implementation levels are
-/// usually a decimal-coded date, such as 200112 for POSIX 2001.12
-/// - `Ok(None)`: the variable has no limit (for limit variables) or is
-/// unsupported (for option variables)
-/// - `Err(x)`: an error occurred
-pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result<Option<c_long>> {
- let raw = unsafe {
- Errno::clear();
- libc::fpathconf(fd, var as c_int)
- };
- if raw == -1 {
- if errno::errno() == 0 {
- Ok(None)
- } else {
- Err(Errno::last())
- }
- } else {
- Ok(Some(raw))
- }
-}
-
-/// Get path-dependent configurable system variables (see
-/// [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html))
-///
-/// Returns the value of a path-dependent configurable system variable. Most
-/// supported variables also have associated compile-time constants, but POSIX
-/// allows their values to change at runtime. There are generally two types of
-/// `pathconf` variables: options and limits. See [pathconf(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pathconf.html) for more details.
-///
-/// # Parameters
-///
-/// - `path`: Lookup the value of `var` for this file or directory
-/// - `var`: The `pathconf` variable to lookup
-///
-/// # Returns
-///
-/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its
-/// implementation level (for option variables). Implementation levels are
-/// usually a decimal-coded date, such as 200112 for POSIX 2001.12
-/// - `Ok(None)`: the variable has no limit (for limit variables) or is
-/// unsupported (for option variables)
-/// - `Err(x)`: an error occurred
-pub fn pathconf<P: ?Sized + NixPath>(path: &P, var: PathconfVar) -> Result<Option<c_long>> {
- let raw = path.with_nix_path(|cstr| {
- unsafe {
- Errno::clear();
- libc::pathconf(cstr.as_ptr(), var as c_int)
- }
- })?;
- if raw == -1 {
- if errno::errno() == 0 {
- Ok(None)
- } else {
- Err(Errno::last())
- }
- } else {
- Ok(Some(raw))
- }
-}
-}
-
-feature! {
-#![feature = "feature"]
-
-/// Variable names for `sysconf`
-///
-/// Nix uses the same naming convention for these variables as the
-/// [getconf(1)](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/getconf.html) utility.
-/// That is, `SysconfVar` variables have the same name as the abstract variables
-/// shown in the `sysconf(3)` man page. Usually, it's the same as the C
-/// variable name without the leading `_SC_`.
-///
-/// All of these symbols are standardized by POSIX 1003.1-2008, but haven't been
-/// implemented by all platforms.
-///
-/// # References
-///
-/// - [sysconf(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html)
-/// - [unistd.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html)
-/// - [limits.h](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
-#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
-#[repr(i32)]
-#[non_exhaustive]
-pub enum SysconfVar {
- /// Maximum number of I/O operations in a single list I/O call supported by
- /// the implementation.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AIO_LISTIO_MAX = libc::_SC_AIO_LISTIO_MAX,
- /// Maximum number of outstanding asynchronous I/O operations supported by
- /// the implementation.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- AIO_MAX = libc::_SC_AIO_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The maximum amount by which a process can decrease its asynchronous I/O
- /// priority level from its own scheduling priority.
- AIO_PRIO_DELTA_MAX = libc::_SC_AIO_PRIO_DELTA_MAX,
- /// Maximum length of argument to the exec functions including environment data.
- ARG_MAX = libc::_SC_ARG_MAX,
- /// Maximum number of functions that may be registered with `atexit`.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- ATEXIT_MAX = libc::_SC_ATEXIT_MAX,
- /// Maximum obase values allowed by the bc utility.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BC_BASE_MAX = libc::_SC_BC_BASE_MAX,
- /// Maximum number of elements permitted in an array by the bc utility.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BC_DIM_MAX = libc::_SC_BC_DIM_MAX,
- /// Maximum scale value allowed by the bc utility.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BC_SCALE_MAX = libc::_SC_BC_SCALE_MAX,
- /// Maximum length of a string constant accepted by the bc utility.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- BC_STRING_MAX = libc::_SC_BC_STRING_MAX,
- /// Maximum number of simultaneous processes per real user ID.
- CHILD_MAX = libc::_SC_CHILD_MAX,
- // The number of clock ticks per second.
- CLK_TCK = libc::_SC_CLK_TCK,
- /// Maximum number of weights that can be assigned to an entry of the
- /// LC_COLLATE order keyword in the locale definition file
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- COLL_WEIGHTS_MAX = libc::_SC_COLL_WEIGHTS_MAX,
- /// Maximum number of timer expiration overruns.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- DELAYTIMER_MAX = libc::_SC_DELAYTIMER_MAX,
- /// Maximum number of expressions that can be nested within parentheses by
- /// the expr utility.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- EXPR_NEST_MAX = libc::_SC_EXPR_NEST_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Maximum length of a host name (not including the terminating null) as
- /// returned from the `gethostname` function
- HOST_NAME_MAX = libc::_SC_HOST_NAME_MAX,
- /// Maximum number of iovec structures that one process has available for
- /// use with `readv` or `writev`.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- IOV_MAX = libc::_SC_IOV_MAX,
- /// Unless otherwise noted, the maximum length, in bytes, of a utility's
- /// input line (either standard input or another file), when the utility is
- /// described as processing text files. The length includes room for the
- /// trailing newline.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- LINE_MAX = libc::_SC_LINE_MAX,
- /// Maximum length of a login name.
- #[cfg(not(target_os = "haiku"))]
- LOGIN_NAME_MAX = libc::_SC_LOGIN_NAME_MAX,
- /// Maximum number of simultaneous supplementary group IDs per process.
- NGROUPS_MAX = libc::_SC_NGROUPS_MAX,
- /// Initial size of `getgrgid_r` and `getgrnam_r` data buffers
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- GETGR_R_SIZE_MAX = libc::_SC_GETGR_R_SIZE_MAX,
- /// Initial size of `getpwuid_r` and `getpwnam_r` data buffers
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- GETPW_R_SIZE_MAX = libc::_SC_GETPW_R_SIZE_MAX,
- /// The maximum number of open message queue descriptors a process may hold.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MQ_OPEN_MAX = libc::_SC_MQ_OPEN_MAX,
- /// The maximum number of message priorities supported by the implementation.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- MQ_PRIO_MAX = libc::_SC_MQ_PRIO_MAX,
- /// A value one greater than the maximum value that the system may assign to
- /// a newly-created file descriptor.
- OPEN_MAX = libc::_SC_OPEN_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Advisory Information option.
- _POSIX_ADVISORY_INFO = libc::_SC_ADVISORY_INFO,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports barriers.
- _POSIX_BARRIERS = libc::_SC_BARRIERS,
- /// The implementation supports asynchronous input and output.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_ASYNCHRONOUS_IO = libc::_SC_ASYNCHRONOUS_IO,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports clock selection.
- _POSIX_CLOCK_SELECTION = libc::_SC_CLOCK_SELECTION,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Process CPU-Time Clocks option.
- _POSIX_CPUTIME = libc::_SC_CPUTIME,
- /// The implementation supports the File Synchronization option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_FSYNC = libc::_SC_FSYNC,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the IPv6 option.
- _POSIX_IPV6 = libc::_SC_IPV6,
- /// The implementation supports job control.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_JOB_CONTROL = libc::_SC_JOB_CONTROL,
- /// The implementation supports memory mapped Files.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_MAPPED_FILES = libc::_SC_MAPPED_FILES,
- /// The implementation supports the Process Memory Locking option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_MEMLOCK = libc::_SC_MEMLOCK,
- /// The implementation supports the Range Memory Locking option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_MEMLOCK_RANGE = libc::_SC_MEMLOCK_RANGE,
- /// The implementation supports memory protection.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_MEMORY_PROTECTION = libc::_SC_MEMORY_PROTECTION,
- /// The implementation supports the Message Passing option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_MESSAGE_PASSING = libc::_SC_MESSAGE_PASSING,
- /// The implementation supports the Monotonic Clock option.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_MONOTONIC_CLOCK = libc::_SC_MONOTONIC_CLOCK,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "illumos", target_os = "ios", target_os="linux",
- target_os = "macos", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Prioritized Input and Output option.
- _POSIX_PRIORITIZED_IO = libc::_SC_PRIORITIZED_IO,
- /// The implementation supports the Process Scheduling option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_PRIORITY_SCHEDULING = libc::_SC_PRIORITY_SCHEDULING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Raw Sockets option.
- _POSIX_RAW_SOCKETS = libc::_SC_RAW_SOCKETS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports read-write locks.
- _POSIX_READER_WRITER_LOCKS = libc::_SC_READER_WRITER_LOCKS,
- #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports realtime signals.
- _POSIX_REALTIME_SIGNALS = libc::_SC_REALTIME_SIGNALS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "illumos",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd", target_os = "solaris"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Regular Expression Handling option.
- _POSIX_REGEXP = libc::_SC_REGEXP,
- /// Each process has a saved set-user-ID and a saved set-group-ID.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_SAVED_IDS = libc::_SC_SAVED_IDS,
- /// The implementation supports semaphores.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_SEMAPHORES = libc::_SC_SEMAPHORES,
- /// The implementation supports the Shared Memory Objects option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_SHARED_MEMORY_OBJECTS = libc::_SC_SHARED_MEMORY_OBJECTS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the POSIX shell.
- _POSIX_SHELL = libc::_SC_SHELL,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Spawn option.
- _POSIX_SPAWN = libc::_SC_SPAWN,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports spin locks.
- _POSIX_SPIN_LOCKS = libc::_SC_SPIN_LOCKS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Process Sporadic Server option.
- _POSIX_SPORADIC_SERVER = libc::_SC_SPORADIC_SERVER,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_SS_REPL_MAX = libc::_SC_SS_REPL_MAX,
- /// The implementation supports the Synchronized Input and Output option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_SYNCHRONIZED_IO = libc::_SC_SYNCHRONIZED_IO,
- /// The implementation supports the Thread Stack Address Attribute option.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREAD_ATTR_STACKADDR = libc::_SC_THREAD_ATTR_STACKADDR,
- /// The implementation supports the Thread Stack Size Attribute option.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREAD_ATTR_STACKSIZE = libc::_SC_THREAD_ATTR_STACKSIZE,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="netbsd", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Thread CPU-Time Clocks option.
- _POSIX_THREAD_CPUTIME = libc::_SC_THREAD_CPUTIME,
- /// The implementation supports the Non-Robust Mutex Priority Inheritance
- /// option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREAD_PRIO_INHERIT = libc::_SC_THREAD_PRIO_INHERIT,
- /// The implementation supports the Non-Robust Mutex Priority Protection option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREAD_PRIO_PROTECT = libc::_SC_THREAD_PRIO_PROTECT,
- /// The implementation supports the Thread Execution Scheduling option.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREAD_PRIORITY_SCHEDULING = libc::_SC_THREAD_PRIORITY_SCHEDULING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Thread Process-Shared Synchronization
- /// option.
- _POSIX_THREAD_PROCESS_SHARED = libc::_SC_THREAD_PROCESS_SHARED,
- #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Robust Mutex Priority Inheritance option.
- _POSIX_THREAD_ROBUST_PRIO_INHERIT = libc::_SC_THREAD_ROBUST_PRIO_INHERIT,
- #[cfg(any(target_os="dragonfly", target_os="linux", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Robust Mutex Priority Protection option.
- _POSIX_THREAD_ROBUST_PRIO_PROTECT = libc::_SC_THREAD_ROBUST_PRIO_PROTECT,
- /// The implementation supports thread-safe functions.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREAD_SAFE_FUNCTIONS = libc::_SC_THREAD_SAFE_FUNCTIONS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Thread Sporadic Server option.
- _POSIX_THREAD_SPORADIC_SERVER = libc::_SC_THREAD_SPORADIC_SERVER,
- /// The implementation supports threads.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_THREADS = libc::_SC_THREADS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports timeouts.
- _POSIX_TIMEOUTS = libc::_SC_TIMEOUTS,
- /// The implementation supports timers.
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_TIMERS = libc::_SC_TIMERS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Trace option.
- _POSIX_TRACE = libc::_SC_TRACE,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Trace Event Filter option.
- _POSIX_TRACE_EVENT_FILTER = libc::_SC_TRACE_EVENT_FILTER,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_TRACE_EVENT_NAME_MAX = libc::_SC_TRACE_EVENT_NAME_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Trace Inherit option.
- _POSIX_TRACE_INHERIT = libc::_SC_TRACE_INHERIT,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Trace Log option.
- _POSIX_TRACE_LOG = libc::_SC_TRACE_LOG,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_TRACE_NAME_MAX = libc::_SC_TRACE_NAME_MAX,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_TRACE_SYS_MAX = libc::_SC_TRACE_SYS_MAX,
- #[cfg(any(target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX_TRACE_USER_EVENT_MAX = libc::_SC_TRACE_USER_EVENT_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Typed Memory Objects option.
- _POSIX_TYPED_MEMORY_OBJECTS = libc::_SC_TYPED_MEMORY_OBJECTS,
- /// Integer value indicating version of this standard (C-language binding)
- /// to which the implementation conforms. For implementations conforming to
- /// POSIX.1-2008, the value shall be 200809L.
- _POSIX_VERSION = libc::_SC_VERSION,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation provides a C-language compilation environment with
- /// 32-bit `int`, `long`, `pointer`, and `off_t` types.
- _POSIX_V6_ILP32_OFF32 = libc::_SC_V6_ILP32_OFF32,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation provides a C-language compilation environment with
- /// 32-bit `int`, `long`, and pointer types and an `off_t` type using at
- /// least 64 bits.
- _POSIX_V6_ILP32_OFFBIG = libc::_SC_V6_ILP32_OFFBIG,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation provides a C-language compilation environment with
- /// 32-bit `int` and 64-bit `long`, `pointer`, and `off_t` types.
- _POSIX_V6_LP64_OFF64 = libc::_SC_V6_LP64_OFF64,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation provides a C-language compilation environment with an
- /// `int` type using at least 32 bits and `long`, pointer, and `off_t` types
- /// using at least 64 bits.
- _POSIX_V6_LPBIG_OFFBIG = libc::_SC_V6_LPBIG_OFFBIG,
- /// The implementation supports the C-Language Binding option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_C_BIND = libc::_SC_2_C_BIND,
- /// The implementation supports the C-Language Development Utilities option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_C_DEV = libc::_SC_2_C_DEV,
- /// The implementation supports the Terminal Characteristics option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_CHAR_TERM = libc::_SC_2_CHAR_TERM,
- /// The implementation supports the FORTRAN Development Utilities option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_FORT_DEV = libc::_SC_2_FORT_DEV,
- /// The implementation supports the FORTRAN Runtime Utilities option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_FORT_RUN = libc::_SC_2_FORT_RUN,
- /// The implementation supports the creation of locales by the localedef
- /// utility.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_LOCALEDEF = libc::_SC_2_LOCALEDEF,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Batch Environment Services and Utilities
- /// option.
- _POSIX2_PBS = libc::_SC_2_PBS,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Batch Accounting option.
- _POSIX2_PBS_ACCOUNTING = libc::_SC_2_PBS_ACCOUNTING,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Batch Checkpoint/Restart option.
- _POSIX2_PBS_CHECKPOINT = libc::_SC_2_PBS_CHECKPOINT,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Locate Batch Job Request option.
- _POSIX2_PBS_LOCATE = libc::_SC_2_PBS_LOCATE,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Batch Job Message Request option.
- _POSIX2_PBS_MESSAGE = libc::_SC_2_PBS_MESSAGE,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Track Batch Job Request option.
- _POSIX2_PBS_TRACK = libc::_SC_2_PBS_TRACK,
- /// The implementation supports the Software Development Utilities option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_SW_DEV = libc::_SC_2_SW_DEV,
- /// The implementation supports the User Portability Utilities option.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_UPE = libc::_SC_2_UPE,
- /// Integer value indicating version of the Shell and Utilities volume of
- /// POSIX.1 to which the implementation conforms.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _POSIX2_VERSION = libc::_SC_2_VERSION,
- /// The size of a system page in bytes.
- ///
- /// POSIX also defines an alias named `PAGESIZE`, but Rust does not allow two
- /// enum constants to have the same value, so nix omits `PAGESIZE`.
- PAGE_SIZE = libc::_SC_PAGE_SIZE,
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PTHREAD_DESTRUCTOR_ITERATIONS = libc::_SC_THREAD_DESTRUCTOR_ITERATIONS,
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PTHREAD_KEYS_MAX = libc::_SC_THREAD_KEYS_MAX,
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PTHREAD_STACK_MIN = libc::_SC_THREAD_STACK_MIN,
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- PTHREAD_THREADS_MAX = libc::_SC_THREAD_THREADS_MAX,
- #[cfg(not(target_os = "haiku"))]
- RE_DUP_MAX = libc::_SC_RE_DUP_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- RTSIG_MAX = libc::_SC_RTSIG_MAX,
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SEM_NSEMS_MAX = libc::_SC_SEM_NSEMS_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SEM_VALUE_MAX = libc::_SC_SEM_VALUE_MAX,
- #[cfg(any(target_os = "android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os = "openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SIGQUEUE_MAX = libc::_SC_SIGQUEUE_MAX,
- STREAM_MAX = libc::_SC_STREAM_MAX,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="netbsd",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- SYMLOOP_MAX = libc::_SC_SYMLOOP_MAX,
- #[cfg(not(target_os = "redox"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- TIMER_MAX = libc::_SC_TIMER_MAX,
- TTY_NAME_MAX = libc::_SC_TTY_NAME_MAX,
- TZNAME_MAX = libc::_SC_TZNAME_MAX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the X/Open Encryption Option Group.
- _XOPEN_CRYPT = libc::_SC_XOPEN_CRYPT,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the Issue 4, Version 2 Enhanced
- /// Internationalization Option Group.
- _XOPEN_ENH_I18N = libc::_SC_XOPEN_ENH_I18N,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _XOPEN_LEGACY = libc::_SC_XOPEN_LEGACY,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the X/Open Realtime Option Group.
- _XOPEN_REALTIME = libc::_SC_XOPEN_REALTIME,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the X/Open Realtime Threads Option Group.
- _XOPEN_REALTIME_THREADS = libc::_SC_XOPEN_REALTIME_THREADS,
- /// The implementation supports the Issue 4, Version 2 Shared Memory Option
- /// Group.
- #[cfg(not(any(target_os = "redox", target_os = "haiku")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- _XOPEN_SHM = libc::_SC_XOPEN_SHM,
- #[cfg(any(target_os="dragonfly", target_os="freebsd", target_os = "ios",
- target_os="linux", target_os = "macos", target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the XSI STREAMS Option Group.
- _XOPEN_STREAMS = libc::_SC_XOPEN_STREAMS,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// The implementation supports the XSI option
- _XOPEN_UNIX = libc::_SC_XOPEN_UNIX,
- #[cfg(any(target_os="android", target_os="dragonfly", target_os="freebsd",
- target_os = "ios", target_os="linux", target_os = "macos",
- target_os="openbsd"))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- /// Integer value indicating version of the X/Open Portability Guide to
- /// which the implementation conforms.
- _XOPEN_VERSION = libc::_SC_XOPEN_VERSION,
- /// The number of pages of physical memory. Note that it is possible for
- /// the product of this value to overflow.
- #[cfg(any(target_os="android", target_os="linux"))]
- _PHYS_PAGES = libc::_SC_PHYS_PAGES,
- /// The number of currently available pages of physical memory.
- #[cfg(any(target_os="android", target_os="linux"))]
- _AVPHYS_PAGES = libc::_SC_AVPHYS_PAGES,
- /// The number of processors configured.
- #[cfg(any(target_os="android", target_os="linux"))]
- _NPROCESSORS_CONF = libc::_SC_NPROCESSORS_CONF,
- /// The number of processors currently online (available).
- #[cfg(any(target_os="android", target_os="linux"))]
- _NPROCESSORS_ONLN = libc::_SC_NPROCESSORS_ONLN,
-}
-
-/// Get configurable system variables (see
-/// [sysconf(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html))
-///
-/// Returns the value of a configurable system variable. Most supported
-/// variables also have associated compile-time constants, but POSIX
-/// allows their values to change at runtime. There are generally two types of
-/// sysconf variables: options and limits. See sysconf(3) for more details.
-///
-/// # Returns
-///
-/// - `Ok(Some(x))`: the variable's limit (for limit variables) or its
-/// implementation level (for option variables). Implementation levels are
-/// usually a decimal-coded date, such as 200112 for POSIX 2001.12
-/// - `Ok(None)`: the variable has no limit (for limit variables) or is
-/// unsupported (for option variables)
-/// - `Err(x)`: an error occurred
-pub fn sysconf(var: SysconfVar) -> Result<Option<c_long>> {
- let raw = unsafe {
- Errno::clear();
- libc::sysconf(var as c_int)
- };
- if raw == -1 {
- if errno::errno() == 0 {
- Ok(None)
- } else {
- Err(Errno::last())
- }
- } else {
- Ok(Some(raw))
- }
-}
-}
-
-feature! {
-#![feature = "fs"]
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod pivot_root {
- use crate::{Result, NixPath};
- use crate::errno::Errno;
-
- pub fn pivot_root<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
- new_root: &P1, put_old: &P2) -> Result<()> {
- let res = new_root.with_nix_path(|new_root| {
- put_old.with_nix_path(|put_old| {
- unsafe {
- libc::syscall(libc::SYS_pivot_root, new_root.as_ptr(), put_old.as_ptr())
- }
- })
- })??;
-
- Errno::result(res).map(drop)
- }
-}
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "openbsd"
-))]
-mod setres {
- feature! {
- #![feature = "user"]
-
- use crate::Result;
- use crate::errno::Errno;
- use super::{Uid, Gid};
-
- /// Sets the real, effective, and saved uid.
- /// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html))
- ///
- /// * `ruid`: real user id
- /// * `euid`: effective user id
- /// * `suid`: saved user id
- /// * returns: Ok or libc error code.
- ///
- /// Err is returned if the user doesn't have permission to set this UID.
- #[inline]
- pub fn setresuid(ruid: Uid, euid: Uid, suid: Uid) -> Result<()> {
- let res = unsafe { libc::setresuid(ruid.into(), euid.into(), suid.into()) };
-
- Errno::result(res).map(drop)
- }
-
- /// Sets the real, effective, and saved gid.
- /// ([see setresuid(2)](https://man7.org/linux/man-pages/man2/setresuid.2.html))
- ///
- /// * `rgid`: real group id
- /// * `egid`: effective group id
- /// * `sgid`: saved group id
- /// * returns: Ok or libc error code.
- ///
- /// Err is returned if the user doesn't have permission to set this GID.
- #[inline]
- pub fn setresgid(rgid: Gid, egid: Gid, sgid: Gid) -> Result<()> {
- let res = unsafe { libc::setresgid(rgid.into(), egid.into(), sgid.into()) };
-
- Errno::result(res).map(drop)
- }
- }
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "openbsd"
-))]
-mod getres {
- feature! {
- #![feature = "user"]
-
- use crate::Result;
- use crate::errno::Errno;
- use super::{Uid, Gid};
-
- /// Real, effective and saved user IDs.
- #[derive(Debug, Copy, Clone, Eq, PartialEq)]
- pub struct ResUid {
- pub real: Uid,
- pub effective: Uid,
- pub saved: Uid
- }
-
- /// Real, effective and saved group IDs.
- #[derive(Debug, Copy, Clone, Eq, PartialEq)]
- pub struct ResGid {
- pub real: Gid,
- pub effective: Gid,
- pub saved: Gid
- }
-
- /// Gets the real, effective, and saved user IDs.
- ///
- /// ([see getresuid(2)](http://man7.org/linux/man-pages/man2/getresuid.2.html))
- ///
- /// #Returns
- ///
- /// - `Ok((Uid, Uid, Uid))`: tuple of real, effective and saved uids on success.
- /// - `Err(x)`: libc error code on failure.
- ///
- #[inline]
- pub fn getresuid() -> Result<ResUid> {
- let mut ruid = libc::uid_t::max_value();
- let mut euid = libc::uid_t::max_value();
- let mut suid = libc::uid_t::max_value();
- let res = unsafe { libc::getresuid(&mut ruid, &mut euid, &mut suid) };
-
- Errno::result(res).map(|_| ResUid{ real: Uid(ruid), effective: Uid(euid), saved: Uid(suid) })
- }
-
- /// Gets the real, effective, and saved group IDs.
- ///
- /// ([see getresgid(2)](http://man7.org/linux/man-pages/man2/getresgid.2.html))
- ///
- /// #Returns
- ///
- /// - `Ok((Gid, Gid, Gid))`: tuple of real, effective and saved gids on success.
- /// - `Err(x)`: libc error code on failure.
- ///
- #[inline]
- pub fn getresgid() -> Result<ResGid> {
- let mut rgid = libc::gid_t::max_value();
- let mut egid = libc::gid_t::max_value();
- let mut sgid = libc::gid_t::max_value();
- let res = unsafe { libc::getresgid(&mut rgid, &mut egid, &mut sgid) };
-
- Errno::result(res).map(|_| ResGid { real: Gid(rgid), effective: Gid(egid), saved: Gid(sgid) } )
- }
- }
-}
-
-#[cfg(feature = "fs")]
-libc_bitflags! {
- /// Options for access()
- #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
- pub struct AccessFlags : c_int {
- /// Test for existence of file.
- F_OK;
- /// Test for read permission.
- R_OK;
- /// Test for write permission.
- W_OK;
- /// Test for execute (search) permission.
- X_OK;
- }
-}
-
-feature! {
-#![feature = "fs"]
-
-/// Checks the file named by `path` for accessibility according to the flags given by `amode`
-/// See [access(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)
-pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::access(cstr.as_ptr(), amode.bits)
- }
- })?;
- Errno::result(res).map(drop)
-}
-
-/// Checks the file named by `path` for accessibility according to the flags given by `mode`
-///
-/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
-///
-/// If `dirfd` is `None`, then `path` is relative to the current working directory.
-///
-/// # References
-///
-/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html)
-// redox: does not appear to support the *at family of syscalls.
-#[cfg(not(target_os = "redox"))]
-pub fn faccessat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: &P, mode: AccessFlags, flags: AtFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::faccessat(at_rawfd(dirfd), cstr.as_ptr(), mode.bits(), flags.bits())
- }
- })?;
- Errno::result(res).map(drop)
-}
-
-/// Checks the file named by `path` for accessibility according to the flags given
-/// by `mode` using effective UID, effective GID and supplementary group lists.
-///
-/// # References
-///
-/// * [FreeBSD man page](https://www.freebsd.org/cgi/man.cgi?query=eaccess&sektion=2&n=1)
-/// * [Linux man page](https://man7.org/linux/man-pages/man3/euidaccess.3.html)
-#[cfg(any(
- all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
-pub fn eaccess<P: ?Sized + NixPath>(path: &P, mode: AccessFlags) -> Result<()> {
- let res = path.with_nix_path(|cstr| {
- unsafe {
- libc::eaccess(cstr.as_ptr(), mode.bits)
- }
- })?;
- Errno::result(res).map(drop)
-}
-}
-
-feature! {
-#![feature = "user"]
-
-/// Representation of a User, based on `libc::passwd`
-///
-/// The reason some fields in this struct are `String` and others are `CString` is because some
-/// fields are based on the user's locale, which could be non-UTF8, while other fields are
-/// guaranteed to conform to [`NAME_REGEX`](https://serverfault.com/a/73101/407341), which only
-/// contains ASCII.
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct User {
- /// Username
- pub name: String,
- /// User password (probably hashed)
- pub passwd: CString,
- /// User ID
- pub uid: Uid,
- /// Group ID
- pub gid: Gid,
- /// User information
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
- pub gecos: CString,
- /// Home directory
- pub dir: PathBuf,
- /// Path to shell
- pub shell: PathBuf,
- /// Login class
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub class: CString,
- /// Last password change
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub change: libc::time_t,
- /// Expiration time of account
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- #[cfg_attr(docsrs, doc(cfg(all())))]
- pub expire: libc::time_t
-}
-
-#[cfg(not(target_os = "redox"))] //RedoxFS does not support passwd
-impl From<&libc::passwd> for User {
- fn from(pw: &libc::passwd) -> User {
- unsafe {
- User {
- name: if pw.pw_name.is_null() { Default::default() } else { CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned() },
- passwd: if pw.pw_passwd.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes()).unwrap() },
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
- gecos: if pw.pw_gecos.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes()).unwrap() },
- dir: if pw.pw_dir.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_dir).to_bytes())) },
- shell: if pw.pw_shell.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_shell).to_bytes())) },
- uid: Uid::from_raw(pw.pw_uid),
- gid: Gid::from_raw(pw.pw_gid),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes()).unwrap(),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- change: pw.pw_change,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- expire: pw.pw_expire
- }
- }
- }
-}
-
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
-impl From<User> for libc::passwd {
- fn from(u: User) -> Self {
- let name = match CString::new(u.name) {
- Ok(n) => n.into_raw(),
- Err(_) => CString::new("").unwrap().into_raw(),
- };
- let dir = match u.dir.into_os_string().into_string() {
- Ok(s) => CString::new(s.as_str()).unwrap().into_raw(),
- Err(_) => CString::new("").unwrap().into_raw(),
- };
- let shell = match u.shell.into_os_string().into_string() {
- Ok(s) => CString::new(s.as_str()).unwrap().into_raw(),
- Err(_) => CString::new("").unwrap().into_raw(),
- };
- Self {
- pw_name: name,
- pw_passwd: u.passwd.into_raw(),
- #[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
- pw_gecos: u.gecos.into_raw(),
- pw_dir: dir,
- pw_shell: shell,
- pw_uid: u.uid.0,
- pw_gid: u.gid.0,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- pw_class: u.class.into_raw(),
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- pw_change: u.change,
- #[cfg(not(any(target_os = "android",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos",
- target_os = "linux",
- target_os = "solaris")))]
- pw_expire: u.expire,
- #[cfg(target_os = "illumos")]
- pw_age: CString::new("").unwrap().into_raw(),
- #[cfg(target_os = "illumos")]
- pw_comment: CString::new("").unwrap().into_raw(),
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- pw_fields: 0,
- }
- }
-}
-
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
-impl User {
- fn from_anything<F>(f: F) -> Result<Option<Self>>
- where
- F: Fn(*mut libc::passwd,
- *mut c_char,
- libc::size_t,
- *mut *mut libc::passwd) -> libc::c_int
- {
- let buflimit = 1048576;
- let bufsize = match sysconf(SysconfVar::GETPW_R_SIZE_MAX) {
- Ok(Some(n)) => n as usize,
- Ok(None) | Err(_) => 16384,
- };
-
- let mut cbuf = Vec::with_capacity(bufsize);
- let mut pwd = mem::MaybeUninit::<libc::passwd>::uninit();
- let mut res = ptr::null_mut();
-
- loop {
- let error = f(pwd.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
- if error == 0 {
- if res.is_null() {
- return Ok(None);
- } else {
- let pwd = unsafe { pwd.assume_init() };
- return Ok(Some(User::from(&pwd)));
- }
- } else if Errno::last() == Errno::ERANGE {
- // Trigger the internal buffer resizing logic.
- reserve_double_buffer_size(&mut cbuf, buflimit)?;
- } else {
- return Err(Errno::last());
- }
- }
- }
-
- /// Get a user by UID.
- ///
- /// Internally, this function calls
- /// [getpwuid_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
- ///
- /// # Examples
- ///
- /// ```
- /// use nix::unistd::{Uid, User};
- /// // Returns an Result<Option<User>>, thus the double unwrap.
- /// let res = User::from_uid(Uid::from_raw(0)).unwrap().unwrap();
- /// assert_eq!(res.name, "root");
- /// ```
- pub fn from_uid(uid: Uid) -> Result<Option<Self>> {
- User::from_anything(|pwd, cbuf, cap, res| {
- unsafe { libc::getpwuid_r(uid.0, pwd, cbuf, cap, res) }
- })
- }
-
- /// Get a user by name.
- ///
- /// Internally, this function calls
- /// [getpwnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
- ///
- /// # Examples
- ///
- /// ```
- /// use nix::unistd::User;
- /// // Returns an Result<Option<User>>, thus the double unwrap.
- /// let res = User::from_name("root").unwrap().unwrap();
- /// assert_eq!(res.name, "root");
- /// ```
- pub fn from_name(name: &str) -> Result<Option<Self>> {
- let name = match CString::new(name) {
- Ok(c_str) => c_str,
- Err(_nul_error) => return Ok(None),
- };
- User::from_anything(|pwd, cbuf, cap, res| {
- unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) }
- })
- }
-}
-
-/// Representation of a Group, based on `libc::group`
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Group {
- /// Group name
- pub name: String,
- /// Group password
- pub passwd: CString,
- /// Group ID
- pub gid: Gid,
- /// List of Group members
- pub mem: Vec<String>
-}
-
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
-impl From<&libc::group> for Group {
- fn from(gr: &libc::group) -> Group {
- unsafe {
- Group {
- name: CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned(),
- passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes()).unwrap(),
- gid: Gid::from_raw(gr.gr_gid),
- mem: Group::members(gr.gr_mem)
- }
- }
- }
-}
-
-#[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd
-impl Group {
- unsafe fn members(mem: *mut *mut c_char) -> Vec<String> {
- let mut ret = Vec::new();
-
- for i in 0.. {
- let u = mem.offset(i);
- if (*u).is_null() {
- break;
- } else {
- let s = CStr::from_ptr(*u).to_string_lossy().into_owned();
- ret.push(s);
- }
- }
-
- ret
- }
-
- fn from_anything<F>(f: F) -> Result<Option<Self>>
- where
- F: Fn(*mut libc::group,
- *mut c_char,
- libc::size_t,
- *mut *mut libc::group) -> libc::c_int
- {
- let buflimit = 1048576;
- let bufsize = match sysconf(SysconfVar::GETGR_R_SIZE_MAX) {
- Ok(Some(n)) => n as usize,
- Ok(None) | Err(_) => 16384,
- };
-
- let mut cbuf = Vec::with_capacity(bufsize);
- let mut grp = mem::MaybeUninit::<libc::group>::uninit();
- let mut res = ptr::null_mut();
-
- loop {
- let error = f(grp.as_mut_ptr(), cbuf.as_mut_ptr(), cbuf.capacity(), &mut res);
- if error == 0 {
- if res.is_null() {
- return Ok(None);
- } else {
- let grp = unsafe { grp.assume_init() };
- return Ok(Some(Group::from(&grp)));
- }
- } else if Errno::last() == Errno::ERANGE {
- // Trigger the internal buffer resizing logic.
- reserve_double_buffer_size(&mut cbuf, buflimit)?;
- } else {
- return Err(Errno::last());
- }
- }
- }
-
- /// Get a group by GID.
- ///
- /// Internally, this function calls
- /// [getgrgid_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
- ///
- /// # Examples
- ///
- // Disable this test on all OS except Linux as root group may not exist.
- #[cfg_attr(not(target_os = "linux"), doc = " ```no_run")]
- #[cfg_attr(target_os = "linux", doc = " ```")]
- /// use nix::unistd::{Gid, Group};
- /// // Returns an Result<Option<Group>>, thus the double unwrap.
- /// let res = Group::from_gid(Gid::from_raw(0)).unwrap().unwrap();
- /// assert!(res.name == "root");
- /// ```
- pub fn from_gid(gid: Gid) -> Result<Option<Self>> {
- Group::from_anything(|grp, cbuf, cap, res| {
- unsafe { libc::getgrgid_r(gid.0, grp, cbuf, cap, res) }
- })
- }
-
- /// Get a group by name.
- ///
- /// Internally, this function calls
- /// [getgrnam_r(3)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwuid_r.html)
- ///
- /// # Examples
- ///
- // Disable this test on all OS except Linux as root group may not exist.
- #[cfg_attr(not(target_os = "linux"), doc = " ```no_run")]
- #[cfg_attr(target_os = "linux", doc = " ```")]
- /// use nix::unistd::Group;
- /// // Returns an Result<Option<Group>>, thus the double unwrap.
- /// let res = Group::from_name("root").unwrap().unwrap();
- /// assert!(res.name == "root");
- /// ```
- pub fn from_name(name: &str) -> Result<Option<Self>> {
- let name = match CString::new(name) {
- Ok(c_str) => c_str,
- Err(_nul_error) => return Ok(None),
- };
- Group::from_anything(|grp, cbuf, cap, res| {
- unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) }
- })
- }
-}
-}
-
-feature! {
-#![feature = "term"]
-
-/// Get the name of the terminal device that is open on file descriptor fd
-/// (see [`ttyname(3)`](https://man7.org/linux/man-pages/man3/ttyname.3.html)).
-#[cfg(not(target_os = "fuchsia"))]
-pub fn ttyname(fd: RawFd) -> Result<PathBuf> {
- const PATH_MAX: usize = libc::PATH_MAX as usize;
- let mut buf = vec![0_u8; PATH_MAX];
- let c_buf = buf.as_mut_ptr() as *mut libc::c_char;
-
- let ret = unsafe { libc::ttyname_r(fd, c_buf, buf.len()) };
- if ret != 0 {
- return Err(Errno::from_i32(ret));
- }
-
- let nul = buf.iter().position(|c| *c == b'\0').unwrap();
- buf.truncate(nul);
- Ok(OsString::from_vec(buf).into())
-}
-}
-
-feature! {
-#![all(feature = "socket", feature = "user")]
-
-/// Get the effective user ID and group ID associated with a Unix domain socket.
-///
-/// See also [getpeereid(3)](https://www.freebsd.org/cgi/man.cgi?query=getpeereid)
-#[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "dragonfly",
-))]
-pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> {
- let mut uid = 1;
- let mut gid = 1;
-
- let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) };
-
- Errno::result(ret).map(|_| (Uid(uid), Gid(gid)))
-}
-}
-
-feature! {
-#![all(feature = "fs")]
-
-/// Set the file flags.
-///
-/// See also [chflags(2)](https://www.freebsd.org/cgi/man.cgi?query=chflags&sektion=2)
-#[cfg(any(
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "macos",
- target_os = "ios"
-))]
-pub fn chflags<P: ?Sized + NixPath>(path: &P, flags: FileFlag) -> Result<()> {
- let res = path.with_nix_path(|cstr| unsafe {
- libc::chflags(cstr.as_ptr(), flags.bits())
- })?;
-
- Errno::result(res).map(drop)
-}
-}
diff --git a/vendor/nix/test/common/mod.rs b/vendor/nix/test/common/mod.rs
deleted file mode 100644
index bb056aab8..000000000
--- a/vendor/nix/test/common/mod.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-use cfg_if::cfg_if;
-
-#[macro_export]
-macro_rules! skip {
- ($($reason: expr),+) => {
- use ::std::io::{self, Write};
-
- let stderr = io::stderr();
- let mut handle = stderr.lock();
- writeln!(handle, $($reason),+).unwrap();
- return;
- }
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- #[macro_export] macro_rules! require_capability {
- ($name:expr, $capname:ident) => {
- use ::caps::{Capability, CapSet, has_cap};
-
- if !has_cap(None, CapSet::Effective, Capability::$capname)
- .unwrap()
- {
- skip!("{} requires capability {}. Skipping test.", $name, Capability::$capname);
- }
- }
- }
- } else if #[cfg(not(target_os = "redox"))] {
- #[macro_export] macro_rules! require_capability {
- ($name:expr, $capname:ident) => {}
- }
- }
-}
-
-/// Skip the test if we don't have the ability to mount file systems.
-#[cfg(target_os = "freebsd")]
-#[macro_export]
-macro_rules! require_mount {
- ($name:expr) => {
- use ::sysctl::{CtlValue, Sysctl};
- use nix::unistd::Uid;
-
- let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap();
- if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap()
- {
- skip!(
- "{} requires the ability to mount file systems. Skipping test.",
- $name
- );
- }
- };
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[macro_export]
-macro_rules! skip_if_cirrus {
- ($reason:expr) => {
- if std::env::var_os("CIRRUS_CI").is_some() {
- skip!("{}", $reason);
- }
- };
-}
-
-#[cfg(target_os = "freebsd")]
-#[macro_export]
-macro_rules! skip_if_jailed {
- ($name:expr) => {
- use ::sysctl::{CtlValue, Sysctl};
-
- let ctl = ::sysctl::Ctl::new("security.jail.jailed").unwrap();
- if let CtlValue::Int(1) = ctl.value().unwrap() {
- skip!("{} cannot run in a jail. Skipping test.", $name);
- }
- };
-}
-
-#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
-#[macro_export]
-macro_rules! skip_if_not_root {
- ($name:expr) => {
- use nix::unistd::Uid;
-
- if !Uid::current().is_root() {
- skip!("{} requires root privileges. Skipping test.", $name);
- }
- };
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- #[macro_export] macro_rules! skip_if_seccomp {
- ($name:expr) => {
- if let Ok(s) = std::fs::read_to_string("/proc/self/status") {
- for l in s.lines() {
- let mut fields = l.split_whitespace();
- if fields.next() == Some("Seccomp:") &&
- fields.next() != Some("0")
- {
- skip!("{} cannot be run in Seccomp mode. Skipping test.",
- stringify!($name));
- }
- }
- }
- }
- }
- } else if #[cfg(not(target_os = "redox"))] {
- #[macro_export] macro_rules! skip_if_seccomp {
- ($name:expr) => {}
- }
- }
-}
-
-cfg_if! {
- if #[cfg(target_os = "linux")] {
- #[macro_export] macro_rules! require_kernel_version {
- ($name:expr, $version_requirement:expr) => {
- use semver::{Version, VersionReq};
-
- let version_requirement = VersionReq::parse($version_requirement)
- .expect("Bad match_version provided");
-
- let uname = nix::sys::utsname::uname().unwrap();
- println!("{}", uname.sysname().to_str().unwrap());
- println!("{}", uname.nodename().to_str().unwrap());
- println!("{}", uname.release().to_str().unwrap());
- println!("{}", uname.version().to_str().unwrap());
- println!("{}", uname.machine().to_str().unwrap());
-
- // Fix stuff that the semver parser can't handle
- let fixed_release = &uname.release().to_str().unwrap().to_string()
- // Fedora 33 reports version as 4.18.el8_2.x86_64 or
- // 5.18.200-fc33.x86_64. Remove the underscore.
- .replace("_", "-")
- // Cirrus-CI reports version as 4.19.112+ . Remove the +
- .replace("+", "");
- let mut version = Version::parse(fixed_release).unwrap();
-
- //Keep only numeric parts
- version.pre = semver::Prerelease::EMPTY;
- version.build = semver::BuildMetadata::EMPTY;
-
- if !version_requirement.matches(&version) {
- skip!("Skip {} because kernel version `{}` doesn't match the requirement `{}`",
- stringify!($name), version, version_requirement);
- }
- }
- }
- }
-}
diff --git a/vendor/nix/test/sys/mod.rs b/vendor/nix/test/sys/mod.rs
deleted file mode 100644
index 20312120a..000000000
--- a/vendor/nix/test/sys/mod.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-mod test_signal;
-
-// NOTE: DragonFly lacks a kernel-level implementation of Posix AIO as of
-// this writing. There is an user-level implementation, but whether aio
-// works or not heavily depends on which pthread implementation is chosen
-// by the user at link time. For this reason we do not want to run aio test
-// cases on DragonFly.
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "macos",
- target_os = "netbsd"
-))]
-mod test_aio;
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-mod test_ioctl;
-#[cfg(not(target_os = "redox"))]
-mod test_mman;
-#[cfg(not(target_os = "redox"))]
-mod test_select;
-#[cfg(target_os = "linux")]
-mod test_signalfd;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-mod test_socket;
-#[cfg(not(any(target_os = "redox")))]
-mod test_sockopt;
-mod test_stat;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_sysinfo;
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-mod test_termios;
-mod test_uio;
-mod test_wait;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_epoll;
-#[cfg(target_os = "linux")]
-mod test_inotify;
-mod test_pthread;
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-mod test_ptrace;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_timerfd;
diff --git a/vendor/nix/test/sys/test_aio.rs b/vendor/nix/test/sys/test_aio.rs
deleted file mode 100644
index 84086f80c..000000000
--- a/vendor/nix/test/sys/test_aio.rs
+++ /dev/null
@@ -1,626 +0,0 @@
-use std::{
- io::{Read, Seek, Write},
- ops::Deref,
- os::unix::io::AsRawFd,
- pin::Pin,
- sync::atomic::{AtomicBool, Ordering},
- thread, time,
-};
-
-use libc::c_int;
-use nix::{
- errno::*,
- sys::{
- aio::*,
- signal::{
- sigaction, SaFlags, SigAction, SigHandler, SigSet, SigevNotify,
- Signal,
- },
- time::{TimeSpec, TimeValLike},
- },
-};
-use tempfile::tempfile;
-
-lazy_static! {
- pub static ref SIGNALED: AtomicBool = AtomicBool::new(false);
-}
-
-extern "C" fn sigfunc(_: c_int) {
- SIGNALED.store(true, Ordering::Relaxed);
-}
-
-// Helper that polls an AioCb for completion or error
-macro_rules! poll_aio {
- ($aiocb: expr) => {
- loop {
- let err = $aiocb.as_mut().error();
- if err != Err(Errno::EINPROGRESS) {
- break err;
- };
- thread::sleep(time::Duration::from_millis(10));
- }
- };
-}
-
-mod aio_fsync {
- use super::*;
-
- #[test]
- fn test_accessors() {
- let aiocb = AioFsync::new(
- 1001,
- AioFsyncMode::O_SYNC,
- 42,
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(AioFsyncMode::O_SYNC, aiocb.mode());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- /// `AioFsync::submit` should not modify the `AioCb` object if
- /// `libc::aio_fsync` returns an error
- // Skip on Linux, because Linux's AIO implementation can't detect errors
- // synchronously
- #[test]
- #[cfg(any(target_os = "freebsd", target_os = "macos"))]
- fn error() {
- use std::mem;
-
- const INITIAL: &[u8] = b"abcdef123456";
- // Create an invalid AioFsyncMode
- let mode = unsafe { mem::transmute(666) };
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiof = Box::pin(AioFsync::new(
- f.as_raw_fd(),
- mode,
- 0,
- SigevNotify::SigevNone,
- ));
- let err = aiof.as_mut().submit();
- err.expect_err("assertion failed");
- }
-
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let fd = f.as_raw_fd();
- let mut aiof = Box::pin(AioFsync::new(
- fd,
- AioFsyncMode::O_SYNC,
- 0,
- SigevNotify::SigevNone,
- ));
- aiof.as_mut().submit().unwrap();
- poll_aio!(&mut aiof).unwrap();
- aiof.as_mut().aio_return().unwrap();
- }
-}
-
-mod aio_read {
- use super::*;
-
- #[test]
- fn test_accessors() {
- let mut rbuf = vec![0; 4];
- let aiocb = AioRead::new(
- 1001,
- 2, //offset
- &mut rbuf,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(4, aiocb.nbytes());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- // Tests AioWrite.cancel. We aren't trying to test the OS's implementation,
- // only our bindings. So it's sufficient to check that cancel
- // returned any AioCancelStat value.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn cancel() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let fd = f.as_raw_fd();
- let mut aior =
- Box::pin(AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone));
- aior.as_mut().submit().unwrap();
-
- aior.as_mut().cancel().unwrap();
-
- // Wait for aiow to complete, but don't care whether it succeeded
- let _ = poll_aio!(&mut aior);
- let _ = aior.as_mut().aio_return();
- }
-
- /// `AioRead::submit` should not modify the `AioCb` object if
- /// `libc::aio_read` returns an error
- // Skip on Linux, because Linux's AIO implementation can't detect errors
- // synchronously
- #[test]
- #[cfg(any(target_os = "freebsd", target_os = "macos"))]
- fn error() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aior = Box::pin(AioRead::new(
- f.as_raw_fd(),
- -1, //an invalid offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aior.as_mut().submit().expect_err("assertion failed");
- }
-
- // Test a simple aio operation with no completion notification. We must
- // poll for completion
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- const EXPECT: &[u8] = b"cdef";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- {
- let fd = f.as_raw_fd();
- let mut aior = Box::pin(AioRead::new(
- fd,
- 2,
- &mut rbuf,
- 0,
- SigevNotify::SigevNone,
- ));
- aior.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aior);
- assert_eq!(err, Ok(()));
- assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len());
- }
- assert_eq!(EXPECT, rbuf.deref().deref());
- }
-
- // Like ok, but allocates the structure on the stack.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn on_stack() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf = vec![0; 4];
- const EXPECT: &[u8] = b"cdef";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- {
- let fd = f.as_raw_fd();
- let mut aior =
- AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone);
- let mut aior = unsafe { Pin::new_unchecked(&mut aior) };
- aior.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aior);
- assert_eq!(err, Ok(()));
- assert_eq!(aior.as_mut().aio_return().unwrap(), EXPECT.len());
- }
- assert_eq!(EXPECT, rbuf.deref().deref());
- }
-}
-
-#[cfg(target_os = "freebsd")]
-#[cfg(fbsd14)]
-mod aio_readv {
- use std::io::IoSliceMut;
-
- use super::*;
-
- #[test]
- fn test_accessors() {
- let mut rbuf0 = vec![0; 4];
- let mut rbuf1 = vec![0; 8];
- let mut rbufs =
- [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)];
- let aiocb = AioReadv::new(
- 1001,
- 2, //offset
- &mut rbufs,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(2, aiocb.iovlen());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let mut rbuf0 = vec![0; 4];
- let mut rbuf1 = vec![0; 2];
- let mut rbufs =
- [IoSliceMut::new(&mut rbuf0), IoSliceMut::new(&mut rbuf1)];
- const EXPECT0: &[u8] = b"cdef";
- const EXPECT1: &[u8] = b"12";
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- {
- let fd = f.as_raw_fd();
- let mut aior = Box::pin(AioReadv::new(
- fd,
- 2,
- &mut rbufs,
- 0,
- SigevNotify::SigevNone,
- ));
- aior.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aior);
- assert_eq!(err, Ok(()));
- assert_eq!(
- aior.as_mut().aio_return().unwrap(),
- EXPECT0.len() + EXPECT1.len()
- );
- }
- assert_eq!(&EXPECT0, &rbuf0);
- assert_eq!(&EXPECT1, &rbuf1);
- }
-}
-
-mod aio_write {
- use super::*;
-
- #[test]
- fn test_accessors() {
- let wbuf = vec![0; 4];
- let aiocb = AioWrite::new(
- 1001,
- 2, //offset
- &wbuf,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(4, aiocb.nbytes());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- // Tests AioWrite.cancel. We aren't trying to test the OS's implementation,
- // only our bindings. So it's sufficient to check that cancel
- // returned any AioCancelStat value.
- #[test]
- #[cfg_attr(target_env = "musl", ignore)]
- fn cancel() {
- let wbuf: &[u8] = b"CDEF";
-
- let f = tempfile().unwrap();
- let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 0,
- wbuf,
- 0,
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().unwrap();
- let err = aiow.as_mut().error();
- assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS));
-
- aiow.as_mut().cancel().unwrap();
-
- // Wait for aiow to complete, but don't care whether it succeeded
- let _ = poll_aio!(&mut aiow);
- let _ = aiow.as_mut().aio_return();
- }
-
- // Test a simple aio operation with no completion notification. We must
- // poll for completion.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let wbuf = "CDEF".to_string().into_bytes();
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"abCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2,
- &wbuf,
- 0,
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aiow);
- assert_eq!(err, Ok(()));
- assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len());
-
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
- }
-
- // Like ok, but allocates the structure on the stack.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn on_stack() {
- const INITIAL: &[u8] = b"abcdef123456";
- let wbuf = "CDEF".to_string().into_bytes();
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"abCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- &wbuf,
- 0, //priority
- SigevNotify::SigevNone,
- );
- let mut aiow = unsafe { Pin::new_unchecked(&mut aiow) };
- aiow.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aiow);
- assert_eq!(err, Ok(()));
- assert_eq!(aiow.as_mut().aio_return().unwrap(), wbuf.len());
-
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
- }
-
- /// `AioWrite::write` should not modify the `AioCb` object if
- /// `libc::aio_write` returns an error.
- // Skip on Linux, because Linux's AIO implementation can't detect errors
- // synchronously
- #[test]
- #[cfg(any(target_os = "freebsd", target_os = "macos"))]
- fn error() {
- let wbuf = "CDEF".to_string().into_bytes();
- let mut aiow = Box::pin(AioWrite::new(
- 666, // An invalid file descriptor
- 0, //offset
- &wbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().expect_err("assertion failed");
- // Dropping the AioWrite at this point should not panic
- }
-}
-
-#[cfg(target_os = "freebsd")]
-#[cfg(fbsd14)]
-mod aio_writev {
- use std::io::IoSlice;
-
- use super::*;
-
- #[test]
- fn test_accessors() {
- let wbuf0 = vec![0; 4];
- let wbuf1 = vec![0; 8];
- let wbufs = [IoSlice::new(&wbuf0), IoSlice::new(&wbuf1)];
- let aiocb = AioWritev::new(
- 1001,
- 2, //offset
- &wbufs,
- 42, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 99,
- },
- );
- assert_eq!(1001, aiocb.fd());
- assert_eq!(2, aiocb.iovlen());
- assert_eq!(2, aiocb.offset());
- assert_eq!(42, aiocb.priority());
- let sev = aiocb.sigevent().sigevent();
- assert_eq!(Signal::SIGUSR2 as i32, sev.sigev_signo);
- assert_eq!(99, sev.sigev_value.sival_ptr as i64);
- }
-
- // Test a simple aio operation with no completion notification. We must
- // poll for completion.
- #[test]
- #[cfg_attr(all(target_env = "musl", target_arch = "x86_64"), ignore)]
- fn ok() {
- const INITIAL: &[u8] = b"abcdef123456";
- let wbuf0 = b"BC";
- let wbuf1 = b"DEF";
- let wbufs = [IoSlice::new(wbuf0), IoSlice::new(wbuf1)];
- let wlen = wbuf0.len() + wbuf1.len();
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"aBCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = Box::pin(AioWritev::new(
- f.as_raw_fd(),
- 1,
- &wbufs,
- 0,
- SigevNotify::SigevNone,
- ));
- aiow.as_mut().submit().unwrap();
-
- let err = poll_aio!(&mut aiow);
- assert_eq!(err, Ok(()));
- assert_eq!(aiow.as_mut().aio_return().unwrap(), wlen);
-
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
- }
-}
-
-// Test an aio operation with completion delivered by a signal
-#[test]
-#[cfg_attr(
- any(
- all(target_env = "musl", target_arch = "x86_64"),
- target_arch = "mips",
- target_arch = "mips64"
- ),
- ignore
-)]
-fn sigev_signal() {
- let _m = crate::SIGNAL_MTX.lock();
- let sa = SigAction::new(
- SigHandler::Handler(sigfunc),
- SaFlags::SA_RESETHAND,
- SigSet::empty(),
- );
- SIGNALED.store(false, Ordering::Relaxed);
- unsafe { sigaction(Signal::SIGUSR2, &sa) }.unwrap();
-
- const INITIAL: &[u8] = b"abcdef123456";
- const WBUF: &[u8] = b"CDEF";
- let mut rbuf = Vec::new();
- const EXPECT: &[u8] = b"abCDEF123456";
-
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
- let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- WBUF,
- 0, //priority
- SigevNotify::SigevSignal {
- signal: Signal::SIGUSR2,
- si_value: 0, //TODO: validate in sigfunc
- },
- ));
- aiow.as_mut().submit().unwrap();
- while !SIGNALED.load(Ordering::Relaxed) {
- thread::sleep(time::Duration::from_millis(10));
- }
-
- assert_eq!(aiow.as_mut().aio_return().unwrap(), WBUF.len());
- f.rewind().unwrap();
- let len = f.read_to_end(&mut rbuf).unwrap();
- assert_eq!(len, EXPECT.len());
- assert_eq!(rbuf, EXPECT);
-}
-
-// Tests using aio_cancel_all for all outstanding IOs.
-#[test]
-#[cfg_attr(target_env = "musl", ignore)]
-fn test_aio_cancel_all() {
- let wbuf: &[u8] = b"CDEF";
-
- let f = tempfile().unwrap();
- let mut aiocb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 0, //offset
- wbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aiocb.as_mut().submit().unwrap();
- let err = aiocb.as_mut().error();
- assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS));
-
- aio_cancel_all(f.as_raw_fd()).unwrap();
-
- // Wait for aiocb to complete, but don't care whether it succeeded
- let _ = poll_aio!(&mut aiocb);
- let _ = aiocb.as_mut().aio_return();
-}
-
-#[test]
-// On Cirrus on Linux, this test fails due to a glibc bug.
-// https://github.com/nix-rust/nix/issues/1099
-#[cfg_attr(target_os = "linux", ignore)]
-// On Cirrus, aio_suspend is failing with EINVAL
-// https://github.com/nix-rust/nix/issues/1361
-#[cfg_attr(target_os = "macos", ignore)]
-fn test_aio_suspend() {
- const INITIAL: &[u8] = b"abcdef123456";
- const WBUF: &[u8] = b"CDEFG";
- let timeout = TimeSpec::seconds(10);
- let mut rbuf = vec![0; 4];
- let rlen = rbuf.len();
- let mut f = tempfile().unwrap();
- f.write_all(INITIAL).unwrap();
-
- let mut wcb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- ));
-
- let mut rcb = Box::pin(AioRead::new(
- f.as_raw_fd(),
- 8, //offset
- &mut rbuf,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- wcb.as_mut().submit().unwrap();
- rcb.as_mut().submit().unwrap();
- loop {
- {
- let cbbuf = [
- &*wcb as &dyn AsRef<libc::aiocb>,
- &*rcb as &dyn AsRef<libc::aiocb>,
- ];
- let r = aio_suspend(&cbbuf[..], Some(timeout));
- match r {
- Err(Errno::EINTR) => continue,
- Err(e) => panic!("aio_suspend returned {:?}", e),
- Ok(_) => (),
- };
- }
- if rcb.as_mut().error() != Err(Errno::EINPROGRESS)
- && wcb.as_mut().error() != Err(Errno::EINPROGRESS)
- {
- break;
- }
- }
-
- assert_eq!(wcb.as_mut().aio_return().unwrap(), WBUF.len());
- assert_eq!(rcb.as_mut().aio_return().unwrap(), rlen);
-}
diff --git a/vendor/nix/test/sys/test_aio_drop.rs b/vendor/nix/test/sys/test_aio_drop.rs
deleted file mode 100644
index bbe6623fd..000000000
--- a/vendor/nix/test/sys/test_aio_drop.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Test dropping an AioCb that hasn't yet finished.
-// This must happen in its own process, because on OSX this test seems to hose
-// the AIO subsystem and causes subsequent tests to fail
-#[test]
-#[should_panic(expected = "Dropped an in-progress AioCb")]
-#[cfg(all(
- not(target_env = "musl"),
- not(target_env = "uclibc"),
- any(
- target_os = "linux",
- target_os = "ios",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "netbsd"
- )
-))]
-fn test_drop() {
- use nix::sys::aio::*;
- use nix::sys::signal::*;
- use std::os::unix::io::AsRawFd;
- use tempfile::tempfile;
-
- const WBUF: &[u8] = b"CDEF";
-
- let f = tempfile().unwrap();
- f.set_len(6).unwrap();
- let mut aiocb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
- 2, //offset
- WBUF,
- 0, //priority
- SigevNotify::SigevNone,
- ));
- aiocb.as_mut().submit().unwrap();
-}
diff --git a/vendor/nix/test/sys/test_epoll.rs b/vendor/nix/test/sys/test_epoll.rs
deleted file mode 100644
index 915691595..000000000
--- a/vendor/nix/test/sys/test_epoll.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use nix::errno::Errno;
-use nix::sys::epoll::{epoll_create1, epoll_ctl};
-use nix::sys::epoll::{EpollCreateFlags, EpollEvent, EpollFlags, EpollOp};
-
-#[test]
-pub fn test_epoll_errno() {
- let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
- let result = epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None);
- result.expect_err("assertion failed");
- assert_eq!(result.unwrap_err(), Errno::ENOENT);
-
- let result = epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, None);
- result.expect_err("assertion failed");
- assert_eq!(result.unwrap_err(), Errno::EINVAL);
-}
-
-#[test]
-pub fn test_epoll_ctl() {
- let efd = epoll_create1(EpollCreateFlags::empty()).unwrap();
- let mut event =
- EpollEvent::new(EpollFlags::EPOLLIN | EpollFlags::EPOLLERR, 1);
- epoll_ctl(efd, EpollOp::EpollCtlAdd, 1, &mut event).unwrap();
- epoll_ctl(efd, EpollOp::EpollCtlDel, 1, None).unwrap();
-}
diff --git a/vendor/nix/test/sys/test_inotify.rs b/vendor/nix/test/sys/test_inotify.rs
deleted file mode 100644
index bb5851a90..000000000
--- a/vendor/nix/test/sys/test_inotify.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use nix::errno::Errno;
-use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify};
-use std::ffi::OsString;
-use std::fs::{rename, File};
-
-#[test]
-pub fn test_inotify() {
- let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap();
- let tempdir = tempfile::tempdir().unwrap();
-
- instance
- .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS)
- .unwrap();
-
- let events = instance.read_events();
- assert_eq!(events.unwrap_err(), Errno::EAGAIN);
-
- File::create(tempdir.path().join("test")).unwrap();
-
- let events = instance.read_events().unwrap();
- assert_eq!(events[0].name, Some(OsString::from("test")));
-}
-
-#[test]
-pub fn test_inotify_multi_events() {
- let instance = Inotify::init(InitFlags::IN_NONBLOCK).unwrap();
- let tempdir = tempfile::tempdir().unwrap();
-
- instance
- .add_watch(tempdir.path(), AddWatchFlags::IN_ALL_EVENTS)
- .unwrap();
-
- let events = instance.read_events();
- assert_eq!(events.unwrap_err(), Errno::EAGAIN);
-
- File::create(tempdir.path().join("test")).unwrap();
- rename(tempdir.path().join("test"), tempdir.path().join("test2")).unwrap();
-
- // Now there should be 5 events in queue:
- // - IN_CREATE on test
- // - IN_OPEN on test
- // - IN_CLOSE_WRITE on test
- // - IN_MOVED_FROM on test with a cookie
- // - IN_MOVED_TO on test2 with the same cookie
-
- let events = instance.read_events().unwrap();
- assert_eq!(events.len(), 5);
-
- assert_eq!(events[0].mask, AddWatchFlags::IN_CREATE);
- assert_eq!(events[0].name, Some(OsString::from("test")));
-
- assert_eq!(events[1].mask, AddWatchFlags::IN_OPEN);
- assert_eq!(events[1].name, Some(OsString::from("test")));
-
- assert_eq!(events[2].mask, AddWatchFlags::IN_CLOSE_WRITE);
- assert_eq!(events[2].name, Some(OsString::from("test")));
-
- assert_eq!(events[3].mask, AddWatchFlags::IN_MOVED_FROM);
- assert_eq!(events[3].name, Some(OsString::from("test")));
-
- assert_eq!(events[4].mask, AddWatchFlags::IN_MOVED_TO);
- assert_eq!(events[4].name, Some(OsString::from("test2")));
-
- assert_eq!(events[3].cookie, events[4].cookie);
-}
diff --git a/vendor/nix/test/sys/test_ioctl.rs b/vendor/nix/test/sys/test_ioctl.rs
deleted file mode 100644
index 40f60cfdb..000000000
--- a/vendor/nix/test/sys/test_ioctl.rs
+++ /dev/null
@@ -1,376 +0,0 @@
-#![allow(dead_code)]
-
-// Simple tests to ensure macro generated fns compile
-ioctl_none_bad!(do_bad, 0x1234);
-ioctl_read_bad!(do_bad_read, 0x1234, u16);
-ioctl_write_int_bad!(do_bad_write_int, 0x1234);
-ioctl_write_ptr_bad!(do_bad_write_ptr, 0x1234, u8);
-ioctl_readwrite_bad!(do_bad_readwrite, 0x1234, u32);
-ioctl_none!(do_none, 0, 0);
-ioctl_read!(read_test, 0, 0, u32);
-ioctl_write_int!(write_ptr_int, 0, 0);
-ioctl_write_ptr!(write_ptr_u8, 0, 0, u8);
-ioctl_write_ptr!(write_ptr_u32, 0, 0, u32);
-ioctl_write_ptr!(write_ptr_u64, 0, 0, u64);
-ioctl_readwrite!(readwrite_test, 0, 0, u64);
-ioctl_read_buf!(readbuf_test, 0, 0, u32);
-const SPI_IOC_MAGIC: u8 = b'k';
-const SPI_IOC_MESSAGE: u8 = 0;
-ioctl_write_buf!(writebuf_test_consts, SPI_IOC_MAGIC, SPI_IOC_MESSAGE, u8);
-ioctl_write_buf!(writebuf_test_u8, 0, 0, u8);
-ioctl_write_buf!(writebuf_test_u32, 0, 0, u32);
-ioctl_write_buf!(writebuf_test_u64, 0, 0, u64);
-ioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32);
-
-// See C code for source of values for op calculations (does NOT work for mips/powerpc):
-// https://gist.github.com/posborne/83ea6880770a1aef332e
-//
-// TODO: Need a way to compute these constants at test time. Using precomputed
-// values is fragile and needs to be maintained.
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod linux {
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_none() {
- if cfg!(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64"
- )) {
- assert_eq!(request_code_none!(b'q', 10) as u32, 0x2000_710A);
- assert_eq!(request_code_none!(b'a', 255) as u32, 0x2000_61FF);
- } else {
- assert_eq!(request_code_none!(b'q', 10) as u32, 0x0000_710A);
- assert_eq!(request_code_none!(b'a', 255) as u32, 0x0000_61FF);
- }
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_write() {
- if cfg!(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64"
- )) {
- assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x8001_7A0A);
- assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x8200_7A0A);
- } else {
- assert_eq!(request_code_write!(b'z', 10, 1) as u32, 0x4001_7A0A);
- assert_eq!(request_code_write!(b'z', 10, 512) as u32, 0x4200_7A0A);
- }
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_write_64() {
- if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) {
- assert_eq!(
- request_code_write!(b'z', 10, 1u64 << 32) as u32,
- 0x8000_7A0A
- );
- } else {
- assert_eq!(
- request_code_write!(b'z', 10, 1u64 << 32) as u32,
- 0x4000_7A0A
- );
- }
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_read() {
- if cfg!(any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc",
- target_arch = "powerpc64"
- )) {
- assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x4001_7A0A);
- assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x4200_7A0A);
- } else {
- assert_eq!(request_code_read!(b'z', 10, 1) as u32, 0x8001_7A0A);
- assert_eq!(request_code_read!(b'z', 10, 512) as u32, 0x8200_7A0A);
- }
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_64() {
- if cfg!(any(target_arch = "mips64", target_arch = "powerpc64")) {
- assert_eq!(
- request_code_read!(b'z', 10, 1u64 << 32) as u32,
- 0x4000_7A0A
- );
- } else {
- assert_eq!(
- request_code_read!(b'z', 10, 1u64 << 32) as u32,
- 0x8000_7A0A
- );
- }
- }
-
- // The cast is not unnecessary on all platforms.
- #[allow(clippy::unnecessary_cast)]
- #[test]
- fn test_op_read_write() {
- assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A);
- assert_eq!(request_code_readwrite!(b'z', 10, 512) as u32, 0xC200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_write_64() {
- assert_eq!(
- request_code_readwrite!(b'z', 10, 1u64 << 32) as u32,
- 0xC000_7A0A
- );
- }
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd"
-))]
-mod bsd {
- #[test]
- fn test_op_none() {
- assert_eq!(request_code_none!(b'q', 10), 0x2000_710A);
- assert_eq!(request_code_none!(b'a', 255), 0x2000_61FF);
- }
-
- #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
- #[test]
- fn test_op_write_int() {
- assert_eq!(request_code_write_int!(b'v', 4), 0x2004_7604);
- assert_eq!(request_code_write_int!(b'p', 2), 0x2004_7002);
- }
-
- #[test]
- fn test_op_write() {
- assert_eq!(request_code_write!(b'z', 10, 1), 0x8001_7A0A);
- assert_eq!(request_code_write!(b'z', 10, 512), 0x8200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_write_64() {
- assert_eq!(request_code_write!(b'z', 10, 1u64 << 32), 0x8000_7A0A);
- }
-
- #[test]
- fn test_op_read() {
- assert_eq!(request_code_read!(b'z', 10, 1), 0x4001_7A0A);
- assert_eq!(request_code_read!(b'z', 10, 512), 0x4200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_64() {
- assert_eq!(request_code_read!(b'z', 10, 1u64 << 32), 0x4000_7A0A);
- }
-
- #[test]
- fn test_op_read_write() {
- assert_eq!(request_code_readwrite!(b'z', 10, 1), 0xC001_7A0A);
- assert_eq!(request_code_readwrite!(b'z', 10, 512), 0xC200_7A0A);
- }
-
- #[cfg(target_pointer_width = "64")]
- #[test]
- fn test_op_read_write_64() {
- assert_eq!(request_code_readwrite!(b'z', 10, 1u64 << 32), 0xC000_7A0A);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod linux_ioctls {
- use std::mem;
- use std::os::unix::io::AsRawFd;
-
- use libc::{termios, TCGETS, TCSBRK, TCSETS, TIOCNXCL};
- use tempfile::tempfile;
-
- use nix::errno::Errno;
-
- ioctl_none_bad!(tiocnxcl, TIOCNXCL);
- #[test]
- fn test_ioctl_none_bad() {
- let file = tempfile().unwrap();
- let res = unsafe { tiocnxcl(file.as_raw_fd()) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_read_bad!(tcgets, TCGETS, termios);
- #[test]
- fn test_ioctl_read_bad() {
- let file = tempfile().unwrap();
- let mut termios = unsafe { mem::zeroed() };
- let res = unsafe { tcgets(file.as_raw_fd(), &mut termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_write_int_bad!(tcsbrk, TCSBRK);
- #[test]
- fn test_ioctl_write_int_bad() {
- let file = tempfile().unwrap();
- let res = unsafe { tcsbrk(file.as_raw_fd(), 0) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_write_ptr_bad!(tcsets, TCSETS, termios);
- #[test]
- fn test_ioctl_write_ptr_bad() {
- let file = tempfile().unwrap();
- let termios: termios = unsafe { mem::zeroed() };
- let res = unsafe { tcsets(file.as_raw_fd(), &termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- // FIXME: Find a suitable example for `ioctl_readwrite_bad`
-
- // From linux/videodev2.h
- ioctl_none!(log_status, b'V', 70);
- #[test]
- fn test_ioctl_none() {
- let file = tempfile().unwrap();
- let res = unsafe { log_status(file.as_raw_fd()) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- #[repr(C)]
- pub struct v4l2_audio {
- index: u32,
- name: [u8; 32],
- capability: u32,
- mode: u32,
- reserved: [u32; 2],
- }
-
- // From linux/videodev2.h
- ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
- #[test]
- fn test_ioctl_write_ptr() {
- let file = tempfile().unwrap();
- let data: v4l2_audio = unsafe { mem::zeroed() };
- let res = unsafe { s_audio(file.as_raw_fd(), &data) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // From linux/net/bluetooth/hci_sock.h
- const HCI_IOC_MAGIC: u8 = b'H';
- const HCI_IOC_HCIDEVUP: u8 = 201;
- ioctl_write_int!(hcidevup, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
- #[test]
- fn test_ioctl_write_int() {
- let file = tempfile().unwrap();
- let res = unsafe { hcidevup(file.as_raw_fd(), 0) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // From linux/videodev2.h
- ioctl_read!(g_audio, b'V', 33, v4l2_audio);
- #[test]
- fn test_ioctl_read() {
- let file = tempfile().unwrap();
- let mut data: v4l2_audio = unsafe { mem::zeroed() };
- let res = unsafe { g_audio(file.as_raw_fd(), &mut data) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // From linux/videodev2.h
- ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
- #[test]
- fn test_ioctl_readwrite() {
- let file = tempfile().unwrap();
- let mut data: v4l2_audio = unsafe { mem::zeroed() };
- let res = unsafe { enum_audio(file.as_raw_fd(), &mut data) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // FIXME: Find a suitable example for `ioctl_read_buf`.
-
- #[repr(C)]
- pub struct spi_ioc_transfer {
- tx_buf: u64,
- rx_buf: u64,
- len: u32,
- speed_hz: u32,
- delay_usecs: u16,
- bits_per_word: u8,
- cs_change: u8,
- tx_nbits: u8,
- rx_nbits: u8,
- pad: u16,
- }
-
- // From linux/spi/spidev.h
- ioctl_write_buf!(
- spi_ioc_message,
- super::SPI_IOC_MAGIC,
- super::SPI_IOC_MESSAGE,
- spi_ioc_transfer
- );
- #[test]
- fn test_ioctl_write_buf() {
- let file = tempfile().unwrap();
- let data: [spi_ioc_transfer; 4] = unsafe { mem::zeroed() };
- let res = unsafe { spi_ioc_message(file.as_raw_fd(), &data[..]) };
- assert!(res == Err(Errno::ENOTTY) || res == Err(Errno::ENOSYS));
- }
-
- // FIXME: Find a suitable example for `ioctl_readwrite_buf`.
-}
-
-#[cfg(target_os = "freebsd")]
-mod freebsd_ioctls {
- use std::mem;
- use std::os::unix::io::AsRawFd;
-
- use libc::termios;
- use tempfile::tempfile;
-
- use nix::errno::Errno;
-
- // From sys/sys/ttycom.h
- const TTY_IOC_MAGIC: u8 = b't';
- const TTY_IOC_TYPE_NXCL: u8 = 14;
- const TTY_IOC_TYPE_GETA: u8 = 19;
- const TTY_IOC_TYPE_SETA: u8 = 20;
-
- ioctl_none!(tiocnxcl, TTY_IOC_MAGIC, TTY_IOC_TYPE_NXCL);
- #[test]
- fn test_ioctl_none() {
- let file = tempfile().unwrap();
- let res = unsafe { tiocnxcl(file.as_raw_fd()) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_read!(tiocgeta, TTY_IOC_MAGIC, TTY_IOC_TYPE_GETA, termios);
- #[test]
- fn test_ioctl_read() {
- let file = tempfile().unwrap();
- let mut termios = unsafe { mem::zeroed() };
- let res = unsafe { tiocgeta(file.as_raw_fd(), &mut termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-
- ioctl_write_ptr!(tiocseta, TTY_IOC_MAGIC, TTY_IOC_TYPE_SETA, termios);
- #[test]
- fn test_ioctl_write_ptr() {
- let file = tempfile().unwrap();
- let termios: termios = unsafe { mem::zeroed() };
- let res = unsafe { tiocseta(file.as_raw_fd(), &termios) };
- assert_eq!(res, Err(Errno::ENOTTY));
- }
-}
diff --git a/vendor/nix/test/sys/test_mman.rs b/vendor/nix/test/sys/test_mman.rs
deleted file mode 100644
index e748427bc..000000000
--- a/vendor/nix/test/sys/test_mman.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use nix::sys::mman::{mmap, MapFlags, ProtFlags};
-use std::num::NonZeroUsize;
-
-#[test]
-fn test_mmap_anonymous() {
- unsafe {
- let ptr = mmap(
- None,
- NonZeroUsize::new(1).unwrap(),
- ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
- MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS,
- -1,
- 0,
- )
- .unwrap() as *mut u8;
- assert_eq!(*ptr, 0x00u8);
- *ptr = 0xffu8;
- assert_eq!(*ptr, 0xffu8);
- }
-}
-
-#[test]
-#[cfg(any(target_os = "linux", target_os = "netbsd"))]
-fn test_mremap_grow() {
- use nix::libc::{c_void, size_t};
- use nix::sys::mman::{mremap, MRemapFlags};
-
- const ONE_K: size_t = 1024;
- let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
-
- let slice: &mut [u8] = unsafe {
- let mem = mmap(
- None,
- one_k_non_zero,
- ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
- MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
- -1,
- 0,
- )
- .unwrap();
- std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
- };
- assert_eq!(slice[ONE_K - 1], 0x00);
- slice[ONE_K - 1] = 0xFF;
- assert_eq!(slice[ONE_K - 1], 0xFF);
-
- let slice: &mut [u8] = unsafe {
- #[cfg(target_os = "linux")]
- let mem = mremap(
- slice.as_mut_ptr() as *mut c_void,
- ONE_K,
- 10 * ONE_K,
- MRemapFlags::MREMAP_MAYMOVE,
- None,
- )
- .unwrap();
- #[cfg(target_os = "netbsd")]
- let mem = mremap(
- slice.as_mut_ptr() as *mut c_void,
- ONE_K,
- 10 * ONE_K,
- MRemapFlags::MAP_REMAPDUP,
- None,
- )
- .unwrap();
- std::slice::from_raw_parts_mut(mem as *mut u8, 10 * ONE_K)
- };
-
- // The first KB should still have the old data in it.
- assert_eq!(slice[ONE_K - 1], 0xFF);
-
- // The additional range should be zero-init'd and accessible.
- assert_eq!(slice[10 * ONE_K - 1], 0x00);
- slice[10 * ONE_K - 1] = 0xFF;
- assert_eq!(slice[10 * ONE_K - 1], 0xFF);
-}
-
-#[test]
-#[cfg(any(target_os = "linux", target_os = "netbsd"))]
-// Segfaults for unknown reasons under QEMU for 32-bit targets
-#[cfg_attr(all(target_pointer_width = "32", qemu), ignore)]
-fn test_mremap_shrink() {
- use nix::libc::{c_void, size_t};
- use nix::sys::mman::{mremap, MRemapFlags};
- use std::num::NonZeroUsize;
-
- const ONE_K: size_t = 1024;
- let ten_one_k = NonZeroUsize::new(10 * ONE_K).unwrap();
- let slice: &mut [u8] = unsafe {
- let mem = mmap(
- None,
- ten_one_k,
- ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
- MapFlags::MAP_ANONYMOUS | MapFlags::MAP_PRIVATE,
- -1,
- 0,
- )
- .unwrap();
- std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
- };
- assert_eq!(slice[ONE_K - 1], 0x00);
- slice[ONE_K - 1] = 0xFF;
- assert_eq!(slice[ONE_K - 1], 0xFF);
-
- let slice: &mut [u8] = unsafe {
- let mem = mremap(
- slice.as_mut_ptr() as *mut c_void,
- ten_one_k.into(),
- ONE_K,
- MRemapFlags::empty(),
- None,
- )
- .unwrap();
- // Since we didn't supply MREMAP_MAYMOVE, the address should be the
- // same.
- assert_eq!(mem, slice.as_mut_ptr() as *mut c_void);
- std::slice::from_raw_parts_mut(mem as *mut u8, ONE_K)
- };
-
- // The first KB should still be accessible and have the old data in it.
- assert_eq!(slice[ONE_K - 1], 0xFF);
-}
diff --git a/vendor/nix/test/sys/test_pthread.rs b/vendor/nix/test/sys/test_pthread.rs
deleted file mode 100644
index ce048bae6..000000000
--- a/vendor/nix/test/sys/test_pthread.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use nix::sys::pthread::*;
-
-#[cfg(any(target_env = "musl", target_os = "redox"))]
-#[test]
-fn test_pthread_self() {
- let tid = pthread_self();
- assert!(!tid.is_null());
-}
-
-#[cfg(not(any(target_env = "musl", target_os = "redox")))]
-#[test]
-fn test_pthread_self() {
- let tid = pthread_self();
- assert_ne!(tid, 0);
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_pthread_kill_none() {
- pthread_kill(pthread_self(), None)
- .expect("Should be able to send signal to my thread.");
-}
diff --git a/vendor/nix/test/sys/test_ptrace.rs b/vendor/nix/test/sys/test_ptrace.rs
deleted file mode 100644
index 530560fe1..000000000
--- a/vendor/nix/test/sys/test_ptrace.rs
+++ /dev/null
@@ -1,275 +0,0 @@
-#[cfg(all(
- target_os = "linux",
- any(target_arch = "x86_64", target_arch = "x86"),
- target_env = "gnu"
-))]
-use memoffset::offset_of;
-use nix::errno::Errno;
-use nix::sys::ptrace;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use nix::sys::ptrace::Options;
-use nix::unistd::getpid;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use std::mem;
-
-use crate::*;
-
-#[test]
-fn test_ptrace() {
- // Just make sure ptrace can be called at all, for now.
- // FIXME: qemu-user doesn't implement ptrace on all arches, so permit ENOSYS
- require_capability!("test_ptrace", CAP_SYS_PTRACE);
- let err = ptrace::attach(getpid()).unwrap_err();
- assert!(
- err == Errno::EPERM || err == Errno::EINVAL || err == Errno::ENOSYS
- );
-}
-
-// Just make sure ptrace_setoptions can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_setoptions() {
- require_capability!("test_ptrace_setoptions", CAP_SYS_PTRACE);
- let err = ptrace::setoptions(getpid(), Options::PTRACE_O_TRACESYSGOOD)
- .unwrap_err();
- assert_ne!(err, Errno::EOPNOTSUPP);
-}
-
-// Just make sure ptrace_getevent can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_getevent() {
- require_capability!("test_ptrace_getevent", CAP_SYS_PTRACE);
- let err = ptrace::getevent(getpid()).unwrap_err();
- assert_ne!(err, Errno::EOPNOTSUPP);
-}
-
-// Just make sure ptrace_getsiginfo can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_getsiginfo() {
- require_capability!("test_ptrace_getsiginfo", CAP_SYS_PTRACE);
- if let Err(Errno::EOPNOTSUPP) = ptrace::getsiginfo(getpid()) {
- panic!("ptrace_getsiginfo returns Errno::EOPNOTSUPP!");
- }
-}
-
-// Just make sure ptrace_setsiginfo can be called at all, for now.
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptrace_setsiginfo() {
- require_capability!("test_ptrace_setsiginfo", CAP_SYS_PTRACE);
- let siginfo = unsafe { mem::zeroed() };
- if let Err(Errno::EOPNOTSUPP) = ptrace::setsiginfo(getpid(), &siginfo) {
- panic!("ptrace_setsiginfo returns Errno::EOPNOTSUPP!");
- }
-}
-
-#[test]
-fn test_ptrace_cont() {
- use nix::sys::ptrace;
- use nix::sys::signal::{raise, Signal};
- use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus};
- use nix::unistd::fork;
- use nix::unistd::ForkResult::*;
-
- require_capability!("test_ptrace_cont", CAP_SYS_PTRACE);
-
- let _m = crate::FORK_MTX.lock();
-
- // FIXME: qemu-user doesn't implement ptrace on all architectures
- // and returns ENOSYS in this case.
- // We (ab)use this behavior to detect the affected platforms
- // and skip the test then.
- // On valid platforms the ptrace call should return Errno::EPERM, this
- // is already tested by `test_ptrace`.
- let err = ptrace::attach(getpid()).unwrap_err();
- if err == Errno::ENOSYS {
- return;
- }
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- ptrace::traceme().unwrap();
- // As recommended by ptrace(2), raise SIGTRAP to pause the child
- // until the parent is ready to continue
- loop {
- raise(Signal::SIGTRAP).unwrap();
- }
- }
- Parent { child } => {
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGTRAP))
- );
- ptrace::cont(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGTRAP))
- );
- ptrace::cont(child, Some(Signal::SIGKILL)).unwrap();
- match waitpid(child, None) {
- Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _))
- if pid == child =>
- {
- // FIXME It's been observed on some systems (apple) the
- // tracee may not be killed but remain as a zombie process
- // affecting other wait based tests. Add an extra kill just
- // to make sure there are no zombies.
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() {
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- }
- }
- _ => panic!("The process should have been killed"),
- }
- }
- }
-}
-
-#[cfg(target_os = "linux")]
-#[test]
-fn test_ptrace_interrupt() {
- use nix::sys::ptrace;
- use nix::sys::signal::Signal;
- use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus};
- use nix::unistd::fork;
- use nix::unistd::ForkResult::*;
- use std::thread::sleep;
- use std::time::Duration;
-
- require_capability!("test_ptrace_interrupt", CAP_SYS_PTRACE);
-
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => loop {
- sleep(Duration::from_millis(1000));
- },
- Parent { child } => {
- ptrace::seize(child, ptrace::Options::PTRACE_O_TRACESYSGOOD)
- .unwrap();
- ptrace::interrupt(child).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceEvent(child, Signal::SIGTRAP, 128))
- );
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceSyscall(child))
- );
- ptrace::detach(child, Some(Signal::SIGKILL)).unwrap();
- match waitpid(child, None) {
- Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _))
- if pid == child =>
- {
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- while ptrace::cont(child, Some(Signal::SIGKILL)).is_ok() {
- let _ = waitpid(child, Some(WaitPidFlag::WNOHANG));
- }
- }
- _ => panic!("The process should have been killed"),
- }
- }
- }
-}
-
-// ptrace::{setoptions, getregs} are only available in these platforms
-#[cfg(all(
- target_os = "linux",
- any(target_arch = "x86_64", target_arch = "x86"),
- target_env = "gnu"
-))]
-#[test]
-fn test_ptrace_syscall() {
- use nix::sys::ptrace;
- use nix::sys::signal::kill;
- use nix::sys::signal::Signal;
- use nix::sys::wait::{waitpid, WaitStatus};
- use nix::unistd::fork;
- use nix::unistd::getpid;
- use nix::unistd::ForkResult::*;
-
- require_capability!("test_ptrace_syscall", CAP_SYS_PTRACE);
-
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- ptrace::traceme().unwrap();
- // first sigstop until parent is ready to continue
- let pid = getpid();
- kill(pid, Signal::SIGSTOP).unwrap();
- kill(pid, Signal::SIGTERM).unwrap();
- unsafe {
- ::libc::_exit(0);
- }
- }
-
- Parent { child } => {
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGSTOP))
- );
-
- // set this option to recognize syscall-stops
- ptrace::setoptions(child, ptrace::Options::PTRACE_O_TRACESYSGOOD)
- .unwrap();
-
- #[cfg(target_arch = "x86_64")]
- let get_syscall_id =
- || ptrace::getregs(child).unwrap().orig_rax as libc::c_long;
-
- #[cfg(target_arch = "x86")]
- let get_syscall_id =
- || ptrace::getregs(child).unwrap().orig_eax as libc::c_long;
-
- // this duplicates `get_syscall_id` for the purpose of testing `ptrace::read_user`.
- #[cfg(target_arch = "x86_64")]
- let rax_offset = offset_of!(libc::user_regs_struct, orig_rax);
- #[cfg(target_arch = "x86")]
- let rax_offset = offset_of!(libc::user_regs_struct, orig_eax);
-
- let get_syscall_from_user_area = || {
- // Find the offset of `user.regs.rax` (or `user.regs.eax` for x86)
- let rax_offset = offset_of!(libc::user, regs) + rax_offset;
- ptrace::read_user(child, rax_offset as _).unwrap()
- as libc::c_long
- };
-
- // kill entry
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceSyscall(child))
- );
- assert_eq!(get_syscall_id(), ::libc::SYS_kill);
- assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill);
-
- // kill exit
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceSyscall(child))
- );
- assert_eq!(get_syscall_id(), ::libc::SYS_kill);
- assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill);
-
- // receive signal
- ptrace::syscall(child, None).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, Signal::SIGTERM))
- );
-
- // inject signal
- ptrace::syscall(child, Signal::SIGTERM).unwrap();
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Signaled(child, Signal::SIGTERM, false))
- );
- }
- }
-}
diff --git a/vendor/nix/test/sys/test_select.rs b/vendor/nix/test/sys/test_select.rs
deleted file mode 100644
index 40bda4d90..000000000
--- a/vendor/nix/test/sys/test_select.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-use nix::sys::select::*;
-use nix::sys::signal::SigSet;
-use nix::sys::time::{TimeSpec, TimeValLike};
-use nix::unistd::{pipe, write};
-
-#[test]
-pub fn test_pselect() {
- let _mtx = crate::SIGNAL_MTX.lock();
-
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let timeout = TimeSpec::seconds(10);
- let sigmask = SigSet::empty();
- assert_eq!(
- 1,
- pselect(None, &mut fd_set, None, None, &timeout, &sigmask).unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
-}
-
-#[test]
-pub fn test_pselect_nfds2() {
- let (r1, w1) = pipe().unwrap();
- write(w1, b"hi!").unwrap();
- let (r2, _w2) = pipe().unwrap();
-
- let mut fd_set = FdSet::new();
- fd_set.insert(r1);
- fd_set.insert(r2);
-
- let timeout = TimeSpec::seconds(10);
- assert_eq!(
- 1,
- pselect(
- ::std::cmp::max(r1, r2) + 1,
- &mut fd_set,
- None,
- None,
- &timeout,
- None
- )
- .unwrap()
- );
- assert!(fd_set.contains(r1));
- assert!(!fd_set.contains(r2));
-}
-
-macro_rules! generate_fdset_bad_fd_tests {
- ($fd:expr, $($method:ident),* $(,)?) => {
- $(
- #[test]
- #[should_panic]
- fn $method() {
- FdSet::new().$method($fd);
- }
- )*
- }
-}
-
-mod test_fdset_negative_fd {
- use super::*;
- generate_fdset_bad_fd_tests!(-1, insert, remove, contains);
-}
-
-mod test_fdset_too_large_fd {
- use super::*;
- use std::convert::TryInto;
- generate_fdset_bad_fd_tests!(
- FD_SETSIZE.try_into().unwrap(),
- insert,
- remove,
- contains,
- );
-}
diff --git a/vendor/nix/test/sys/test_signal.rs b/vendor/nix/test/sys/test_signal.rs
deleted file mode 100644
index 3ad14f40c..000000000
--- a/vendor/nix/test/sys/test_signal.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-#[cfg(not(target_os = "redox"))]
-use nix::errno::Errno;
-use nix::sys::signal::*;
-use nix::unistd::*;
-use std::convert::TryFrom;
-use std::sync::atomic::{AtomicBool, Ordering};
-
-#[test]
-fn test_kill_none() {
- kill(getpid(), None).expect("Should be able to send signal to myself.");
-}
-
-#[test]
-#[cfg(not(target_os = "fuchsia"))]
-fn test_killpg_none() {
- killpg(getpgrp(), None)
- .expect("Should be able to send signal to my process group.");
-}
-
-#[test]
-fn test_old_sigaction_flags() {
- let _m = crate::SIGNAL_MTX.lock();
-
- extern "C" fn handler(_: ::libc::c_int) {}
- let act = SigAction::new(
- SigHandler::Handler(handler),
- SaFlags::empty(),
- SigSet::empty(),
- );
- let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
- let _flags = oact.flags();
- let oact = unsafe { sigaction(SIGINT, &act) }.unwrap();
- let _flags = oact.flags();
-}
-
-#[test]
-fn test_sigprocmask_noop() {
- sigprocmask(SigmaskHow::SIG_BLOCK, None, None)
- .expect("this should be an effective noop");
-}
-
-#[test]
-fn test_sigprocmask() {
- let _m = crate::SIGNAL_MTX.lock();
-
- // This needs to be a signal that rust doesn't use in the test harness.
- const SIGNAL: Signal = Signal::SIGCHLD;
-
- let mut old_signal_set = SigSet::empty();
- sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
- .expect("expect to be able to retrieve old signals");
-
- // Make sure the old set doesn't contain the signal, otherwise the following
- // test don't make sense.
- assert!(
- !old_signal_set.contains(SIGNAL),
- "the {:?} signal is already blocked, please change to a \
- different one",
- SIGNAL
- );
-
- // Now block the signal.
- let mut signal_set = SigSet::empty();
- signal_set.add(SIGNAL);
- sigprocmask(SigmaskHow::SIG_BLOCK, Some(&signal_set), None)
- .expect("expect to be able to block signals");
-
- // And test it again, to make sure the change was effective.
- old_signal_set.clear();
- sigprocmask(SigmaskHow::SIG_BLOCK, None, Some(&mut old_signal_set))
- .expect("expect to be able to retrieve old signals");
- assert!(
- old_signal_set.contains(SIGNAL),
- "expected the {:?} to be blocked",
- SIGNAL
- );
-
- // Reset the signal.
- sigprocmask(SigmaskHow::SIG_UNBLOCK, Some(&signal_set), None)
- .expect("expect to be able to block signals");
-}
-
-lazy_static! {
- static ref SIGNALED: AtomicBool = AtomicBool::new(false);
-}
-
-extern "C" fn test_sigaction_handler(signal: libc::c_int) {
- let signal = Signal::try_from(signal).unwrap();
- SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
-}
-
-#[cfg(not(target_os = "redox"))]
-extern "C" fn test_sigaction_action(
- _: libc::c_int,
- _: *mut libc::siginfo_t,
- _: *mut libc::c_void,
-) {
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_signal_sigaction() {
- let _m = crate::SIGNAL_MTX.lock();
-
- let action_handler = SigHandler::SigAction(test_sigaction_action);
- assert_eq!(
- unsafe { signal(Signal::SIGINT, action_handler) }.unwrap_err(),
- Errno::ENOTSUP
- );
-}
-
-#[test]
-fn test_signal() {
- let _m = crate::SIGNAL_MTX.lock();
-
- unsafe { signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
- raise(Signal::SIGINT).unwrap();
- assert_eq!(
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
- SigHandler::SigIgn
- );
-
- let handler = SigHandler::Handler(test_sigaction_handler);
- assert_eq!(
- unsafe { signal(Signal::SIGINT, handler) }.unwrap(),
- SigHandler::SigDfl
- );
- raise(Signal::SIGINT).unwrap();
- assert!(SIGNALED.load(Ordering::Relaxed));
-
- #[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
- assert_eq!(
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
- handler
- );
-
- // System V based OSes (e.g. illumos and Solaris) always resets the
- // disposition to SIG_DFL prior to calling the signal handler
- #[cfg(any(target_os = "illumos", target_os = "solaris"))]
- assert_eq!(
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap(),
- SigHandler::SigDfl
- );
-
- // Restore default signal handler
- unsafe { signal(Signal::SIGINT, SigHandler::SigDfl) }.unwrap();
-}
diff --git a/vendor/nix/test/sys/test_signalfd.rs b/vendor/nix/test/sys/test_signalfd.rs
deleted file mode 100644
index 87153c957..000000000
--- a/vendor/nix/test/sys/test_signalfd.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use std::convert::TryFrom;
-
-#[test]
-fn test_signalfd() {
- use nix::sys::signal::{self, raise, SigSet, Signal};
- use nix::sys::signalfd::SignalFd;
-
- // Grab the mutex for altering signals so we don't interfere with other tests.
- let _m = crate::SIGNAL_MTX.lock();
-
- // Block the SIGUSR1 signal from automatic processing for this thread
- let mut mask = SigSet::empty();
- mask.add(signal::SIGUSR1);
- mask.thread_block().unwrap();
-
- let mut fd = SignalFd::new(&mask).unwrap();
-
- // Send a SIGUSR1 signal to the current process. Note that this uses `raise` instead of `kill`
- // because `kill` with `getpid` isn't correct during multi-threaded execution like during a
- // cargo test session. Instead use `raise` which does the correct thing by default.
- raise(signal::SIGUSR1).expect("Error: raise(SIGUSR1) failed");
-
- // And now catch that same signal.
- let res = fd.read_signal().unwrap().unwrap();
- let signo = Signal::try_from(res.ssi_signo as i32).unwrap();
- assert_eq!(signo, signal::SIGUSR1);
-}
diff --git a/vendor/nix/test/sys/test_socket.rs b/vendor/nix/test/sys/test_socket.rs
deleted file mode 100644
index 5adc77ed6..000000000
--- a/vendor/nix/test/sys/test_socket.rs
+++ /dev/null
@@ -1,2628 +0,0 @@
-#[cfg(any(target_os = "linux", target_os = "android"))]
-use crate::*;
-use libc::{c_char, sockaddr_storage};
-#[allow(deprecated)]
-use nix::sys::socket::InetAddr;
-use nix::sys::socket::{
- getsockname, sockaddr, sockaddr_in6, AddressFamily, UnixAddr,
-};
-use std::collections::hash_map::DefaultHasher;
-use std::hash::{Hash, Hasher};
-use std::mem::{self, MaybeUninit};
-use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
-use std::os::unix::io::RawFd;
-use std::path::Path;
-use std::slice;
-use std::str::FromStr;
-
-#[allow(deprecated)]
-#[test]
-pub fn test_inetv4_addr_to_sock_addr() {
- let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
- let addr = InetAddr::from_std(&actual);
-
- match addr {
- InetAddr::V4(addr) => {
- let ip: u32 = 0x7f00_0001;
- let port: u16 = 3000;
- let saddr = addr.sin_addr.s_addr;
-
- assert_eq!(saddr, ip.to_be());
- assert_eq!(addr.sin_port, port.to_be());
- }
- _ => panic!("nope"),
- }
-
- assert_eq!(addr.to_string(), "127.0.0.1:3000");
-
- let inet = addr.to_std();
- assert_eq!(actual, inet);
-}
-
-#[allow(deprecated)]
-#[test]
-pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() {
- use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr};
-
- let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
- let addr = InetAddr::from_std(&actual);
- let sockaddr = SockAddr::new_inet(addr);
-
- let (storage, ffi_size) = {
- let mut storage = MaybeUninit::<sockaddr_storage>::zeroed();
- let storage_ptr = storage.as_mut_ptr().cast::<sockaddr>();
- let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
- assert_eq!(mem::size_of::<sockaddr>(), ffi_size as usize);
- unsafe {
- storage_ptr.copy_from_nonoverlapping(ffi_ptr as *const sockaddr, 1);
- (storage.assume_init(), ffi_size)
- }
- };
-
- let from_storage =
- sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap();
- assert_eq!(from_storage, sockaddr);
- let from_storage =
- sockaddr_storage_to_addr(&storage, mem::size_of::<sockaddr_storage>())
- .unwrap();
- assert_eq!(from_storage, sockaddr);
-}
-
-#[cfg(any(target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_timestamping() {
- use nix::sys::socket::{
- recvmsg, sendmsg, setsockopt, socket, sockopt::Timestamping,
- ControlMessageOwned, MsgFlags, SockFlag, SockType, SockaddrIn,
- TimestampingFlag,
- };
- use std::io::{IoSlice, IoSliceMut};
-
- let sock_addr = SockaddrIn::from_str("127.0.0.1:6790").unwrap();
-
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- nix::sys::socket::bind(rsock, &sock_addr).unwrap();
-
- setsockopt(rsock, Timestamping, &TimestampingFlag::all()).unwrap();
-
- let sbuf = [0u8; 2048];
- let mut rbuf = [0u8; 2048];
- let flags = MsgFlags::empty();
- let iov1 = [IoSlice::new(&sbuf)];
- let mut iov2 = [IoSliceMut::new(&mut rbuf)];
-
- let mut cmsg = cmsg_space!(nix::sys::socket::Timestamps);
- sendmsg(ssock, &iov1, &[], flags, Some(&sock_addr)).unwrap();
- let recv = recvmsg::<()>(rsock, &mut iov2, Some(&mut cmsg), flags).unwrap();
-
- let mut ts = None;
- for c in recv.cmsgs() {
- if let ControlMessageOwned::ScmTimestampsns(timestamps) = c {
- ts = Some(timestamps.system);
- }
- }
- let ts = ts.expect("ScmTimestampns is present");
- let sys_time =
- ::nix::time::clock_gettime(::nix::time::ClockId::CLOCK_REALTIME)
- .unwrap();
- let diff = if ts > sys_time {
- ts - sys_time
- } else {
- sys_time - ts
- };
- assert!(std::time::Duration::from(diff).as_secs() < 60);
-}
-
-#[allow(deprecated)]
-#[test]
-pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() {
- use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr};
-
- let port: u16 = 3000;
- let flowinfo: u32 = 1;
- let scope_id: u32 = 2;
- let ip: Ipv6Addr = "fe80::1".parse().unwrap();
-
- let actual =
- SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id));
- let addr = InetAddr::from_std(&actual);
- let sockaddr = SockAddr::new_inet(addr);
-
- let (storage, ffi_size) = {
- let mut storage = MaybeUninit::<sockaddr_storage>::zeroed();
- let storage_ptr = storage.as_mut_ptr().cast::<sockaddr_in6>();
- let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
- assert_eq!(mem::size_of::<sockaddr_in6>(), ffi_size as usize);
- unsafe {
- storage_ptr.copy_from_nonoverlapping(
- (ffi_ptr as *const sockaddr).cast::<sockaddr_in6>(),
- 1,
- );
- (storage.assume_init(), ffi_size)
- }
- };
-
- let from_storage =
- sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap();
- assert_eq!(from_storage, sockaddr);
- let from_storage =
- sockaddr_storage_to_addr(&storage, mem::size_of::<sockaddr_storage>())
- .unwrap();
- assert_eq!(from_storage, sockaddr);
-}
-
-#[test]
-pub fn test_path_to_sock_addr() {
- let path = "/foo/bar";
- let actual = Path::new(path);
- let addr = UnixAddr::new(actual).unwrap();
-
- let expect: &[c_char] = unsafe {
- slice::from_raw_parts(path.as_ptr() as *const c_char, path.len())
- };
- assert_eq!(unsafe { &(*addr.as_ptr()).sun_path[..8] }, expect);
-
- assert_eq!(addr.path(), Some(actual));
-}
-
-fn calculate_hash<T: Hash>(t: &T) -> u64 {
- let mut s = DefaultHasher::new();
- t.hash(&mut s);
- s.finish()
-}
-
-#[test]
-pub fn test_addr_equality_path() {
- let path = "/foo/bar";
- let actual = Path::new(path);
- let addr1 = UnixAddr::new(actual).unwrap();
- let mut addr2 = addr1;
-
- unsafe { (*addr2.as_mut_ptr()).sun_path[10] = 127 };
-
- assert_eq!(addr1, addr2);
- assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_abstract_sun_path_too_long() {
- let name = String::from("nix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0tesnix\0abstract\0testttttnix\0abstract\0test\0make\0sure\0this\0is\0long\0enough");
- let addr = UnixAddr::new_abstract(name.as_bytes());
- addr.expect_err("assertion failed");
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_addr_equality_abstract() {
- let name = String::from("nix\0abstract\0test");
- let addr1 = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let mut addr2 = addr1;
-
- assert_eq!(addr1, addr2);
- assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
-
- unsafe { (*addr2.as_mut_ptr()).sun_path[17] = 127 };
- assert_ne!(addr1, addr2);
- assert_ne!(calculate_hash(&addr1), calculate_hash(&addr2));
-}
-
-// Test getting/setting abstract addresses (without unix socket creation)
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_abstract_uds_addr() {
- let empty = String::new();
- let addr = UnixAddr::new_abstract(empty.as_bytes()).unwrap();
- let sun_path: [u8; 0] = [];
- assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
-
- let name = String::from("nix\0abstract\0test");
- let addr = UnixAddr::new_abstract(name.as_bytes()).unwrap();
- let sun_path = [
- 110u8, 105, 120, 0, 97, 98, 115, 116, 114, 97, 99, 116, 0, 116, 101,
- 115, 116,
- ];
- assert_eq!(addr.as_abstract(), Some(&sun_path[..]));
- assert_eq!(addr.path(), None);
-
- // Internally, name is null-prefixed (abstract namespace)
- assert_eq!(unsafe { (*addr.as_ptr()).sun_path[0] }, 0);
-}
-
-// Test getting an unnamed address (without unix socket creation)
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_unnamed_uds_addr() {
- use crate::nix::sys::socket::SockaddrLike;
-
- let addr = UnixAddr::new_unnamed();
-
- assert!(addr.is_unnamed());
- assert_eq!(addr.len(), 2);
- assert!(addr.path().is_none());
- assert_eq!(addr.path_len(), 0);
-
- assert!(addr.as_abstract().is_none());
-}
-
-#[test]
-pub fn test_getsockname() {
- use nix::sys::socket::bind;
- use nix::sys::socket::{socket, AddressFamily, SockFlag, SockType};
-
- let tempdir = tempfile::tempdir().unwrap();
- let sockname = tempdir.path().join("sock");
- let sock = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
- let sockaddr = UnixAddr::new(&sockname).unwrap();
- bind(sock, &sockaddr).expect("bind failed");
- assert_eq!(sockaddr, getsockname(sock).expect("getsockname failed"));
-}
-
-#[test]
-pub fn test_socketpair() {
- use nix::sys::socket::{socketpair, AddressFamily, SockFlag, SockType};
- use nix::unistd::{read, write};
-
- let (fd1, fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- write(fd1, b"hello").unwrap();
- let mut buf = [0; 5];
- read(fd2, &mut buf).unwrap();
-
- assert_eq!(&buf[..], b"hello");
-}
-
-#[test]
-pub fn test_std_conversions() {
- use nix::sys::socket::*;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
- assert_eq!(std_sa, sock_addr.into());
-
- let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap();
- let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa);
- assert_eq!(std_sa, sock_addr.into());
-}
-
-mod recvfrom {
- use super::*;
- use nix::sys::socket::*;
- use nix::{errno::Errno, Result};
- use std::thread;
-
- const MSG: &[u8] = b"Hello, World!";
-
- fn sendrecv<Fs, Fr>(
- rsock: RawFd,
- ssock: RawFd,
- f_send: Fs,
- mut f_recv: Fr,
- ) -> Option<SockaddrStorage>
- where
- Fs: Fn(RawFd, &[u8], MsgFlags) -> Result<usize> + Send + 'static,
- Fr: FnMut(usize, Option<SockaddrStorage>),
- {
- let mut buf: [u8; 13] = [0u8; 13];
- let mut l = 0;
- let mut from = None;
-
- let send_thread = thread::spawn(move || {
- let mut l = 0;
- while l < std::mem::size_of_val(MSG) {
- l += f_send(ssock, &MSG[l..], MsgFlags::empty()).unwrap();
- }
- });
-
- while l < std::mem::size_of_val(MSG) {
- let (len, from_) = recvfrom(rsock, &mut buf[l..]).unwrap();
- f_recv(len, from_);
- from = from_;
- l += len;
- }
- assert_eq!(&buf, MSG);
- send_thread.join().unwrap();
- from
- }
-
- #[test]
- pub fn stream() {
- let (fd2, fd1) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- // Ignore from for stream sockets
- let _ = sendrecv(fd1, fd2, send, |_, _| {});
- }
-
- #[test]
- pub fn udp() {
- let std_sa = SocketAddrV4::from_str("127.0.0.1:6789").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- let from = sendrecv(
- rsock,
- ssock,
- move |s, m, flags| sendto(s, m, &sock_addr, flags),
- |_, _| {},
- );
- // UDP sockets should set the from address
- assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap());
- }
-
- #[cfg(target_os = "linux")]
- mod udp_offload {
- use super::*;
- use nix::sys::socket::sockopt::{UdpGroSegment, UdpGsoSegment};
- use std::io::IoSlice;
-
- #[test]
- // Disable the test under emulation because it fails in Cirrus-CI. Lack
- // of QEMU support is suspected.
- #[cfg_attr(qemu, ignore)]
- pub fn gso() {
- require_kernel_version!(udp_offload::gso, ">= 4.18");
-
- // In this test, we send the data and provide a GSO segment size.
- // Since we are sending the buffer of size 13, six UDP packets
- // with size 2 and two UDP packet with size 1 will be sent.
- let segment_size: u16 = 2;
-
- let sock_addr = SockaddrIn::new(127, 0, 0, 1, 6791);
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- setsockopt(rsock, UdpGsoSegment, &(segment_size as _))
- .expect("setsockopt UDP_SEGMENT failed");
-
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let mut num_packets_received: i32 = 0;
-
- sendrecv(
- rsock,
- ssock,
- move |s, m, flags| {
- let iov = [IoSlice::new(m)];
- let cmsg = ControlMessage::UdpGsoSegments(&segment_size);
- sendmsg(s, &iov, &[cmsg], flags, Some(&sock_addr))
- },
- {
- let num_packets_received_ref = &mut num_packets_received;
-
- move |len, _| {
- // check that we receive UDP packets with payload size
- // less or equal to segment size
- assert!(len <= segment_size as usize);
- *num_packets_received_ref += 1;
- }
- },
- );
-
- // Buffer size is 13, we will receive six packets of size 2,
- // and one packet of size 1.
- assert_eq!(7, num_packets_received);
- }
-
- #[test]
- // Disable the test on emulated platforms because it fails in Cirrus-CI.
- // Lack of QEMU support is suspected.
- #[cfg_attr(qemu, ignore)]
- pub fn gro() {
- require_kernel_version!(udp_offload::gro, ">= 5.3");
-
- // It's hard to guarantee receiving GRO packets. Just checking
- // that `setsockopt` doesn't fail with error
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- setsockopt(rsock, UdpGroSegment, &true)
- .expect("setsockopt UDP_GRO failed");
- }
- }
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- ))]
- #[test]
- pub fn udp_sendmmsg() {
- use std::io::IoSlice;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:6793").unwrap();
- let std_sa2 = SocketAddrV4::from_str("127.0.0.1:6794").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
- let sock_addr2 = SockaddrIn::from(std_sa2);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let from = sendrecv(
- rsock,
- ssock,
- move |s, m, flags| {
- let batch_size = 15;
- let mut iovs = Vec::with_capacity(1 + batch_size);
- let mut addrs = Vec::with_capacity(1 + batch_size);
- let mut data = MultiHeaders::preallocate(1 + batch_size, None);
- let iov = IoSlice::new(m);
- // first chunk:
- iovs.push([iov]);
- addrs.push(Some(sock_addr));
-
- for _ in 0..batch_size {
- iovs.push([iov]);
- addrs.push(Some(sock_addr2));
- }
-
- let res = sendmmsg(s, &mut data, &iovs, addrs, [], flags)?;
- let mut sent_messages = 0;
- let mut sent_bytes = 0;
- for item in res {
- sent_messages += 1;
- sent_bytes += item.bytes;
- }
- //
- assert_eq!(sent_messages, iovs.len());
- assert_eq!(sent_bytes, sent_messages * m.len());
- Ok(sent_messages)
- },
- |_, _| {},
- );
- // UDP sockets should set the from address
- assert_eq!(AddressFamily::Inet, from.unwrap().family().unwrap());
- }
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- ))]
- #[test]
- pub fn udp_recvmmsg() {
- use nix::sys::socket::{recvmmsg, MsgFlags};
- use std::io::IoSliceMut;
-
- const NUM_MESSAGES_SENT: usize = 2;
- const DATA: [u8; 2] = [1, 2];
-
- let inet_addr = SocketAddrV4::from_str("127.0.0.1:6798").unwrap();
- let sock_addr = SockaddrIn::from(inet_addr);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let send_thread = thread::spawn(move || {
- for _ in 0..NUM_MESSAGES_SENT {
- sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty())
- .unwrap();
- }
- });
-
- let mut msgs = std::collections::LinkedList::new();
-
- // Buffers to receive exactly `NUM_MESSAGES_SENT` messages
- let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT];
- msgs.extend(
- receive_buffers
- .iter_mut()
- .map(|buf| [IoSliceMut::new(&mut buf[..])]),
- );
-
- let mut data =
- MultiHeaders::<SockaddrIn>::preallocate(msgs.len(), None);
-
- let res: Vec<RecvMsg<SockaddrIn>> =
- recvmmsg(rsock, &mut data, msgs.iter(), MsgFlags::empty(), None)
- .expect("recvmmsg")
- .collect();
- assert_eq!(res.len(), DATA.len());
-
- for RecvMsg { address, bytes, .. } in res.into_iter() {
- assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap());
- assert_eq!(DATA.len(), bytes);
- }
-
- for buf in &receive_buffers {
- assert_eq!(&buf[..DATA.len()], DATA);
- }
-
- send_thread.join().unwrap();
- }
-
- #[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "freebsd",
- target_os = "netbsd",
- ))]
- #[test]
- pub fn udp_recvmmsg_dontwait_short_read() {
- use nix::sys::socket::{recvmmsg, MsgFlags};
- use std::io::IoSliceMut;
-
- const NUM_MESSAGES_SENT: usize = 2;
- const DATA: [u8; 4] = [1, 2, 3, 4];
-
- let inet_addr = SocketAddrV4::from_str("127.0.0.1:6799").unwrap();
- let sock_addr = SockaddrIn::from(inet_addr);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let send_thread = thread::spawn(move || {
- for _ in 0..NUM_MESSAGES_SENT {
- sendto(ssock, &DATA[..], &sock_addr, MsgFlags::empty())
- .unwrap();
- }
- });
- // Ensure we've sent all the messages before continuing so `recvmmsg`
- // will return right away
- send_thread.join().unwrap();
-
- let mut msgs = std::collections::LinkedList::new();
-
- // Buffers to receive >`NUM_MESSAGES_SENT` messages to ensure `recvmmsg`
- // will return when there are fewer than requested messages in the
- // kernel buffers when using `MSG_DONTWAIT`.
- let mut receive_buffers = [[0u8; 32]; NUM_MESSAGES_SENT + 2];
- msgs.extend(
- receive_buffers
- .iter_mut()
- .map(|buf| [IoSliceMut::new(&mut buf[..])]),
- );
-
- let mut data = MultiHeaders::<SockaddrIn>::preallocate(
- NUM_MESSAGES_SENT + 2,
- None,
- );
-
- let res: Vec<RecvMsg<SockaddrIn>> = recvmmsg(
- rsock,
- &mut data,
- msgs.iter(),
- MsgFlags::MSG_DONTWAIT,
- None,
- )
- .expect("recvmmsg")
- .collect();
- assert_eq!(res.len(), NUM_MESSAGES_SENT);
-
- for RecvMsg { address, bytes, .. } in res.into_iter() {
- assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap());
- assert_eq!(DATA.len(), bytes);
- }
-
- for buf in &receive_buffers[..NUM_MESSAGES_SENT] {
- assert_eq!(&buf[..DATA.len()], DATA);
- }
- }
-
- #[test]
- pub fn udp_inet6() {
- let addr = std::net::Ipv6Addr::from_str("::1").unwrap();
- let rport = 6789;
- let rstd_sa = SocketAddrV6::new(addr, rport, 0, 0);
- let raddr = SockaddrIn6::from(rstd_sa);
- let sport = 6790;
- let sstd_sa = SocketAddrV6::new(addr, sport, 0, 0);
- let saddr = SockaddrIn6::from(sstd_sa);
- let rsock = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- match bind(rsock, &raddr) {
- Err(Errno::EADDRNOTAVAIL) => {
- println!("IPv6 not available, skipping test.");
- return;
- }
- Err(e) => panic!("bind: {}", e),
- Ok(()) => (),
- }
- let ssock = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- bind(ssock, &saddr).unwrap();
- let from = sendrecv(
- rsock,
- ssock,
- move |s, m, flags| sendto(s, m, &raddr, flags),
- |_, _| {},
- );
- assert_eq!(AddressFamily::Inet6, from.unwrap().family().unwrap());
- let osent_addr = from.unwrap();
- let sent_addr = osent_addr.as_sockaddr_in6().unwrap();
- assert_eq!(sent_addr.ip(), addr);
- assert_eq!(sent_addr.port(), sport);
- }
-}
-
-// Test error handling of our recvmsg wrapper
-#[test]
-pub fn test_recvmsg_ebadf() {
- use nix::errno::Errno;
- use nix::sys::socket::{recvmsg, MsgFlags};
- use std::io::IoSliceMut;
-
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
-
- let fd = -1; // Bad file descriptor
- let r = recvmsg::<()>(fd, &mut iov, None, MsgFlags::empty());
-
- assert_eq!(r.err().unwrap(), Errno::EBADF);
-}
-
-// Disable the test on emulated platforms due to a bug in QEMU versions <
-// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_scm_rights() {
- use nix::sys::socket::{
- recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
- ControlMessageOwned, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::{close, pipe, read, write};
- use std::io::{IoSlice, IoSliceMut};
-
- let (fd1, fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let (r, w) = pipe().unwrap();
- let mut received_r: Option<RawFd> = None;
-
- {
- let iov = [IoSlice::new(b"hello")];
- let fds = [r];
- let cmsg = ControlMessage::ScmRights(&fds);
- assert_eq!(
- sendmsg::<()>(fd1, &iov, &[cmsg], MsgFlags::empty(), None).unwrap(),
- 5
- );
- close(r).unwrap();
- close(fd1).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
-
- let mut iov = [IoSliceMut::new(&mut buf[..])];
- let mut cmsgspace = cmsg_space!([RawFd; 1]);
- let msg = recvmsg::<()>(
- fd2,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::empty(),
- )
- .unwrap();
-
- for cmsg in msg.cmsgs() {
- if let ControlMessageOwned::ScmRights(fd) = cmsg {
- assert_eq!(received_r, None);
- assert_eq!(fd.len(), 1);
- received_r = Some(fd[0]);
- } else {
- panic!("unexpected cmsg");
- }
- }
- assert_eq!(msg.bytes, 5);
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- close(fd2).unwrap();
- }
-
- let received_r = received_r.expect("Did not receive passed fd");
- // Ensure that the received file descriptor works
- write(w, b"world").unwrap();
- let mut buf = [0u8; 5];
- read(received_r, &mut buf).unwrap();
- assert_eq!(&buf[..], b"world");
- close(received_r).unwrap();
- close(w).unwrap();
-}
-
-// Disable the test on emulated platforms due to not enabled support of AF_ALG in QEMU from rust cross
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_af_alg_cipher() {
- use nix::sys::socket::sockopt::AlgSetKey;
- use nix::sys::socket::{
- accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr,
- ControlMessage, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::read;
- use std::io::IoSlice;
-
- skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
- // Travis's seccomp profile blocks AF_ALG
- // https://docs.docker.com/engine/security/seccomp/
- skip_if_seccomp!(test_af_alg_cipher);
-
- let alg_type = "skcipher";
- let alg_name = "ctr-aes-aesni";
- // 256-bits secret key
- let key = vec![0u8; 32];
- // 16-bytes IV
- let iv_len = 16;
- let iv = vec![1u8; iv_len];
- // 256-bytes plain payload
- let payload_len = 256;
- let payload = vec![2u8; payload_len];
-
- let sock = socket(
- AddressFamily::Alg,
- SockType::SeqPacket,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sockaddr = AlgAddr::new(alg_type, alg_name);
- bind(sock, &sockaddr).expect("bind failed");
-
- assert_eq!(sockaddr.alg_name().to_string_lossy(), alg_name);
- assert_eq!(sockaddr.alg_type().to_string_lossy(), alg_type);
-
- setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt");
- let session_socket = accept(sock).expect("accept failed");
-
- let msgs = [
- ControlMessage::AlgSetOp(&libc::ALG_OP_ENCRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ];
- let iov = IoSlice::new(&payload);
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg encrypt");
-
- // allocate buffer for encrypted data
- let mut encrypted = vec![0u8; payload_len];
- let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
- assert_eq!(num_bytes, payload_len);
-
- let iov = IoSlice::new(&encrypted);
-
- let iv = vec![1u8; iv_len];
-
- let msgs = [
- ControlMessage::AlgSetOp(&libc::ALG_OP_DECRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ];
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg decrypt");
-
- // allocate buffer for decrypted data
- let mut decrypted = vec![0u8; payload_len];
- let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt");
-
- assert_eq!(num_bytes, payload_len);
- assert_eq!(decrypted, payload);
-}
-
-// Disable the test on emulated platforms due to not enabled support of AF_ALG
-// in QEMU from rust cross
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_af_alg_aead() {
- use libc::{ALG_OP_DECRYPT, ALG_OP_ENCRYPT};
- use nix::fcntl::{fcntl, FcntlArg, OFlag};
- use nix::sys::socket::sockopt::{AlgSetAeadAuthSize, AlgSetKey};
- use nix::sys::socket::{
- accept, bind, sendmsg, setsockopt, socket, AddressFamily, AlgAddr,
- ControlMessage, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::{close, read};
- use std::io::IoSlice;
-
- skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1352");
- // Travis's seccomp profile blocks AF_ALG
- // https://docs.docker.com/engine/security/seccomp/
- skip_if_seccomp!(test_af_alg_aead);
-
- let auth_size = 4usize;
- let assoc_size = 16u32;
-
- let alg_type = "aead";
- let alg_name = "gcm(aes)";
- // 256-bits secret key
- let key = vec![0u8; 32];
- // 12-bytes IV
- let iv_len = 12;
- let iv = vec![1u8; iv_len];
- // 256-bytes plain payload
- let payload_len = 256;
- let mut payload =
- vec![2u8; payload_len + (assoc_size as usize) + auth_size];
-
- for i in 0..assoc_size {
- payload[i as usize] = 10;
- }
-
- let len = payload.len();
-
- for i in 0..auth_size {
- payload[len - 1 - i] = 0;
- }
-
- let sock = socket(
- AddressFamily::Alg,
- SockType::SeqPacket,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sockaddr = AlgAddr::new(alg_type, alg_name);
- bind(sock, &sockaddr).expect("bind failed");
-
- setsockopt(sock, AlgSetAeadAuthSize, &auth_size)
- .expect("setsockopt AlgSetAeadAuthSize");
- setsockopt(sock, AlgSetKey::default(), &key).expect("setsockopt AlgSetKey");
- let session_socket = accept(sock).expect("accept failed");
-
- let msgs = [
- ControlMessage::AlgSetOp(&ALG_OP_ENCRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ControlMessage::AlgSetAeadAssoclen(&assoc_size),
- ];
-
- let iov = IoSlice::new(&payload);
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg encrypt");
-
- // allocate buffer for encrypted data
- let mut encrypted =
- vec![0u8; (assoc_size as usize) + payload_len + auth_size];
- let num_bytes = read(session_socket, &mut encrypted).expect("read encrypt");
- assert_eq!(num_bytes, payload_len + auth_size + (assoc_size as usize));
- close(session_socket).expect("close");
-
- for i in 0..assoc_size {
- encrypted[i as usize] = 10;
- }
-
- let iov = IoSlice::new(&encrypted);
-
- let iv = vec![1u8; iv_len];
-
- let session_socket = accept(sock).expect("accept failed");
-
- let msgs = [
- ControlMessage::AlgSetOp(&ALG_OP_DECRYPT),
- ControlMessage::AlgSetIv(iv.as_slice()),
- ControlMessage::AlgSetAeadAssoclen(&assoc_size),
- ];
- sendmsg::<()>(session_socket, &[iov], &msgs, MsgFlags::empty(), None)
- .expect("sendmsg decrypt");
-
- // allocate buffer for decrypted data
- let mut decrypted =
- vec![0u8; payload_len + (assoc_size as usize) + auth_size];
- // Starting with kernel 4.9, the interface changed slightly such that the
- // authentication tag memory is only needed in the output buffer for encryption
- // and in the input buffer for decryption.
- // Do not block on read, as we may have fewer bytes than buffer size
- fcntl(session_socket, FcntlArg::F_SETFL(OFlag::O_NONBLOCK))
- .expect("fcntl non_blocking");
- let num_bytes = read(session_socket, &mut decrypted).expect("read decrypt");
-
- assert!(num_bytes >= payload_len + (assoc_size as usize));
- assert_eq!(
- decrypted[(assoc_size as usize)..(payload_len + (assoc_size as usize))],
- payload[(assoc_size as usize)..payload_len + (assoc_size as usize)]
- );
-}
-
-// Verify `ControlMessage::Ipv4PacketInfo` for `sendmsg`.
-// This creates a (udp) socket bound to localhost, then sends a message to
-// itself but uses Ipv4PacketInfo to force the source address to be localhost.
-//
-// This would be a more interesting test if we could assume that the test host
-// has more than one IP address (since we could select a different address to
-// test from).
-#[cfg(any(target_os = "linux", target_os = "macos", target_os = "netbsd"))]
-#[test]
-pub fn test_sendmsg_ipv4packetinfo() {
- use cfg_if::cfg_if;
- use nix::sys::socket::{
- bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
- SockFlag, SockType, SockaddrIn,
- };
- use std::io::IoSlice;
-
- let sock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sock_addr = SockaddrIn::new(127, 0, 0, 1, 4000);
-
- bind(sock, &sock_addr).expect("bind failed");
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- cfg_if! {
- if #[cfg(target_os = "netbsd")] {
- let pi = libc::in_pktinfo {
- ipi_ifindex: 0, /* Unspecified interface */
- ipi_addr: libc::in_addr { s_addr: 0 },
- };
- } else {
- let pi = libc::in_pktinfo {
- ipi_ifindex: 0, /* Unspecified interface */
- ipi_addr: libc::in_addr { s_addr: 0 },
- ipi_spec_dst: sock_addr.as_ref().sin_addr,
- };
- }
- }
-
- let cmsg = [ControlMessage::Ipv4PacketInfo(&pi)];
-
- sendmsg(sock, &iov, &cmsg, MsgFlags::empty(), Some(&sock_addr))
- .expect("sendmsg");
-}
-
-// Verify `ControlMessage::Ipv6PacketInfo` for `sendmsg`.
-// This creates a (udp) socket bound to ip6-localhost, then sends a message to
-// itself but uses Ipv6PacketInfo to force the source address to be
-// ip6-localhost.
-//
-// This would be a more interesting test if we could assume that the test host
-// has more than one IP address (since we could select a different address to
-// test from).
-#[cfg(any(
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "freebsd"
-))]
-#[test]
-pub fn test_sendmsg_ipv6packetinfo() {
- use nix::errno::Errno;
- use nix::sys::socket::{
- bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
- SockFlag, SockType, SockaddrIn6,
- };
- use std::io::IoSlice;
-
- let sock = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let std_sa = SocketAddrV6::from_str("[::1]:6000").unwrap();
- let sock_addr: SockaddrIn6 = SockaddrIn6::from(std_sa);
-
- if let Err(Errno::EADDRNOTAVAIL) = bind(sock, &sock_addr) {
- println!("IPv6 not available, skipping test.");
- return;
- }
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let pi = libc::in6_pktinfo {
- ipi6_ifindex: 0, /* Unspecified interface */
- ipi6_addr: sock_addr.as_ref().sin6_addr,
- };
-
- let cmsg = [ControlMessage::Ipv6PacketInfo(&pi)];
-
- sendmsg::<SockaddrIn6>(
- sock,
- &iov,
- &cmsg,
- MsgFlags::empty(),
- Some(&sock_addr),
- )
- .expect("sendmsg");
-}
-
-// Verify that ControlMessage::Ipv4SendSrcAddr works for sendmsg. This
-// creates a UDP socket bound to all local interfaces (0.0.0.0). It then
-// sends message to itself at 127.0.0.1 while explicitly specifying
-// 127.0.0.1 as the source address through an Ipv4SendSrcAddr
-// (IP_SENDSRCADDR) control message.
-//
-// Note that binding to 0.0.0.0 is *required* on FreeBSD; sendmsg
-// returns EINVAL otherwise. (See FreeBSD's ip(4) man page.)
-#[cfg(any(
- target_os = "netbsd",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "dragonfly",
-))]
-#[test]
-pub fn test_sendmsg_ipv4sendsrcaddr() {
- use nix::sys::socket::{
- bind, sendmsg, socket, AddressFamily, ControlMessage, MsgFlags,
- SockFlag, SockType, SockaddrIn,
- };
- use std::io::IoSlice;
-
- let sock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let unspec_sock_addr = SockaddrIn::new(0, 0, 0, 0, 0);
- bind(sock, &unspec_sock_addr).expect("bind failed");
- let bound_sock_addr: SockaddrIn = getsockname(sock).unwrap();
- let localhost_sock_addr: SockaddrIn =
- SockaddrIn::new(127, 0, 0, 1, bound_sock_addr.port());
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
- let cmsg = [ControlMessage::Ipv4SendSrcAddr(
- &localhost_sock_addr.as_ref().sin_addr,
- )];
-
- sendmsg(
- sock,
- &iov,
- &cmsg,
- MsgFlags::empty(),
- Some(&localhost_sock_addr),
- )
- .expect("sendmsg");
-}
-
-/// Tests that passing multiple fds using a single `ControlMessage` works.
-// Disable the test on emulated platforms due to a bug in QEMU versions <
-// 2.12.0. https://bugs.launchpad.net/qemu/+bug/1701808
-#[cfg_attr(qemu, ignore)]
-#[test]
-fn test_scm_rights_single_cmsg_multiple_fds() {
- use nix::sys::socket::{
- recvmsg, sendmsg, ControlMessage, ControlMessageOwned, MsgFlags,
- };
- use std::io::{IoSlice, IoSliceMut};
- use std::os::unix::io::{AsRawFd, RawFd};
- use std::os::unix::net::UnixDatagram;
- use std::thread;
-
- let (send, receive) = UnixDatagram::pair().unwrap();
- let thread = thread::spawn(move || {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
-
- let mut space = cmsg_space!([RawFd; 2]);
- let msg = recvmsg::<()>(
- receive.as_raw_fd(),
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .unwrap();
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
-
- let mut cmsgs = msg.cmsgs();
- match cmsgs.next() {
- Some(ControlMessageOwned::ScmRights(fds)) => {
- assert_eq!(
- fds.len(),
- 2,
- "unexpected fd count (expected 2 fds, got {})",
- fds.len()
- );
- }
- _ => panic!(),
- }
- assert!(cmsgs.next().is_none(), "unexpected control msg");
-
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- });
-
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
- let fds = [libc::STDIN_FILENO, libc::STDOUT_FILENO]; // pass stdin and stdout
- let cmsg = [ControlMessage::ScmRights(&fds)];
- sendmsg::<()>(send.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None)
- .unwrap();
- thread.join().unwrap();
-}
-
-// Verify `sendmsg` builds a valid `msghdr` when passing an empty
-// `cmsgs` argument. This should result in a msghdr with a nullptr
-// msg_control field and a msg_controllen of 0 when calling into the
-// raw `sendmsg`.
-#[test]
-pub fn test_sendmsg_empty_cmsgs() {
- use nix::sys::socket::{
- recvmsg, sendmsg, socketpair, AddressFamily, MsgFlags, SockFlag,
- SockType,
- };
- use nix::unistd::close;
- use std::io::{IoSlice, IoSliceMut};
-
- let (fd1, fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
-
- {
- let iov = [IoSlice::new(b"hello")];
- assert_eq!(
- sendmsg::<()>(fd1, &iov, &[], MsgFlags::empty(), None).unwrap(),
- 5
- );
- close(fd1).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
-
- let mut cmsgspace = cmsg_space!([RawFd; 1]);
- let msg = recvmsg::<()>(
- fd2,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::empty(),
- )
- .unwrap();
-
- for _ in msg.cmsgs() {
- panic!("unexpected cmsg");
- }
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.bytes, 5);
- close(fd2).unwrap();
- }
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "linux",
- target_os = "freebsd",
- target_os = "dragonfly",
-))]
-#[test]
-fn test_scm_credentials() {
- use nix::sys::socket::{
- recvmsg, sendmsg, socketpair, AddressFamily, ControlMessage,
- ControlMessageOwned, MsgFlags, SockFlag, SockType, UnixCredentials,
- };
- #[cfg(any(target_os = "android", target_os = "linux"))]
- use nix::sys::socket::{setsockopt, sockopt::PassCred};
- use nix::unistd::{close, getgid, getpid, getuid};
- use std::io::{IoSlice, IoSliceMut};
-
- let (send, recv) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- #[cfg(any(target_os = "android", target_os = "linux"))]
- setsockopt(recv, PassCred, &true).unwrap();
-
- {
- let iov = [IoSlice::new(b"hello")];
- #[cfg(any(target_os = "android", target_os = "linux"))]
- let cred = UnixCredentials::new();
- #[cfg(any(target_os = "android", target_os = "linux"))]
- let cmsg = ControlMessage::ScmCredentials(&cred);
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- let cmsg = ControlMessage::ScmCreds;
- assert_eq!(
- sendmsg::<()>(send, &iov, &[cmsg], MsgFlags::empty(), None)
- .unwrap(),
- 5
- );
- close(send).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
-
- let mut cmsgspace = cmsg_space!(UnixCredentials);
- let msg = recvmsg::<()>(
- recv,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::empty(),
- )
- .unwrap();
- let mut received_cred = None;
-
- for cmsg in msg.cmsgs() {
- let cred = match cmsg {
- #[cfg(any(target_os = "android", target_os = "linux"))]
- ControlMessageOwned::ScmCredentials(cred) => cred,
- #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
- ControlMessageOwned::ScmCreds(cred) => cred,
- other => panic!("unexpected cmsg {:?}", other),
- };
- assert!(received_cred.is_none());
- assert_eq!(cred.pid(), getpid().as_raw());
- assert_eq!(cred.uid(), getuid().as_raw());
- assert_eq!(cred.gid(), getgid().as_raw());
- received_cred = Some(cred);
- }
- received_cred.expect("no creds received");
- assert_eq!(msg.bytes, 5);
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- close(recv).unwrap();
- }
-}
-
-/// Ensure that we can send `SCM_CREDENTIALS` and `SCM_RIGHTS` with a single
-/// `sendmsg` call.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation
-// see https://bugs.launchpad.net/qemu/+bug/1781280
-#[cfg_attr(qemu, ignore)]
-#[test]
-fn test_scm_credentials_and_rights() {
- let space = cmsg_space!(libc::ucred, RawFd);
- test_impl_scm_credentials_and_rights(space);
-}
-
-/// Ensure that passing a an oversized control message buffer to recvmsg
-/// still works.
-#[cfg(any(target_os = "android", target_os = "linux"))]
-// qemu's handling of multiple cmsgs is bugged, ignore tests under emulation
-// see https://bugs.launchpad.net/qemu/+bug/1781280
-#[cfg_attr(qemu, ignore)]
-#[test]
-fn test_too_large_cmsgspace() {
- let space = vec![0u8; 1024];
- test_impl_scm_credentials_and_rights(space);
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
- use libc::ucred;
- use nix::sys::socket::sockopt::PassCred;
- use nix::sys::socket::{
- recvmsg, sendmsg, setsockopt, socketpair, ControlMessage,
- ControlMessageOwned, MsgFlags, SockFlag, SockType,
- };
- use nix::unistd::{close, getgid, getpid, getuid, pipe, write};
- use std::io::{IoSlice, IoSliceMut};
-
- let (send, recv) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- setsockopt(recv, PassCred, &true).unwrap();
-
- let (r, w) = pipe().unwrap();
- let mut received_r: Option<RawFd> = None;
-
- {
- let iov = [IoSlice::new(b"hello")];
- let cred = ucred {
- pid: getpid().as_raw(),
- uid: getuid().as_raw(),
- gid: getgid().as_raw(),
- }
- .into();
- let fds = [r];
- let cmsgs = [
- ControlMessage::ScmCredentials(&cred),
- ControlMessage::ScmRights(&fds),
- ];
- assert_eq!(
- sendmsg::<()>(send, &iov, &cmsgs, MsgFlags::empty(), None).unwrap(),
- 5
- );
- close(r).unwrap();
- close(send).unwrap();
- }
-
- {
- let mut buf = [0u8; 5];
- let mut iov = [IoSliceMut::new(&mut buf[..])];
- let msg =
- recvmsg::<()>(recv, &mut iov, Some(&mut space), MsgFlags::empty())
- .unwrap();
- let mut received_cred = None;
-
- assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
-
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::ScmRights(fds) => {
- assert_eq!(received_r, None, "already received fd");
- assert_eq!(fds.len(), 1);
- received_r = Some(fds[0]);
- }
- ControlMessageOwned::ScmCredentials(cred) => {
- assert!(received_cred.is_none());
- assert_eq!(cred.pid(), getpid().as_raw());
- assert_eq!(cred.uid(), getuid().as_raw());
- assert_eq!(cred.gid(), getgid().as_raw());
- received_cred = Some(cred);
- }
- _ => panic!("unexpected cmsg"),
- }
- }
- received_cred.expect("no creds received");
- assert_eq!(msg.bytes, 5);
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- close(recv).unwrap();
- }
-
- let received_r = received_r.expect("Did not receive passed fd");
- // Ensure that the received file descriptor works
- write(w, b"world").unwrap();
- let mut buf = [0u8; 5];
- read(received_r, &mut buf).unwrap();
- assert_eq!(&buf[..], b"world");
- close(received_r).unwrap();
- close(w).unwrap();
-}
-
-// Test creating and using named unix domain sockets
-#[test]
-pub fn test_named_unixdomain() {
- use nix::sys::socket::{accept, bind, connect, listen, socket, UnixAddr};
- use nix::sys::socket::{SockFlag, SockType};
- use nix::unistd::{close, read, write};
- use std::thread;
-
- let tempdir = tempfile::tempdir().unwrap();
- let sockname = tempdir.path().join("sock");
- let s1 = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
- let sockaddr = UnixAddr::new(&sockname).unwrap();
- bind(s1, &sockaddr).expect("bind failed");
- listen(s1, 10).expect("listen failed");
-
- let thr = thread::spawn(move || {
- let s2 = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
- connect(s2, &sockaddr).expect("connect failed");
- write(s2, b"hello").expect("write failed");
- close(s2).unwrap();
- });
-
- let s3 = accept(s1).expect("accept failed");
-
- let mut buf = [0; 5];
- read(s3, &mut buf).unwrap();
- close(s3).unwrap();
- close(s1).unwrap();
- thr.join().unwrap();
-
- assert_eq!(&buf[..], b"hello");
-}
-
-// Test using unnamed unix domain addresses
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_unnamed_unixdomain() {
- use nix::sys::socket::{getsockname, socketpair};
- use nix::sys::socket::{SockFlag, SockType};
- use nix::unistd::close;
-
- let (fd_1, fd_2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .expect("socketpair failed");
-
- let addr_1: UnixAddr = getsockname(fd_1).expect("getsockname failed");
- assert!(addr_1.is_unnamed());
-
- close(fd_1).unwrap();
- close(fd_2).unwrap();
-}
-
-// Test creating and using unnamed unix domain addresses for autobinding sockets
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-pub fn test_unnamed_unixdomain_autobind() {
- use nix::sys::socket::{bind, getsockname, socket};
- use nix::sys::socket::{SockFlag, SockType};
- use nix::unistd::close;
-
- let fd = socket(
- AddressFamily::Unix,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- // unix(7): "If a bind(2) call specifies addrlen as `sizeof(sa_family_t)`, or [...], then the
- // socket is autobound to an abstract address"
- bind(fd, &UnixAddr::new_unnamed()).expect("bind failed");
-
- let addr: UnixAddr = getsockname(fd).expect("getsockname failed");
- let addr = addr.as_abstract().unwrap();
-
- // changed from 8 to 5 bytes in Linux 2.3.15, and rust's minimum supported Linux version is 3.2
- // (as of 2022-11)
- assert_eq!(addr.len(), 5);
-
- close(fd).unwrap();
-}
-
-// Test creating and using named system control sockets
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-#[test]
-pub fn test_syscontrol() {
- use nix::errno::Errno;
- use nix::sys::socket::{
- socket, SockFlag, SockProtocol, SockType, SysControlAddr,
- };
-
- let fd = socket(
- AddressFamily::System,
- SockType::Datagram,
- SockFlag::empty(),
- SockProtocol::KextControl,
- )
- .expect("socket failed");
- SysControlAddr::from_name(fd, "com.apple.net.utun_control", 0)
- .expect("resolving sys_control name failed");
- assert_eq!(
- SysControlAddr::from_name(fd, "foo.bar.lol", 0).err(),
- Some(Errno::ENOENT)
- );
-
- // requires root privileges
- // connect(fd, &sockaddr).expect("connect failed");
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-fn loopback_address(
- family: AddressFamily,
-) -> Option<nix::ifaddrs::InterfaceAddress> {
- use nix::ifaddrs::getifaddrs;
- use nix::net::if_::*;
- use nix::sys::socket::SockaddrLike;
- use std::io;
- use std::io::Write;
-
- let mut addrs = match getifaddrs() {
- Ok(iter) => iter,
- Err(e) => {
- let stdioerr = io::stderr();
- let mut handle = stdioerr.lock();
- writeln!(handle, "getifaddrs: {:?}", e).unwrap();
- return None;
- }
- };
- // return first address matching family
- addrs.find(|ifaddr| {
- ifaddr.flags.contains(InterfaceFlags::IFF_LOOPBACK)
- && ifaddr.address.as_ref().and_then(SockaddrLike::family)
- == Some(family)
- })
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
-))]
-// qemu doesn't seem to be emulating this correctly in these architectures
-#[cfg_attr(
- all(
- qemu,
- any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc64",
- )
- ),
- ignore
-)]
-#[test]
-pub fn test_recv_ipv4pktinfo() {
- use nix::net::if_::*;
- use nix::sys::socket::sockopt::Ipv4PacketInfo;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet);
- let (lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv4 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv4PacketInfo, &true).expect("setsockopt failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
-
- let mut space = cmsg_space!(libc::in_pktinfo);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
-
- let mut cmsgs = msg.cmsgs();
- if let Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) = cmsgs.next()
- {
- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
- assert_eq!(
- pktinfo.ipi_ifindex as libc::c_uint, i,
- "unexpected ifindex (expected {}, got {})",
- i, pktinfo.ipi_ifindex
- );
- }
- assert!(cmsgs.next().is_none(), "unexpected additional control msg");
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-// qemu doesn't seem to be emulating this correctly in these architectures
-#[cfg_attr(
- all(
- qemu,
- any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc64",
- )
- ),
- ignore
-)]
-#[test]
-pub fn test_recvif() {
- use nix::net::if_::*;
- use nix::sys::socket::sockopt::{Ipv4RecvDstAddr, Ipv4RecvIf};
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet);
- let (lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv4 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv4RecvIf, &true)
- .expect("setsockopt IP_RECVIF failed");
- setsockopt(receive, Ipv4RecvDstAddr, &true)
- .expect("setsockopt IP_RECVDSTADDR failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut space = cmsg_space!(libc::sockaddr_dl, libc::in_addr);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
-
- let mut rx_recvif = false;
- let mut rx_recvdstaddr = false;
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::Ipv4RecvIf(dl) => {
- rx_recvif = true;
- let i = if_nametoindex(lo_name.as_bytes())
- .expect("if_nametoindex");
- assert_eq!(
- dl.sdl_index as libc::c_uint, i,
- "unexpected ifindex (expected {}, got {})",
- i, dl.sdl_index
- );
- }
- ControlMessageOwned::Ipv4RecvDstAddr(addr) => {
- rx_recvdstaddr = true;
- if let Some(sin) = lo.as_sockaddr_in() {
- assert_eq!(sin.as_ref().sin_addr.s_addr,
- addr.s_addr,
- "unexpected destination address (expected {}, got {})",
- sin.as_ref().sin_addr.s_addr,
- addr.s_addr);
- } else {
- panic!("unexpected Sockaddr");
- }
- }
- _ => panic!("unexpected additional control msg"),
- }
- }
- assert!(rx_recvif);
- assert!(rx_recvdstaddr);
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_recvif_ipv4() {
- use nix::sys::socket::sockopt::Ipv4OrigDstAddr;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet);
- let (_lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv4 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv4OrigDstAddr, &true)
- .expect("setsockopt IP_ORIGDSTADDR failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut space = cmsg_space!(libc::sockaddr_in);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs");
-
- let mut rx_recvorigdstaddr = false;
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::Ipv4OrigDstAddr(addr) => {
- rx_recvorigdstaddr = true;
- if let Some(sin) = lo.as_sockaddr_in() {
- assert_eq!(sin.as_ref().sin_addr.s_addr,
- addr.sin_addr.s_addr,
- "unexpected destination address (expected {}, got {})",
- sin.as_ref().sin_addr.s_addr,
- addr.sin_addr.s_addr);
- } else {
- panic!("unexpected Sockaddr");
- }
- }
- _ => panic!("unexpected additional control msg"),
- }
- }
- assert!(rx_recvorigdstaddr);
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-#[test]
-pub fn test_recvif_ipv6() {
- use nix::sys::socket::sockopt::Ipv6OrigDstAddr;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet6);
- let (_lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv6 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv6OrigDstAddr, &true)
- .expect("setsockopt IP_ORIGDSTADDR failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut space = cmsg_space!(libc::sockaddr_in6);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs");
-
- let mut rx_recvorigdstaddr = false;
- for cmsg in msg.cmsgs() {
- match cmsg {
- ControlMessageOwned::Ipv6OrigDstAddr(addr) => {
- rx_recvorigdstaddr = true;
- if let Some(sin) = lo.as_sockaddr_in6() {
- assert_eq!(sin.as_ref().sin6_addr.s6_addr,
- addr.sin6_addr.s6_addr,
- "unexpected destination address (expected {:?}, got {:?})",
- sin.as_ref().sin6_addr.s6_addr,
- addr.sin6_addr.s6_addr);
- } else {
- panic!("unexpected Sockaddr");
- }
- }
- _ => panic!("unexpected additional control msg"),
- }
- }
- assert!(rx_recvorigdstaddr);
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-// qemu doesn't seem to be emulating this correctly in these architectures
-#[cfg_attr(
- all(
- qemu,
- any(
- target_arch = "mips",
- target_arch = "mips64",
- target_arch = "powerpc64",
- )
- ),
- ignore
-)]
-#[test]
-pub fn test_recv_ipv6pktinfo() {
- use nix::net::if_::*;
- use nix::sys::socket::sockopt::Ipv6RecvPacketInfo;
- use nix::sys::socket::{bind, SockFlag, SockType, SockaddrIn6};
- use nix::sys::socket::{getsockname, setsockopt, socket};
- use nix::sys::socket::{recvmsg, sendmsg, ControlMessageOwned, MsgFlags};
- use std::io::{IoSlice, IoSliceMut};
-
- let lo_ifaddr = loopback_address(AddressFamily::Inet6);
- let (lo_name, lo) = match lo_ifaddr {
- Some(ifaddr) => (
- ifaddr.interface_name,
- ifaddr.address.expect("Expect IPv6 address on interface"),
- ),
- None => return,
- };
- let receive = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("receive socket failed");
- bind(receive, &lo).expect("bind failed");
- let sa: SockaddrIn6 = getsockname(receive).expect("getsockname failed");
- setsockopt(receive, Ipv6RecvPacketInfo, &true).expect("setsockopt failed");
-
- {
- let slice = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let iov = [IoSlice::new(&slice)];
-
- let send = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
- sendmsg(send, &iov, &[], MsgFlags::empty(), Some(&sa))
- .expect("sendmsg failed");
- }
-
- {
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
-
- let mut space = cmsg_space!(libc::in6_pktinfo);
- let msg = recvmsg::<()>(
- receive,
- &mut iovec,
- Some(&mut space),
- MsgFlags::empty(),
- )
- .expect("recvmsg failed");
- assert!(!msg
- .flags
- .intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
-
- let mut cmsgs = msg.cmsgs();
- if let Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) = cmsgs.next()
- {
- let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
- assert_eq!(
- pktinfo.ipi6_ifindex as libc::c_uint, i,
- "unexpected ifindex (expected {}, got {})",
- i, pktinfo.ipi6_ifindex
- );
- }
- assert!(cmsgs.next().is_none(), "unexpected additional control msg");
- assert_eq!(msg.bytes, 8);
- assert_eq!(*iovec[0], [1u8, 2, 3, 4, 5, 6, 7, 8]);
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(graviton, ignore = "Not supported by the CI environment")]
-#[test]
-pub fn test_vsock() {
- use nix::errno::Errno;
- use nix::sys::socket::{
- bind, connect, listen, socket, AddressFamily, SockFlag, SockType,
- VsockAddr,
- };
- use nix::unistd::close;
- use std::thread;
-
- let port: u32 = 3000;
-
- let s1 = socket(
- AddressFamily::Vsock,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- // VMADDR_CID_HYPERVISOR is reserved, so we expect an EADDRNOTAVAIL error.
- let sockaddr_hv = VsockAddr::new(libc::VMADDR_CID_HYPERVISOR, port);
- assert_eq!(bind(s1, &sockaddr_hv).err(), Some(Errno::EADDRNOTAVAIL));
-
- let sockaddr_any = VsockAddr::new(libc::VMADDR_CID_ANY, port);
- assert_eq!(bind(s1, &sockaddr_any), Ok(()));
- listen(s1, 10).expect("listen failed");
-
- let thr = thread::spawn(move || {
- let cid: u32 = libc::VMADDR_CID_HOST;
-
- let s2 = socket(
- AddressFamily::Vsock,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .expect("socket failed");
-
- let sockaddr_host = VsockAddr::new(cid, port);
-
- // The current implementation does not support loopback devices, so,
- // for now, we expect a failure on the connect.
- assert_ne!(connect(s2, &sockaddr_host), Ok(()));
-
- close(s2).unwrap();
- });
-
- close(s1).unwrap();
- thr.join().unwrap();
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(all(target_os = "linux"))]
-#[test]
-fn test_recvmsg_timestampns() {
- use nix::sys::socket::*;
- use nix::sys::time::*;
- use std::io::{IoSlice, IoSliceMut};
- use std::time::*;
-
- // Set up
- let message = "Ohayō!".as_bytes();
- let in_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap();
- let localhost = SockaddrIn::new(127, 0, 0, 1, 0);
- bind(in_socket, &localhost).unwrap();
- let address: SockaddrIn = getsockname(in_socket).unwrap();
- // Get initial time
- let time0 = SystemTime::now();
- // Send the message
- let iov = [IoSlice::new(message)];
- let flags = MsgFlags::empty();
- let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
- assert_eq!(message.len(), l);
- // Receive the message
- let mut buffer = vec![0u8; message.len()];
- let mut cmsgspace = nix::cmsg_space!(TimeSpec);
-
- let mut iov = [IoSliceMut::new(&mut buffer)];
- let r = recvmsg::<()>(in_socket, &mut iov, Some(&mut cmsgspace), flags)
- .unwrap();
- let rtime = match r.cmsgs().next() {
- Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
- Some(_) => panic!("Unexpected control message"),
- None => panic!("No control message"),
- };
- // Check the final time
- let time1 = SystemTime::now();
- // the packet's received timestamp should lie in-between the two system
- // times, unless the system clock was adjusted in the meantime.
- let rduration =
- Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32);
- assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
- assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
- // Close socket
- nix::unistd::close(in_socket).unwrap();
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(all(target_os = "linux"))]
-#[test]
-fn test_recvmmsg_timestampns() {
- use nix::sys::socket::*;
- use nix::sys::time::*;
- use std::io::{IoSlice, IoSliceMut};
- use std::time::*;
-
- // Set up
- let message = "Ohayō!".as_bytes();
- let in_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap();
- let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
- bind(in_socket, &localhost).unwrap();
- let address: SockaddrIn = getsockname(in_socket).unwrap();
- // Get initial time
- let time0 = SystemTime::now();
- // Send the message
- let iov = [IoSlice::new(message)];
- let flags = MsgFlags::empty();
- let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
- assert_eq!(message.len(), l);
- // Receive the message
- let mut buffer = vec![0u8; message.len()];
- let cmsgspace = nix::cmsg_space!(TimeSpec);
- let iov = vec![[IoSliceMut::new(&mut buffer)]];
- let mut data = MultiHeaders::preallocate(1, Some(cmsgspace));
- let r: Vec<RecvMsg<()>> =
- recvmmsg(in_socket, &mut data, iov.iter(), flags, None)
- .unwrap()
- .collect();
- let rtime = match r[0].cmsgs().next() {
- Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
- Some(_) => panic!("Unexpected control message"),
- None => panic!("No control message"),
- };
- // Check the final time
- let time1 = SystemTime::now();
- // the packet's received timestamp should lie in-between the two system
- // times, unless the system clock was adjusted in the meantime.
- let rduration =
- Duration::new(rtime.tv_sec() as u64, rtime.tv_nsec() as u32);
- assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
- assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
- // Close socket
- nix::unistd::close(in_socket).unwrap();
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
-#[test]
-fn test_recvmsg_rxq_ovfl() {
- use nix::sys::socket::sockopt::{RcvBuf, RxqOvfl};
- use nix::sys::socket::*;
- use nix::Error;
- use std::io::{IoSlice, IoSliceMut};
-
- let message = [0u8; 2048];
- let bufsize = message.len() * 2;
-
- let in_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- let out_socket = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- let localhost = SockaddrIn::from_str("127.0.0.1:0").unwrap();
- bind(in_socket, &localhost).unwrap();
-
- let address: SockaddrIn = getsockname(in_socket).unwrap();
- connect(out_socket, &address).unwrap();
-
- // Set SO_RXQ_OVFL flag.
- setsockopt(in_socket, RxqOvfl, &1).unwrap();
-
- // Set the receiver buffer size to hold only 2 messages.
- setsockopt(in_socket, RcvBuf, &bufsize).unwrap();
-
- let mut drop_counter = 0;
-
- for _ in 0..2 {
- let iov = [IoSlice::new(&message)];
- let flags = MsgFlags::empty();
-
- // Send the 3 messages (the receiver buffer can only hold 2 messages)
- // to create an overflow.
- for _ in 0..3 {
- let l =
- sendmsg(out_socket, &iov, &[], flags, Some(&address)).unwrap();
- assert_eq!(message.len(), l);
- }
-
- // Receive the message and check the drop counter if any.
- loop {
- let mut buffer = vec![0u8; message.len()];
- let mut cmsgspace = nix::cmsg_space!(u32);
-
- let mut iov = [IoSliceMut::new(&mut buffer)];
-
- match recvmsg::<()>(
- in_socket,
- &mut iov,
- Some(&mut cmsgspace),
- MsgFlags::MSG_DONTWAIT,
- ) {
- Ok(r) => {
- drop_counter = match r.cmsgs().next() {
- Some(ControlMessageOwned::RxqOvfl(drop_counter)) => {
- drop_counter
- }
- Some(_) => panic!("Unexpected control message"),
- None => 0,
- };
- }
- Err(Error::EAGAIN) => {
- break;
- }
- _ => {
- panic!("unknown recvmsg() error");
- }
- }
- }
- }
-
- // One packet lost.
- assert_eq!(drop_counter, 1);
-
- // Close sockets
- nix::unistd::close(in_socket).unwrap();
- nix::unistd::close(out_socket).unwrap();
-}
-
-#[cfg(any(target_os = "linux", target_os = "android",))]
-mod linux_errqueue {
- use super::FromStr;
- use nix::sys::socket::*;
-
- // Send a UDP datagram to a bogus destination address and observe an ICMP error (v4).
- //
- // Disable the test on QEMU because QEMU emulation of IP_RECVERR is broken (as documented on PR
- // #1514).
- #[cfg_attr(qemu, ignore)]
- #[test]
- fn test_recverr_v4() {
- #[repr(u8)]
- enum IcmpTypes {
- DestUnreach = 3, // ICMP_DEST_UNREACH
- }
- #[repr(u8)]
- enum IcmpUnreachCodes {
- PortUnreach = 3, // ICMP_PORT_UNREACH
- }
-
- test_recverr_impl::<sockaddr_in, _, _>(
- "127.0.0.1:6800",
- AddressFamily::Inet,
- sockopt::Ipv4RecvErr,
- libc::SO_EE_ORIGIN_ICMP,
- IcmpTypes::DestUnreach as u8,
- IcmpUnreachCodes::PortUnreach as u8,
- // Closure handles protocol-specific testing and returns generic sock_extended_err for
- // protocol-independent test impl.
- |cmsg| {
- if let ControlMessageOwned::Ipv4RecvErr(ext_err, err_addr) =
- cmsg
- {
- if let Some(origin) = err_addr {
- // Validate that our network error originated from 127.0.0.1:0.
- assert_eq!(origin.sin_family, AddressFamily::Inet as _);
- assert_eq!(
- origin.sin_addr.s_addr,
- u32::from_be(0x7f000001)
- );
- assert_eq!(origin.sin_port, 0);
- } else {
- panic!("Expected some error origin");
- }
- *ext_err
- } else {
- panic!("Unexpected control message {:?}", cmsg);
- }
- },
- )
- }
-
- // Essentially the same test as v4.
- //
- // Disable the test on QEMU because QEMU emulation of IPV6_RECVERR is broken (as documented on
- // PR #1514).
- #[cfg_attr(qemu, ignore)]
- #[test]
- fn test_recverr_v6() {
- #[repr(u8)]
- enum IcmpV6Types {
- DestUnreach = 1, // ICMPV6_DEST_UNREACH
- }
- #[repr(u8)]
- enum IcmpV6UnreachCodes {
- PortUnreach = 4, // ICMPV6_PORT_UNREACH
- }
-
- test_recverr_impl::<sockaddr_in6, _, _>(
- "[::1]:6801",
- AddressFamily::Inet6,
- sockopt::Ipv6RecvErr,
- libc::SO_EE_ORIGIN_ICMP6,
- IcmpV6Types::DestUnreach as u8,
- IcmpV6UnreachCodes::PortUnreach as u8,
- // Closure handles protocol-specific testing and returns generic sock_extended_err for
- // protocol-independent test impl.
- |cmsg| {
- if let ControlMessageOwned::Ipv6RecvErr(ext_err, err_addr) =
- cmsg
- {
- if let Some(origin) = err_addr {
- // Validate that our network error originated from localhost:0.
- assert_eq!(
- origin.sin6_family,
- AddressFamily::Inet6 as _
- );
- assert_eq!(
- origin.sin6_addr.s6_addr,
- std::net::Ipv6Addr::LOCALHOST.octets()
- );
- assert_eq!(origin.sin6_port, 0);
- } else {
- panic!("Expected some error origin");
- }
- *ext_err
- } else {
- panic!("Unexpected control message {:?}", cmsg);
- }
- },
- )
- }
-
- fn test_recverr_impl<SA, OPT, TESTF>(
- sa: &str,
- af: AddressFamily,
- opt: OPT,
- ee_origin: u8,
- ee_type: u8,
- ee_code: u8,
- testf: TESTF,
- ) where
- OPT: SetSockOpt<Val = bool>,
- TESTF: FnOnce(&ControlMessageOwned) -> libc::sock_extended_err,
- {
- use nix::errno::Errno;
- use std::io::IoSliceMut;
-
- const MESSAGE_CONTENTS: &str = "ABCDEF";
- let std_sa = std::net::SocketAddr::from_str(sa).unwrap();
- let sock_addr = SockaddrStorage::from(std_sa);
- let sock = socket(af, SockType::Datagram, SockFlag::SOCK_CLOEXEC, None)
- .unwrap();
- setsockopt(sock, opt, &true).unwrap();
- if let Err(e) = sendto(
- sock,
- MESSAGE_CONTENTS.as_bytes(),
- &sock_addr,
- MsgFlags::empty(),
- ) {
- assert_eq!(e, Errno::EADDRNOTAVAIL);
- println!("{:?} not available, skipping test.", af);
- return;
- }
-
- let mut buf = [0u8; 8];
- let mut iovec = [IoSliceMut::new(&mut buf)];
- let mut cspace = cmsg_space!(libc::sock_extended_err, SA);
-
- let msg = recvmsg(
- sock,
- &mut iovec,
- Some(&mut cspace),
- MsgFlags::MSG_ERRQUEUE,
- )
- .unwrap();
- // The sent message / destination associated with the error is returned:
- assert_eq!(msg.bytes, MESSAGE_CONTENTS.as_bytes().len());
- // recvmsg(2): "The original destination address of the datagram that caused the error is
- // supplied via msg_name;" however, this is not literally true. E.g., an earlier version
- // of this test used 0.0.0.0 (::0) as the destination address, which was mutated into
- // 127.0.0.1 (::1).
- assert_eq!(msg.address, Some(sock_addr));
-
- // Check for expected control message.
- let ext_err = match msg.cmsgs().next() {
- Some(cmsg) => testf(&cmsg),
- None => panic!("No control message"),
- };
-
- assert_eq!(ext_err.ee_errno, libc::ECONNREFUSED as u32);
- assert_eq!(ext_err.ee_origin, ee_origin);
- // ip(7): ee_type and ee_code are set from the type and code fields of the ICMP (ICMPv6)
- // header.
- assert_eq!(ext_err.ee_type, ee_type);
- assert_eq!(ext_err.ee_code, ee_code);
- // ip(7): ee_info contains the discovered MTU for EMSGSIZE errors.
- assert_eq!(ext_err.ee_info, 0);
-
- let bytes = msg.bytes;
- assert_eq!(&buf[..bytes], MESSAGE_CONTENTS.as_bytes());
- }
-}
-
-// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-#[cfg(target_os = "linux")]
-#[test]
-pub fn test_txtime() {
- use nix::sys::socket::{
- bind, recvmsg, sendmsg, setsockopt, socket, sockopt, ControlMessage,
- MsgFlags, SockFlag, SockType, SockaddrIn,
- };
- use nix::sys::time::TimeValLike;
- use nix::time::{clock_gettime, ClockId};
-
- require_kernel_version!(test_txtime, ">= 5.8");
-
- let sock_addr = SockaddrIn::from_str("127.0.0.1:6802").unwrap();
-
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .expect("send socket failed");
-
- let txtime_cfg = libc::sock_txtime {
- clockid: libc::CLOCK_MONOTONIC,
- flags: 0,
- };
- setsockopt(ssock, sockopt::TxTime, &txtime_cfg).unwrap();
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
-
- let sbuf = [0u8; 2048];
- let iov1 = [std::io::IoSlice::new(&sbuf)];
-
- let now = clock_gettime(ClockId::CLOCK_MONOTONIC).unwrap();
- let delay = std::time::Duration::from_secs(1).into();
- let txtime = (now + delay).num_nanoseconds() as u64;
-
- let cmsg = ControlMessage::TxTime(&txtime);
- sendmsg(ssock, &iov1, &[cmsg], MsgFlags::empty(), Some(&sock_addr))
- .unwrap();
-
- let mut rbuf = [0u8; 2048];
- let mut iov2 = [std::io::IoSliceMut::new(&mut rbuf)];
- recvmsg::<()>(rsock, &mut iov2, None, MsgFlags::empty()).unwrap();
-}
diff --git a/vendor/nix/test/sys/test_sockopt.rs b/vendor/nix/test/sys/test_sockopt.rs
deleted file mode 100644
index 34bef945e..000000000
--- a/vendor/nix/test/sys/test_sockopt.rs
+++ /dev/null
@@ -1,431 +0,0 @@
-#[cfg(any(target_os = "android", target_os = "linux"))]
-use crate::*;
-use nix::sys::socket::{
- getsockopt, setsockopt, socket, sockopt, AddressFamily, SockFlag,
- SockProtocol, SockType,
-};
-use rand::{thread_rng, Rng};
-
-// NB: FreeBSD supports LOCAL_PEERCRED for SOCK_SEQPACKET, but OSX does not.
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd",))]
-#[test]
-pub fn test_local_peercred_seqpacket() {
- use nix::{
- sys::socket::socketpair,
- unistd::{Gid, Uid},
- };
-
- let (fd1, _fd2) = socketpair(
- AddressFamily::Unix,
- SockType::SeqPacket,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap();
- assert_eq!(xucred.version(), 0);
- assert_eq!(Uid::from_raw(xucred.uid()), Uid::current());
- assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current());
-}
-
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios"
-))]
-#[test]
-pub fn test_local_peercred_stream() {
- use nix::{
- sys::socket::socketpair,
- unistd::{Gid, Uid},
- };
-
- let (fd1, _fd2) = socketpair(
- AddressFamily::Unix,
- SockType::Stream,
- None,
- SockFlag::empty(),
- )
- .unwrap();
- let xucred = getsockopt(fd1, sockopt::LocalPeerCred).unwrap();
- assert_eq!(xucred.version(), 0);
- assert_eq!(Uid::from_raw(xucred.uid()), Uid::current());
- assert_eq!(Gid::from_raw(xucred.groups()[0]), Gid::current());
-}
-
-#[cfg(target_os = "linux")]
-#[test]
-fn is_so_mark_functional() {
- use nix::sys::socket::sockopt;
-
- require_capability!("is_so_mark_functional", CAP_NET_ADMIN);
-
- let s = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(s, sockopt::Mark, &1337).unwrap();
- let mark = getsockopt(s, sockopt::Mark).unwrap();
- assert_eq!(mark, 1337);
-}
-
-#[test]
-fn test_so_buf() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- SockProtocol::Udp,
- )
- .unwrap();
- let bufsize: usize = thread_rng().gen_range(4096..131_072);
- setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap();
- let actual = getsockopt(fd, sockopt::SndBuf).unwrap();
- assert!(actual >= bufsize);
- setsockopt(fd, sockopt::RcvBuf, &bufsize).unwrap();
- let actual = getsockopt(fd, sockopt::RcvBuf).unwrap();
- assert!(actual >= bufsize);
-}
-
-#[test]
-fn test_so_tcp_maxseg() {
- use nix::sys::socket::{accept, bind, connect, listen, SockaddrIn};
- use nix::unistd::{close, write};
- use std::net::SocketAddrV4;
- use std::str::FromStr;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap();
- let sock_addr = SockaddrIn::from(std_sa);
-
- let rsock = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- bind(rsock, &sock_addr).unwrap();
- listen(rsock, 10).unwrap();
- let initial = getsockopt(rsock, sockopt::TcpMaxSeg).unwrap();
- // Initial MSS is expected to be 536 (https://tools.ietf.org/html/rfc879#section-1) but some
- // platforms keep it even lower. This might fail if you've tuned your initial MSS to be larger
- // than 700
- cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- let segsize: u32 = 873;
- assert!(initial < segsize);
- setsockopt(rsock, sockopt::TcpMaxSeg, &segsize).unwrap();
- } else {
- assert!(initial < 700);
- }
- }
-
- // Connect and check the MSS that was advertised
- let ssock = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- connect(ssock, &sock_addr).unwrap();
- let rsess = accept(rsock).unwrap();
- write(rsess, b"hello").unwrap();
- let actual = getsockopt(ssock, sockopt::TcpMaxSeg).unwrap();
- // Actual max segment size takes header lengths into account, max IPv4 options (60 bytes) + max
- // TCP options (40 bytes) are subtracted from the requested maximum as a lower boundary.
- cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- assert!((segsize - 100) <= actual);
- assert!(actual <= segsize);
- } else {
- assert!(initial < actual);
- assert!(536 < actual);
- }
- }
- close(rsock).unwrap();
- close(ssock).unwrap();
-}
-
-#[test]
-fn test_so_type() {
- let sockfd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- assert_eq!(Ok(SockType::Stream), getsockopt(sockfd, sockopt::SockType));
-}
-
-/// getsockopt(_, sockopt::SockType) should gracefully handle unknown socket
-/// types. Regression test for https://github.com/nix-rust/nix/issues/1819
-#[cfg(any(target_os = "android", target_os = "linux",))]
-#[test]
-fn test_so_type_unknown() {
- use nix::errno::Errno;
-
- require_capability!("test_so_type", CAP_NET_RAW);
- let sockfd = unsafe { libc::socket(libc::AF_PACKET, libc::SOCK_PACKET, 0) };
- assert!(sockfd >= 0, "Error opening socket: {}", nix::Error::last());
-
- assert_eq!(Err(Errno::EINVAL), getsockopt(sockfd, sockopt::SockType));
-}
-
-// The CI doesn't supported getsockopt and setsockopt on emulated processors.
-// It's believed that a QEMU issue, the tests run ok on a fully emulated system.
-// Current CI just run the binary with QEMU but the Kernel remains the same as the host.
-// So the syscall doesn't work properly unless the kernel is also emulated.
-#[test]
-#[cfg(all(
- any(target_arch = "x86", target_arch = "x86_64"),
- any(target_os = "freebsd", target_os = "linux")
-))]
-fn test_tcp_congestion() {
- use std::ffi::OsString;
-
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- let val = getsockopt(fd, sockopt::TcpCongestion).unwrap();
- setsockopt(fd, sockopt::TcpCongestion, &val).unwrap();
-
- setsockopt(
- fd,
- sockopt::TcpCongestion,
- &OsString::from("tcp_congestion_does_not_exist"),
- )
- .unwrap_err();
-
- assert_eq!(getsockopt(fd, sockopt::TcpCongestion).unwrap(), val);
-}
-
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_bindtodevice() {
- skip_if_not_root!("test_bindtodevice");
-
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- None,
- )
- .unwrap();
-
- let val = getsockopt(fd, sockopt::BindToDevice).unwrap();
- setsockopt(fd, sockopt::BindToDevice, &val).unwrap();
-
- assert_eq!(getsockopt(fd, sockopt::BindToDevice).unwrap(), val);
-}
-
-#[test]
-fn test_so_tcp_keepalive() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- setsockopt(fd, sockopt::KeepAlive, &true).unwrap();
- assert!(getsockopt(fd, sockopt::KeepAlive).unwrap());
-
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
- ))]
- {
- let x = getsockopt(fd, sockopt::TcpKeepIdle).unwrap();
- setsockopt(fd, sockopt::TcpKeepIdle, &(x + 1)).unwrap();
- assert_eq!(getsockopt(fd, sockopt::TcpKeepIdle).unwrap(), x + 1);
-
- let x = getsockopt(fd, sockopt::TcpKeepCount).unwrap();
- setsockopt(fd, sockopt::TcpKeepCount, &(x + 1)).unwrap();
- assert_eq!(getsockopt(fd, sockopt::TcpKeepCount).unwrap(), x + 1);
-
- let x = getsockopt(fd, sockopt::TcpKeepInterval).unwrap();
- setsockopt(fd, sockopt::TcpKeepInterval, &(x + 1)).unwrap();
- assert_eq!(getsockopt(fd, sockopt::TcpKeepInterval).unwrap(), x + 1);
- }
-}
-
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[cfg_attr(qemu, ignore)]
-fn test_get_mtu() {
- use nix::sys::socket::{bind, connect, SockaddrIn};
- use std::net::SocketAddrV4;
- use std::str::FromStr;
-
- let std_sa = SocketAddrV4::from_str("127.0.0.1:4001").unwrap();
- let std_sb = SocketAddrV4::from_str("127.0.0.1:4002").unwrap();
-
- let usock = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- SockProtocol::Udp,
- )
- .unwrap();
-
- // Bind and initiate connection
- bind(usock, &SockaddrIn::from(std_sa)).unwrap();
- connect(usock, &SockaddrIn::from(std_sb)).unwrap();
-
- // Loopback connections have 2^16 - the maximum - MTU
- assert_eq!(getsockopt(usock, sockopt::IpMtu), Ok(u16::MAX as i32))
-}
-
-#[test]
-#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
-fn test_ttl_opts() {
- let fd4 = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd4, sockopt::Ipv4Ttl, &1)
- .expect("setting ipv4ttl on an inet socket should succeed");
- let fd6 = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd6, sockopt::Ipv6Ttl, &1)
- .expect("setting ipv6ttl on an inet6 socket should succeed");
-}
-
-#[test]
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-fn test_dontfrag_opts() {
- let fd4 = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- setsockopt(fd4, sockopt::IpDontFrag, &true)
- .expect("setting IP_DONTFRAG on an inet stream socket should succeed");
- setsockopt(fd4, sockopt::IpDontFrag, &false).expect(
- "unsetting IP_DONTFRAG on an inet stream socket should succeed",
- );
- let fd4d = socket(
- AddressFamily::Inet,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd4d, sockopt::IpDontFrag, &true).expect(
- "setting IP_DONTFRAG on an inet datagram socket should succeed",
- );
- setsockopt(fd4d, sockopt::IpDontFrag, &false).expect(
- "unsetting IP_DONTFRAG on an inet datagram socket should succeed",
- );
-}
-
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
-))]
-// Disable the test under emulation because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-fn test_v6dontfrag_opts() {
- let fd6 = socket(
- AddressFamily::Inet6,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- setsockopt(fd6, sockopt::Ipv6DontFrag, &true).expect(
- "setting IPV6_DONTFRAG on an inet6 stream socket should succeed",
- );
- setsockopt(fd6, sockopt::Ipv6DontFrag, &false).expect(
- "unsetting IPV6_DONTFRAG on an inet6 stream socket should succeed",
- );
- let fd6d = socket(
- AddressFamily::Inet6,
- SockType::Datagram,
- SockFlag::empty(),
- None,
- )
- .unwrap();
- setsockopt(fd6d, sockopt::Ipv6DontFrag, &true).expect(
- "setting IPV6_DONTFRAG on an inet6 datagram socket should succeed",
- );
- setsockopt(fd6d, sockopt::Ipv6DontFrag, &false).expect(
- "unsetting IPV6_DONTFRAG on an inet6 datagram socket should succeed",
- );
-}
-
-#[test]
-#[cfg(target_os = "linux")]
-fn test_so_priority() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- let priority = 3;
- setsockopt(fd, sockopt::Priority, &priority).unwrap();
- assert_eq!(getsockopt(fd, sockopt::Priority).unwrap(), priority);
-}
-
-#[test]
-#[cfg(target_os = "linux")]
-fn test_ip_tos() {
- let fd = socket(
- AddressFamily::Inet,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- let tos = 0x80; // CS4
- setsockopt(fd, sockopt::IpTos, &tos).unwrap();
- assert_eq!(getsockopt(fd, sockopt::IpTos).unwrap(), tos);
-}
-
-#[test]
-#[cfg(target_os = "linux")]
-// Disable the test under emulation because it fails in Cirrus-CI. Lack
-// of QEMU support is suspected.
-#[cfg_attr(qemu, ignore)]
-fn test_ipv6_tclass() {
- let fd = socket(
- AddressFamily::Inet6,
- SockType::Stream,
- SockFlag::empty(),
- SockProtocol::Tcp,
- )
- .unwrap();
- let class = 0x80; // CS4
- setsockopt(fd, sockopt::Ipv6TClass, &class).unwrap();
- assert_eq!(getsockopt(fd, sockopt::Ipv6TClass).unwrap(), class);
-}
diff --git a/vendor/nix/test/sys/test_stat.rs b/vendor/nix/test/sys/test_stat.rs
deleted file mode 100644
index 426b4b658..000000000
--- a/vendor/nix/test/sys/test_stat.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-// The conversion is not useless on all platforms.
-#[allow(clippy::useless_conversion)]
-#[cfg(target_os = "freebsd")]
-#[test]
-fn test_chflags() {
- use nix::{
- sys::stat::{fstat, FileFlag},
- unistd::chflags,
- };
- use std::os::unix::io::AsRawFd;
- use tempfile::NamedTempFile;
-
- let f = NamedTempFile::new().unwrap();
-
- let initial = FileFlag::from_bits_truncate(
- fstat(f.as_raw_fd()).unwrap().st_flags.into(),
- );
- // UF_OFFLINE is preserved by all FreeBSD file systems, but not interpreted
- // in any way, so it's handy for testing.
- let commanded = initial ^ FileFlag::UF_OFFLINE;
-
- chflags(f.path(), commanded).unwrap();
-
- let changed = FileFlag::from_bits_truncate(
- fstat(f.as_raw_fd()).unwrap().st_flags.into(),
- );
-
- assert_eq!(commanded, changed);
-}
diff --git a/vendor/nix/test/sys/test_sysinfo.rs b/vendor/nix/test/sys/test_sysinfo.rs
deleted file mode 100644
index 2897366ef..000000000
--- a/vendor/nix/test/sys/test_sysinfo.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use nix::sys::sysinfo::*;
-
-#[test]
-fn sysinfo_works() {
- let info = sysinfo().unwrap();
-
- let (l1, l5, l15) = info.load_average();
- assert!(l1 >= 0.0);
- assert!(l5 >= 0.0);
- assert!(l15 >= 0.0);
-
- info.uptime(); // just test Duration construction
-
- assert!(
- info.swap_free() <= info.swap_total(),
- "more swap available than installed (free: {}, total: {})",
- info.swap_free(),
- info.swap_total()
- );
-}
diff --git a/vendor/nix/test/sys/test_termios.rs b/vendor/nix/test/sys/test_termios.rs
deleted file mode 100644
index aaf00084f..000000000
--- a/vendor/nix/test/sys/test_termios.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-use std::os::unix::prelude::*;
-use tempfile::tempfile;
-
-use nix::errno::Errno;
-use nix::fcntl;
-use nix::pty::openpty;
-use nix::sys::termios::{self, tcgetattr, LocalFlags, OutputFlags};
-use nix::unistd::{close, read, write};
-
-/// Helper function analogous to `std::io::Write::write_all`, but for `RawFd`s
-fn write_all(f: RawFd, buf: &[u8]) {
- let mut len = 0;
- while len < buf.len() {
- len += write(f, &buf[len..]).unwrap();
- }
-}
-
-// Test tcgetattr on a terminal
-#[test]
-fn test_tcgetattr_pty() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- let pty = openpty(None, None).expect("openpty failed");
- termios::tcgetattr(pty.slave).unwrap();
- close(pty.master).expect("closing the master failed");
- close(pty.slave).expect("closing the slave failed");
-}
-
-// Test tcgetattr on something that isn't a terminal
-#[test]
-fn test_tcgetattr_enotty() {
- let file = tempfile().unwrap();
- assert_eq!(
- termios::tcgetattr(file.as_raw_fd()).err(),
- Some(Errno::ENOTTY)
- );
-}
-
-// Test tcgetattr on an invalid file descriptor
-#[test]
-fn test_tcgetattr_ebadf() {
- assert_eq!(termios::tcgetattr(-1).err(), Some(Errno::EBADF));
-}
-
-// Test modifying output flags
-#[test]
-fn test_output_flags() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open one pty to get attributes for the second one
- let mut termios = {
- let pty = openpty(None, None).expect("openpty failed");
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
- let termios = tcgetattr(pty.slave).expect("tcgetattr failed");
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- termios
- };
-
- // Make sure postprocessing '\r' isn't specified by default or this test is useless.
- assert!(!termios
- .output_flags
- .contains(OutputFlags::OPOST | OutputFlags::OCRNL));
-
- // Specify that '\r' characters should be transformed to '\n'
- // OPOST is specified to enable post-processing
- termios
- .output_flags
- .insert(OutputFlags::OPOST | OutputFlags::OCRNL);
-
- // Open a pty
- let pty = openpty(None, &termios).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Write into the master
- let string = "foofoofoo\r";
- write_all(pty.master, string.as_bytes());
-
- // Read from the slave verifying that the output has been properly transformed
- let mut buf = [0u8; 10];
- crate::read_exact(pty.slave, &mut buf);
- let transformed_string = "foofoofoo\n";
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- assert_eq!(&buf, transformed_string.as_bytes());
-}
-
-// Test modifying local flags
-#[test]
-fn test_local_flags() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open one pty to get attributes for the second one
- let mut termios = {
- let pty = openpty(None, None).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
- let termios = tcgetattr(pty.slave).unwrap();
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- termios
- };
-
- // Make sure echo is specified by default or this test is useless.
- assert!(termios.local_flags.contains(LocalFlags::ECHO));
-
- // Disable local echo
- termios.local_flags.remove(LocalFlags::ECHO);
-
- // Open a new pty with our modified termios settings
- let pty = openpty(None, &termios).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Set the master is in nonblocking mode or reading will never return.
- let flags = fcntl::fcntl(pty.master, fcntl::F_GETFL).unwrap();
- let new_flags =
- fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK;
- fcntl::fcntl(pty.master, fcntl::F_SETFL(new_flags)).unwrap();
-
- // Write into the master
- let string = "foofoofoo\r";
- write_all(pty.master, string.as_bytes());
-
- // Try to read from the master, which should not have anything as echoing was disabled.
- let mut buf = [0u8; 10];
- let read = read(pty.master, &mut buf).unwrap_err();
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- assert_eq!(read, Errno::EAGAIN);
-}
diff --git a/vendor/nix/test/sys/test_timerfd.rs b/vendor/nix/test/sys/test_timerfd.rs
deleted file mode 100644
index 08e292106..000000000
--- a/vendor/nix/test/sys/test_timerfd.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use nix::sys::time::{TimeSpec, TimeValLike};
-use nix::sys::timerfd::{
- ClockId, Expiration, TimerFd, TimerFlags, TimerSetTimeFlags,
-};
-use std::time::Instant;
-
-#[test]
-pub fn test_timerfd_oneshot() {
- let timer =
- TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
-
- let before = Instant::now();
-
- timer
- .set(
- Expiration::OneShot(TimeSpec::seconds(1)),
- TimerSetTimeFlags::empty(),
- )
- .unwrap();
-
- timer.wait().unwrap();
-
- let millis = before.elapsed().as_millis();
- assert!(millis > 900);
-}
-
-#[test]
-pub fn test_timerfd_interval() {
- let timer =
- TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
-
- let before = Instant::now();
- timer
- .set(
- Expiration::IntervalDelayed(
- TimeSpec::seconds(1),
- TimeSpec::seconds(2),
- ),
- TimerSetTimeFlags::empty(),
- )
- .unwrap();
-
- timer.wait().unwrap();
-
- let start_delay = before.elapsed().as_millis();
- assert!(start_delay > 900);
-
- timer.wait().unwrap();
-
- let interval_delay = before.elapsed().as_millis();
- assert!(interval_delay > 2900);
-}
-
-#[test]
-pub fn test_timerfd_unset() {
- let timer =
- TimerFd::new(ClockId::CLOCK_MONOTONIC, TimerFlags::empty()).unwrap();
-
- timer
- .set(
- Expiration::OneShot(TimeSpec::seconds(1)),
- TimerSetTimeFlags::empty(),
- )
- .unwrap();
-
- timer.unset().unwrap();
-
- assert!(timer.get().unwrap().is_none());
-}
diff --git a/vendor/nix/test/sys/test_uio.rs b/vendor/nix/test/sys/test_uio.rs
deleted file mode 100644
index 0f4b8a656..000000000
--- a/vendor/nix/test/sys/test_uio.rs
+++ /dev/null
@@ -1,270 +0,0 @@
-use nix::sys::uio::*;
-use nix::unistd::*;
-use rand::distributions::Alphanumeric;
-use rand::{thread_rng, Rng};
-use std::fs::OpenOptions;
-use std::io::IoSlice;
-use std::os::unix::io::AsRawFd;
-use std::{cmp, iter};
-
-#[cfg(not(target_os = "redox"))]
-use std::io::IoSliceMut;
-
-use tempfile::tempdir;
-#[cfg(not(target_os = "redox"))]
-use tempfile::tempfile;
-
-#[test]
-fn test_writev() {
- let mut to_write = Vec::with_capacity(16 * 128);
- for _ in 0..16 {
- let s: String = thread_rng()
- .sample_iter(&Alphanumeric)
- .map(char::from)
- .take(128)
- .collect();
- let b = s.as_bytes();
- to_write.extend(b.iter().cloned());
- }
- // Allocate and fill iovecs
- let mut iovecs = Vec::new();
- let mut consumed = 0;
- while consumed < to_write.len() {
- let left = to_write.len() - consumed;
- let slice_len = if left <= 64 {
- left
- } else {
- thread_rng().gen_range(64..cmp::min(256, left))
- };
- let b = &to_write[consumed..consumed + slice_len];
- iovecs.push(IoSlice::new(b));
- consumed += slice_len;
- }
- let pipe_res = pipe();
- let (reader, writer) = pipe_res.expect("Couldn't create pipe");
- // FileDesc will close its filedesc (reader).
- let mut read_buf: Vec<u8> = iter::repeat(0u8).take(128 * 16).collect();
- // Blocking io, should write all data.
- let write_res = writev(writer, &iovecs);
- let written = write_res.expect("couldn't write");
- // Check whether we written all data
- assert_eq!(to_write.len(), written);
- let read_res = read(reader, &mut read_buf[..]);
- let read = read_res.expect("couldn't read");
- // Check we have read as much as we written
- assert_eq!(read, written);
- // Check equality of written and read data
- assert_eq!(&to_write, &read_buf);
- close(writer).expect("closed writer");
- close(reader).expect("closed reader");
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_readv() {
- let s: String = thread_rng()
- .sample_iter(&Alphanumeric)
- .map(char::from)
- .take(128)
- .collect();
- let to_write = s.as_bytes().to_vec();
- let mut storage = Vec::new();
- let mut allocated = 0;
- while allocated < to_write.len() {
- let left = to_write.len() - allocated;
- let vec_len = if left <= 64 {
- left
- } else {
- thread_rng().gen_range(64..cmp::min(256, left))
- };
- let v: Vec<u8> = iter::repeat(0u8).take(vec_len).collect();
- storage.push(v);
- allocated += vec_len;
- }
- let mut iovecs = Vec::with_capacity(storage.len());
- for v in &mut storage {
- iovecs.push(IoSliceMut::new(&mut v[..]));
- }
- let (reader, writer) = pipe().expect("couldn't create pipe");
- // Blocking io, should write all data.
- write(writer, &to_write).expect("write failed");
- let read = readv(reader, &mut iovecs[..]).expect("read failed");
- // Check whether we've read all data
- assert_eq!(to_write.len(), read);
- // Cccumulate data from iovecs
- let mut read_buf = Vec::with_capacity(to_write.len());
- for iovec in &iovecs {
- read_buf.extend(iovec.iter().cloned());
- }
- // Check whether iovecs contain all written data
- assert_eq!(read_buf.len(), to_write.len());
- // Check equality of written and read data
- assert_eq!(&read_buf, &to_write);
- close(reader).expect("couldn't close reader");
- close(writer).expect("couldn't close writer");
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_pwrite() {
- use std::io::Read;
-
- let mut file = tempfile().unwrap();
- let buf = [1u8; 8];
- assert_eq!(Ok(8), pwrite(file.as_raw_fd(), &buf, 8));
- let mut file_content = Vec::new();
- file.read_to_end(&mut file_content).unwrap();
- let mut expected = vec![0u8; 8];
- expected.extend(vec![1; 8]);
- assert_eq!(file_content, expected);
-}
-
-#[test]
-fn test_pread() {
- use std::io::Write;
-
- let tempdir = tempdir().unwrap();
-
- let path = tempdir.path().join("pread_test_file");
- let mut file = OpenOptions::new()
- .write(true)
- .read(true)
- .create(true)
- .truncate(true)
- .open(path)
- .unwrap();
- let file_content: Vec<u8> = (0..64).collect();
- file.write_all(&file_content).unwrap();
-
- let mut buf = [0u8; 16];
- assert_eq!(Ok(16), pread(file.as_raw_fd(), &mut buf, 16));
- let expected: Vec<_> = (16..32).collect();
- assert_eq!(&buf[..], &expected[..]);
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_pwritev() {
- use std::io::Read;
-
- let to_write: Vec<u8> = (0..128).collect();
- let expected: Vec<u8> = [vec![0; 100], to_write.clone()].concat();
-
- let iovecs = [
- IoSlice::new(&to_write[0..17]),
- IoSlice::new(&to_write[17..64]),
- IoSlice::new(&to_write[64..128]),
- ];
-
- let tempdir = tempdir().unwrap();
-
- // pwritev them into a temporary file
- let path = tempdir.path().join("pwritev_test_file");
- let mut file = OpenOptions::new()
- .write(true)
- .read(true)
- .create(true)
- .truncate(true)
- .open(path)
- .unwrap();
-
- let written = pwritev(file.as_raw_fd(), &iovecs, 100).ok().unwrap();
- assert_eq!(written, to_write.len());
-
- // Read the data back and make sure it matches
- let mut contents = Vec::new();
- file.read_to_end(&mut contents).unwrap();
- assert_eq!(contents, expected);
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_preadv() {
- use std::io::Write;
-
- let to_write: Vec<u8> = (0..200).collect();
- let expected: Vec<u8> = (100..200).collect();
-
- let tempdir = tempdir().unwrap();
-
- let path = tempdir.path().join("preadv_test_file");
-
- let mut file = OpenOptions::new()
- .read(true)
- .write(true)
- .create(true)
- .truncate(true)
- .open(path)
- .unwrap();
- file.write_all(&to_write).unwrap();
-
- let mut buffers: Vec<Vec<u8>> = vec![vec![0; 24], vec![0; 1], vec![0; 75]];
-
- {
- // Borrow the buffers into IoVecs and preadv into them
- let mut iovecs: Vec<_> = buffers
- .iter_mut()
- .map(|buf| IoSliceMut::new(&mut buf[..]))
- .collect();
- assert_eq!(Ok(100), preadv(file.as_raw_fd(), &mut iovecs, 100));
- }
-
- let all = buffers.concat();
- assert_eq!(all, expected);
-}
-
-#[test]
-#[cfg(all(target_os = "linux", not(target_env = "uclibc")))]
-// uclibc doesn't implement process_vm_readv
-// qemu-user doesn't implement process_vm_readv/writev on most arches
-#[cfg_attr(qemu, ignore)]
-fn test_process_vm_readv() {
- use crate::*;
- use nix::sys::signal::*;
- use nix::sys::wait::*;
- use nix::unistd::ForkResult::*;
-
- require_capability!("test_process_vm_readv", CAP_SYS_PTRACE);
- let _m = crate::FORK_MTX.lock();
-
- // Pre-allocate memory in the child, since allocation isn't safe
- // post-fork (~= async-signal-safe)
- let mut vector = vec![1u8, 2, 3, 4, 5];
-
- let (r, w) = pipe().unwrap();
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Parent { child } => {
- close(w).unwrap();
- // wait for child
- read(r, &mut [0u8]).unwrap();
- close(r).unwrap();
-
- let ptr = vector.as_ptr() as usize;
- let remote_iov = RemoteIoVec { base: ptr, len: 5 };
- let mut buf = vec![0u8; 5];
-
- let ret = process_vm_readv(
- child,
- &mut [IoSliceMut::new(&mut buf)],
- &[remote_iov],
- );
-
- kill(child, SIGTERM).unwrap();
- waitpid(child, None).unwrap();
-
- assert_eq!(Ok(5), ret);
- assert_eq!(20u8, buf.iter().sum());
- }
- Child => {
- let _ = close(r);
- for i in &mut vector {
- *i += 1;
- }
- let _ = write(w, b"\0");
- let _ = close(w);
- loop {
- pause();
- }
- }
- }
-}
diff --git a/vendor/nix/test/sys/test_wait.rs b/vendor/nix/test/sys/test_wait.rs
deleted file mode 100644
index d472f1ec1..000000000
--- a/vendor/nix/test/sys/test_wait.rs
+++ /dev/null
@@ -1,257 +0,0 @@
-use libc::_exit;
-use nix::errno::Errno;
-use nix::sys::signal::*;
-use nix::sys::wait::*;
-use nix::unistd::ForkResult::*;
-use nix::unistd::*;
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_wait_signal() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- pause();
- unsafe { _exit(123) }
- }
- Parent { child } => {
- kill(child, Some(SIGKILL)).expect("Error: Kill Failed");
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Signaled(child, SIGKILL, false))
- );
- }
- }
-}
-
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- //target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
-fn test_waitid_signal() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => {
- pause();
- unsafe { _exit(123) }
- }
- Parent { child } => {
- kill(child, Some(SIGKILL)).expect("Error: Kill Failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::Signaled(child, SIGKILL, false)),
- );
- }
- }
-}
-
-#[test]
-fn test_wait_exit() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: Child only calls `_exit`, which is async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => unsafe {
- _exit(12);
- },
- Parent { child } => {
- assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
- }
- }
-}
-
-#[cfg(not(target_os = "haiku"))]
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-#[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
-fn test_waitid_exit() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: Child only calls `_exit`, which is async-signal-safe.
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => unsafe {
- _exit(12);
- },
- Parent { child } => {
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::Exited(child, 12)),
- );
- }
- }
-}
-
-#[test]
-fn test_waitstatus_from_raw() {
- let pid = Pid::from_raw(1);
- assert_eq!(
- WaitStatus::from_raw(pid, 0x0002),
- Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false))
- );
- assert_eq!(
- WaitStatus::from_raw(pid, 0x0200),
- Ok(WaitStatus::Exited(pid, 2))
- );
- assert_eq!(WaitStatus::from_raw(pid, 0x7f7f), Err(Errno::EINVAL));
-}
-
-#[test]
-fn test_waitstatus_pid() {
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.unwrap() {
- Child => unsafe { _exit(0) },
- Parent { child } => {
- let status = waitpid(child, None).unwrap();
- assert_eq!(status.pid(), Some(child));
- }
- }
-}
-
-#[test]
-#[cfg(any(
- target_os = "android",
- target_os = "freebsd",
- target_os = "haiku",
- all(target_os = "linux", not(target_env = "uclibc")),
-))]
-fn test_waitid_pid() {
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.unwrap() {
- Child => unsafe { _exit(0) },
- Parent { child } => {
- let status = waitid(Id::Pid(child), WaitPidFlag::WEXITED).unwrap();
- assert_eq!(status.pid(), Some(child));
- }
- }
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-// FIXME: qemu-user doesn't implement ptrace on most arches
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-mod ptrace {
- use crate::*;
- use libc::_exit;
- use nix::sys::ptrace::{self, Event, Options};
- use nix::sys::signal::*;
- use nix::sys::wait::*;
- use nix::unistd::ForkResult::*;
- use nix::unistd::*;
-
- fn ptrace_child() -> ! {
- ptrace::traceme().unwrap();
- // As recommended by ptrace(2), raise SIGTRAP to pause the child
- // until the parent is ready to continue
- raise(SIGTRAP).unwrap();
- unsafe { _exit(0) }
- }
-
- fn ptrace_wait_parent(child: Pid) {
- // Wait for the raised SIGTRAP
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::Stopped(child, SIGTRAP))
- );
- // We want to test a syscall stop and a PTRACE_EVENT stop
- ptrace::setoptions(
- child,
- Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT,
- )
- .expect("setoptions failed");
-
- // First, stop on the next system call, which will be exit()
- ptrace::syscall(child, None).expect("syscall failed");
- assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
- // Then get the ptrace event for the process exiting
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(
- waitpid(child, None),
- Ok(WaitStatus::PtraceEvent(
- child,
- SIGTRAP,
- Event::PTRACE_EVENT_EXIT as i32
- ))
- );
- // Finally get the normal wait() result, now that the process has exited
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0)));
- }
-
- #[cfg(not(target_env = "uclibc"))]
- fn ptrace_waitid_parent(child: Pid) {
- // Wait for the raised SIGTRAP
- //
- // Unlike waitpid(), waitid() can distinguish trap events from regular
- // stop events, so unlike ptrace_wait_parent(), we get a PtraceEvent here
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::PtraceEvent(child, SIGTRAP, 0)),
- );
- // We want to test a syscall stop and a PTRACE_EVENT stop
- ptrace::setoptions(
- child,
- Options::PTRACE_O_TRACESYSGOOD | Options::PTRACE_O_TRACEEXIT,
- )
- .expect("setopts failed");
-
- // First, stop on the next system call, which will be exit()
- ptrace::syscall(child, None).expect("syscall failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::PtraceSyscall(child)),
- );
- // Then get the ptrace event for the process exiting
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::PtraceEvent(
- child,
- SIGTRAP,
- Event::PTRACE_EVENT_EXIT as i32
- )),
- );
- // Finally get the normal wait() result, now that the process has exited
- ptrace::cont(child, None).expect("cont failed");
- assert_eq!(
- waitid(Id::Pid(child), WaitPidFlag::WEXITED),
- Ok(WaitStatus::Exited(child, 0)),
- );
- }
-
- #[test]
- fn test_wait_ptrace() {
- require_capability!("test_wait_ptrace", CAP_SYS_PTRACE);
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => ptrace_child(),
- Parent { child } => ptrace_wait_parent(child),
- }
- }
-
- #[test]
- #[cfg(not(target_env = "uclibc"))]
- fn test_waitid_ptrace() {
- require_capability!("test_waitid_ptrace", CAP_SYS_PTRACE);
- let _m = crate::FORK_MTX.lock();
-
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => ptrace_child(),
- Parent { child } => ptrace_waitid_parent(child),
- }
- }
-}
diff --git a/vendor/nix/test/test.rs b/vendor/nix/test/test.rs
deleted file mode 100644
index 6b42aad95..000000000
--- a/vendor/nix/test/test.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-#[macro_use]
-extern crate cfg_if;
-#[cfg_attr(not(any(target_os = "redox", target_os = "haiku")), macro_use)]
-extern crate nix;
-#[macro_use]
-extern crate lazy_static;
-
-mod common;
-mod sys;
-#[cfg(not(target_os = "redox"))]
-mod test_dir;
-mod test_fcntl;
-#[cfg(any(target_os = "android", target_os = "linux"))]
-mod test_kmod;
-#[cfg(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "fushsia",
- target_os = "linux",
- target_os = "netbsd"
-))]
-mod test_mq;
-#[cfg(not(target_os = "redox"))]
-mod test_net;
-mod test_nix_path;
-#[cfg(target_os = "freebsd")]
-mod test_nmount;
-mod test_poll;
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-mod test_pty;
-mod test_resource;
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- all(target_os = "freebsd", fbsd14),
- target_os = "linux"
-))]
-mod test_sched;
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos"
-))]
-mod test_sendfile;
-mod test_stat;
-mod test_time;
-#[cfg(all(
- any(
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd"
- ),
- feature = "time",
- feature = "signal"
-))]
-mod test_timer;
-mod test_unistd;
-
-use nix::unistd::{chdir, getcwd, read};
-use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
-use std::os::unix::io::RawFd;
-use std::path::PathBuf;
-
-/// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
-fn read_exact(f: RawFd, buf: &mut [u8]) {
- let mut len = 0;
- while len < buf.len() {
- // get_mut would be better than split_at_mut, but it requires nightly
- let (_, remaining) = buf.split_at_mut(len);
- len += read(f, remaining).unwrap();
- }
-}
-
-lazy_static! {
- /// Any test that changes the process's current working directory must grab
- /// the RwLock exclusively. Any process that cares about the current
- /// working directory must grab it shared.
- pub static ref CWD_LOCK: RwLock<()> = RwLock::new(());
- /// Any test that creates child processes must grab this mutex, regardless
- /// of what it does with those children.
- pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
- /// Any test that changes the process's supplementary groups must grab this
- /// mutex
- pub static ref GROUPS_MTX: Mutex<()> = Mutex::new(());
- /// Any tests that loads or unloads kernel modules must grab this mutex
- pub static ref KMOD_MTX: Mutex<()> = Mutex::new(());
- /// Any test that calls ptsname(3) must grab this mutex.
- pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(());
- /// Any test that alters signal handling must grab this mutex.
- pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
-}
-
-/// RAII object that restores a test's original directory on drop
-struct DirRestore<'a> {
- d: PathBuf,
- _g: RwLockWriteGuard<'a, ()>,
-}
-
-impl<'a> DirRestore<'a> {
- fn new() -> Self {
- let guard = crate::CWD_LOCK.write();
- DirRestore {
- _g: guard,
- d: getcwd().unwrap(),
- }
- }
-}
-
-impl<'a> Drop for DirRestore<'a> {
- fn drop(&mut self) {
- let r = chdir(&self.d);
- if std::thread::panicking() {
- r.unwrap();
- }
- }
-}
diff --git a/vendor/nix/test/test_clearenv.rs b/vendor/nix/test/test_clearenv.rs
deleted file mode 100644
index 28a776804..000000000
--- a/vendor/nix/test/test_clearenv.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use std::env;
-
-#[test]
-fn clearenv() {
- env::set_var("FOO", "BAR");
- unsafe { nix::env::clearenv() }.unwrap();
- assert_eq!(env::var("FOO").unwrap_err(), env::VarError::NotPresent);
- assert_eq!(env::vars().count(), 0);
-}
diff --git a/vendor/nix/test/test_dir.rs b/vendor/nix/test/test_dir.rs
deleted file mode 100644
index 2af4aa5c0..000000000
--- a/vendor/nix/test/test_dir.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use nix::dir::{Dir, Type};
-use nix::fcntl::OFlag;
-use nix::sys::stat::Mode;
-use std::fs::File;
-use tempfile::tempdir;
-
-#[cfg(test)]
-fn flags() -> OFlag {
- #[cfg(target_os = "illumos")]
- let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC;
-
- #[cfg(not(target_os = "illumos"))]
- let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC | OFlag::O_DIRECTORY;
-
- f
-}
-
-#[test]
-#[allow(clippy::unnecessary_sort_by)] // False positive
-fn read() {
- let tmp = tempdir().unwrap();
- File::create(tmp.path().join("foo")).unwrap();
- std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap();
- let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap();
- let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect();
- entries.sort_by(|a, b| a.file_name().cmp(b.file_name()));
- let entry_names: Vec<_> = entries
- .iter()
- .map(|e| e.file_name().to_str().unwrap().to_owned())
- .collect();
- assert_eq!(&entry_names[..], &[".", "..", "bar", "foo"]);
-
- // Check file types. The system is allowed to return DT_UNKNOWN (aka None here) but if it does
- // return a type, ensure it's correct.
- assert!(&[Some(Type::Directory), None].contains(&entries[0].file_type())); // .: dir
- assert!(&[Some(Type::Directory), None].contains(&entries[1].file_type())); // ..: dir
- assert!(&[Some(Type::Symlink), None].contains(&entries[2].file_type())); // bar: symlink
- assert!(&[Some(Type::File), None].contains(&entries[3].file_type())); // foo: regular file
-}
-
-#[test]
-fn rewind() {
- let tmp = tempdir().unwrap();
- let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap();
- let entries1: Vec<_> = dir
- .iter()
- .map(|e| e.unwrap().file_name().to_owned())
- .collect();
- let entries2: Vec<_> = dir
- .iter()
- .map(|e| e.unwrap().file_name().to_owned())
- .collect();
- let entries3: Vec<_> = dir
- .into_iter()
- .map(|e| e.unwrap().file_name().to_owned())
- .collect();
- assert_eq!(entries1, entries2);
- assert_eq!(entries2, entries3);
-}
-
-#[cfg(not(target_os = "haiku"))]
-#[test]
-fn ebadf() {
- assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::EBADF);
-}
diff --git a/vendor/nix/test/test_fcntl.rs b/vendor/nix/test/test_fcntl.rs
deleted file mode 100644
index e51044a06..000000000
--- a/vendor/nix/test/test_fcntl.rs
+++ /dev/null
@@ -1,565 +0,0 @@
-#[cfg(not(target_os = "redox"))]
-use nix::errno::*;
-#[cfg(not(target_os = "redox"))]
-use nix::fcntl::{open, readlink, OFlag};
-#[cfg(not(target_os = "redox"))]
-use nix::fcntl::{openat, readlinkat, renameat};
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
- any(
- target_arch = "x86_64",
- target_arch = "x32",
- target_arch = "powerpc",
- target_arch = "s390x"
- )
-))]
-use nix::fcntl::{renameat2, RenameFlags};
-#[cfg(not(target_os = "redox"))]
-use nix::sys::stat::Mode;
-#[cfg(not(target_os = "redox"))]
-use nix::unistd::{close, read};
-#[cfg(not(target_os = "redox"))]
-use std::fs::File;
-#[cfg(not(target_os = "redox"))]
-use std::io::prelude::*;
-#[cfg(not(target_os = "redox"))]
-use std::os::unix::fs;
-#[cfg(not(target_os = "redox"))]
-use tempfile::{self, NamedTempFile};
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-// QEMU does not handle openat well enough to satisfy this test
-// https://gitlab.com/qemu-project/qemu/-/issues/829
-#[cfg_attr(qemu, ignore)]
-fn test_openat() {
- const CONTENTS: &[u8] = b"abcd";
- let mut tmp = NamedTempFile::new().unwrap();
- tmp.write_all(CONTENTS).unwrap();
-
- let dirfd =
- open(tmp.path().parent().unwrap(), OFlag::empty(), Mode::empty())
- .unwrap();
- let fd = openat(
- dirfd,
- tmp.path().file_name().unwrap(),
- OFlag::O_RDONLY,
- Mode::empty(),
- )
- .unwrap();
-
- let mut buf = [0u8; 1024];
- assert_eq!(4, read(fd, &mut buf).unwrap());
- assert_eq!(CONTENTS, &buf[0..4]);
-
- close(fd).unwrap();
- close(dirfd).unwrap();
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_renameat() {
- let old_dir = tempfile::tempdir().unwrap();
- let old_dirfd =
- open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let old_path = old_dir.path().join("old");
- File::create(old_path).unwrap();
- let new_dir = tempfile::tempdir().unwrap();
- let new_dirfd =
- open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap();
- assert_eq!(
- renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap_err(),
- Errno::ENOENT
- );
- close(old_dirfd).unwrap();
- close(new_dirfd).unwrap();
- assert!(new_dir.path().join("new").exists());
-}
-
-#[test]
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
- any(
- target_arch = "x86_64",
- target_arch = "x32",
- target_arch = "powerpc",
- target_arch = "s390x"
- )
-))]
-fn test_renameat2_behaves_like_renameat_with_no_flags() {
- let old_dir = tempfile::tempdir().unwrap();
- let old_dirfd =
- open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let old_path = old_dir.path().join("old");
- File::create(old_path).unwrap();
- let new_dir = tempfile::tempdir().unwrap();
- let new_dirfd =
- open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- renameat2(
- Some(old_dirfd),
- "old",
- Some(new_dirfd),
- "new",
- RenameFlags::empty(),
- )
- .unwrap();
- assert_eq!(
- renameat2(
- Some(old_dirfd),
- "old",
- Some(new_dirfd),
- "new",
- RenameFlags::empty()
- )
- .unwrap_err(),
- Errno::ENOENT
- );
- close(old_dirfd).unwrap();
- close(new_dirfd).unwrap();
- assert!(new_dir.path().join("new").exists());
-}
-
-#[test]
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
- any(
- target_arch = "x86_64",
- target_arch = "x32",
- target_arch = "powerpc",
- target_arch = "s390x"
- )
-))]
-fn test_renameat2_exchange() {
- let old_dir = tempfile::tempdir().unwrap();
- let old_dirfd =
- open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let old_path = old_dir.path().join("old");
- {
- let mut old_f = File::create(&old_path).unwrap();
- old_f.write_all(b"old").unwrap();
- }
- let new_dir = tempfile::tempdir().unwrap();
- let new_dirfd =
- open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let new_path = new_dir.path().join("new");
- {
- let mut new_f = File::create(&new_path).unwrap();
- new_f.write_all(b"new").unwrap();
- }
- renameat2(
- Some(old_dirfd),
- "old",
- Some(new_dirfd),
- "new",
- RenameFlags::RENAME_EXCHANGE,
- )
- .unwrap();
- let mut buf = String::new();
- let mut new_f = File::open(&new_path).unwrap();
- new_f.read_to_string(&mut buf).unwrap();
- assert_eq!(buf, "old");
- buf = "".to_string();
- let mut old_f = File::open(&old_path).unwrap();
- old_f.read_to_string(&mut buf).unwrap();
- assert_eq!(buf, "new");
- close(old_dirfd).unwrap();
- close(new_dirfd).unwrap();
-}
-
-#[test]
-#[cfg(all(
- target_os = "linux",
- target_env = "gnu",
- any(
- target_arch = "x86_64",
- target_arch = "x32",
- target_arch = "powerpc",
- target_arch = "s390x"
- )
-))]
-fn test_renameat2_noreplace() {
- let old_dir = tempfile::tempdir().unwrap();
- let old_dirfd =
- open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let old_path = old_dir.path().join("old");
- File::create(old_path).unwrap();
- let new_dir = tempfile::tempdir().unwrap();
- let new_dirfd =
- open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let new_path = new_dir.path().join("new");
- File::create(new_path).unwrap();
- assert_eq!(
- renameat2(
- Some(old_dirfd),
- "old",
- Some(new_dirfd),
- "new",
- RenameFlags::RENAME_NOREPLACE
- )
- .unwrap_err(),
- Errno::EEXIST
- );
- close(old_dirfd).unwrap();
- close(new_dirfd).unwrap();
- assert!(new_dir.path().join("new").exists());
- assert!(old_dir.path().join("old").exists());
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_readlink() {
- let tempdir = tempfile::tempdir().unwrap();
- let src = tempdir.path().join("a");
- let dst = tempdir.path().join("b");
- println!("a: {:?}, b: {:?}", &src, &dst);
- fs::symlink(src.as_path(), dst.as_path()).unwrap();
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let expected_dir = src.to_str().unwrap();
-
- assert_eq!(readlink(&dst).unwrap().to_str().unwrap(), expected_dir);
- assert_eq!(
- readlinkat(dirfd, "b").unwrap().to_str().unwrap(),
- expected_dir
- );
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod linux_android {
- use libc::loff_t;
- use std::io::prelude::*;
- use std::io::IoSlice;
- use std::os::unix::prelude::*;
-
- use nix::fcntl::*;
- use nix::unistd::{close, pipe, read, write};
-
- use tempfile::tempfile;
- #[cfg(any(target_os = "linux"))]
- use tempfile::NamedTempFile;
-
- use crate::*;
-
- /// This test creates a temporary file containing the contents
- /// 'foobarbaz' and uses the `copy_file_range` call to transfer
- /// 3 bytes at offset 3 (`bar`) to another empty file at offset 0. The
- /// resulting file is read and should contain the contents `bar`.
- /// The from_offset should be updated by the call to reflect
- /// the 3 bytes read (6).
- #[test]
- // QEMU does not support copy_file_range. Skip under qemu
- #[cfg_attr(qemu, ignore)]
- fn test_copy_file_range() {
- const CONTENTS: &[u8] = b"foobarbaz";
-
- let mut tmp1 = tempfile().unwrap();
- let mut tmp2 = tempfile().unwrap();
-
- tmp1.write_all(CONTENTS).unwrap();
- tmp1.flush().unwrap();
-
- let mut from_offset: i64 = 3;
- copy_file_range(
- tmp1.as_raw_fd(),
- Some(&mut from_offset),
- tmp2.as_raw_fd(),
- None,
- 3,
- )
- .unwrap();
-
- let mut res: String = String::new();
- tmp2.rewind().unwrap();
- tmp2.read_to_string(&mut res).unwrap();
-
- assert_eq!(res, String::from("bar"));
- assert_eq!(from_offset, 6);
- }
-
- #[test]
- fn test_splice() {
- const CONTENTS: &[u8] = b"abcdef123456";
- let mut tmp = tempfile().unwrap();
- tmp.write_all(CONTENTS).unwrap();
-
- let (rd, wr) = pipe().unwrap();
- let mut offset: loff_t = 5;
- let res = splice(
- tmp.as_raw_fd(),
- Some(&mut offset),
- wr,
- None,
- 2,
- SpliceFFlags::empty(),
- )
- .unwrap();
-
- assert_eq!(2, res);
-
- let mut buf = [0u8; 1024];
- assert_eq!(2, read(rd, &mut buf).unwrap());
- assert_eq!(b"f1", &buf[0..2]);
- assert_eq!(7, offset);
-
- close(rd).unwrap();
- close(wr).unwrap();
- }
-
- #[test]
- fn test_tee() {
- let (rd1, wr1) = pipe().unwrap();
- let (rd2, wr2) = pipe().unwrap();
-
- write(wr1, b"abc").unwrap();
- let res = tee(rd1, wr2, 2, SpliceFFlags::empty()).unwrap();
-
- assert_eq!(2, res);
-
- let mut buf = [0u8; 1024];
-
- // Check the tee'd bytes are at rd2.
- assert_eq!(2, read(rd2, &mut buf).unwrap());
- assert_eq!(b"ab", &buf[0..2]);
-
- // Check all the bytes are still at rd1.
- assert_eq!(3, read(rd1, &mut buf).unwrap());
- assert_eq!(b"abc", &buf[0..3]);
-
- close(rd1).unwrap();
- close(wr1).unwrap();
- close(rd2).unwrap();
- close(wr2).unwrap();
- }
-
- #[test]
- fn test_vmsplice() {
- let (rd, wr) = pipe().unwrap();
-
- let buf1 = b"abcdef";
- let buf2 = b"defghi";
- let iovecs = vec![IoSlice::new(&buf1[0..3]), IoSlice::new(&buf2[0..3])];
-
- let res = vmsplice(wr, &iovecs[..], SpliceFFlags::empty()).unwrap();
-
- assert_eq!(6, res);
-
- // Check the bytes can be read at rd.
- let mut buf = [0u8; 32];
- assert_eq!(6, read(rd, &mut buf).unwrap());
- assert_eq!(b"abcdef", &buf[0..6]);
-
- close(rd).unwrap();
- close(wr).unwrap();
- }
-
- #[cfg(any(target_os = "linux"))]
- #[test]
- fn test_fallocate() {
- let tmp = NamedTempFile::new().unwrap();
-
- let fd = tmp.as_raw_fd();
- fallocate(fd, FallocateFlags::empty(), 0, 100).unwrap();
-
- // Check if we read exactly 100 bytes
- let mut buf = [0u8; 200];
- assert_eq!(100, read(fd, &mut buf).unwrap());
- }
-
- // The tests below are disabled for the listed targets
- // due to OFD locks not being available in the kernel/libc
- // versions used in the CI environment, probably because
- // they run under QEMU.
-
- #[test]
- #[cfg(all(target_os = "linux", not(target_env = "musl")))]
- #[cfg_attr(target_env = "uclibc", ignore)] // uclibc doesn't support OFD locks, but the test should still compile
- fn test_ofd_write_lock() {
- use nix::sys::stat::fstat;
- use std::mem;
-
- let tmp = NamedTempFile::new().unwrap();
-
- let fd = tmp.as_raw_fd();
- let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap();
- if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC {
- // OverlayFS is a union file system. It returns one inode value in
- // stat(2), but a different one shows up in /proc/locks. So we must
- // skip the test.
- skip!("/proc/locks does not work on overlayfs");
- }
- let inode = fstat(fd).expect("fstat failed").st_ino as usize;
-
- let mut flock: libc::flock = unsafe {
- mem::zeroed() // required for Linux/mips
- };
- flock.l_type = libc::F_WRLCK as libc::c_short;
- flock.l_whence = libc::SEEK_SET as libc::c_short;
- flock.l_start = 0;
- flock.l_len = 0;
- flock.l_pid = 0;
- fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write lock failed");
- assert_eq!(
- Some(("OFDLCK".to_string(), "WRITE".to_string())),
- lock_info(inode)
- );
-
- flock.l_type = libc::F_UNLCK as libc::c_short;
- fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("write unlock failed");
- assert_eq!(None, lock_info(inode));
- }
-
- #[test]
- #[cfg(all(target_os = "linux", not(target_env = "musl")))]
- #[cfg_attr(target_env = "uclibc", ignore)] // uclibc doesn't support OFD locks, but the test should still compile
- fn test_ofd_read_lock() {
- use nix::sys::stat::fstat;
- use std::mem;
-
- let tmp = NamedTempFile::new().unwrap();
-
- let fd = tmp.as_raw_fd();
- let statfs = nix::sys::statfs::fstatfs(&tmp).unwrap();
- if statfs.filesystem_type() == nix::sys::statfs::OVERLAYFS_SUPER_MAGIC {
- // OverlayFS is a union file system. It returns one inode value in
- // stat(2), but a different one shows up in /proc/locks. So we must
- // skip the test.
- skip!("/proc/locks does not work on overlayfs");
- }
- let inode = fstat(fd).expect("fstat failed").st_ino as usize;
-
- let mut flock: libc::flock = unsafe {
- mem::zeroed() // required for Linux/mips
- };
- flock.l_type = libc::F_RDLCK as libc::c_short;
- flock.l_whence = libc::SEEK_SET as libc::c_short;
- flock.l_start = 0;
- flock.l_len = 0;
- flock.l_pid = 0;
- fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read lock failed");
- assert_eq!(
- Some(("OFDLCK".to_string(), "READ".to_string())),
- lock_info(inode)
- );
-
- flock.l_type = libc::F_UNLCK as libc::c_short;
- fcntl(fd, FcntlArg::F_OFD_SETLKW(&flock)).expect("read unlock failed");
- assert_eq!(None, lock_info(inode));
- }
-
- #[cfg(all(target_os = "linux", not(target_env = "musl")))]
- fn lock_info(inode: usize) -> Option<(String, String)> {
- use std::{fs::File, io::BufReader};
-
- let file = File::open("/proc/locks").expect("open /proc/locks failed");
- let buf = BufReader::new(file);
-
- for line in buf.lines() {
- let line = line.unwrap();
- let parts: Vec<_> = line.split_whitespace().collect();
- let lock_type = parts[1];
- let lock_access = parts[3];
- let ino_parts: Vec<_> = parts[5].split(':').collect();
- let ino: usize = ino_parts[2].parse().unwrap();
- if ino == inode {
- return Some((lock_type.to_string(), lock_access.to_string()));
- }
- }
- None
- }
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "wasi",
- target_env = "uclibc",
- target_os = "freebsd"
-))]
-mod test_posix_fadvise {
-
- use nix::errno::Errno;
- use nix::fcntl::*;
- use nix::unistd::pipe;
- use std::os::unix::io::{AsRawFd, RawFd};
- use tempfile::NamedTempFile;
-
- #[test]
- fn test_success() {
- let tmp = NamedTempFile::new().unwrap();
- let fd = tmp.as_raw_fd();
- posix_fadvise(fd, 0, 100, PosixFadviseAdvice::POSIX_FADV_WILLNEED)
- .expect("posix_fadvise failed");
- }
-
- #[test]
- fn test_errno() {
- let (rd, _wr) = pipe().unwrap();
- let res = posix_fadvise(
- rd as RawFd,
- 0,
- 100,
- PosixFadviseAdvice::POSIX_FADV_WILLNEED,
- );
- assert_eq!(res, Err(Errno::ESPIPE));
- }
-}
-
-#[cfg(any(
- target_os = "linux",
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "wasi",
- target_os = "freebsd"
-))]
-mod test_posix_fallocate {
-
- use nix::errno::Errno;
- use nix::fcntl::*;
- use nix::unistd::pipe;
- use std::{
- io::Read,
- os::unix::io::{AsRawFd, RawFd},
- };
- use tempfile::NamedTempFile;
-
- #[test]
- fn success() {
- const LEN: usize = 100;
- let mut tmp = NamedTempFile::new().unwrap();
- let fd = tmp.as_raw_fd();
- let res = posix_fallocate(fd, 0, LEN as libc::off_t);
- match res {
- Ok(_) => {
- let mut data = [1u8; LEN];
- assert_eq!(tmp.read(&mut data).expect("read failure"), LEN);
- assert_eq!(&data[..], &[0u8; LEN][..]);
- }
- Err(Errno::EINVAL) => {
- // POSIX requires posix_fallocate to return EINVAL both for
- // invalid arguments (i.e. len < 0) and if the operation is not
- // supported by the file system.
- // There's no way to tell for sure whether the file system
- // supports posix_fallocate, so we must pass the test if it
- // returns EINVAL.
- }
- _ => res.unwrap(),
- }
- }
-
- #[test]
- fn errno() {
- let (rd, _wr) = pipe().unwrap();
- let err = posix_fallocate(rd as RawFd, 0, 100).unwrap_err();
- match err {
- Errno::EINVAL | Errno::ENODEV | Errno::ESPIPE | Errno::EBADF => (),
- errno => panic!("unexpected errno {}", errno,),
- }
- }
-}
diff --git a/vendor/nix/test/test_kmod/hello_mod/Makefile b/vendor/nix/test/test_kmod/hello_mod/Makefile
deleted file mode 100644
index 74c99b77e..000000000
--- a/vendor/nix/test/test_kmod/hello_mod/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-obj-m += hello.o
-
-all:
- make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
-
-clean:
- make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
diff --git a/vendor/nix/test/test_kmod/mod.rs b/vendor/nix/test/test_kmod/mod.rs
deleted file mode 100644
index 6f9aaa897..000000000
--- a/vendor/nix/test/test_kmod/mod.rs
+++ /dev/null
@@ -1,188 +0,0 @@
-use crate::*;
-use std::fs::copy;
-use std::path::PathBuf;
-use std::process::Command;
-use tempfile::{tempdir, TempDir};
-
-fn compile_kernel_module() -> (PathBuf, String, TempDir) {
- let _m = crate::FORK_MTX.lock();
-
- let tmp_dir =
- tempdir().expect("unable to create temporary build directory");
-
- copy(
- "test/test_kmod/hello_mod/hello.c",
- tmp_dir.path().join("hello.c"),
- )
- .expect("unable to copy hello.c to temporary build directory");
- copy(
- "test/test_kmod/hello_mod/Makefile",
- tmp_dir.path().join("Makefile"),
- )
- .expect("unable to copy Makefile to temporary build directory");
-
- let status = Command::new("make")
- .current_dir(tmp_dir.path())
- .status()
- .expect("failed to run make");
-
- assert!(status.success());
-
- // Return the relative path of the build kernel module
- (tmp_dir.path().join("hello.ko"), "hello".to_owned(), tmp_dir)
-}
-
-use nix::errno::Errno;
-use nix::kmod::{delete_module, DeleteModuleFlags};
-use nix::kmod::{finit_module, init_module, ModuleInitFlags};
-use std::ffi::CString;
-use std::fs::File;
-use std::io::Read;
-
-#[test]
-fn test_finit_and_delete_module() {
- require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE);
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
-
- let f = File::open(kmod_path).expect("unable to open kernel module");
- finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty())
- .expect("unable to load kernel module");
-
- delete_module(
- &CString::new(kmod_name).unwrap(),
- DeleteModuleFlags::empty(),
- )
- .expect("unable to unload kernel module");
-}
-
-#[test]
-fn test_finit_and_delete_module_with_params() {
- require_capability!(
- "test_finit_and_delete_module_with_params",
- CAP_SYS_MODULE
- );
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
-
- let f = File::open(kmod_path).expect("unable to open kernel module");
- finit_module(
- &f,
- &CString::new("who=Rust number=2018").unwrap(),
- ModuleInitFlags::empty(),
- )
- .expect("unable to load kernel module");
-
- delete_module(
- &CString::new(kmod_name).unwrap(),
- DeleteModuleFlags::empty(),
- )
- .expect("unable to unload kernel module");
-}
-
-#[test]
-fn test_init_and_delete_module() {
- require_capability!("test_init_and_delete_module", CAP_SYS_MODULE);
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
-
- let mut f = File::open(kmod_path).expect("unable to open kernel module");
- let mut contents: Vec<u8> = Vec::new();
- f.read_to_end(&mut contents)
- .expect("unable to read kernel module content to buffer");
- init_module(&contents, &CString::new("").unwrap())
- .expect("unable to load kernel module");
-
- delete_module(
- &CString::new(kmod_name).unwrap(),
- DeleteModuleFlags::empty(),
- )
- .expect("unable to unload kernel module");
-}
-
-#[test]
-fn test_init_and_delete_module_with_params() {
- require_capability!(
- "test_init_and_delete_module_with_params",
- CAP_SYS_MODULE
- );
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
-
- let mut f = File::open(kmod_path).expect("unable to open kernel module");
- let mut contents: Vec<u8> = Vec::new();
- f.read_to_end(&mut contents)
- .expect("unable to read kernel module content to buffer");
- init_module(&contents, &CString::new("who=Nix number=2015").unwrap())
- .expect("unable to load kernel module");
-
- delete_module(
- &CString::new(kmod_name).unwrap(),
- DeleteModuleFlags::empty(),
- )
- .expect("unable to unload kernel module");
-}
-
-#[test]
-fn test_finit_module_invalid() {
- require_capability!("test_finit_module_invalid", CAP_SYS_MODULE);
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let kmod_path = "/dev/zero";
-
- let f = File::open(kmod_path).expect("unable to open kernel module");
- let result =
- finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty());
-
- assert_eq!(result.unwrap_err(), Errno::EINVAL);
-}
-
-#[test]
-fn test_finit_module_twice_and_delete_module() {
- require_capability!(
- "test_finit_module_twice_and_delete_module",
- CAP_SYS_MODULE
- );
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module();
-
- let f = File::open(kmod_path).expect("unable to open kernel module");
- finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty())
- .expect("unable to load kernel module");
-
- let result =
- finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty());
-
- assert_eq!(result.unwrap_err(), Errno::EEXIST);
-
- delete_module(
- &CString::new(kmod_name).unwrap(),
- DeleteModuleFlags::empty(),
- )
- .expect("unable to unload kernel module");
-}
-
-#[test]
-fn test_delete_module_not_loaded() {
- require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE);
- let _m0 = crate::KMOD_MTX.lock();
- let _m1 = crate::CWD_LOCK.read();
-
- let result = delete_module(
- &CString::new("hello").unwrap(),
- DeleteModuleFlags::empty(),
- );
-
- assert_eq!(result.unwrap_err(), Errno::ENOENT);
-}
diff --git a/vendor/nix/test/test_mount.rs b/vendor/nix/test/test_mount.rs
deleted file mode 100644
index 2fd612e35..000000000
--- a/vendor/nix/test/test_mount.rs
+++ /dev/null
@@ -1,271 +0,0 @@
-mod common;
-
-// Implementation note: to allow unprivileged users to run it, this test makes
-// use of user and mount namespaces. On systems that allow unprivileged user
-// namespaces (Linux >= 3.8 compiled with CONFIG_USER_NS), the test should run
-// without root.
-
-#[cfg(target_os = "linux")]
-mod test_mount {
- use std::fs::{self, File};
- use std::io::{self, Read, Write};
- use std::os::unix::fs::OpenOptionsExt;
- use std::os::unix::fs::PermissionsExt;
- use std::process::{self, Command};
-
- use libc::{EACCES, EROFS};
-
- use nix::errno::Errno;
- use nix::mount::{mount, umount, MsFlags};
- use nix::sched::{unshare, CloneFlags};
- use nix::sys::stat::{self, Mode};
- use nix::unistd::getuid;
-
- static SCRIPT_CONTENTS: &[u8] = b"#!/bin/sh
-exit 23";
-
- const EXPECTED_STATUS: i32 = 23;
-
- const NONE: Option<&'static [u8]> = None;
- #[allow(clippy::bind_instead_of_map)] // False positive
- pub fn test_mount_tmpfs_without_flags_allows_rwx() {
- let tempdir = tempfile::tempdir().unwrap();
-
- mount(
- NONE,
- tempdir.path(),
- Some(b"tmpfs".as_ref()),
- MsFlags::empty(),
- NONE,
- )
- .unwrap_or_else(|e| panic!("mount failed: {}", e));
-
- let test_path = tempdir.path().join("test");
-
- // Verify write.
- fs::OpenOptions::new()
- .create(true)
- .write(true)
- .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
- .open(&test_path)
- .or_else(|e| {
- if Errno::from_i32(e.raw_os_error().unwrap())
- == Errno::EOVERFLOW
- {
- // Skip tests on certain Linux kernels which have a bug
- // regarding tmpfs in namespaces.
- // Ubuntu 14.04 and 16.04 are known to be affected; 16.10 is
- // not. There is no legitimate reason for open(2) to return
- // EOVERFLOW here.
- // https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1659087
- let stderr = io::stderr();
- let mut handle = stderr.lock();
- writeln!(
- handle,
- "Buggy Linux kernel detected. Skipping test."
- )
- .unwrap();
- process::exit(0);
- } else {
- panic!("open failed: {}", e);
- }
- })
- .and_then(|mut f| f.write(SCRIPT_CONTENTS))
- .unwrap_or_else(|e| panic!("write failed: {}", e));
-
- // Verify read.
- let mut buf = Vec::new();
- File::open(&test_path)
- .and_then(|mut f| f.read_to_end(&mut buf))
- .unwrap_or_else(|e| panic!("read failed: {}", e));
- assert_eq!(buf, SCRIPT_CONTENTS);
-
- // Verify execute.
- assert_eq!(
- EXPECTED_STATUS,
- Command::new(&test_path)
- .status()
- .unwrap_or_else(|e| panic!("exec failed: {}", e))
- .code()
- .unwrap_or_else(|| panic!("child killed by signal"))
- );
-
- umount(tempdir.path())
- .unwrap_or_else(|e| panic!("umount failed: {}", e));
- }
-
- pub fn test_mount_rdonly_disallows_write() {
- let tempdir = tempfile::tempdir().unwrap();
-
- mount(
- NONE,
- tempdir.path(),
- Some(b"tmpfs".as_ref()),
- MsFlags::MS_RDONLY,
- NONE,
- )
- .unwrap_or_else(|e| panic!("mount failed: {}", e));
-
- // EROFS: Read-only file system
- assert_eq!(
- EROFS,
- File::create(tempdir.path().join("test"))
- .unwrap_err()
- .raw_os_error()
- .unwrap()
- );
-
- umount(tempdir.path())
- .unwrap_or_else(|e| panic!("umount failed: {}", e));
- }
-
- pub fn test_mount_noexec_disallows_exec() {
- let tempdir = tempfile::tempdir().unwrap();
-
- mount(
- NONE,
- tempdir.path(),
- Some(b"tmpfs".as_ref()),
- MsFlags::MS_NOEXEC,
- NONE,
- )
- .unwrap_or_else(|e| panic!("mount failed: {}", e));
-
- let test_path = tempdir.path().join("test");
-
- fs::OpenOptions::new()
- .create(true)
- .write(true)
- .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
- .open(&test_path)
- .and_then(|mut f| f.write(SCRIPT_CONTENTS))
- .unwrap_or_else(|e| panic!("write failed: {}", e));
-
- // Verify that we cannot execute despite a+x permissions being set.
- let mode = stat::Mode::from_bits_truncate(
- fs::metadata(&test_path)
- .map(|md| md.permissions().mode())
- .unwrap_or_else(|e| panic!("metadata failed: {}", e)),
- );
-
- assert!(
- mode.contains(Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IXOTH),
- "{:?} did not have execute permissions",
- &test_path
- );
-
- // EACCES: Permission denied
- assert_eq!(
- EACCES,
- Command::new(&test_path)
- .status()
- .unwrap_err()
- .raw_os_error()
- .unwrap()
- );
-
- umount(tempdir.path())
- .unwrap_or_else(|e| panic!("umount failed: {}", e));
- }
-
- pub fn test_mount_bind() {
- let tempdir = tempfile::tempdir().unwrap();
- let file_name = "test";
-
- {
- let mount_point = tempfile::tempdir().unwrap();
-
- mount(
- Some(tempdir.path()),
- mount_point.path(),
- NONE,
- MsFlags::MS_BIND,
- NONE,
- )
- .unwrap_or_else(|e| panic!("mount failed: {}", e));
-
- fs::OpenOptions::new()
- .create(true)
- .write(true)
- .mode((Mode::S_IRWXU | Mode::S_IRWXG | Mode::S_IRWXO).bits())
- .open(mount_point.path().join(file_name))
- .and_then(|mut f| f.write(SCRIPT_CONTENTS))
- .unwrap_or_else(|e| panic!("write failed: {}", e));
-
- umount(mount_point.path())
- .unwrap_or_else(|e| panic!("umount failed: {}", e));
- }
-
- // Verify the file written in the mount shows up in source directory, even
- // after unmounting.
-
- let mut buf = Vec::new();
- File::open(tempdir.path().join(file_name))
- .and_then(|mut f| f.read_to_end(&mut buf))
- .unwrap_or_else(|e| panic!("read failed: {}", e));
- assert_eq!(buf, SCRIPT_CONTENTS);
- }
-
- pub fn setup_namespaces() {
- // Hold on to the uid in the parent namespace.
- let uid = getuid();
-
- unshare(CloneFlags::CLONE_NEWNS | CloneFlags::CLONE_NEWUSER).unwrap_or_else(|e| {
- let stderr = io::stderr();
- let mut handle = stderr.lock();
- writeln!(handle,
- "unshare failed: {}. Are unprivileged user namespaces available?",
- e).unwrap();
- writeln!(handle, "mount is not being tested").unwrap();
- // Exit with success because not all systems support unprivileged user namespaces, and
- // that's not what we're testing for.
- process::exit(0);
- });
-
- // Map user as uid 1000.
- fs::OpenOptions::new()
- .write(true)
- .open("/proc/self/uid_map")
- .and_then(|mut f| f.write(format!("1000 {} 1\n", uid).as_bytes()))
- .unwrap_or_else(|e| panic!("could not write uid map: {}", e));
- }
-}
-
-// Test runner
-
-/// Mimic normal test output (hackishly).
-#[cfg(target_os = "linux")]
-macro_rules! run_tests {
- ( $($test_fn:ident),* ) => {{
- println!();
-
- $(
- print!("test test_mount::{} ... ", stringify!($test_fn));
- $test_fn();
- println!("ok");
- )*
-
- println!();
- }}
-}
-
-#[cfg(target_os = "linux")]
-fn main() {
- use test_mount::{
- setup_namespaces, test_mount_bind, test_mount_noexec_disallows_exec,
- test_mount_rdonly_disallows_write,
- test_mount_tmpfs_without_flags_allows_rwx,
- };
- skip_if_cirrus!("Fails for an unknown reason Cirrus CI. Bug #1351");
- setup_namespaces();
-
- run_tests!(
- test_mount_tmpfs_without_flags_allows_rwx,
- test_mount_rdonly_disallows_write,
- test_mount_noexec_disallows_exec,
- test_mount_bind
- );
-}
-
-#[cfg(not(target_os = "linux"))]
-fn main() {}
diff --git a/vendor/nix/test/test_mq.rs b/vendor/nix/test/test_mq.rs
deleted file mode 100644
index 7b48e7ac7..000000000
--- a/vendor/nix/test/test_mq.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-use cfg_if::cfg_if;
-use std::ffi::CString;
-use std::str;
-
-use nix::errno::Errno;
-use nix::mqueue::{mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send};
-use nix::mqueue::{MQ_OFlag, MqAttr};
-use nix::sys::stat::Mode;
-
-// Defined as a macro such that the error source is reported as the caller's location.
-macro_rules! assert_attr_eq {
- ($read_attr:ident, $initial_attr:ident) => {
- cfg_if! {
- if #[cfg(any(target_os = "dragonfly", target_os = "netbsd"))] {
- // NetBSD (and others which inherit its implementation) include other flags
- // in read_attr, such as those specified by oflag. Just make sure at least
- // the correct bits are set.
- assert_eq!($read_attr.flags() & $initial_attr.flags(), $initial_attr.flags());
- assert_eq!($read_attr.maxmsg(), $initial_attr.maxmsg());
- assert_eq!($read_attr.msgsize(), $initial_attr.msgsize());
- assert_eq!($read_attr.curmsgs(), $initial_attr.curmsgs());
- } else {
- assert_eq!($read_attr, $initial_attr);
- }
- }
- }
-}
-
-#[test]
-fn test_mq_send_and_receive() {
- const MSG_SIZE: mq_attr_member_t = 32;
- let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
- let mq_name = &CString::new(b"/a_nix_test_queue".as_ref()).unwrap();
-
- let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
- let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
- let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
- if let Err(Errno::ENOSYS) = r0 {
- println!("message queues not supported or module not loaded?");
- return;
- };
- let mqd0 = r0.unwrap();
- let msg_to_send = "msg_1";
- mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap();
-
- let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
- let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap();
- let mut buf = [0u8; 32];
- let mut prio = 0u32;
- let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap();
- assert_eq!(prio, 1);
-
- mq_close(mqd1).unwrap();
- mq_close(mqd0).unwrap();
- assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
-}
-
-#[test]
-fn test_mq_getattr() {
- use nix::mqueue::mq_getattr;
- const MSG_SIZE: mq_attr_member_t = 32;
- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
- let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
- let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
- let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
- let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
- if let Err(Errno::ENOSYS) = r {
- println!("message queues not supported or module not loaded?");
- return;
- };
- let mqd = r.unwrap();
-
- let read_attr = mq_getattr(&mqd).unwrap();
- assert_attr_eq!(read_attr, initial_attr);
- mq_close(mqd).unwrap();
-}
-
-// FIXME: Fix failures for mips in QEMU
-#[test]
-#[cfg_attr(
- all(qemu, any(target_arch = "mips", target_arch = "mips64")),
- ignore
-)]
-fn test_mq_setattr() {
- use nix::mqueue::{mq_getattr, mq_setattr};
- const MSG_SIZE: mq_attr_member_t = 32;
- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
- let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
- let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
- let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
- let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
- if let Err(Errno::ENOSYS) = r {
- println!("message queues not supported or module not loaded?");
- return;
- };
- let mqd = r.unwrap();
-
- let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100);
- let old_attr = mq_setattr(&mqd, &new_attr).unwrap();
- assert_attr_eq!(old_attr, initial_attr);
-
- // No changes here because according to the Linux man page only
- // O_NONBLOCK can be set (see tests below)
- #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
- {
- let new_attr_get = mq_getattr(&mqd).unwrap();
- assert_ne!(new_attr_get, new_attr);
- }
-
- let new_attr_non_blocking = MqAttr::new(
- MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t,
- 10,
- MSG_SIZE,
- 0,
- );
- mq_setattr(&mqd, &new_attr_non_blocking).unwrap();
- let new_attr_get = mq_getattr(&mqd).unwrap();
-
- // now the O_NONBLOCK flag has been set
- #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
- {
- assert_ne!(new_attr_get, initial_attr);
- }
- assert_attr_eq!(new_attr_get, new_attr_non_blocking);
- mq_close(mqd).unwrap();
-}
-
-// FIXME: Fix failures for mips in QEMU
-#[test]
-#[cfg_attr(
- all(qemu, any(target_arch = "mips", target_arch = "mips64")),
- ignore
-)]
-fn test_mq_set_nonblocking() {
- use nix::mqueue::{mq_getattr, mq_remove_nonblock, mq_set_nonblock};
- const MSG_SIZE: mq_attr_member_t = 32;
- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
- let mq_name = &CString::new(b"/attr_test_get_attr".as_ref()).unwrap();
- let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
- let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
- let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
- if let Err(Errno::ENOSYS) = r {
- println!("message queues not supported or module not loaded?");
- return;
- };
- let mqd = r.unwrap();
- mq_set_nonblock(&mqd).unwrap();
- let new_attr = mq_getattr(&mqd);
- let o_nonblock_bits = MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t;
- assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, o_nonblock_bits);
- mq_remove_nonblock(&mqd).unwrap();
- let new_attr = mq_getattr(&mqd);
- assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, 0);
- mq_close(mqd).unwrap();
-}
-
-#[test]
-fn test_mq_unlink() {
- use nix::mqueue::mq_unlink;
- const MSG_SIZE: mq_attr_member_t = 32;
- let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
- let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
- #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
- let mq_name_not_opened =
- &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
- let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
- let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
- let r = mq_open(mq_name_opened, oflag, mode, Some(&initial_attr));
- if let Err(Errno::ENOSYS) = r {
- println!("message queues not supported or module not loaded?");
- return;
- };
- let mqd = r.unwrap();
-
- let res_unlink = mq_unlink(mq_name_opened);
- assert_eq!(res_unlink, Ok(()));
-
- // NetBSD (and others which inherit its implementation) defer removing the message
- // queue name until all references are closed, whereas Linux and others remove the
- // message queue name immediately.
- #[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
- {
- let res_unlink_not_opened = mq_unlink(mq_name_not_opened);
- assert_eq!(res_unlink_not_opened, Err(Errno::ENOENT));
- }
-
- mq_close(mqd).unwrap();
- let res_unlink_after_close = mq_unlink(mq_name_opened);
- assert_eq!(res_unlink_after_close, Err(Errno::ENOENT));
-}
diff --git a/vendor/nix/test/test_net.rs b/vendor/nix/test/test_net.rs
deleted file mode 100644
index c44655a4c..000000000
--- a/vendor/nix/test/test_net.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use nix::net::if_::*;
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-const LOOPBACK: &[u8] = b"lo";
-
-#[cfg(not(any(
- target_os = "android",
- target_os = "linux",
- target_os = "haiku"
-)))]
-const LOOPBACK: &[u8] = b"lo0";
-
-#[cfg(target_os = "haiku")]
-const LOOPBACK: &[u8] = b"loop";
-
-#[test]
-fn test_if_nametoindex() {
- if_nametoindex(LOOPBACK).expect("assertion failed");
-}
diff --git a/vendor/nix/test/test_nix_path.rs b/vendor/nix/test/test_nix_path.rs
deleted file mode 100644
index 8b1378917..000000000
--- a/vendor/nix/test/test_nix_path.rs
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/vendor/nix/test/test_nmount.rs b/vendor/nix/test/test_nmount.rs
deleted file mode 100644
index dec806a55..000000000
--- a/vendor/nix/test/test_nmount.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-use crate::*;
-use nix::{
- errno::Errno,
- mount::{unmount, MntFlags, Nmount},
-};
-use std::{ffi::CString, fs::File, path::Path};
-use tempfile::tempdir;
-
-#[test]
-fn ok() {
- require_mount!("nullfs");
-
- let mountpoint = tempdir().unwrap();
- let target = tempdir().unwrap();
- let _sentry = File::create(target.path().join("sentry")).unwrap();
-
- let fstype = CString::new("fstype").unwrap();
- let nullfs = CString::new("nullfs").unwrap();
- Nmount::new()
- .str_opt(&fstype, &nullfs)
- .str_opt_owned("fspath", mountpoint.path().to_str().unwrap())
- .str_opt_owned("target", target.path().to_str().unwrap())
- .nmount(MntFlags::empty())
- .unwrap();
-
- // Now check that the sentry is visible through the mountpoint
- let exists = Path::exists(&mountpoint.path().join("sentry"));
-
- // Cleanup the mountpoint before asserting
- unmount(mountpoint.path(), MntFlags::empty()).unwrap();
-
- assert!(exists);
-}
-
-#[test]
-fn bad_fstype() {
- let mountpoint = tempdir().unwrap();
- let target = tempdir().unwrap();
- let _sentry = File::create(target.path().join("sentry")).unwrap();
-
- let e = Nmount::new()
- .str_opt_owned("fspath", mountpoint.path().to_str().unwrap())
- .str_opt_owned("target", target.path().to_str().unwrap())
- .nmount(MntFlags::empty())
- .unwrap_err();
-
- assert_eq!(e.error(), Errno::EINVAL);
- assert_eq!(e.errmsg(), Some("Invalid fstype"));
-}
diff --git a/vendor/nix/test/test_poll.rs b/vendor/nix/test/test_poll.rs
deleted file mode 100644
index 53964e26b..000000000
--- a/vendor/nix/test/test_poll.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use nix::{
- errno::Errno,
- poll::{poll, PollFd, PollFlags},
- unistd::{pipe, write},
-};
-
-macro_rules! loop_while_eintr {
- ($poll_expr: expr) => {
- loop {
- match $poll_expr {
- Ok(nfds) => break nfds,
- Err(Errno::EINTR) => (),
- Err(e) => panic!("{}", e),
- }
- }
- };
-}
-
-#[test]
-fn test_poll() {
- let (r, w) = pipe().unwrap();
- let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
-
- // Poll an idle pipe. Should timeout
- let nfds = loop_while_eintr!(poll(&mut fds, 100));
- assert_eq!(nfds, 0);
- assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
-
- write(w, b".").unwrap();
-
- // Poll a readable pipe. Should return an event.
- let nfds = poll(&mut fds, 100).unwrap();
- assert_eq!(nfds, 1);
- assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
-}
-
-// ppoll(2) is the same as poll except for how it handles timeouts and signals.
-// Repeating the test for poll(2) should be sufficient to check that our
-// bindings are correct.
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"
-))]
-#[test]
-fn test_ppoll() {
- use nix::poll::ppoll;
- use nix::sys::signal::SigSet;
- use nix::sys::time::{TimeSpec, TimeValLike};
-
- let timeout = TimeSpec::milliseconds(1);
- let (r, w) = pipe().unwrap();
- let mut fds = [PollFd::new(r, PollFlags::POLLIN)];
-
- // Poll an idle pipe. Should timeout
- let sigset = SigSet::empty();
- let nfds = loop_while_eintr!(ppoll(&mut fds, Some(timeout), Some(sigset)));
- assert_eq!(nfds, 0);
- assert!(!fds[0].revents().unwrap().contains(PollFlags::POLLIN));
-
- write(w, b".").unwrap();
-
- // Poll a readable pipe. Should return an event.
- let nfds = ppoll(&mut fds, Some(timeout), None).unwrap();
- assert_eq!(nfds, 1);
- assert!(fds[0].revents().unwrap().contains(PollFlags::POLLIN));
-}
-
-#[test]
-fn test_pollfd_fd() {
- use std::os::unix::io::AsRawFd;
-
- let pfd = PollFd::new(0x1234, PollFlags::empty());
- assert_eq!(pfd.as_raw_fd(), 0x1234);
-}
-
-#[test]
-fn test_pollfd_events() {
- let mut pfd = PollFd::new(-1, PollFlags::POLLIN);
- assert_eq!(pfd.events(), PollFlags::POLLIN);
- pfd.set_events(PollFlags::POLLOUT);
- assert_eq!(pfd.events(), PollFlags::POLLOUT);
-}
diff --git a/vendor/nix/test/test_pty.rs b/vendor/nix/test/test_pty.rs
deleted file mode 100644
index 5c27e2d63..000000000
--- a/vendor/nix/test/test_pty.rs
+++ /dev/null
@@ -1,313 +0,0 @@
-use std::fs::File;
-use std::io::{Read, Write};
-use std::os::unix::prelude::*;
-use std::path::Path;
-use tempfile::tempfile;
-
-use libc::{_exit, STDOUT_FILENO};
-use nix::fcntl::{open, OFlag};
-use nix::pty::*;
-use nix::sys::stat;
-use nix::sys::termios::*;
-use nix::unistd::{close, pause, write};
-
-/// Regression test for Issue #659
-/// This is the correct way to explicitly close a `PtyMaster`
-#[test]
-fn test_explicit_close() {
- let mut f = {
- let m = posix_openpt(OFlag::O_RDWR).unwrap();
- close(m.into_raw_fd()).unwrap();
- tempfile().unwrap()
- };
- // This should work. But if there's been a double close, then it will
- // return EBADF
- f.write_all(b"whatever").unwrap();
-}
-
-/// Test equivalence of `ptsname` and `ptsname_r`
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_equivalence() {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name = unsafe { ptsname(&master_fd) }.unwrap();
- let slave_name_r = ptsname_r(&master_fd).unwrap();
- assert_eq!(slave_name, slave_name_r);
-}
-
-/// Test data copying of `ptsname`
-// TODO need to run in a subprocess, since ptsname is non-reentrant
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_copy() {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name1 = unsafe { ptsname(&master_fd) }.unwrap();
- let slave_name2 = unsafe { ptsname(&master_fd) }.unwrap();
- assert_eq!(slave_name1, slave_name2);
- // Also make sure that the string was actually copied and they point to different parts of
- // memory.
- assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr());
-}
-
-/// Test data copying of `ptsname_r`
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_r_copy() {
- // Open a new PTTY master
- let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name1 = ptsname_r(&master_fd).unwrap();
- let slave_name2 = ptsname_r(&master_fd).unwrap();
- assert_eq!(slave_name1, slave_name2);
- assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr());
-}
-
-/// Test that `ptsname` returns different names for different devices
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_unique() {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master1_fd.as_raw_fd() > 0);
-
- // Open a second PTTY master
- let master2_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master2_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name1 = unsafe { ptsname(&master1_fd) }.unwrap();
- let slave_name2 = unsafe { ptsname(&master2_fd) }.unwrap();
- assert_ne!(slave_name1, slave_name2);
-}
-
-/// Common setup for testing PTTY pairs
-fn open_ptty_pair() -> (PtyMaster, File) {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
-
- // Allow a slave to be generated for it
- grantpt(&master).expect("grantpt failed");
- unlockpt(&master).expect("unlockpt failed");
-
- // Get the name of the slave
- let slave_name = unsafe { ptsname(&master) }.expect("ptsname failed");
-
- // Open the slave device
- let slave_fd =
- open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty())
- .unwrap();
-
- #[cfg(target_os = "illumos")]
- // TODO: rewrite using ioctl!
- #[allow(clippy::comparison_chain)]
- {
- use libc::{ioctl, I_FIND, I_PUSH};
-
- // On illumos systems, as per pts(7D), one must push STREAMS modules
- // after opening a device path returned from ptsname().
- let ptem = b"ptem\0";
- let ldterm = b"ldterm\0";
- let r = unsafe { ioctl(slave_fd, I_FIND, ldterm.as_ptr()) };
- if r < 0 {
- panic!("I_FIND failure");
- } else if r == 0 {
- if unsafe { ioctl(slave_fd, I_PUSH, ptem.as_ptr()) } < 0 {
- panic!("I_PUSH ptem failure");
- }
- if unsafe { ioctl(slave_fd, I_PUSH, ldterm.as_ptr()) } < 0 {
- panic!("I_PUSH ldterm failure");
- }
- }
- }
-
- let slave = unsafe { File::from_raw_fd(slave_fd) };
-
- (master, slave)
-}
-
-/// Test opening a master/slave PTTY pair
-///
-/// This uses a common `open_ptty_pair` because much of these functions aren't useful by
-/// themselves. So for this test we perform the basic act of getting a file handle for a
-/// master/slave PTTY pair, then just sanity-check the raw values.
-#[test]
-fn test_open_ptty_pair() {
- let (master, slave) = open_ptty_pair();
- assert!(master.as_raw_fd() > 0);
- assert!(slave.as_raw_fd() > 0);
-}
-
-/// Put the terminal in raw mode.
-fn make_raw(fd: RawFd) {
- let mut termios = tcgetattr(fd).unwrap();
- cfmakeraw(&mut termios);
- tcsetattr(fd, SetArg::TCSANOW, &termios).unwrap();
-}
-
-/// Test `io::Read` on the PTTY master
-#[test]
-fn test_read_ptty_pair() {
- let (mut master, mut slave) = open_ptty_pair();
- make_raw(slave.as_raw_fd());
-
- let mut buf = [0u8; 5];
- slave.write_all(b"hello").unwrap();
- master.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"hello");
-
- let mut master = &master;
- slave.write_all(b"hello").unwrap();
- master.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"hello");
-}
-
-/// Test `io::Write` on the PTTY master
-#[test]
-fn test_write_ptty_pair() {
- let (mut master, mut slave) = open_ptty_pair();
- make_raw(slave.as_raw_fd());
-
- let mut buf = [0u8; 5];
- master.write_all(b"adios").unwrap();
- slave.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"adios");
-
- let mut master = &master;
- master.write_all(b"adios").unwrap();
- slave.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"adios");
-}
-
-#[test]
-fn test_openpty() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- let pty = openpty(None, None).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Writing to one should be readable on the other one
- let string = "foofoofoo\n";
- let mut buf = [0u8; 10];
- write(pty.master, string.as_bytes()).unwrap();
- crate::read_exact(pty.slave, &mut buf);
-
- assert_eq!(&buf, string.as_bytes());
-
- // Read the echo as well
- let echoed_string = "foofoofoo\r\n";
- let mut buf = [0u8; 11];
- crate::read_exact(pty.master, &mut buf);
- assert_eq!(&buf, echoed_string.as_bytes());
-
- let string2 = "barbarbarbar\n";
- let echoed_string2 = "barbarbarbar\r\n";
- let mut buf = [0u8; 14];
- write(pty.slave, string2.as_bytes()).unwrap();
- crate::read_exact(pty.master, &mut buf);
-
- assert_eq!(&buf, echoed_string2.as_bytes());
-
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
-}
-
-#[test]
-fn test_openpty_with_termios() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open one pty to get attributes for the second one
- let mut termios = {
- let pty = openpty(None, None).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
- let termios = tcgetattr(pty.slave).unwrap();
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- termios
- };
- // Make sure newlines are not transformed so the data is preserved when sent.
- termios.output_flags.remove(OutputFlags::ONLCR);
-
- let pty = openpty(None, &termios).unwrap();
- // Must be valid file descriptors
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Writing to one should be readable on the other one
- let string = "foofoofoo\n";
- let mut buf = [0u8; 10];
- write(pty.master, string.as_bytes()).unwrap();
- crate::read_exact(pty.slave, &mut buf);
-
- assert_eq!(&buf, string.as_bytes());
-
- // read the echo as well
- let echoed_string = "foofoofoo\n";
- crate::read_exact(pty.master, &mut buf);
- assert_eq!(&buf, echoed_string.as_bytes());
-
- let string2 = "barbarbarbar\n";
- let echoed_string2 = "barbarbarbar\n";
- let mut buf = [0u8; 13];
- write(pty.slave, string2.as_bytes()).unwrap();
- crate::read_exact(pty.master, &mut buf);
-
- assert_eq!(&buf, echoed_string2.as_bytes());
-
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
-}
-
-#[test]
-fn test_forkpty() {
- use nix::sys::signal::*;
- use nix::sys::wait::wait;
- use nix::unistd::ForkResult::*;
- // forkpty calls openpty which uses ptname(3) internally.
- let _m0 = crate::PTSNAME_MTX.lock();
- // forkpty spawns a child process
- let _m1 = crate::FORK_MTX.lock();
-
- let string = "naninani\n";
- let echoed_string = "naninani\r\n";
- let pty = unsafe { forkpty(None, None).unwrap() };
- match pty.fork_result {
- Child => {
- write(STDOUT_FILENO, string.as_bytes()).unwrap();
- pause(); // we need the child to stay alive until the parent calls read
- unsafe {
- _exit(0);
- }
- }
- Parent { child } => {
- let mut buf = [0u8; 10];
- assert!(child.as_raw() > 0);
- crate::read_exact(pty.master, &mut buf);
- kill(child, SIGTERM).unwrap();
- wait().unwrap(); // keep other tests using generic wait from getting our child
- assert_eq!(&buf, echoed_string.as_bytes());
- close(pty.master).unwrap();
- }
- }
-}
diff --git a/vendor/nix/test/test_ptymaster_drop.rs b/vendor/nix/test/test_ptymaster_drop.rs
deleted file mode 100644
index ffbaa5697..000000000
--- a/vendor/nix/test/test_ptymaster_drop.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
-mod t {
- use nix::fcntl::OFlag;
- use nix::pty::*;
- use nix::unistd::close;
- use std::os::unix::io::AsRawFd;
-
- /// Regression test for Issue #659
- ///
- /// `PtyMaster` should panic rather than double close the file descriptor
- /// This must run in its own test process because it deliberately creates a
- /// race condition.
- #[test]
- #[should_panic(expected = "Closing an invalid file descriptor!")]
- fn test_double_close() {
- let m = posix_openpt(OFlag::O_RDWR).unwrap();
- close(m.as_raw_fd()).unwrap();
- drop(m); // should panic here
- }
-}
diff --git a/vendor/nix/test/test_resource.rs b/vendor/nix/test/test_resource.rs
deleted file mode 100644
index 2ab581ba2..000000000
--- a/vendor/nix/test/test_resource.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "haiku"
-)))]
-use nix::sys::resource::{getrlimit, setrlimit, Resource};
-
-/// Tests the RLIMIT_NOFILE functionality of getrlimit(), where the resource RLIMIT_NOFILE refers
-/// to the maximum file descriptor number that can be opened by the process (aka the maximum number
-/// of file descriptors that the process can open, since Linux 4.5).
-///
-/// We first fetch the existing file descriptor maximum values using getrlimit(), then edit the
-/// soft limit to make sure it has a new and distinct value to the hard limit. We then setrlimit()
-/// to put the new soft limit in effect, and then getrlimit() once more to ensure the limits have
-/// been updated.
-#[test]
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "illumos",
- target_os = "haiku"
-)))]
-pub fn test_resource_limits_nofile() {
- let (mut soft_limit, hard_limit) =
- getrlimit(Resource::RLIMIT_NOFILE).unwrap();
-
- soft_limit -= 1;
- assert_ne!(soft_limit, hard_limit);
- setrlimit(Resource::RLIMIT_NOFILE, soft_limit, hard_limit).unwrap();
-
- let (new_soft_limit, _) = getrlimit(Resource::RLIMIT_NOFILE).unwrap();
- assert_eq!(new_soft_limit, soft_limit);
-}
diff --git a/vendor/nix/test/test_sched.rs b/vendor/nix/test/test_sched.rs
deleted file mode 100644
index c52616b8b..000000000
--- a/vendor/nix/test/test_sched.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use nix::sched::{sched_getaffinity, sched_getcpu, sched_setaffinity, CpuSet};
-use nix::unistd::Pid;
-
-#[test]
-fn test_sched_affinity() {
- // If pid is zero, then the mask of the calling process is returned.
- let initial_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap();
- let mut at_least_one_cpu = false;
- let mut last_valid_cpu = 0;
- for field in 0..CpuSet::count() {
- if initial_affinity.is_set(field).unwrap() {
- at_least_one_cpu = true;
- last_valid_cpu = field;
- }
- }
- assert!(at_least_one_cpu);
-
- // Now restrict the running CPU
- let mut new_affinity = CpuSet::new();
- new_affinity.set(last_valid_cpu).unwrap();
- sched_setaffinity(Pid::from_raw(0), &new_affinity).unwrap();
-
- // And now re-check the affinity which should be only the one we set.
- let updated_affinity = sched_getaffinity(Pid::from_raw(0)).unwrap();
- for field in 0..CpuSet::count() {
- // Should be set only for the CPU we set previously
- assert_eq!(
- updated_affinity.is_set(field).unwrap(),
- field == last_valid_cpu
- )
- }
-
- // Now check that we're also currently running on the CPU in question.
- let cur_cpu = sched_getcpu().unwrap();
- assert_eq!(cur_cpu, last_valid_cpu);
-
- // Finally, reset the initial CPU set
- sched_setaffinity(Pid::from_raw(0), &initial_affinity).unwrap();
-}
diff --git a/vendor/nix/test/test_sendfile.rs b/vendor/nix/test/test_sendfile.rs
deleted file mode 100644
index f73a3b56c..000000000
--- a/vendor/nix/test/test_sendfile.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-use std::io::prelude::*;
-use std::os::unix::prelude::*;
-
-use libc::off_t;
-use nix::sys::sendfile::*;
-use tempfile::tempfile;
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- use nix::unistd::{close, pipe, read};
- } else if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos"))] {
- use std::net::Shutdown;
- use std::os::unix::net::UnixStream;
- }
-}
-
-#[cfg(any(target_os = "android", target_os = "linux"))]
-#[test]
-fn test_sendfile_linux() {
- const CONTENTS: &[u8] = b"abcdef123456";
- let mut tmp = tempfile().unwrap();
- tmp.write_all(CONTENTS).unwrap();
-
- let (rd, wr) = pipe().unwrap();
- let mut offset: off_t = 5;
- let res = sendfile(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap();
-
- assert_eq!(2, res);
-
- let mut buf = [0u8; 1024];
- assert_eq!(2, read(rd, &mut buf).unwrap());
- assert_eq!(b"f1", &buf[0..2]);
- assert_eq!(7, offset);
-
- close(rd).unwrap();
- close(wr).unwrap();
-}
-
-#[cfg(target_os = "linux")]
-#[test]
-fn test_sendfile64_linux() {
- const CONTENTS: &[u8] = b"abcdef123456";
- let mut tmp = tempfile().unwrap();
- tmp.write_all(CONTENTS).unwrap();
-
- let (rd, wr) = pipe().unwrap();
- let mut offset: libc::off64_t = 5;
- let res = sendfile64(wr, tmp.as_raw_fd(), Some(&mut offset), 2).unwrap();
-
- assert_eq!(2, res);
-
- let mut buf = [0u8; 1024];
- assert_eq!(2, read(rd, &mut buf).unwrap());
- assert_eq!(b"f1", &buf[0..2]);
- assert_eq!(7, offset);
-
- close(rd).unwrap();
- close(wr).unwrap();
-}
-
-#[cfg(target_os = "freebsd")]
-#[test]
-fn test_sendfile_freebsd() {
- // Declare the content
- let header_strings =
- vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
- let body = "Xabcdef123456";
- let body_offset = 1;
- let trailer_strings = vec!["\n", "Served by Make Believe\n"];
-
- // Write the body to a file
- let mut tmp = tempfile().unwrap();
- tmp.write_all(body.as_bytes()).unwrap();
-
- // Prepare headers and trailers for sendfile
- let headers: Vec<&[u8]> =
- header_strings.iter().map(|s| s.as_bytes()).collect();
- let trailers: Vec<&[u8]> =
- trailer_strings.iter().map(|s| s.as_bytes()).collect();
-
- // Prepare socket pair
- let (mut rd, wr) = UnixStream::pair().unwrap();
-
- // Call the test method
- let (res, bytes_written) = sendfile(
- tmp.as_raw_fd(),
- wr.as_raw_fd(),
- body_offset as off_t,
- None,
- Some(headers.as_slice()),
- Some(trailers.as_slice()),
- SfFlags::empty(),
- 0,
- );
- assert!(res.is_ok());
- wr.shutdown(Shutdown::Both).unwrap();
-
- // Prepare the expected result
- let expected_string = header_strings.concat()
- + &body[body_offset..]
- + &trailer_strings.concat();
-
- // Verify the message that was sent
- assert_eq!(bytes_written as usize, expected_string.as_bytes().len());
-
- let mut read_string = String::new();
- let bytes_read = rd.read_to_string(&mut read_string).unwrap();
- assert_eq!(bytes_written as usize, bytes_read);
- assert_eq!(expected_string, read_string);
-}
-
-#[cfg(target_os = "dragonfly")]
-#[test]
-fn test_sendfile_dragonfly() {
- // Declare the content
- let header_strings =
- vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
- let body = "Xabcdef123456";
- let body_offset = 1;
- let trailer_strings = vec!["\n", "Served by Make Believe\n"];
-
- // Write the body to a file
- let mut tmp = tempfile().unwrap();
- tmp.write_all(body.as_bytes()).unwrap();
-
- // Prepare headers and trailers for sendfile
- let headers: Vec<&[u8]> =
- header_strings.iter().map(|s| s.as_bytes()).collect();
- let trailers: Vec<&[u8]> =
- trailer_strings.iter().map(|s| s.as_bytes()).collect();
-
- // Prepare socket pair
- let (mut rd, wr) = UnixStream::pair().unwrap();
-
- // Call the test method
- let (res, bytes_written) = sendfile(
- tmp.as_raw_fd(),
- wr.as_raw_fd(),
- body_offset as off_t,
- None,
- Some(headers.as_slice()),
- Some(trailers.as_slice()),
- );
- assert!(res.is_ok());
- wr.shutdown(Shutdown::Both).unwrap();
-
- // Prepare the expected result
- let expected_string = header_strings.concat()
- + &body[body_offset..]
- + &trailer_strings.concat();
-
- // Verify the message that was sent
- assert_eq!(bytes_written as usize, expected_string.as_bytes().len());
-
- let mut read_string = String::new();
- let bytes_read = rd.read_to_string(&mut read_string).unwrap();
- assert_eq!(bytes_written as usize, bytes_read);
- assert_eq!(expected_string, read_string);
-}
-
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-#[test]
-fn test_sendfile_darwin() {
- // Declare the content
- let header_strings =
- vec!["HTTP/1.1 200 OK\n", "Content-Type: text/plain\n", "\n"];
- let body = "Xabcdef123456";
- let body_offset = 1;
- let trailer_strings = vec!["\n", "Served by Make Believe\n"];
-
- // Write the body to a file
- let mut tmp = tempfile().unwrap();
- tmp.write_all(body.as_bytes()).unwrap();
-
- // Prepare headers and trailers for sendfile
- let headers: Vec<&[u8]> =
- header_strings.iter().map(|s| s.as_bytes()).collect();
- let trailers: Vec<&[u8]> =
- trailer_strings.iter().map(|s| s.as_bytes()).collect();
-
- // Prepare socket pair
- let (mut rd, wr) = UnixStream::pair().unwrap();
-
- // Call the test method
- let (res, bytes_written) = sendfile(
- tmp.as_raw_fd(),
- wr.as_raw_fd(),
- body_offset as off_t,
- None,
- Some(headers.as_slice()),
- Some(trailers.as_slice()),
- );
- assert!(res.is_ok());
- wr.shutdown(Shutdown::Both).unwrap();
-
- // Prepare the expected result
- let expected_string = header_strings.concat()
- + &body[body_offset..]
- + &trailer_strings.concat();
-
- // Verify the message that was sent
- assert_eq!(bytes_written as usize, expected_string.as_bytes().len());
-
- let mut read_string = String::new();
- let bytes_read = rd.read_to_string(&mut read_string).unwrap();
- assert_eq!(bytes_written as usize, bytes_read);
- assert_eq!(expected_string, read_string);
-}
diff --git a/vendor/nix/test/test_stat.rs b/vendor/nix/test/test_stat.rs
deleted file mode 100644
index 55f15c077..000000000
--- a/vendor/nix/test/test_stat.rs
+++ /dev/null
@@ -1,421 +0,0 @@
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use std::fs;
-use std::fs::File;
-#[cfg(not(target_os = "redox"))]
-use std::os::unix::fs::symlink;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use std::os::unix::fs::PermissionsExt;
-use std::os::unix::prelude::AsRawFd;
-#[cfg(not(target_os = "redox"))]
-use std::path::Path;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use std::time::{Duration, UNIX_EPOCH};
-
-use libc::mode_t;
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-use libc::{S_IFLNK, S_IFMT};
-
-#[cfg(not(target_os = "redox"))]
-use nix::errno::Errno;
-#[cfg(not(target_os = "redox"))]
-use nix::fcntl;
-#[cfg(any(
- target_os = "linux",
- target_os = "ios",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "netbsd"
-))]
-use nix::sys::stat::lutimes;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use nix::sys::stat::utimensat;
-#[cfg(not(target_os = "redox"))]
-use nix::sys::stat::FchmodatFlags;
-use nix::sys::stat::Mode;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use nix::sys::stat::UtimensatFlags;
-#[cfg(not(target_os = "redox"))]
-use nix::sys::stat::{self};
-use nix::sys::stat::{fchmod, stat};
-#[cfg(not(target_os = "redox"))]
-use nix::sys::stat::{fchmodat, mkdirat};
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use nix::sys::stat::{futimens, utimes};
-
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-use nix::sys::stat::FileStat;
-
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use nix::sys::time::{TimeSpec, TimeVal, TimeValLike};
-#[cfg(not(target_os = "redox"))]
-use nix::unistd::chdir;
-
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-use nix::Result;
-
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-fn assert_stat_results(stat_result: Result<FileStat>) {
- let stats = stat_result.expect("stat call failed");
- assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent
- assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent
- assert!(stats.st_mode > 0); // must be positive integer
- assert_eq!(stats.st_nlink, 1); // there links created, must be 1
- assert_eq!(stats.st_size, 0); // size is 0 because we did not write anything to the file
- assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent
- assert!(stats.st_blocks <= 16); // Up to 16 blocks can be allocated for a blank file
-}
-
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-// (Android's st_blocks is ulonglong which is always non-negative.)
-#[cfg_attr(target_os = "android", allow(unused_comparisons))]
-#[allow(clippy::absurd_extreme_comparisons)] // Not absurd on all OSes
-fn assert_lstat_results(stat_result: Result<FileStat>) {
- let stats = stat_result.expect("stat call failed");
- assert!(stats.st_dev > 0); // must be positive integer, exact number machine dependent
- assert!(stats.st_ino > 0); // inode is positive integer, exact number machine dependent
- assert!(stats.st_mode > 0); // must be positive integer
-
- // st_mode is c_uint (u32 on Android) while S_IFMT is mode_t
- // (u16 on Android), and that will be a compile error.
- // On other platforms they are the same (either both are u16 or u32).
- assert_eq!(
- (stats.st_mode as usize) & (S_IFMT as usize),
- S_IFLNK as usize
- ); // should be a link
- assert_eq!(stats.st_nlink, 1); // there links created, must be 1
- assert!(stats.st_size > 0); // size is > 0 because it points to another file
- assert!(stats.st_blksize > 0); // must be positive integer, exact number machine dependent
-
- // st_blocks depends on whether the machine's file system uses fast
- // or slow symlinks, so just make sure it's not negative
- assert!(stats.st_blocks >= 0);
-}
-
-#[test]
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-fn test_stat_and_fstat() {
- use nix::sys::stat::fstat;
-
- let tempdir = tempfile::tempdir().unwrap();
- let filename = tempdir.path().join("foo.txt");
- let file = File::create(&filename).unwrap();
-
- let stat_result = stat(&filename);
- assert_stat_results(stat_result);
-
- let fstat_result = fstat(file.as_raw_fd());
- assert_stat_results(fstat_result);
-}
-
-#[test]
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-fn test_fstatat() {
- let tempdir = tempfile::tempdir().unwrap();
- let filename = tempdir.path().join("foo.txt");
- File::create(&filename).unwrap();
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty());
-
- let result =
- stat::fstatat(dirfd.unwrap(), &filename, fcntl::AtFlags::empty());
- assert_stat_results(result);
-}
-
-#[test]
-#[cfg(not(any(target_os = "netbsd", target_os = "redox")))]
-fn test_stat_fstat_lstat() {
- use nix::sys::stat::{fstat, lstat};
-
- let tempdir = tempfile::tempdir().unwrap();
- let filename = tempdir.path().join("bar.txt");
- let linkname = tempdir.path().join("barlink");
-
- File::create(&filename).unwrap();
- symlink("bar.txt", &linkname).unwrap();
- let link = File::open(&linkname).unwrap();
-
- // should be the same result as calling stat,
- // since it's a regular file
- let stat_result = stat(&filename);
- assert_stat_results(stat_result);
-
- let lstat_result = lstat(&linkname);
- assert_lstat_results(lstat_result);
-
- let fstat_result = fstat(link.as_raw_fd());
- assert_stat_results(fstat_result);
-}
-
-#[test]
-fn test_fchmod() {
- let tempdir = tempfile::tempdir().unwrap();
- let filename = tempdir.path().join("foo.txt");
- let file = File::create(&filename).unwrap();
-
- let mut mode1 = Mode::empty();
- mode1.insert(Mode::S_IRUSR);
- mode1.insert(Mode::S_IWUSR);
- fchmod(file.as_raw_fd(), mode1).unwrap();
-
- let file_stat1 = stat(&filename).unwrap();
- assert_eq!(file_stat1.st_mode as mode_t & 0o7777, mode1.bits());
-
- let mut mode2 = Mode::empty();
- mode2.insert(Mode::S_IROTH);
- fchmod(file.as_raw_fd(), mode2).unwrap();
-
- let file_stat2 = stat(&filename).unwrap();
- assert_eq!(file_stat2.st_mode as mode_t & 0o7777, mode2.bits());
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_fchmodat() {
- let _dr = crate::DirRestore::new();
- let tempdir = tempfile::tempdir().unwrap();
- let filename = "foo.txt";
- let fullpath = tempdir.path().join(filename);
- File::create(&fullpath).unwrap();
-
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- let mut mode1 = Mode::empty();
- mode1.insert(Mode::S_IRUSR);
- mode1.insert(Mode::S_IWUSR);
- fchmodat(Some(dirfd), filename, mode1, FchmodatFlags::FollowSymlink)
- .unwrap();
-
- let file_stat1 = stat(&fullpath).unwrap();
- assert_eq!(file_stat1.st_mode as mode_t & 0o7777, mode1.bits());
-
- chdir(tempdir.path()).unwrap();
-
- let mut mode2 = Mode::empty();
- mode2.insert(Mode::S_IROTH);
- fchmodat(None, filename, mode2, FchmodatFlags::FollowSymlink).unwrap();
-
- let file_stat2 = stat(&fullpath).unwrap();
- assert_eq!(file_stat2.st_mode as mode_t & 0o7777, mode2.bits());
-}
-
-/// Asserts that the atime and mtime in a file's metadata match expected values.
-///
-/// The atime and mtime are expressed with a resolution of seconds because some file systems
-/// (like macOS's HFS+) do not have higher granularity.
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn assert_times_eq(
- exp_atime_sec: u64,
- exp_mtime_sec: u64,
- attr: &fs::Metadata,
-) {
- assert_eq!(
- Duration::new(exp_atime_sec, 0),
- attr.accessed().unwrap().duration_since(UNIX_EPOCH).unwrap()
- );
- assert_eq!(
- Duration::new(exp_mtime_sec, 0),
- attr.modified().unwrap().duration_since(UNIX_EPOCH).unwrap()
- );
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_utimes() {
- let tempdir = tempfile::tempdir().unwrap();
- let fullpath = tempdir.path().join("file");
- drop(File::create(&fullpath).unwrap());
-
- utimes(&fullpath, &TimeVal::seconds(9990), &TimeVal::seconds(5550))
- .unwrap();
- assert_times_eq(9990, 5550, &fs::metadata(&fullpath).unwrap());
-}
-
-#[test]
-#[cfg(any(
- target_os = "linux",
- target_os = "ios",
- target_os = "macos",
- target_os = "freebsd",
- target_os = "netbsd"
-))]
-fn test_lutimes() {
- let tempdir = tempfile::tempdir().unwrap();
- let target = tempdir.path().join("target");
- let fullpath = tempdir.path().join("symlink");
- drop(File::create(&target).unwrap());
- symlink(&target, &fullpath).unwrap();
-
- let exp_target_metadata = fs::symlink_metadata(&target).unwrap();
- lutimes(&fullpath, &TimeVal::seconds(4560), &TimeVal::seconds(1230))
- .unwrap();
- assert_times_eq(4560, 1230, &fs::symlink_metadata(&fullpath).unwrap());
-
- let target_metadata = fs::symlink_metadata(&target).unwrap();
- assert_eq!(
- exp_target_metadata.accessed().unwrap(),
- target_metadata.accessed().unwrap(),
- "atime of symlink target was unexpectedly modified"
- );
- assert_eq!(
- exp_target_metadata.modified().unwrap(),
- target_metadata.modified().unwrap(),
- "mtime of symlink target was unexpectedly modified"
- );
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_futimens() {
- let tempdir = tempfile::tempdir().unwrap();
- let fullpath = tempdir.path().join("file");
- drop(File::create(&fullpath).unwrap());
-
- let fd = fcntl::open(&fullpath, fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- futimens(fd, &TimeSpec::seconds(10), &TimeSpec::seconds(20)).unwrap();
- assert_times_eq(10, 20, &fs::metadata(&fullpath).unwrap());
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_utimensat() {
- let _dr = crate::DirRestore::new();
- let tempdir = tempfile::tempdir().unwrap();
- let filename = "foo.txt";
- let fullpath = tempdir.path().join(filename);
- drop(File::create(&fullpath).unwrap());
-
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- utimensat(
- Some(dirfd),
- filename,
- &TimeSpec::seconds(12345),
- &TimeSpec::seconds(678),
- UtimensatFlags::FollowSymlink,
- )
- .unwrap();
- assert_times_eq(12345, 678, &fs::metadata(&fullpath).unwrap());
-
- chdir(tempdir.path()).unwrap();
-
- utimensat(
- None,
- filename,
- &TimeSpec::seconds(500),
- &TimeSpec::seconds(800),
- UtimensatFlags::FollowSymlink,
- )
- .unwrap();
- assert_times_eq(500, 800, &fs::metadata(&fullpath).unwrap());
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_mkdirat_success_path() {
- let tempdir = tempfile::tempdir().unwrap();
- let filename = "example_subdir";
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
- mkdirat(dirfd, filename, Mode::S_IRWXU).expect("mkdirat failed");
- assert!(Path::exists(&tempdir.path().join(filename)));
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_mkdirat_success_mode() {
- let expected_bits =
- stat::SFlag::S_IFDIR.bits() | stat::Mode::S_IRWXU.bits();
- let tempdir = tempfile::tempdir().unwrap();
- let filename = "example_subdir";
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
- mkdirat(dirfd, filename, Mode::S_IRWXU).expect("mkdirat failed");
- let permissions = fs::metadata(tempdir.path().join(filename))
- .unwrap()
- .permissions();
- let mode = permissions.mode();
- assert_eq!(mode as mode_t, expected_bits)
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_mkdirat_fail() {
- let tempdir = tempfile::tempdir().unwrap();
- let not_dir_filename = "example_not_dir";
- let filename = "example_subdir_dir";
- let dirfd = fcntl::open(
- &tempdir.path().join(not_dir_filename),
- fcntl::OFlag::O_CREAT,
- stat::Mode::empty(),
- )
- .unwrap();
- let result = mkdirat(dirfd, filename, Mode::S_IRWXU).unwrap_err();
- assert_eq!(result, Errno::ENOTDIR);
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "ios",
- target_os = "macos",
- target_os = "haiku",
- target_os = "redox"
-)))]
-fn test_mknod() {
- use stat::{lstat, mknod, SFlag};
-
- let file_name = "test_file";
- let tempdir = tempfile::tempdir().unwrap();
- let target = tempdir.path().join(file_name);
- mknod(&target, SFlag::S_IFREG, Mode::S_IRWXU, 0).unwrap();
- let mode = lstat(&target).unwrap().st_mode as mode_t;
- assert_eq!(mode & libc::S_IFREG, libc::S_IFREG);
- assert_eq!(mode & libc::S_IRWXU, libc::S_IRWXU);
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "haiku",
- target_os = "redox"
-)))]
-fn test_mknodat() {
- use fcntl::{AtFlags, OFlag};
- use nix::dir::Dir;
- use stat::{fstatat, mknodat, SFlag};
-
- let file_name = "test_file";
- let tempdir = tempfile::tempdir().unwrap();
- let target_dir =
- Dir::open(tempdir.path(), OFlag::O_DIRECTORY, Mode::S_IRWXU).unwrap();
- mknodat(
- target_dir.as_raw_fd(),
- file_name,
- SFlag::S_IFREG,
- Mode::S_IRWXU,
- 0,
- )
- .unwrap();
- let mode = fstatat(
- target_dir.as_raw_fd(),
- file_name,
- AtFlags::AT_SYMLINK_NOFOLLOW,
- )
- .unwrap()
- .st_mode as mode_t;
- assert_eq!(mode & libc::S_IFREG, libc::S_IFREG);
- assert_eq!(mode & libc::S_IRWXU, libc::S_IRWXU);
-}
diff --git a/vendor/nix/test/test_time.rs b/vendor/nix/test/test_time.rs
deleted file mode 100644
index 5f76e61a2..000000000
--- a/vendor/nix/test/test_time.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
-))]
-use nix::time::clock_getcpuclockid;
-use nix::time::{clock_gettime, ClockId};
-
-#[cfg(not(target_os = "redox"))]
-#[test]
-pub fn test_clock_getres() {
- nix::time::clock_getres(ClockId::CLOCK_REALTIME).expect("assertion failed");
-}
-
-#[test]
-pub fn test_clock_gettime() {
- clock_gettime(ClockId::CLOCK_REALTIME).expect("assertion failed");
-}
-
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
-))]
-#[test]
-pub fn test_clock_getcpuclockid() {
- let clock_id = clock_getcpuclockid(nix::unistd::Pid::this()).unwrap();
- clock_gettime(clock_id).unwrap();
-}
-
-#[cfg(not(target_os = "redox"))]
-#[test]
-pub fn test_clock_id_res() {
- ClockId::CLOCK_REALTIME.res().unwrap();
-}
-
-#[test]
-pub fn test_clock_id_now() {
- ClockId::CLOCK_REALTIME.now().unwrap();
-}
-
-#[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "linux",
- target_os = "android",
- target_os = "emscripten",
-))]
-#[test]
-pub fn test_clock_id_pid_cpu_clock_id() {
- ClockId::pid_cpu_clock_id(nix::unistd::Pid::this())
- .map(ClockId::now)
- .unwrap()
- .unwrap();
-}
diff --git a/vendor/nix/test/test_timer.rs b/vendor/nix/test/test_timer.rs
deleted file mode 100644
index ffd146867..000000000
--- a/vendor/nix/test/test_timer.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use nix::sys::signal::{
- sigaction, SaFlags, SigAction, SigEvent, SigHandler, SigSet, SigevNotify,
- Signal,
-};
-use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags};
-use nix::time::ClockId;
-use std::convert::TryFrom;
-use std::sync::atomic::{AtomicBool, Ordering};
-use std::thread;
-use std::time::{Duration, Instant};
-
-const SIG: Signal = Signal::SIGALRM;
-static ALARM_CALLED: AtomicBool = AtomicBool::new(false);
-
-pub extern "C" fn handle_sigalarm(raw_signal: libc::c_int) {
- let signal = Signal::try_from(raw_signal).unwrap();
- if signal == SIG {
- ALARM_CALLED.store(true, Ordering::Release);
- }
-}
-
-#[test]
-fn alarm_fires() {
- // Avoid interfering with other signal using tests by taking a mutex shared
- // among other tests in this crate.
- let _m = crate::SIGNAL_MTX.lock();
- const TIMER_PERIOD: Duration = Duration::from_millis(100);
-
- //
- // Setup
- //
-
- // Create a handler for the test signal, `SIG`. The handler is responsible
- // for flipping `ALARM_CALLED`.
- let handler = SigHandler::Handler(handle_sigalarm);
- let signal_action =
- SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty());
- let old_handler = unsafe {
- sigaction(SIG, &signal_action)
- .expect("unable to set signal handler for alarm")
- };
-
- // Create the timer. We use the monotonic clock here, though any would do
- // really. The timer is set to fire every 250 milliseconds with no delay for
- // the initial firing.
- let clockid = ClockId::CLOCK_MONOTONIC;
- let sigevent = SigEvent::new(SigevNotify::SigevSignal {
- signal: SIG,
- si_value: 0,
- });
- let mut timer =
- Timer::new(clockid, sigevent).expect("failed to create timer");
- let expiration = Expiration::Interval(TIMER_PERIOD.into());
- let flags = TimerSetTimeFlags::empty();
- timer.set(expiration, flags).expect("could not set timer");
-
- //
- // Test
- //
-
- // Determine that there's still an expiration tracked by the
- // timer. Depending on when this runs either an `Expiration::Interval` or
- // `Expiration::IntervalDelayed` will be present. That is, if the timer has
- // not fired yet we'll get our original `expiration`, else the one that
- // represents a delay to the next expiration. We're only interested in the
- // timer still being extant.
- match timer.get() {
- Ok(Some(exp)) => assert!(matches!(
- exp,
- Expiration::Interval(..) | Expiration::IntervalDelayed(..)
- )),
- _ => panic!("timer lost its expiration"),
- }
-
- // Wait for 2 firings of the alarm before checking that it has fired and
- // been handled at least the once. If we wait for 3 seconds and the handler
- // is never called something has gone sideways and the test fails.
- let starttime = Instant::now();
- loop {
- thread::sleep(2 * TIMER_PERIOD);
- if ALARM_CALLED.load(Ordering::Acquire) {
- break;
- }
- if starttime.elapsed() > Duration::from_secs(3) {
- panic!("Timeout waiting for SIGALRM");
- }
- }
-
- // Cleanup:
- // 1) deregister the OS's timer.
- // 2) Wait for a full timer period, since POSIX does not require that
- // disabling the timer will clear pending signals, and on NetBSD at least
- // it does not.
- // 2) Replace the old signal handler now that we've completed the test. If
- // the test fails this process panics, so the fact we might not get here
- // is okay.
- drop(timer);
- thread::sleep(TIMER_PERIOD);
- unsafe {
- sigaction(SIG, &old_handler).expect("unable to reset signal handler");
- }
-}
diff --git a/vendor/nix/test/test_unistd.rs b/vendor/nix/test/test_unistd.rs
deleted file mode 100644
index 9e20f977e..000000000
--- a/vendor/nix/test/test_unistd.rs
+++ /dev/null
@@ -1,1407 +0,0 @@
-use libc::{_exit, mode_t, off_t};
-use nix::errno::Errno;
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-use nix::fcntl::readlink;
-use nix::fcntl::OFlag;
-#[cfg(not(target_os = "redox"))]
-use nix::fcntl::{self, open};
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt};
-#[cfg(not(target_os = "redox"))]
-use nix::sys::signal::{
- sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal,
-};
-use nix::sys::stat::{self, Mode, SFlag};
-use nix::sys::wait::*;
-use nix::unistd::ForkResult::*;
-use nix::unistd::*;
-use std::env;
-#[cfg(not(any(target_os = "fuchsia", target_os = "redox")))]
-use std::ffi::CString;
-#[cfg(not(target_os = "redox"))]
-use std::fs::DirBuilder;
-use std::fs::{self, File};
-use std::io::Write;
-use std::os::unix::prelude::*;
-#[cfg(not(any(
- target_os = "fuchsia",
- target_os = "redox",
- target_os = "haiku"
-)))]
-use std::path::Path;
-use tempfile::{tempdir, tempfile};
-
-use crate::*;
-
-#[test]
-#[cfg(not(any(target_os = "netbsd")))]
-fn test_fork_and_waitpid() {
- let _m = crate::FORK_MTX.lock();
-
- // Safe: Child only calls `_exit`, which is signal-safe
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => unsafe { _exit(0) },
- Parent { child } => {
- // assert that child was created and pid > 0
- let child_raw: ::libc::pid_t = child.into();
- assert!(child_raw > 0);
- let wait_status = waitpid(child, None);
- match wait_status {
- // assert that waitpid returned correct status and the pid is the one of the child
- Ok(WaitStatus::Exited(pid_t, _)) => assert_eq!(pid_t, child),
-
- // panic, must never happen
- s @ Ok(_) => {
- panic!("Child exited {:?}, should never happen", s)
- }
-
- // panic, waitpid should never fail
- Err(s) => panic!("Error: waitpid returned Err({:?}", s),
- }
- }
- }
-}
-
-#[test]
-fn test_wait() {
- // Grab FORK_MTX so wait doesn't reap a different test's child process
- let _m = crate::FORK_MTX.lock();
-
- // Safe: Child only calls `_exit`, which is signal-safe
- match unsafe { fork() }.expect("Error: Fork Failed") {
- Child => unsafe { _exit(0) },
- Parent { child } => {
- let wait_status = wait();
-
- // just assert that (any) one child returns with WaitStatus::Exited
- assert_eq!(wait_status, Ok(WaitStatus::Exited(child, 0)));
- }
- }
-}
-
-#[test]
-fn test_mkstemp() {
- let mut path = env::temp_dir();
- path.push("nix_tempfile.XXXXXX");
-
- let result = mkstemp(&path);
- match result {
- Ok((fd, path)) => {
- close(fd).unwrap();
- unlink(path.as_path()).unwrap();
- }
- Err(e) => panic!("mkstemp failed: {}", e),
- }
-}
-
-#[test]
-fn test_mkstemp_directory() {
- // mkstemp should fail if a directory is given
- mkstemp(&env::temp_dir()).expect_err("assertion failed");
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_mkfifo() {
- let tempdir = tempdir().unwrap();
- let mkfifo_fifo = tempdir.path().join("mkfifo_fifo");
-
- mkfifo(&mkfifo_fifo, Mode::S_IRUSR).unwrap();
-
- let stats = stat::stat(&mkfifo_fifo).unwrap();
- let typ = stat::SFlag::from_bits_truncate(stats.st_mode as mode_t);
- assert_eq!(typ, SFlag::S_IFIFO);
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_mkfifo_directory() {
- // mkfifo should fail if a directory is given
- mkfifo(&env::temp_dir(), Mode::S_IRUSR).expect_err("assertion failed");
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "redox",
- target_os = "haiku"
-)))]
-fn test_mkfifoat_none() {
- let _m = crate::CWD_LOCK.read();
-
- let tempdir = tempdir().unwrap();
- let mkfifoat_fifo = tempdir.path().join("mkfifoat_fifo");
-
- mkfifoat(None, &mkfifoat_fifo, Mode::S_IRUSR).unwrap();
-
- let stats = stat::stat(&mkfifoat_fifo).unwrap();
- let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
- assert_eq!(typ, SFlag::S_IFIFO);
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "redox",
- target_os = "haiku"
-)))]
-fn test_mkfifoat() {
- use nix::fcntl;
-
- let tempdir = tempdir().unwrap();
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let mkfifoat_name = "mkfifoat_name";
-
- mkfifoat(Some(dirfd), mkfifoat_name, Mode::S_IRUSR).unwrap();
-
- let stats =
- stat::fstatat(dirfd, mkfifoat_name, fcntl::AtFlags::empty()).unwrap();
- let typ = stat::SFlag::from_bits_truncate(stats.st_mode);
- assert_eq!(typ, SFlag::S_IFIFO);
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "redox",
- target_os = "haiku"
-)))]
-fn test_mkfifoat_directory_none() {
- let _m = crate::CWD_LOCK.read();
-
- // mkfifoat should fail if a directory is given
- mkfifoat(None, &env::temp_dir(), Mode::S_IRUSR)
- .expect_err("assertion failed");
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "android",
- target_os = "redox",
- target_os = "haiku"
-)))]
-fn test_mkfifoat_directory() {
- // mkfifoat should fail if a directory is given
- let tempdir = tempdir().unwrap();
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let mkfifoat_dir = "mkfifoat_dir";
- stat::mkdirat(dirfd, mkfifoat_dir, Mode::S_IRUSR).unwrap();
-
- mkfifoat(Some(dirfd), mkfifoat_dir, Mode::S_IRUSR)
- .expect_err("assertion failed");
-}
-
-#[test]
-fn test_getpid() {
- let pid: ::libc::pid_t = getpid().into();
- let ppid: ::libc::pid_t = getppid().into();
- assert!(pid > 0);
- assert!(ppid > 0);
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_getsid() {
- let none_sid: ::libc::pid_t = getsid(None).unwrap().into();
- let pid_sid: ::libc::pid_t = getsid(Some(getpid())).unwrap().into();
- assert!(none_sid > 0);
- assert_eq!(none_sid, pid_sid);
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-mod linux_android {
- use nix::unistd::gettid;
-
- #[test]
- fn test_gettid() {
- let tid: ::libc::pid_t = gettid().into();
- assert!(tid > 0);
- }
-}
-
-#[test]
-// `getgroups()` and `setgroups()` do not behave as expected on Apple platforms
-#[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-fn test_setgroups() {
- // Skip this test when not run as root as `setgroups()` requires root.
- skip_if_not_root!("test_setgroups");
-
- let _m = crate::GROUPS_MTX.lock();
-
- // Save the existing groups
- let old_groups = getgroups().unwrap();
-
- // Set some new made up groups
- let groups = [Gid::from_raw(123), Gid::from_raw(456)];
- setgroups(&groups).unwrap();
-
- let new_groups = getgroups().unwrap();
- assert_eq!(new_groups, groups);
-
- // Revert back to the old groups
- setgroups(&old_groups).unwrap();
-}
-
-#[test]
-// `getgroups()` and `setgroups()` do not behave as expected on Apple platforms
-#[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku",
- target_os = "illumos"
-)))]
-fn test_initgroups() {
- // Skip this test when not run as root as `initgroups()` and `setgroups()`
- // require root.
- skip_if_not_root!("test_initgroups");
-
- let _m = crate::GROUPS_MTX.lock();
-
- // Save the existing groups
- let old_groups = getgroups().unwrap();
-
- // It doesn't matter if the root user is not called "root" or if a user
- // called "root" doesn't exist. We are just checking that the extra,
- // made-up group, `123`, is set.
- // FIXME: Test the other half of initgroups' functionality: whether the
- // groups that the user belongs to are also set.
- let user = CString::new("root").unwrap();
- let group = Gid::from_raw(123);
- let group_list = getgrouplist(&user, group).unwrap();
- assert!(group_list.contains(&group));
-
- initgroups(&user, group).unwrap();
-
- let new_groups = getgroups().unwrap();
- assert_eq!(new_groups, group_list);
-
- // Revert back to the old groups
- setgroups(&old_groups).unwrap();
-}
-
-#[cfg(not(any(target_os = "fuchsia", target_os = "redox")))]
-macro_rules! execve_test_factory (
- ($test_name:ident, $syscall:ident, $exe: expr $(, $pathname:expr, $flags:expr)*) => (
-
- #[cfg(test)]
- mod $test_name {
- use std::ffi::CStr;
- use super::*;
-
- const EMPTY: &'static [u8] = b"\0";
- const DASH_C: &'static [u8] = b"-c\0";
- const BIGARG: &'static [u8] = b"echo nix!!! && echo foo=$foo && echo baz=$baz\0";
- const FOO: &'static [u8] = b"foo=bar\0";
- const BAZ: &'static [u8] = b"baz=quux\0";
-
- fn syscall_cstr_ref() -> Result<std::convert::Infallible, nix::Error> {
- $syscall(
- $exe,
- $(CString::new($pathname).unwrap().as_c_str(), )*
- &[CStr::from_bytes_with_nul(EMPTY).unwrap(),
- CStr::from_bytes_with_nul(DASH_C).unwrap(),
- CStr::from_bytes_with_nul(BIGARG).unwrap()],
- &[CStr::from_bytes_with_nul(FOO).unwrap(),
- CStr::from_bytes_with_nul(BAZ).unwrap()]
- $(, $flags)*)
- }
-
- fn syscall_cstring() -> Result<std::convert::Infallible, nix::Error> {
- $syscall(
- $exe,
- $(CString::new($pathname).unwrap().as_c_str(), )*
- &[CString::from(CStr::from_bytes_with_nul(EMPTY).unwrap()),
- CString::from(CStr::from_bytes_with_nul(DASH_C).unwrap()),
- CString::from(CStr::from_bytes_with_nul(BIGARG).unwrap())],
- &[CString::from(CStr::from_bytes_with_nul(FOO).unwrap()),
- CString::from(CStr::from_bytes_with_nul(BAZ).unwrap())]
- $(, $flags)*)
- }
-
- fn common_test(syscall: fn() -> Result<std::convert::Infallible, nix::Error>) {
- if "execveat" == stringify!($syscall) {
- // Though undocumented, Docker's default seccomp profile seems to
- // block this syscall. https://github.com/nix-rust/nix/issues/1122
- skip_if_seccomp!($test_name);
- }
-
- let m = crate::FORK_MTX.lock();
- // The `exec`d process will write to `writer`, and we'll read that
- // data from `reader`.
- let (reader, writer) = pipe().unwrap();
-
- // Safe: Child calls `exit`, `dup`, `close` and the provided `exec*` family function.
- // NOTE: Technically, this makes the macro unsafe to use because you could pass anything.
- // The tests make sure not to do that, though.
- match unsafe{fork()}.unwrap() {
- Child => {
- // Make `writer` be the stdout of the new process.
- dup2(writer, 1).unwrap();
- let r = syscall();
- let _ = std::io::stderr()
- .write_all(format!("{:?}", r).as_bytes());
- // Should only get here in event of error
- unsafe{ _exit(1) };
- },
- Parent { child } => {
- // Wait for the child to exit.
- let ws = waitpid(child, None);
- drop(m);
- assert_eq!(ws, Ok(WaitStatus::Exited(child, 0)));
- // Read 1024 bytes.
- let mut buf = [0u8; 1024];
- read(reader, &mut buf).unwrap();
- // It should contain the things we printed using `/bin/sh`.
- let string = String::from_utf8_lossy(&buf);
- assert!(string.contains("nix!!!"));
- assert!(string.contains("foo=bar"));
- assert!(string.contains("baz=quux"));
- }
- }
- }
-
- // These tests frequently fail on musl, probably due to
- // https://github.com/nix-rust/nix/issues/555
- #[cfg_attr(target_env = "musl", ignore)]
- #[test]
- fn test_cstr_ref() {
- common_test(syscall_cstr_ref);
- }
-
- // These tests frequently fail on musl, probably due to
- // https://github.com/nix-rust/nix/issues/555
- #[cfg_attr(target_env = "musl", ignore)]
- #[test]
- fn test_cstring() {
- common_test(syscall_cstring);
- }
- }
-
- )
-);
-
-cfg_if! {
- if #[cfg(target_os = "android")] {
- execve_test_factory!(test_execve, execve, CString::new("/system/bin/sh").unwrap().as_c_str());
- execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd());
- } else if #[cfg(any(target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux"))] {
- // These tests frequently fail on musl, probably due to
- // https://github.com/nix-rust/nix/issues/555
- execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
- execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd());
- } else if #[cfg(any(target_os = "illumos",
- target_os = "ios",
- target_os = "macos",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "solaris"))] {
- execve_test_factory!(test_execve, execve, CString::new("/bin/sh").unwrap().as_c_str());
- // No fexecve() on ios, macos, NetBSD, OpenBSD.
- }
-}
-
-#[cfg(any(target_os = "haiku", target_os = "linux", target_os = "openbsd"))]
-execve_test_factory!(test_execvpe, execvpe, &CString::new("sh").unwrap());
-
-cfg_if! {
- if #[cfg(target_os = "android")] {
- use nix::fcntl::AtFlags;
- execve_test_factory!(test_execveat_empty, execveat,
- File::open("/system/bin/sh").unwrap().into_raw_fd(),
- "", AtFlags::AT_EMPTY_PATH);
- execve_test_factory!(test_execveat_relative, execveat,
- File::open("/system/bin/").unwrap().into_raw_fd(),
- "./sh", AtFlags::empty());
- execve_test_factory!(test_execveat_absolute, execveat,
- File::open("/").unwrap().into_raw_fd(),
- "/system/bin/sh", AtFlags::empty());
- } else if #[cfg(all(target_os = "linux", any(target_arch ="x86_64", target_arch ="x86")))] {
- use nix::fcntl::AtFlags;
- execve_test_factory!(test_execveat_empty, execveat, File::open("/bin/sh").unwrap().into_raw_fd(),
- "", AtFlags::AT_EMPTY_PATH);
- execve_test_factory!(test_execveat_relative, execveat, File::open("/bin/").unwrap().into_raw_fd(),
- "./sh", AtFlags::empty());
- execve_test_factory!(test_execveat_absolute, execveat, File::open("/").unwrap().into_raw_fd(),
- "/bin/sh", AtFlags::empty());
- }
-}
-
-#[test]
-#[cfg(not(target_os = "fuchsia"))]
-fn test_fchdir() {
- // fchdir changes the process's cwd
- let _dr = crate::DirRestore::new();
-
- let tmpdir = tempdir().unwrap();
- let tmpdir_path = tmpdir.path().canonicalize().unwrap();
- let tmpdir_fd = File::open(&tmpdir_path).unwrap().into_raw_fd();
-
- fchdir(tmpdir_fd).expect("assertion failed");
- assert_eq!(getcwd().unwrap(), tmpdir_path);
-
- close(tmpdir_fd).expect("assertion failed");
-}
-
-#[test]
-fn test_getcwd() {
- // chdir changes the process's cwd
- let _dr = crate::DirRestore::new();
-
- let tmpdir = tempdir().unwrap();
- let tmpdir_path = tmpdir.path().canonicalize().unwrap();
- chdir(&tmpdir_path).expect("assertion failed");
- assert_eq!(getcwd().unwrap(), tmpdir_path);
-
- // make path 500 chars longer so that buffer doubling in getcwd
- // kicks in. Note: One path cannot be longer than 255 bytes
- // (NAME_MAX) whole path cannot be longer than PATH_MAX (usually
- // 4096 on linux, 1024 on macos)
- let mut inner_tmp_dir = tmpdir_path;
- for _ in 0..5 {
- let newdir = "a".repeat(100);
- inner_tmp_dir.push(newdir);
- mkdir(inner_tmp_dir.as_path(), Mode::S_IRWXU)
- .expect("assertion failed");
- }
- chdir(inner_tmp_dir.as_path()).expect("assertion failed");
- assert_eq!(getcwd().unwrap(), inner_tmp_dir.as_path());
-}
-
-#[test]
-fn test_chown() {
- // Testing for anything other than our own UID/GID is hard.
- let uid = Some(getuid());
- let gid = Some(getgid());
-
- let tempdir = tempdir().unwrap();
- let path = tempdir.path().join("file");
- {
- File::create(&path).unwrap();
- }
-
- chown(&path, uid, gid).unwrap();
- chown(&path, uid, None).unwrap();
- chown(&path, None, gid).unwrap();
-
- fs::remove_file(&path).unwrap();
- chown(&path, uid, gid).unwrap_err();
-}
-
-#[test]
-fn test_fchown() {
- // Testing for anything other than our own UID/GID is hard.
- let uid = Some(getuid());
- let gid = Some(getgid());
-
- let path = tempfile().unwrap();
- let fd = path.as_raw_fd();
-
- fchown(fd, uid, gid).unwrap();
- fchown(fd, uid, None).unwrap();
- fchown(fd, None, gid).unwrap();
- fchown(999999999, uid, gid).unwrap_err();
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_fchownat() {
- let _dr = crate::DirRestore::new();
- // Testing for anything other than our own UID/GID is hard.
- let uid = Some(getuid());
- let gid = Some(getgid());
-
- let tempdir = tempdir().unwrap();
- let path = tempdir.path().join("file");
- {
- File::create(&path).unwrap();
- }
-
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
-
- fchownat(Some(dirfd), "file", uid, gid, FchownatFlags::FollowSymlink)
- .unwrap();
-
- chdir(tempdir.path()).unwrap();
- fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap();
-
- fs::remove_file(&path).unwrap();
- fchownat(None, "file", uid, gid, FchownatFlags::FollowSymlink).unwrap_err();
-}
-
-#[test]
-fn test_lseek() {
- const CONTENTS: &[u8] = b"abcdef123456";
- let mut tmp = tempfile().unwrap();
- tmp.write_all(CONTENTS).unwrap();
- let tmpfd = tmp.into_raw_fd();
-
- let offset: off_t = 5;
- lseek(tmpfd, offset, Whence::SeekSet).unwrap();
-
- let mut buf = [0u8; 7];
- crate::read_exact(tmpfd, &mut buf);
- assert_eq!(b"f123456", &buf);
-
- close(tmpfd).unwrap();
-}
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[test]
-fn test_lseek64() {
- const CONTENTS: &[u8] = b"abcdef123456";
- let mut tmp = tempfile().unwrap();
- tmp.write_all(CONTENTS).unwrap();
- let tmpfd = tmp.into_raw_fd();
-
- lseek64(tmpfd, 5, Whence::SeekSet).unwrap();
-
- let mut buf = [0u8; 7];
- crate::read_exact(tmpfd, &mut buf);
- assert_eq!(b"f123456", &buf);
-
- close(tmpfd).unwrap();
-}
-
-cfg_if! {
- if #[cfg(any(target_os = "android", target_os = "linux"))] {
- macro_rules! require_acct{
- () => {
- require_capability!("test_acct", CAP_SYS_PACCT);
- }
- }
- } else if #[cfg(target_os = "freebsd")] {
- macro_rules! require_acct{
- () => {
- skip_if_not_root!("test_acct");
- skip_if_jailed!("test_acct");
- }
- }
- } else if #[cfg(not(any(target_os = "redox", target_os = "fuchsia", target_os = "haiku")))] {
- macro_rules! require_acct{
- () => {
- skip_if_not_root!("test_acct");
- }
- }
- }
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-fn test_acct() {
- use std::process::Command;
- use std::{thread, time};
- use tempfile::NamedTempFile;
-
- let _m = crate::FORK_MTX.lock();
- require_acct!();
-
- let file = NamedTempFile::new().unwrap();
- let path = file.path().to_str().unwrap();
-
- acct::enable(path).unwrap();
-
- loop {
- Command::new("echo").arg("Hello world").output().unwrap();
- let len = fs::metadata(path).unwrap().len();
- if len > 0 {
- break;
- }
- thread::sleep(time::Duration::from_millis(10));
- }
- acct::disable().unwrap();
-}
-
-#[test]
-fn test_fpathconf_limited() {
- let f = tempfile().unwrap();
- // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
- let path_max = fpathconf(f.as_raw_fd(), PathconfVar::PATH_MAX);
- assert!(
- path_max
- .expect("fpathconf failed")
- .expect("PATH_MAX is unlimited")
- > 0
- );
-}
-
-#[test]
-fn test_pathconf_limited() {
- // AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
- let path_max = pathconf("/", PathconfVar::PATH_MAX);
- assert!(
- path_max
- .expect("pathconf failed")
- .expect("PATH_MAX is unlimited")
- > 0
- );
-}
-
-#[test]
-fn test_sysconf_limited() {
- // AFAIK, OPEN_MAX is limited on all platforms, so it makes a good test
- let open_max = sysconf(SysconfVar::OPEN_MAX);
- assert!(
- open_max
- .expect("sysconf failed")
- .expect("OPEN_MAX is unlimited")
- > 0
- );
-}
-
-#[cfg(target_os = "freebsd")]
-#[test]
-fn test_sysconf_unsupported() {
- // I know of no sysconf variables that are unsupported everywhere, but
- // _XOPEN_CRYPT is unsupported on FreeBSD 11.0, which is one of the platforms
- // we test.
- let open_max = sysconf(SysconfVar::_XOPEN_CRYPT);
- assert!(open_max.expect("sysconf failed").is_none())
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "openbsd"
-))]
-#[test]
-fn test_getresuid() {
- let resuids = getresuid().unwrap();
- assert_ne!(resuids.real.as_raw(), libc::uid_t::MAX);
- assert_ne!(resuids.effective.as_raw(), libc::uid_t::MAX);
- assert_ne!(resuids.saved.as_raw(), libc::uid_t::MAX);
-}
-
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "openbsd"
-))]
-#[test]
-fn test_getresgid() {
- let resgids = getresgid().unwrap();
- assert_ne!(resgids.real.as_raw(), libc::gid_t::MAX);
- assert_ne!(resgids.effective.as_raw(), libc::gid_t::MAX);
- assert_ne!(resgids.saved.as_raw(), libc::gid_t::MAX);
-}
-
-// Test that we can create a pair of pipes. No need to verify that they pass
-// data; that's the domain of the OS, not nix.
-#[test]
-fn test_pipe() {
- let (fd0, fd1) = pipe().unwrap();
- let m0 = stat::SFlag::from_bits_truncate(
- stat::fstat(fd0).unwrap().st_mode as mode_t,
- );
- // S_IFIFO means it's a pipe
- assert_eq!(m0, SFlag::S_IFIFO);
- let m1 = stat::SFlag::from_bits_truncate(
- stat::fstat(fd1).unwrap().st_mode as mode_t,
- );
- assert_eq!(m1, SFlag::S_IFIFO);
-}
-
-// pipe2(2) is the same as pipe(2), except it allows setting some flags. Check
-// that we can set a flag.
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "illumos",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- target_os = "redox",
- target_os = "solaris"
-))]
-#[test]
-fn test_pipe2() {
- use nix::fcntl::{fcntl, FcntlArg, FdFlag};
-
- let (fd0, fd1) = pipe2(OFlag::O_CLOEXEC).unwrap();
- let f0 = FdFlag::from_bits_truncate(fcntl(fd0, FcntlArg::F_GETFD).unwrap());
- assert!(f0.contains(FdFlag::FD_CLOEXEC));
- let f1 = FdFlag::from_bits_truncate(fcntl(fd1, FcntlArg::F_GETFD).unwrap());
- assert!(f1.contains(FdFlag::FD_CLOEXEC));
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
-fn test_truncate() {
- let tempdir = tempdir().unwrap();
- let path = tempdir.path().join("file");
-
- {
- let mut tmp = File::create(&path).unwrap();
- const CONTENTS: &[u8] = b"12345678";
- tmp.write_all(CONTENTS).unwrap();
- }
-
- truncate(&path, 4).unwrap();
-
- let metadata = fs::metadata(&path).unwrap();
- assert_eq!(4, metadata.len());
-}
-
-#[test]
-fn test_ftruncate() {
- let tempdir = tempdir().unwrap();
- let path = tempdir.path().join("file");
-
- let tmpfd = {
- let mut tmp = File::create(&path).unwrap();
- const CONTENTS: &[u8] = b"12345678";
- tmp.write_all(CONTENTS).unwrap();
- tmp.into_raw_fd()
- };
-
- ftruncate(tmpfd, 2).unwrap();
- close(tmpfd).unwrap();
-
- let metadata = fs::metadata(&path).unwrap();
- assert_eq!(2, metadata.len());
-}
-
-// Used in `test_alarm`.
-#[cfg(not(target_os = "redox"))]
-static mut ALARM_CALLED: bool = false;
-
-// Used in `test_alarm`.
-#[cfg(not(target_os = "redox"))]
-pub extern "C" fn alarm_signal_handler(raw_signal: libc::c_int) {
- assert_eq!(
- raw_signal,
- libc::SIGALRM,
- "unexpected signal: {}",
- raw_signal
- );
- unsafe { ALARM_CALLED = true };
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_alarm() {
- use std::{
- thread,
- time::{Duration, Instant},
- };
-
- // Maybe other tests that fork interfere with this one?
- let _m = crate::SIGNAL_MTX.lock();
-
- let handler = SigHandler::Handler(alarm_signal_handler);
- let signal_action =
- SigAction::new(handler, SaFlags::SA_RESTART, SigSet::empty());
- let old_handler = unsafe {
- sigaction(Signal::SIGALRM, &signal_action)
- .expect("unable to set signal handler for alarm")
- };
-
- // Set an alarm.
- assert_eq!(alarm::set(60), None);
-
- // Overwriting an alarm should return the old alarm.
- assert_eq!(alarm::set(1), Some(60));
-
- // We should be woken up after 1 second by the alarm, so we'll sleep for 3
- // seconds to be sure.
- let starttime = Instant::now();
- loop {
- thread::sleep(Duration::from_millis(100));
- if unsafe { ALARM_CALLED } {
- break;
- }
- if starttime.elapsed() > Duration::from_secs(3) {
- panic!("Timeout waiting for SIGALRM");
- }
- }
-
- // Reset the signal.
- unsafe {
- sigaction(Signal::SIGALRM, &old_handler)
- .expect("unable to set signal handler for alarm");
- }
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_canceling_alarm() {
- let _m = crate::SIGNAL_MTX.lock();
-
- assert_eq!(alarm::cancel(), None);
-
- assert_eq!(alarm::set(60), None);
- assert_eq!(alarm::cancel(), Some(60));
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_symlinkat() {
- let _m = crate::CWD_LOCK.read();
-
- let tempdir = tempdir().unwrap();
-
- let target = tempdir.path().join("a");
- let linkpath = tempdir.path().join("b");
- symlinkat(&target, None, &linkpath).unwrap();
- assert_eq!(
- readlink(&linkpath).unwrap().to_str().unwrap(),
- target.to_str().unwrap()
- );
-
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let target = "c";
- let linkpath = "d";
- symlinkat(target, Some(dirfd), linkpath).unwrap();
- assert_eq!(
- readlink(&tempdir.path().join(linkpath))
- .unwrap()
- .to_str()
- .unwrap(),
- target
- );
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_linkat_file() {
- let tempdir = tempdir().unwrap();
- let oldfilename = "foo.txt";
- let oldfilepath = tempdir.path().join(oldfilename);
-
- let newfilename = "bar.txt";
- let newfilepath = tempdir.path().join(newfilename);
-
- // Create file
- File::create(oldfilepath).unwrap();
-
- // Get file descriptor for base directory
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- // Attempt hard link file at relative path
- linkat(
- Some(dirfd),
- oldfilename,
- Some(dirfd),
- newfilename,
- LinkatFlags::SymlinkFollow,
- )
- .unwrap();
- assert!(newfilepath.exists());
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_linkat_olddirfd_none() {
- let _dr = crate::DirRestore::new();
-
- let tempdir_oldfile = tempdir().unwrap();
- let oldfilename = "foo.txt";
- let oldfilepath = tempdir_oldfile.path().join(oldfilename);
-
- let tempdir_newfile = tempdir().unwrap();
- let newfilename = "bar.txt";
- let newfilepath = tempdir_newfile.path().join(newfilename);
-
- // Create file
- File::create(oldfilepath).unwrap();
-
- // Get file descriptor for base directory of new file
- let dirfd = fcntl::open(
- tempdir_newfile.path(),
- fcntl::OFlag::empty(),
- stat::Mode::empty(),
- )
- .unwrap();
-
- // Attempt hard link file using curent working directory as relative path for old file path
- chdir(tempdir_oldfile.path()).unwrap();
- linkat(
- None,
- oldfilename,
- Some(dirfd),
- newfilename,
- LinkatFlags::SymlinkFollow,
- )
- .unwrap();
- assert!(newfilepath.exists());
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_linkat_newdirfd_none() {
- let _dr = crate::DirRestore::new();
-
- let tempdir_oldfile = tempdir().unwrap();
- let oldfilename = "foo.txt";
- let oldfilepath = tempdir_oldfile.path().join(oldfilename);
-
- let tempdir_newfile = tempdir().unwrap();
- let newfilename = "bar.txt";
- let newfilepath = tempdir_newfile.path().join(newfilename);
-
- // Create file
- File::create(oldfilepath).unwrap();
-
- // Get file descriptor for base directory of old file
- let dirfd = fcntl::open(
- tempdir_oldfile.path(),
- fcntl::OFlag::empty(),
- stat::Mode::empty(),
- )
- .unwrap();
-
- // Attempt hard link file using current working directory as relative path for new file path
- chdir(tempdir_newfile.path()).unwrap();
- linkat(
- Some(dirfd),
- oldfilename,
- None,
- newfilename,
- LinkatFlags::SymlinkFollow,
- )
- .unwrap();
- assert!(newfilepath.exists());
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "ios",
- target_os = "macos",
- target_os = "redox",
- target_os = "haiku"
-)))]
-fn test_linkat_no_follow_symlink() {
- let _m = crate::CWD_LOCK.read();
-
- let tempdir = tempdir().unwrap();
- let oldfilename = "foo.txt";
- let oldfilepath = tempdir.path().join(oldfilename);
-
- let symoldfilename = "symfoo.txt";
- let symoldfilepath = tempdir.path().join(symoldfilename);
-
- let newfilename = "nofollowsymbar.txt";
- let newfilepath = tempdir.path().join(newfilename);
-
- // Create file
- File::create(&oldfilepath).unwrap();
-
- // Create symlink to file
- symlinkat(&oldfilepath, None, &symoldfilepath).unwrap();
-
- // Get file descriptor for base directory
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- // Attempt link symlink of file at relative path
- linkat(
- Some(dirfd),
- symoldfilename,
- Some(dirfd),
- newfilename,
- LinkatFlags::NoSymlinkFollow,
- )
- .unwrap();
-
- // Assert newfile is actually a symlink to oldfile.
- assert_eq!(
- readlink(&newfilepath).unwrap().to_str().unwrap(),
- oldfilepath.to_str().unwrap()
- );
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
-fn test_linkat_follow_symlink() {
- let _m = crate::CWD_LOCK.read();
-
- let tempdir = tempdir().unwrap();
- let oldfilename = "foo.txt";
- let oldfilepath = tempdir.path().join(oldfilename);
-
- let symoldfilename = "symfoo.txt";
- let symoldfilepath = tempdir.path().join(symoldfilename);
-
- let newfilename = "nofollowsymbar.txt";
- let newfilepath = tempdir.path().join(newfilename);
-
- // Create file
- File::create(&oldfilepath).unwrap();
-
- // Create symlink to file
- symlinkat(&oldfilepath, None, &symoldfilepath).unwrap();
-
- // Get file descriptor for base directory
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- // Attempt link target of symlink of file at relative path
- linkat(
- Some(dirfd),
- symoldfilename,
- Some(dirfd),
- newfilename,
- LinkatFlags::SymlinkFollow,
- )
- .unwrap();
-
- let newfilestat = stat::stat(&newfilepath).unwrap();
-
- // Check the file type of the new link
- assert_eq!(
- (stat::SFlag::from_bits_truncate(newfilestat.st_mode as mode_t)
- & SFlag::S_IFMT),
- SFlag::S_IFREG
- );
-
- // Check the number of hard links to the original file
- assert_eq!(newfilestat.st_nlink, 2);
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_unlinkat_dir_noremovedir() {
- let tempdir = tempdir().unwrap();
- let dirname = "foo_dir";
- let dirpath = tempdir.path().join(dirname);
-
- // Create dir
- DirBuilder::new().recursive(true).create(dirpath).unwrap();
-
- // Get file descriptor for base directory
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- // Attempt unlink dir at relative path without proper flag
- let err_result =
- unlinkat(Some(dirfd), dirname, UnlinkatFlags::NoRemoveDir).unwrap_err();
- assert!(err_result == Errno::EISDIR || err_result == Errno::EPERM);
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_unlinkat_dir_removedir() {
- let tempdir = tempdir().unwrap();
- let dirname = "foo_dir";
- let dirpath = tempdir.path().join(dirname);
-
- // Create dir
- DirBuilder::new().recursive(true).create(&dirpath).unwrap();
-
- // Get file descriptor for base directory
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- // Attempt unlink dir at relative path with proper flag
- unlinkat(Some(dirfd), dirname, UnlinkatFlags::RemoveDir).unwrap();
- assert!(!dirpath.exists());
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_unlinkat_file() {
- let tempdir = tempdir().unwrap();
- let filename = "foo.txt";
- let filepath = tempdir.path().join(filename);
-
- // Create file
- File::create(&filepath).unwrap();
-
- // Get file descriptor for base directory
- let dirfd =
- fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
- .unwrap();
-
- // Attempt unlink file at relative path
- unlinkat(Some(dirfd), filename, UnlinkatFlags::NoRemoveDir).unwrap();
- assert!(!filepath.exists());
-}
-
-#[test]
-fn test_access_not_existing() {
- let tempdir = tempdir().unwrap();
- let dir = tempdir.path().join("does_not_exist.txt");
- assert_eq!(
- access(&dir, AccessFlags::F_OK).err().unwrap(),
- Errno::ENOENT
- );
-}
-
-#[test]
-fn test_access_file_exists() {
- let tempdir = tempdir().unwrap();
- let path = tempdir.path().join("does_exist.txt");
- let _file = File::create(path.clone()).unwrap();
- access(&path, AccessFlags::R_OK | AccessFlags::W_OK)
- .expect("assertion failed");
-}
-
-//Clippy false positive https://github.com/rust-lang/rust-clippy/issues/9111
-#[allow(clippy::needless_borrow)]
-#[cfg(not(target_os = "redox"))]
-#[test]
-fn test_user_into_passwd() {
- // get the UID of the "nobody" user
- #[cfg(not(target_os = "haiku"))]
- let test_username = "nobody";
- // "nobody" unavailable on haiku
- #[cfg(target_os = "haiku")]
- let test_username = "user";
-
- let nobody = User::from_name(test_username).unwrap().unwrap();
- let pwd: libc::passwd = nobody.into();
- let _: User = (&pwd).into();
-}
-
-/// Tests setting the filesystem UID with `setfsuid`.
-#[cfg(any(target_os = "linux", target_os = "android"))]
-#[test]
-fn test_setfsuid() {
- use std::os::unix::fs::PermissionsExt;
- use std::{fs, io, thread};
- require_capability!("test_setfsuid", CAP_SETUID);
-
- // get the UID of the "nobody" user
- let nobody = User::from_name("nobody").unwrap().unwrap();
-
- // create a temporary file with permissions '-rw-r-----'
- let file = tempfile::NamedTempFile::new_in("/var/tmp").unwrap();
- let temp_path = file.into_temp_path();
- let temp_path_2 = temp_path.to_path_buf();
- let mut permissions = fs::metadata(&temp_path).unwrap().permissions();
- permissions.set_mode(0o640);
-
- // spawn a new thread where to test setfsuid
- thread::spawn(move || {
- // set filesystem UID
- let fuid = setfsuid(nobody.uid);
- // trying to open the temporary file should fail with EACCES
- let res = fs::File::open(&temp_path);
- let err = res.expect_err("assertion failed");
- assert_eq!(err.kind(), io::ErrorKind::PermissionDenied);
-
- // assert fuid actually changes
- let prev_fuid = setfsuid(Uid::from_raw(-1i32 as u32));
- assert_ne!(prev_fuid, fuid);
- })
- .join()
- .unwrap();
-
- // open the temporary file with the current thread filesystem UID
- fs::File::open(temp_path_2).unwrap();
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-fn test_ttyname() {
- let fd = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
- assert!(fd.as_raw_fd() > 0);
-
- // on linux, we can just call ttyname on the pty master directly, but
- // apparently osx requires that ttyname is called on a slave pty (can't
- // find this documented anywhere, but it seems to empirically be the case)
- grantpt(&fd).expect("grantpt failed");
- unlockpt(&fd).expect("unlockpt failed");
- let sname = unsafe { ptsname(&fd) }.expect("ptsname failed");
- let fds = open(Path::new(&sname), OFlag::O_RDWR, stat::Mode::empty())
- .expect("open failed");
- assert!(fds > 0);
-
- let name = ttyname(fds).expect("ttyname failed");
- assert!(name.starts_with("/dev"));
-}
-
-#[test]
-#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
-fn test_ttyname_not_pty() {
- let fd = File::open("/dev/zero").unwrap();
- assert!(fd.as_raw_fd() > 0);
- assert_eq!(ttyname(fd.as_raw_fd()), Err(Errno::ENOTTY));
-}
-
-#[test]
-#[cfg(not(any(
- target_os = "redox",
- target_os = "fuchsia",
- target_os = "haiku"
-)))]
-fn test_ttyname_invalid_fd() {
- assert_eq!(ttyname(-1), Err(Errno::EBADF));
-}
-
-#[test]
-#[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "dragonfly",
-))]
-fn test_getpeereid() {
- use std::os::unix::net::UnixStream;
- let (sock_a, sock_b) = UnixStream::pair().unwrap();
-
- let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap();
- let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap();
-
- let uid = geteuid();
- let gid = getegid();
-
- assert_eq!(uid, uid_a);
- assert_eq!(gid, gid_a);
- assert_eq!(uid_a, uid_b);
- assert_eq!(gid_a, gid_b);
-}
-
-#[test]
-#[cfg(any(
- target_os = "macos",
- target_os = "ios",
- target_os = "freebsd",
- target_os = "openbsd",
- target_os = "netbsd",
- target_os = "dragonfly",
-))]
-fn test_getpeereid_invalid_fd() {
- // getpeereid is not POSIX, so error codes are inconsistent between different Unices.
- getpeereid(-1).expect_err("assertion failed");
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_faccessat_none_not_existing() {
- use nix::fcntl::AtFlags;
- let tempdir = tempfile::tempdir().unwrap();
- let dir = tempdir.path().join("does_not_exist.txt");
- assert_eq!(
- faccessat(None, &dir, AccessFlags::F_OK, AtFlags::empty())
- .err()
- .unwrap(),
- Errno::ENOENT
- );
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_faccessat_not_existing() {
- use nix::fcntl::AtFlags;
- let tempdir = tempfile::tempdir().unwrap();
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let not_exist_file = "does_not_exist.txt";
- assert_eq!(
- faccessat(
- Some(dirfd),
- not_exist_file,
- AccessFlags::F_OK,
- AtFlags::empty(),
- )
- .err()
- .unwrap(),
- Errno::ENOENT
- );
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_faccessat_none_file_exists() {
- use nix::fcntl::AtFlags;
- let tempdir = tempfile::tempdir().unwrap();
- let path = tempdir.path().join("does_exist.txt");
- let _file = File::create(path.clone()).unwrap();
- assert!(faccessat(
- None,
- &path,
- AccessFlags::R_OK | AccessFlags::W_OK,
- AtFlags::empty(),
- )
- .is_ok());
-}
-
-#[test]
-#[cfg(not(target_os = "redox"))]
-fn test_faccessat_file_exists() {
- use nix::fcntl::AtFlags;
- let tempdir = tempfile::tempdir().unwrap();
- let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap();
- let exist_file = "does_exist.txt";
- let path = tempdir.path().join(exist_file);
- let _file = File::create(path.clone()).unwrap();
- assert!(faccessat(
- Some(dirfd),
- &path,
- AccessFlags::R_OK | AccessFlags::W_OK,
- AtFlags::empty(),
- )
- .is_ok());
-}
-
-#[test]
-#[cfg(any(
- all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
-fn test_eaccess_not_existing() {
- let tempdir = tempdir().unwrap();
- let dir = tempdir.path().join("does_not_exist.txt");
- assert_eq!(
- eaccess(&dir, AccessFlags::F_OK).err().unwrap(),
- Errno::ENOENT
- );
-}
-
-#[test]
-#[cfg(any(
- all(target_os = "linux", not(target_env = "uclibc")),
- target_os = "freebsd",
- target_os = "dragonfly"
-))]
-fn test_eaccess_file_exists() {
- let tempdir = tempdir().unwrap();
- let path = tempdir.path().join("does_exist.txt");
- let _file = File::create(path.clone()).unwrap();
- eaccess(&path, AccessFlags::R_OK | AccessFlags::W_OK)
- .expect("assertion failed");
-}