Update nix to 0.29.0
Test: m rust
Bug: 401100059
Change-Id: I6c3a4f1f65e2b02d6feac9c528487594758abec7
diff --git a/crates/nix/.android-checksum.json b/crates/nix/.android-checksum.json
index 820bd8d..53b43bf 100644
--- a/crates/nix/.android-checksum.json
+++ b/crates/nix/.android-checksum.json
@@ -1 +1 @@
-{"package":null,"files":{".cargo-checksum.json":"ca274fd03609e5e33972bd75ef5311417c785870a100ea269ae9fe8100ecf16c","Android.bp":"7f3bbd078169dddeac50fef3f5474478c091a4972d6a7b0861b9ddedb4070ab6","CHANGELOG.md":"ec9f74c874581251fc0c9ad8443de206e5c1be3e5f5cbfa4527ecb6076136c4f","Cargo.toml":"e5d99e20012bb6525da7890f241f49c7acb467d5988d10f8ccd4bdc7f204d253","LICENSE":"ff4177622b3314b5c7199fb4a42e3807acd8362b7f32e45e26630e235260f943","METADATA":"9d893ec628dcf6ad1486c803f46ff27b8859856c28c06c65f5cc1d6e671c8bc1","MODULE_LICENSE_MIT":"0d6f8afa3940b7f06bebee651376d43bc8b0d5b437337be2696d30377451e93a","README.md":"b77b826d1b503d67b659c9090f46cdd57f6693fd7d3b273f9ad045a9df85d47a","TEST_MAPPING":"51f4b8c9722b9825f6a384bee4c2d246ea00ea385f41867e8f7a104a91ad9e42","build.rs":"56c6ddfe87d8a4c2fa125c4dd7bf7613af8a828092210a581b5bb010ddcd9207","cargo_embargo.json":"98edc205c0c2a15cf2a7bb74956cfbc52d7a3b29da0c7d781751ccad9453e478","module_block.bp.fragment":"d265f83f777285b9c1dd903f4b9f9204c4c58e5ac0f34cc49f0ec5ec6e820e7c","patches/memfd.diff":"f30b12198a1a2f7a695cde6d0f942ce6c319d6164e68c546f8e94db29244bdba","src/dir.rs":"3cc2f422e2ee6dc3d1022edf5f559fba7cf1a8d0b5fdc6f74122e828be06bf18","src/env.rs":"a850356a838368c3b28552a2c9750366d2ceaed742f6754477c1fb5385d91957","src/errno.rs":"9daa17bbc59b33527bbf41d26a6913f60da864cb0ae9ba0be21e5911cc3ad69c","src/fcntl.rs":"783e95aceed616f5f93604f3bea06472acbddab0cd821156ec92285754bf9ea6","src/features.rs":"cce028bd977ef8c69b4b4b0a959e94573f3d1a89b53f0fa23aae135a60dbdb3e","src/ifaddrs.rs":"28708d0d15cd124da68c98c76ebc118ed11caf905bf467b80e3de23758219d98","src/kmod.rs":"b96e40714902ef7941d5489f8b68edd9337c3adddf34cce68d90363f0664e8c0","src/lib.rs":"8260ccaf0224525695f195614f28a376269fcba52ef4491a6b2ca476cb46589e","src/macros.rs":"a2c488d2336b89b89f1d4681aab7f050be4db94d46b276a7172089b2d4998b64","src/mount/bsd.rs":"ca1fd0ea33a6aea6ef036eea6e1cac8f207ff703e5bd955381a292306b46b2d8","src/mount/linux.rs":"26a4c359c5cefe8c365f5c2aa5e3661704357cb1fc1348b4377bae45799300f1","src/mount/mod.rs":"63c8b30d3a7f1641796c528f36541836f5eee6d51eee6ae6d7d8ea01f135537b","src/mqueue.rs":"d3b9a29435f5d02888994f1164d2684d7e3756b80e3448dfc5919284ee23c965","src/net/if_.rs":"109e980467d23c1ab4c816e265302f23f60d1ff0c0f4bd3e5df06d9f41748580","src/net/mod.rs":"a88860334410ed47a1f6594a8563dfeb22bbcd3bb4dec308bb8e3de8866b3af4","src/poll.rs":"f57dbc06aa318841cd0eb035579b8e3fa875aff12d66b1e6692e261d65b9b1c7","src/poll_timeout.rs":"16007737ae9219e120d1b0de017067431fe8fa6223d03575bbdbdfe7aab4c1ea","src/pty.rs":"47a4f8fde03ca88627c29a04e5ca6a35daead0edaee61dcd732bc6d7174c9130","src/sched.rs":"303e5b0c605ca019ffb02472691277e81f6f6be0869411814416fedf2368ef40","src/sys/aio.rs":"c178f0ed3713bf0d100195b53d333b8342a2278c19f494e639607d5296a84c9c","src/sys/epoll.rs":"afabda2906ed2d90dfeecbdd96a220be6b3c50835d395e1be2d87eb1d2222cd1","src/sys/event.rs":"4f9f42e4eb4ddac00ed6fcb5d70b9879f3a1291f3160e72de98e1076ed8a98b8","src/sys/eventfd.rs":"5c465648001444c18e55c3d90db208975c125ce003f38fa9a4ab24f97e15733e","src/sys/fanotify.rs":"99121365e760fde466648d9ce6b5091f8d733788bb940d3cccaf01f29d179f7c","src/sys/inotify.rs":"1d1fdf3263c5ee893dd58877cc458b478ae470e3794d50ca5a4d9cd9d7f31eae","src/sys/ioctl/bsd.rs":"10b2ce4d04e0d28277d4a237204e491e896e3fc377c5dcf8792a45001d0f8a26","src/sys/ioctl/linux.rs":"9242e92f8e8bce63af9693af61fc69355082ca882810ab43ddc55f5557803b3c","src/sys/ioctl/mod.rs":"5ef03b0ec57f3270093da800b466dd8f085e62565db60dd403977231758d712e","src/sys/memfd.rs":"c1791230913192d6931cf0a33c1f6ed0de0db00360326e8538ffa559ee321ae0","src/sys/mman.rs":"c5ca69aebfefb03ea5e29857361a0280a93c08fb72aa6e6df034984542124eed","src/sys/mod.rs":"81608664a2880f27699f08c344e9ef23c7055d7e8b79832b81c702510b8e373d","src/sys/personality.rs":"4fc2b82f1e4aa6bd49bd1cf320127d9a0061974096c01b95454f79fd74ee4294","src/sys/prctl.rs":"28b9ccc3e6f9294d33c6a0822bdb52792e40c66a30634b6a8854760be7752d2b","src/sys/pthread.rs":"270213f8050f8bff48e87fe4ad35453b5f0423b959e974dc2b0b8a35eb2491ac","src/sys/ptrace/bsd.rs":"a387ccefa8adb7b8b7f0fea41be619c54c8091c0e111e7b813ee910870f7414e","src/sys/ptrace/linux.rs":"4f6e0e1a1876e044482ab7dedcfe114acd2c2185885729d8070ae4f1dd1a0e3c","src/sys/ptrace/mod.rs":"641edf21d50f73b5079a85c0aed84698acb927e96694161eedba5d9368c1e5fb","src/sys/quota.rs":"944cd578a34011f4e35c28a002f0dd5b7cb53d87d7da8da5b39011e4c56f8052","src/sys/reboot.rs":"390407d521facc8ea3d66e314e7d5a27999b92db86be864919a6e8b2851d6c88","src/sys/resource.rs":"56ee3355124c32b9f6f9b4fea20eadec72bb3db096c0162072f0f7c0f3318335","src/sys/select.rs":"42d38e91eae5ed7a30c31e1b7974860bc419256e6f461164b15a74d2e9653eab","src/sys/sendfile.rs":"9d518732634e6c69482527e68e3d8c132574f7af2c4ff3612860049558016d04","src/sys/signal.rs":"f533567e059e4e16d41c6938559fda15052efdc14ee29266203a0805f1c5fbfd","src/sys/signalfd.rs":"0ecb4cf3287fef0e4ed66f2e5594962af449bb9f28b3ea03a169d71d6e68a275","src/sys/socket/addr.rs":"e092094e4ddc71c8cf7d62530d8bc3b92d900974d492e45de967e8e15ec2658e","src/sys/socket/mod.rs":"ca7ced3676944acb5cc67327ad2ae8e38529df23a85e7b970082d9bf3f5584df","src/sys/socket/sockopt.rs":"9192ebb4030747d387a03c5b616e6724c25aa9da4169e7b48f5a9d91bf82721a","src/sys/stat.rs":"bec1d3b5a7a930989b9a54d350d47653499deeb560d73f3b63efaecf4ebb351e","src/sys/statfs.rs":"83b095a903858a298c1f6b2135bb035f24381374097dddd09289bd4f23f1b389","src/sys/statvfs.rs":"0256273f711e9d2c1c7b8feed6dbf3328295095a9a328afb341ff08bf27ef941","src/sys/sysinfo.rs":"ceeb8c4d709eb02c6ec2fc0d9ec9b8b8dbd40f5263aa8456d0fb8dbbbc850b9c","src/sys/termios.rs":"39ed1da2bc23294fda06536e8cc850a791d5576f339057d3a2e0b165ae6bcb14","src/sys/time.rs":"cbfc06acea72029e1746070c8355c362154fb42bad35e4fc36fa5e5629758da5","src/sys/timer.rs":"d436c5b043b99afd8de9fb42a8fc7ca3509c324d071937b7719bc7ece6986caf","src/sys/timerfd.rs":"ddc1f4f726d1cbc416006c62fc39d80c9edc10297c5d03d70b55106a9df2c7c8","src/sys/uio.rs":"7fd8fccc97ba5b8ee70d74f18399fbd6af60a7f366b9929d90ded2af59a7eb43","src/sys/utsname.rs":"8ab00cc78f82a44a3d47c3955f030418ad846886fabaa9fd178437896a54fee1","src/sys/wait.rs":"467c35c1d1bf5ed38b5e7c0174a2df0471ac2ce37166931747d887b75d2e1266","src/time.rs":"2588796a51798fa053120b809e503bab9c7526f3582159a68c999630cebb2d57","src/ucontext.rs":"0eb33bfd885d9378a8583a7de7409755b73880bc159d502f974d749db84afbfa","src/unistd.rs":"85c9953019c0e7cc1eaef6c4267c973f7e7f1a23b27fcfa5667cf13165a60cf1","test/common/mod.rs":"bbdddcdbaa55bab3bc037b0449b6537ec2df2d4d52d1a7ee5288aa4c346419ee","test/sys/mod.rs":"ca14fec72e970eaf0033b728087e950c132fbeffb269c09f47c51d27b671e8ba","test/sys/test_aio.rs":"070321a72aede1fdd38e55f90768d88d903f0dddad8868d1d26bf77be220c862","test/sys/test_aio_drop.rs":"2dcc71fb768814ee936a384384b11984f9b2d64a5c8245faf466aa4027b33daf","test/sys/test_epoll.rs":"4081004c6c48cd55b27c61865641cc1bf006d2cffbf1a611e4a54d8108ee8c25","test/sys/test_event.rs":"2ecb6f15941d9819f310a5128ddd29c828cee932d55ba70e7f710466af8f5665","test/sys/test_fanotify.rs":"ece6e64a4b2162686ede921d329b5f1b27745be6c47a3f7e5650ed237852b11a","test/sys/test_inotify.rs":"1b3253db06bd6464f3e9ca46646615e62c3bad889dc6813d2068a96fbaa31d46","test/sys/test_ioctl.rs":"ed458ae18b37aaac45df16f38f815cc9fc7080dd17b2e18acc6a05042737e4cf","test/sys/test_mman.rs":"a4e7cfcbdbda707da74d5b49ef56a5c78e5184fd9674860918bedf31d612483c","test/sys/test_prctl.rs":"5c0a7d4f6678d6433080a72926235e5250e50ac9c4c57f52c07b11680c322cc9","test/sys/test_pthread.rs":"9ecc144f8f253589aabd8d5672d837c3145bd9c28f03e9a3f21d0a43babd33b9","test/sys/test_ptrace.rs":"5a9aa8ee660b84896bb1e74700746b3ef7e915e36df6722fa9e1a49483823ecc","test/sys/test_resource.rs":"669e5b22ef0a9ce69bdfab1e9f63a8f53bf1c5ee7c79c8e2e78f2071dc4b8c01","test/sys/test_select.rs":"5ce391b9928f3e9a3588b17818aecf06226deac34b5593ed86d773e469e5758e","test/sys/test_signal.rs":"a7463b6b6c53b5704878ff41cff172c9f48e71632693a5edfb68534afb8fe211","test/sys/test_signalfd.rs":"b3bf16f0d7e88a055a0c93ada1a9619ea5b7cf08a6bf1eddf43c5b7e4599a71d","test/sys/test_socket.rs":"99a6f0329ebc6790af1be2938e84f1bb8e4a59ed72542d6c082128d9e0dbea70","test/sys/test_sockopt.rs":"057e4f6d39d10a834d66676a689928920affbb0499dacdbf8bebd28e243608a1","test/sys/test_stat.rs":"b481cb6e20659dc5a63849e3151610ef2af50140f2c5d1cc39a43bc58560fc75","test/sys/test_statfs.rs":"4522f3817fb1d54816654b7a24325d3db54e19dbd1a94a4a3f5a010052f69456","test/sys/test_statvfs.rs":"ad13a879a5403f98c623051c8a653cfb78f5a31869d90f139c6ae99d6eba9e11","test/sys/test_sysinfo.rs":"6c42cf86731bcb300c50707d83157af92aca3cd3e3c2d46b1333657e463b41ec","test/sys/test_termios.rs":"7e7bf02b420d0664bcec3e199b63cc5d83fc3af625ce675bc845542a41b75ff8","test/sys/test_time.rs":"4cf4195a77844eb097818c2db7cf47921737c8aa53d061cf49d9080b60b50ac1","test/sys/test_timer.rs":"d2364da7af2fc64a458fd2b16caca2c779ceefac0de322c13066f77039c442fe","test/sys/test_timerfd.rs":"712d876754794031dc7a43636f5af47e4c8ea3a8b13c7460a6da5fbb741f491a","test/sys/test_uio.rs":"25cc97565a7b584a4fd626df7dbc6db4a4da901a36ac160d93f0511ea713e6d2","test/sys/test_utsname.rs":"60cdb81efbfb126593bfbbe0437c0f4fb97d5ad3e423996622cb33ccb4d80ea4","test/sys/test_wait.rs":"dc997b861eb8001dca47f11e7bd9458ca20e169816c7de8d45ee0ac2b9d167e1","test/test.rs":"51894d348fd60e0bbf172de28b89e494f64054c69a7139eff8c28811a4b7d0dd","test/test_clearenv.rs":"323054cad8ce178e1531b470f93e49856ef06e66c8faf9e2f0e2d3398c9e842b","test/test_dir.rs":"5fe95812a13b0bbc8cba9da1f3f59a9979edd01a63078c5bc370b383107bd134","test/test_errno.rs":"db50d2f9a9f03fac417547ce5683a65688b03150fc9c1471e4c2add3d89a2c07","test/test_fcntl.rs":"a05e23890df0965fffe83dbb80089104a944a9ad28aae0284e2ec10797f1c679","test/test_kmod/hello_mod/Makefile":"b406e6c31829f06c93c4c22f5343ac0c6d1d873c0df4bc1132dfca8e636bf041","test/test_kmod/hello_mod/hello.c":"6059ebdeb2d2e050be3046be21bca8e830da6a2f8262511fb12d9402c9dea526","test/test_kmod/mod.rs":"9a4452b7fed034c35554885245be3d0c72a454b6efabc21ec4629b8ad53820d5","test/test_mount.rs":"613455ba98196582655cf46a6fc67bc30e7398280423b4e33fbc300beff1318f","test/test_mq.rs":"f2f42b6b9a9b8567e4a419f090fa19398d83185a98983db7c6feb067caed5559","test/test_net.rs":"d03a6d6f57127fab1a9622a628ab13deab616e817944371e522fcb2bcc23c5a7","test/test_nix_path.rs":"a748d4914f216a6642a07c2743b03033a318ad98daab56096bfcb9120454cff4","test/test_nmount.rs":"a48bc85fdba2b5afa6997cdfa50b0808d72a7a7aa5151e7de504660e657125ba","test/test_poll.rs":"1dbdac16e264e54d781dc7c25b41caacdb00b442f76bc53d9e17ac19cfd91eef","test/test_pty.rs":"2acac2e0f9bacf569f48ca58d1eddaae5d79e7ac11ba24eb2fee5c4347ea70c5","test/test_sched.rs":"031932ac8c512c7f881c80c9fe01ecd4c744d9c41b2b0f5fbf904ac0e0e4bf6a","test/test_sendfile.rs":"5a738737602b242b2139deb6c796e01a0aa5a44e0738a017b091342bba162c83","test/test_stat.rs":"cddebbd15ca1fc0ae0bc89594d8c2b5a8be4ce36ef10c9096b6867ad2cbc6826","test/test_time.rs":"7a41b517288fde2b8f9f439bdabe3df1059526793f0bd2ecee2c8ff23a64329a","test/test_unistd.rs":"25db690608fd72e40c544d6911e25e06674580f86a2faccf7bb989520b3d5995"}}
\ No newline at end of file
+{"package":null,"files":{".cargo-checksum.json":"30bb37dc98f065a00d9e5000681c6494164392c2c127d1809b415fa8d1bd89a4","Android.bp":"5aa5a1d27e979282d6e7268595991b5de3af912807f0c5c9a1f4958f951e2d78","CHANGELOG.md":"9357c8dffb7cfea2644f16b52b6bbcdc85f2344fdb6b9b1fcf6703e4ce196bdd","Cargo.toml":"a9d69cbf2002b3b485a81944e21038a09fc98552edd5977037cbc73339a61fb2","LICENSE":"ff4177622b3314b5c7199fb4a42e3807acd8362b7f32e45e26630e235260f943","METADATA":"4d1017f4d7ccfaca742fe0f1e57eba1988f5565bc8584bba161eccce55ba394f","MODULE_LICENSE_MIT":"0d6f8afa3940b7f06bebee651376d43bc8b0d5b437337be2696d30377451e93a","README.md":"b77b826d1b503d67b659c9090f46cdd57f6693fd7d3b273f9ad045a9df85d47a","TEST_MAPPING":"51f4b8c9722b9825f6a384bee4c2d246ea00ea385f41867e8f7a104a91ad9e42","build.rs":"a3d803c1e739a4a306213eb6914c83ce35b430dda7ad21d7660076f49577da20","cargo_embargo.json":"98edc205c0c2a15cf2a7bb74956cfbc52d7a3b29da0c7d781751ccad9453e478","module_block.bp.fragment":"d265f83f777285b9c1dd903f4b9f9204c4c58e5ac0f34cc49f0ec5ec6e820e7c","patches/memfd.diff":"f30b12198a1a2f7a695cde6d0f942ce6c319d6164e68c546f8e94db29244bdba","src/dir.rs":"7140d727266419ae57ec39ab785469abe52ff0b3fd3b4955f4df2f4a2213dbc7","src/env.rs":"a850356a838368c3b28552a2c9750366d2ceaed742f6754477c1fb5385d91957","src/errno.rs":"9daa17bbc59b33527bbf41d26a6913f60da864cb0ae9ba0be21e5911cc3ad69c","src/fcntl.rs":"6c442b5f2fe32f4033104583601c833e7d308099f1f897dc021a54f411c97e49","src/features.rs":"cce028bd977ef8c69b4b4b0a959e94573f3d1a89b53f0fa23aae135a60dbdb3e","src/ifaddrs.rs":"28708d0d15cd124da68c98c76ebc118ed11caf905bf467b80e3de23758219d98","src/kmod.rs":"b96e40714902ef7941d5489f8b68edd9337c3adddf34cce68d90363f0664e8c0","src/lib.rs":"f954a43d970557cbe94a3ee075525afa1ea37f1498dfb7d39cc38b7255654ca9","src/macros.rs":"a2c488d2336b89b89f1d4681aab7f050be4db94d46b276a7172089b2d4998b64","src/mount/apple.rs":"8108058b35548cbe274acd0b213b2e9ed8dd88a609cda6e589d3e768392ee440","src/mount/bsd_without_apple.rs":"bf859eb02ddc8030ca5c2a0f8a8d80165facd41c27e3300d93505347697b4d1a","src/mount/linux.rs":"e0303501e66addb14ef3b700f2e5490ed5d6dce7e6f75fef6415a60ed8ec9ee9","src/mount/mod.rs":"d7c459aa273c6d068d1fa2b2f3a64c9da2a90e4f81eb6b712b1d3b46fbad84b9","src/mqueue.rs":"d3b9a29435f5d02888994f1164d2684d7e3756b80e3448dfc5919284ee23c965","src/net/if_.rs":"65d71ba2bceaf68e40e27f6cee61578b5414539f9880ec2a1f17efee0b3f8991","src/net/mod.rs":"a88860334410ed47a1f6594a8563dfeb22bbcd3bb4dec308bb8e3de8866b3af4","src/poll.rs":"f57dbc06aa318841cd0eb035579b8e3fa875aff12d66b1e6692e261d65b9b1c7","src/poll_timeout.rs":"16007737ae9219e120d1b0de017067431fe8fa6223d03575bbdbdfe7aab4c1ea","src/pty.rs":"e6ae49216b79e4ca7bf6ec51b6c354fc92c161ff8dacdbe269282b8ca628361a","src/sched.rs":"303e5b0c605ca019ffb02472691277e81f6f6be0869411814416fedf2368ef40","src/sys/aio.rs":"0f8452943cfe71b77606116376a834ab70ed0d5c7c2c8922ed4652f7c6d87b3b","src/sys/epoll.rs":"afabda2906ed2d90dfeecbdd96a220be6b3c50835d395e1be2d87eb1d2222cd1","src/sys/event.rs":"4f9f42e4eb4ddac00ed6fcb5d70b9879f3a1291f3160e72de98e1076ed8a98b8","src/sys/eventfd.rs":"5c465648001444c18e55c3d90db208975c125ce003f38fa9a4ab24f97e15733e","src/sys/fanotify.rs":"06eb950263d5d35afccf215f9c2c1d3cca640c1deef9b043fa5b81d9b0c51c4d","src/sys/inotify.rs":"1d1fdf3263c5ee893dd58877cc458b478ae470e3794d50ca5a4d9cd9d7f31eae","src/sys/ioctl/bsd.rs":"10b2ce4d04e0d28277d4a237204e491e896e3fc377c5dcf8792a45001d0f8a26","src/sys/ioctl/linux.rs":"9242e92f8e8bce63af9693af61fc69355082ca882810ab43ddc55f5557803b3c","src/sys/ioctl/mod.rs":"5ef03b0ec57f3270093da800b466dd8f085e62565db60dd403977231758d712e","src/sys/memfd.rs":"c1791230913192d6931cf0a33c1f6ed0de0db00360326e8538ffa559ee321ae0","src/sys/mman.rs":"c5ca69aebfefb03ea5e29857361a0280a93c08fb72aa6e6df034984542124eed","src/sys/mod.rs":"81608664a2880f27699f08c344e9ef23c7055d7e8b79832b81c702510b8e373d","src/sys/personality.rs":"4fc2b82f1e4aa6bd49bd1cf320127d9a0061974096c01b95454f79fd74ee4294","src/sys/prctl.rs":"974f1509730463abb14dc2f795546f00fb9f44b44c8c542c7e1b99530dd9f4f6","src/sys/pthread.rs":"270213f8050f8bff48e87fe4ad35453b5f0423b959e974dc2b0b8a35eb2491ac","src/sys/ptrace/bsd.rs":"a387ccefa8adb7b8b7f0fea41be619c54c8091c0e111e7b813ee910870f7414e","src/sys/ptrace/linux.rs":"2830cb8add0960b6e2b8f07b1f4fc0e8dcf0b5c23b79bc7e23774038c04ea52f","src/sys/ptrace/mod.rs":"641edf21d50f73b5079a85c0aed84698acb927e96694161eedba5d9368c1e5fb","src/sys/quota.rs":"944cd578a34011f4e35c28a002f0dd5b7cb53d87d7da8da5b39011e4c56f8052","src/sys/reboot.rs":"390407d521facc8ea3d66e314e7d5a27999b92db86be864919a6e8b2851d6c88","src/sys/resource.rs":"9a57f48f39c378f92cd439fb71f70533b4ca282fdb60503f23035af83077fb08","src/sys/select.rs":"42d38e91eae5ed7a30c31e1b7974860bc419256e6f461164b15a74d2e9653eab","src/sys/sendfile.rs":"9d518732634e6c69482527e68e3d8c132574f7af2c4ff3612860049558016d04","src/sys/signal.rs":"f1241639eb51d36ff9fa5b2a516ecbe53e31bd6b1a69623a768b1eb577f7dc2d","src/sys/signalfd.rs":"c4a88ff4d8838ffc37cc58b415b20d88a7b89ea5432c26bf0455efc8a4572180","src/sys/socket/addr.rs":"c21e2b25d0e0982a8cf7c71816f53eaa4b54d3b33bcb267125c13f0c46b221cc","src/sys/socket/mod.rs":"ce07bf90be0a32ec1199526f5dd05e19e2ca6c95fb23bb7cda2b0550cf80594e","src/sys/socket/sockopt.rs":"56b5bb6ed6749e299b1f0dff5533eef213d301a2e38b48ff96526408deb89c40","src/sys/stat.rs":"bec1d3b5a7a930989b9a54d350d47653499deeb560d73f3b63efaecf4ebb351e","src/sys/statfs.rs":"83b095a903858a298c1f6b2135bb035f24381374097dddd09289bd4f23f1b389","src/sys/statvfs.rs":"0256273f711e9d2c1c7b8feed6dbf3328295095a9a328afb341ff08bf27ef941","src/sys/sysinfo.rs":"ab216769fce561e3a123aceb29c8bd9dee94895450becf32c04411295b88d5f8","src/sys/termios.rs":"39ed1da2bc23294fda06536e8cc850a791d5576f339057d3a2e0b165ae6bcb14","src/sys/time.rs":"cbfc06acea72029e1746070c8355c362154fb42bad35e4fc36fa5e5629758da5","src/sys/timer.rs":"d436c5b043b99afd8de9fb42a8fc7ca3509c324d071937b7719bc7ece6986caf","src/sys/timerfd.rs":"ddc1f4f726d1cbc416006c62fc39d80c9edc10297c5d03d70b55106a9df2c7c8","src/sys/uio.rs":"7fd8fccc97ba5b8ee70d74f18399fbd6af60a7f366b9929d90ded2af59a7eb43","src/sys/utsname.rs":"8ab00cc78f82a44a3d47c3955f030418ad846886fabaa9fd178437896a54fee1","src/sys/wait.rs":"467c35c1d1bf5ed38b5e7c0174a2df0471ac2ce37166931747d887b75d2e1266","src/time.rs":"2588796a51798fa053120b809e503bab9c7526f3582159a68c999630cebb2d57","src/ucontext.rs":"0eb33bfd885d9378a8583a7de7409755b73880bc159d502f974d749db84afbfa","src/unistd.rs":"539d4f4834b389d5945044ecf2ac27ae95517518b4eafa48fa498970d3b29334","test/common/mod.rs":"d13b9c054b8fcf0a13dbc7e615ff0cad83e9c85931882ab7058743cb37ad442c","test/mount/mod.rs":"8e8cdd0a1bfde61fb72eef9e3b3e31034eaa118becb21144e9c8ba8a9574bc6f","test/mount/test_mount.rs":"0bb99024cde383a14ba06c9e7f6c540dd34271fc0c7a85b16fca275756c352c2","test/mount/test_mount_apple.rs":"c90372c72c09f4c025c8a7052cfe182b54183675b62b4863c7c9fd81d1a4cba4","test/mount/test_nmount.rs":"a48bc85fdba2b5afa6997cdfa50b0808d72a7a7aa5151e7de504660e657125ba","test/sys/mod.rs":"ca14fec72e970eaf0033b728087e950c132fbeffb269c09f47c51d27b671e8ba","test/sys/test_aio.rs":"4b59e4641c2f682d4eabfa0715ae1b4eb4f192c8b4cc0626e474cbdc1bffe92a","test/sys/test_aio_drop.rs":"19d990e37142a1320ee827e381d43cf95573824887756be19f764f064a9eab10","test/sys/test_epoll.rs":"4081004c6c48cd55b27c61865641cc1bf006d2cffbf1a611e4a54d8108ee8c25","test/sys/test_event.rs":"2ecb6f15941d9819f310a5128ddd29c828cee932d55ba70e7f710466af8f5665","test/sys/test_fanotify.rs":"58f9db09dafbd456c0d58661cf6b9dd21da274bd6705dddf2c3fe99c85c8405e","test/sys/test_inotify.rs":"1b3253db06bd6464f3e9ca46646615e62c3bad889dc6813d2068a96fbaa31d46","test/sys/test_ioctl.rs":"ed458ae18b37aaac45df16f38f815cc9fc7080dd17b2e18acc6a05042737e4cf","test/sys/test_mman.rs":"a4e7cfcbdbda707da74d5b49ef56a5c78e5184fd9674860918bedf31d612483c","test/sys/test_prctl.rs":"551ae558a9450571e9e855050d687ebae6e7cf436b620a03a94e56f012f2c2cf","test/sys/test_pthread.rs":"9ecc144f8f253589aabd8d5672d837c3145bd9c28f03e9a3f21d0a43babd33b9","test/sys/test_ptrace.rs":"16e1ea1c96b35f7ff493b0b277f443b7098d59ec136f014de64ae5d74cffa7ca","test/sys/test_resource.rs":"669e5b22ef0a9ce69bdfab1e9f63a8f53bf1c5ee7c79c8e2e78f2071dc4b8c01","test/sys/test_select.rs":"5ce391b9928f3e9a3588b17818aecf06226deac34b5593ed86d773e469e5758e","test/sys/test_signal.rs":"2dc1bdcd9f3f850b1e1d21ffbf4c9131b3a2c5334d4dd764e5f901b33cfb80cc","test/sys/test_signalfd.rs":"a0f401ebebca1431530f67b3d4343874553d30932f29cf00e882695c7645cbf3","test/sys/test_socket.rs":"8802c70f4c278973894bd1faf488323823d68aebd4de954e30a5dc2eba475ada","test/sys/test_sockopt.rs":"1798960fe94f4947e374c821971816920eeb1735f66a73c4d55621d0a1fb1e8b","test/sys/test_stat.rs":"b481cb6e20659dc5a63849e3151610ef2af50140f2c5d1cc39a43bc58560fc75","test/sys/test_statfs.rs":"563efb7a1ad24919dfa15effb5e459c8d46096655fe557b133228b36ad91216c","test/sys/test_statvfs.rs":"ad13a879a5403f98c623051c8a653cfb78f5a31869d90f139c6ae99d6eba9e11","test/sys/test_sysinfo.rs":"6c42cf86731bcb300c50707d83157af92aca3cd3e3c2d46b1333657e463b41ec","test/sys/test_termios.rs":"7e7bf02b420d0664bcec3e199b63cc5d83fc3af625ce675bc845542a41b75ff8","test/sys/test_time.rs":"4cf4195a77844eb097818c2db7cf47921737c8aa53d061cf49d9080b60b50ac1","test/sys/test_timer.rs":"d2364da7af2fc64a458fd2b16caca2c779ceefac0de322c13066f77039c442fe","test/sys/test_timerfd.rs":"712d876754794031dc7a43636f5af47e4c8ea3a8b13c7460a6da5fbb741f491a","test/sys/test_uio.rs":"25cc97565a7b584a4fd626df7dbc6db4a4da901a36ac160d93f0511ea713e6d2","test/sys/test_utsname.rs":"60cdb81efbfb126593bfbbe0437c0f4fb97d5ad3e423996622cb33ccb4d80ea4","test/sys/test_wait.rs":"dc997b861eb8001dca47f11e7bd9458ca20e169816c7de8d45ee0ac2b9d167e1","test/test.rs":"bc80258bbfc6a567efa419a00137cc05bde654016e1682f5d07b77eed2533a0c","test/test_clearenv.rs":"323054cad8ce178e1531b470f93e49856ef06e66c8faf9e2f0e2d3398c9e842b","test/test_dir.rs":"5fe95812a13b0bbc8cba9da1f3f59a9979edd01a63078c5bc370b383107bd134","test/test_errno.rs":"db50d2f9a9f03fac417547ce5683a65688b03150fc9c1471e4c2add3d89a2c07","test/test_fcntl.rs":"9616c1eaa72c3942edfb14f99525d49175ccb53325767b895366c8c78f4e2e52","test/test_kmod/hello_mod/Makefile":"b406e6c31829f06c93c4c22f5343ac0c6d1d873c0df4bc1132dfca8e636bf041","test/test_kmod/hello_mod/hello.c":"6059ebdeb2d2e050be3046be21bca8e830da6a2f8262511fb12d9402c9dea526","test/test_kmod/mod.rs":"9a4452b7fed034c35554885245be3d0c72a454b6efabc21ec4629b8ad53820d5","test/test_mq.rs":"f2f42b6b9a9b8567e4a419f090fa19398d83185a98983db7c6feb067caed5559","test/test_net.rs":"e1384964c28708ba4ab04955c51b20a71576f7166d010bbcd7f963ae20400422","test/test_nix_path.rs":"a748d4914f216a6642a07c2743b03033a318ad98daab56096bfcb9120454cff4","test/test_poll.rs":"1dbdac16e264e54d781dc7c25b41caacdb00b442f76bc53d9e17ac19cfd91eef","test/test_pty.rs":"00adf9878e9d1ad7c603e5ffce7c52d8927de646f841524cf8eb429e936dcfb6","test/test_sched.rs":"031932ac8c512c7f881c80c9fe01ecd4c744d9c41b2b0f5fbf904ac0e0e4bf6a","test/test_sendfile.rs":"5a738737602b242b2139deb6c796e01a0aa5a44e0738a017b091342bba162c83","test/test_stat.rs":"cddebbd15ca1fc0ae0bc89594d8c2b5a8be4ce36ef10c9096b6867ad2cbc6826","test/test_time.rs":"7a41b517288fde2b8f9f439bdabe3df1059526793f0bd2ecee2c8ff23a64329a","test/test_unistd.rs":"880416fa3ace154ac8856308db8ccd524d804cbdd93e91533928f61c1093d814"}}
\ No newline at end of file
diff --git a/crates/nix/.cargo-checksum.json b/crates/nix/.cargo-checksum.json
index 3cd0495..b0ee1d5 100644
--- a/crates/nix/.cargo-checksum.json
+++ b/crates/nix/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"CHANGELOG.md":"67c8efb2646c390f76029cf2fbb6205bd23e6e15c149ed32a1549e25bef1babe","Cargo.toml":"cd8795ba96b904a16c840e69c94b9493d8032b966579e4589b9adb35efdfec5a","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"de89eb5b6e00eff6eb3043475da16abf3ae63906cbe3103a450c4bf27cad3f3e","build.rs":"f4b3c533039fe39f167251372b4f378ebef43203654f0ac2340dc0e222206787","src/dir.rs":"10a6ff94e56b849ac8ea762905efa85d11812e5539587ce8e5cce932961c7141","src/env.rs":"9d1e7d52c6c5f46d790a8cbc6d5d2ff9097fb7728594c518d51824ebfb70c9b3","src/errno.rs":"204dd49244d461da6827142386a6b491aaeb6c4ca3760bbe9df5fd2f90e9f4ea","src/fcntl.rs":"1014853b9782285f1467dbe79cff435d0bb1d4122dca0b23d7872ddbeb7688c0","src/features.rs":"6edc53dbbadf56a193dc71053f6512b6cf0d09feb5efb8eb991877de1d70c43c","src/ifaddrs.rs":"40ed9c631b5bff403a697889971f44ad87d6fd6bebbd99cb047cf47c190ee87e","src/kmod.rs":"1e77141714fc7da27fcc59caaae0e31b5801f6e164a57f8d6d399a1b4051d5b1","src/lib.rs":"268b7ad111b99ceaf7c78a348824e8a2be84380bdfe8826e8378b6510eac6b9e","src/macros.rs":"ea6b3a5c117f82ab97d0a410501e7ec250ee11baf3c44b1f207ec404ea682d85","src/mount/bsd.rs":"47477e79ee2862b1d7a5afaf099884036fd81e6384624e60d5d2719a9ddbc112","src/mount/linux.rs":"57ada5949a7a393c427e8076e8556938104f70a73c51452d95ab3d78838f442b","src/mount/mod.rs":"8d8c51f25130e02c860f1d85959d02322b4d9ec748295dfc5a4544e6231725a0","src/mqueue.rs":"0c094b340c918796aff8aa43bc78da566c6203c779a41ce5f490fd41110628f1","src/net/if_.rs":"3d32aceb516606271d8edd2dffd5c710a11868aab54119aebec5a70b35cd963b","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"6d27611db0bc1a64bee80cc74155bb593b1e488092d753fdee102404e7e408ec","src/poll_timeout.rs":"c32412689fcafa561514df9d974206c11bb1276ef79fc10964f11b5416f51a00","src/pty.rs":"d30a7bb587bf727615fc505bc8987d5cae543be0d79d2a8f71a41d9cec2afb6e","src/sched.rs":"542bd9b1d8e1ed132c9a16c3485c70d3d47e30f702c4da1b39906fc64da4c308","src/sys/aio.rs":"b57cc89b70b1052c699264427661c293425536db9577f2fa2c6bdfc805fe06ae","src/sys/epoll.rs":"49ce070f560c8ac7a6f338b4b182f70049303c7d895320a7186fb98b666cafa9","src/sys/event.rs":"3e6e737a880f802644b7c5656a6579d747a66b595ba26ab6cb59df1141ac6eda","src/sys/eventfd.rs":"244ec41689cf90ba0527dd3501ea9f2623873b35cb66577dfc652c35e8492fe4","src/sys/fanotify.rs":"769282c558c7ceb3ea3f9661b6717d507641add46b8b033d4bd200c87df2a66d","src/sys/inotify.rs":"5ce6d83beb2f328c33acf0dd3639a1bdd7b5c2e362745b3cb0fa4c549a641e90","src/sys/ioctl/bsd.rs":"e6affc2babd4fa4539574426e416b330b7e32ba4fd2821899a67417261e7089e","src/sys/ioctl/linux.rs":"8c8bdfc239aa175efb4fc2f666a6ecc799b7d614f85e9143595fff05d37f76f0","src/sys/ioctl/mod.rs":"304a959e9eb24dccfd3fc6153719b417367d9208dc7e6859239fb020c407d103","src/sys/memfd.rs":"a7c2c446143f1dda5537a4342a84b83bb536072215ca973de71f87a33ed8bd37","src/sys/mman.rs":"e75b3ae89c18f541ba8fed01b9147661078f9d035eeb4eaf792ba0e4ff1167fe","src/sys/mod.rs":"30057a1c687859394f27581247ae9e412f5f68d4484bd5196797c1bc1939a6c7","src/sys/personality.rs":"f7fa4e97de0943aa6a969465ca7d2d69ac98015f7c339fdbb88d83ffe26db4ce","src/sys/prctl.rs":"785f97a545e010069d67ef11b22a70ca5000e131ee8ca990a2652a596ade77e5","src/sys/pthread.rs":"258cdf7ff0b61a4afa6d228109e4cb4fb88d859bb8dfe6c959d95130fb010906","src/sys/ptrace/bsd.rs":"54b92e1ffe6455a545f807ed7de9011be05251adfdc71a5823b1965579650939","src/sys/ptrace/linux.rs":"c347075fc8d9afd63d6eaf1acf84afb3a2c956b236eef9f17c19e883a6aaa73d","src/sys/ptrace/mod.rs":"a9aefa2b10cc63c8b40adcd3e7dd612a8f4677bf6f37420cdd09e7129ba02c95","src/sys/quota.rs":"1638e34bddd955c7f98f1814d239eb76647101295c8a1ae40c78dd7dd7638f20","src/sys/reboot.rs":"b748217e4877c94c1870885407b9ab1ab9e059c9fb7d04818a1b29477eac81c6","src/sys/resource.rs":"e701020b893666321f44c08df9e60f8927d00ac1035c89965e967dc0b44c6222","src/sys/select.rs":"9cfcb3a9d15a46b2f209e66cbaf136dab6894c711031313557bc58534ecedc70","src/sys/sendfile.rs":"fc7ac628424eb1132674c73bbe19f0d82a28d6752b0beffbf111965ea3885760","src/sys/signal.rs":"da1720190cdedc854649a525f2cd2556daec1c069d3fe32ad65c4302cca8efd9","src/sys/signalfd.rs":"f0b4d32e642a3a02d349b38d317a805eedc6e60e9e773f650fb0ee4ad7f655a7","src/sys/socket/addr.rs":"75d94b8404711b4ec08b44c3d43c7854f7cd9cf8e17665056dddaf6398d1df2a","src/sys/socket/mod.rs":"12c1a291648553516437bec168602fbebcae3d1ad657a7e55cd86f842db29d50","src/sys/socket/sockopt.rs":"69ab0440767e808c0fe2f2d269eae67653b4657e51b8fe356fab95b7ab26546a","src/sys/stat.rs":"074401a0b0fe74d9516640e0790fe67b7727213115accfdb331a9767ae20064c","src/sys/statfs.rs":"991370ce27196f8721a03a88c3b906cc248f46f147ebd6524d45c61433dc0239","src/sys/statvfs.rs":"526c2e69b640f49331e8ca7a2e59cdb803887c91a53fa41f866364fec93bce24","src/sys/sysinfo.rs":"b4519b1ca091c9dbe94d2a6fd6304944bf3df5626973d2c6884022559706f0d9","src/sys/termios.rs":"dd68b78e4a87786d22334c014d258e43d12f4e9370acda61209eb2c9ed176c86","src/sys/time.rs":"a63f6b5cf67a9323ccc3a225ffec88bb078c5dcf22d0eba78ae071db67aefc53","src/sys/timer.rs":"8c10f0e7cfac857ad00460be30bc68b957909cc9296e70718d3b5d4a0babafde","src/sys/timerfd.rs":"569d662725018427b517ffcfa78d8d03e150a344b8b8533d3f16e3bfd5c762da","src/sys/uio.rs":"d0886bf517e9b21af8ad6a25d332003fe9e132fed43cd642ec61b32d27622bd6","src/sys/utsname.rs":"e1f81d363621445633101800ba34debdb222eaf3a25553f8b486f74d49e4be41","src/sys/wait.rs":"338235d42a2ec29633cf64dada7b9b1d434ed0005776bffdecfd5c69922eed89","src/time.rs":"30038bbe683857469d106631cea13ee1e43f149cb4c947a8353824270ee4267c","src/ucontext.rs":"b8f2e04757a9c2bc38c3b1e259d3a013da8a730fe9bfbe5487637395681b43d3","src/unistd.rs":"5bb3b5ad2984793be4eed6adf653bbc52592c2459b9063009b92edb83ed562cf","test/common/mod.rs":"953155de9a50974fda7a43a66269211154bbb5898791e0abd97dc4184d482f23","test/sys/mod.rs":"f08046850a4b7a9bbf203d8eba0ee3ae9c32b6bd4d9c7bf52ca29efb3eb74f35","test/sys/test_aio.rs":"902ae4abda9286db551e65a7eccf267baee16eeefd1cdddac8399bef2ede0060","test/sys/test_aio_drop.rs":"e9e45333b24381bba99235372d5917a22fbd8692eddfbebcf519697c603de812","test/sys/test_epoll.rs":"c30b08d665a1fe7d7a04fe51d50ec78fc74c2ac707ae0f95f82104d5c76ceaf2","test/sys/test_event.rs":"be4b1b1abd25f87f00b3d115105ef832b2c654fd7028c42f1a304a935935b479","test/sys/test_fanotify.rs":"55b0917f8b85fdc8277e6a796d06251a39398b9f2da88d9eec98a763ff03e918","test/sys/test_inotify.rs":"a141b9a995892547b51ceeb6761a70a6b86d37e8f38d13ea2c497b81b4b0f49f","test/sys/test_ioctl.rs":"07d08a46c4ac84161974b655a0d040e03efc9338e7a7505e0d16826b7653b5c2","test/sys/test_mman.rs":"f129659d6995fcada15e7c923cb943d8dd4c6e4aaa141c6cc5bacfa3257793f5","test/sys/test_prctl.rs":"9c3d0fb16a41c3fd80541b313c2bb63de75634ad4711a71af106e58b0cec9ea8","test/sys/test_pthread.rs":"ace36a2f5587f1874854281b4fd84e4e4d892a1e3c5cc38ced57975739522ad6","test/sys/test_ptrace.rs":"ac4fff669bfc58955e94ed0171e4d47ecf2366fce62509c659e78192f9de7a6d","test/sys/test_resource.rs":"aa58f566efb8132b42ae98be6e50b72fee86ef50c4bcc4a7bf49b275f6762008","test/sys/test_select.rs":"09fe9d020e4f1cdb0951ebd27a6c3f408b23471ce2c51d2f1e4708500fc15261","test/sys/test_signal.rs":"ac6cbd345cbd93b1c9bead56794bd978dc44435beea921bedbdb8a2761e557d5","test/sys/test_signalfd.rs":"8db0c371d0cac7d68208505990291ebc2b2cb8671b0edba16ef22b6b9e56dab2","test/sys/test_socket.rs":"8c6190cbea80d5b2866d0891c6f44fddaba337b655af7e5628dc9537e1cbfab9","test/sys/test_sockopt.rs":"dd1839c495ce37535b2fbf78290dfbb1350f40ed7ed92c7fcedc16a88730ecf1","test/sys/test_stat.rs":"6630a28217fd708bb84cd4f7e7101836b74f2420f9888923fdab664ccc331c1d","test/sys/test_statfs.rs":"a32f6319ea7e989747707de27b06332e7942b07e07ab1602af408be91fae7e73","test/sys/test_statvfs.rs":"05cf8f1bcab0f0cd8fbefe8a2a72f9ac6d95aa760c355ac6d4b6f9c61649bc38","test/sys/test_sysinfo.rs":"ffd49bc96375914a2c4a4a59730cae8072f85771e2c4a80d3403df38d967e272","test/sys/test_termios.rs":"6c6897e0320d063a758f6702228c64ef2b459b4a5affa07ae7e76c1142432f0a","test/sys/test_time.rs":"aff97dd1bfc4aa9b616cc71e9cc11f25fb3ad983f1406c856648736847778c19","test/sys/test_timer.rs":"3ae20d364f075d2811f3ff94eda9886682cc21d8807656007d2464fe36d1e361","test/sys/test_timerfd.rs":"cfed3abf58118611d08f6985251a7739cff67108e11214222a1d2394a3a026ce","test/sys/test_uio.rs":"dda569818e3256ff45aa07b33cffb59828983c83b20266b864cdfa38103cffc9","test/sys/test_utsname.rs":"b8371dca02c9cdfc0c8e93df9b5cf5b5cb8a92b114977966854918abeb01ad73","test/sys/test_wait.rs":"c958e51b10a7d0396d0013e9d637a2848ad9d061d526408b40dfefb850c22beb","test/test.rs":"e1da3bf8ef929a9e4aca354bf72578f6649c80dd5f32400eb124b229bd4506f8","test/test_clearenv.rs":"45ca548035b3c20ec87314715feaba2be973709a635d85b8cde46fd1d9f1ecd4","test/test_dir.rs":"e6a100685f945b6007312d22575ac5e27363c649f3fed19fb10b18ac5d905449","test/test_errno.rs":"e7a1320e97350c2883368ffe9fc47fd041f4f9ecdee360d21d36254a63a305a3","test/test_fcntl.rs":"4467e1e8698256c982df17108dacd1fcb6ba0eda18044fe198eff25629827e66","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":"9fc453613eab116841a7f2ba57098eebec853fc16ce0e59cb459a203e006115b","test/test_mq.rs":"d8ec2a3f3acad4369851663b3f7fef03177d9f8395b585dee8e2c53f6a2a9b4a","test/test_net.rs":"cfa1d3b4e252193a4b119141f8e93d637e3c32e9029aef72f8bb83e00be6c3b5","test/test_nix_path.rs":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","test/test_nmount.rs":"d6c112547bb80968170b5497cda4b6cbf69dabec6f51d494bd52298995ceff18","test/test_poll.rs":"25b4fa094bbcda5a5317a25d2f292465965dbe3e066374b04a9b27a8d55897ac","test/test_pty.rs":"ec54c5fe096396b5aed5677276acaf80b4c58be7222ee285cfd4eaadf7b34ce0","test/test_sched.rs":"c4579bd376fab8816e63b07fa9ace31dc08e63ebb7c855a2c450698090d1d1e8","test/test_sendfile.rs":"6f82e9f66359a85a7aa819ffd38c7c3326c1bb2384950d681085dc7823fc4a20","test/test_stat.rs":"dae37bd9b5e46e1a76696bed435d8bc4e98ecb91bb3476e7133a6197178d6644","test/test_time.rs":"6eb3536936c67bcfbc80a73a902b4a485943aab5375fc7e3880da6695a4eafce","test/test_unistd.rs":"828a990974b4d843d59f3d134758d4b6a9afa43da3d07dcaf314fcc1615bd732"},"package":"ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"}
\ No newline at end of file
+{"files":{"CHANGELOG.md":"6d533687df51339d3c064c47af7b0d80676c685be27636a4b1f2e18162c9bea1","Cargo.toml":"30a3d3032dda335327557f9b1fca7bccf70c8f46b024221fe842f8a707b6f6cf","LICENSE":"66e3ee1fa7f909ad3c612d556f2a0cdabcd809ad6e66f3b0605015ac64841b70","README.md":"de89eb5b6e00eff6eb3043475da16abf3ae63906cbe3103a450c4bf27cad3f3e","build.rs":"7e47b7c39f11b745b4eb3d30560be80247ebaba1342c9ac62c4a8bfdd463e977","src/dir.rs":"d0926c0804d7d4b9292acd9385674810ab26c78fc15d613f0342ebe267068bdf","src/env.rs":"9d1e7d52c6c5f46d790a8cbc6d5d2ff9097fb7728594c518d51824ebfb70c9b3","src/errno.rs":"204dd49244d461da6827142386a6b491aaeb6c4ca3760bbe9df5fd2f90e9f4ea","src/fcntl.rs":"c697a448eaa83df6d2219f39781b8d41014f1ee418cccb15b41279a780745c5a","src/features.rs":"6edc53dbbadf56a193dc71053f6512b6cf0d09feb5efb8eb991877de1d70c43c","src/ifaddrs.rs":"40ed9c631b5bff403a697889971f44ad87d6fd6bebbd99cb047cf47c190ee87e","src/kmod.rs":"1e77141714fc7da27fcc59caaae0e31b5801f6e164a57f8d6d399a1b4051d5b1","src/lib.rs":"c9bc3d8a2c1b067b15988ee7c0c40a5e62762da910d4f0174f06ed1bc262fe06","src/macros.rs":"ea6b3a5c117f82ab97d0a410501e7ec250ee11baf3c44b1f207ec404ea682d85","src/mount/apple.rs":"bb98335449b95e5135708d33da649472498d305d225564c81cb7f1279ba3b5b9","src/mount/bsd_without_apple.rs":"e79e9b88ceea9476d2b68fcc619e06ebcc9163f954f5d9d5455f3433d3bec97b","src/mount/linux.rs":"83b4716728c54ed1d6db3fd6e2c4499f8bbe77af7e513d29c4e75525ce0d759d","src/mount/mod.rs":"1bfbdf0b8781ac6f8d320a43aedbbdfd72ac7e5d8f2a87e03f4f87cb5857ece3","src/mqueue.rs":"0c094b340c918796aff8aa43bc78da566c6203c779a41ce5f490fd41110628f1","src/net/if_.rs":"ae1c6a38865162ff9b94625055baa50c75906660f9adde840eed3ddea4db639e","src/net/mod.rs":"577f70170e53d4a6de1abb70bf8f1031ec3e65c0e63ef5fcf05c907125e7ac17","src/poll.rs":"6d27611db0bc1a64bee80cc74155bb593b1e488092d753fdee102404e7e408ec","src/poll_timeout.rs":"c32412689fcafa561514df9d974206c11bb1276ef79fc10964f11b5416f51a00","src/pty.rs":"03a50d339350b1942b1038cd6de938b560062ec9fdd9d8d3b1149f91624884f3","src/sched.rs":"542bd9b1d8e1ed132c9a16c3485c70d3d47e30f702c4da1b39906fc64da4c308","src/sys/aio.rs":"e39e5597298a5e9cd282ad27f9ffc7110b97b1b362fe21d5a1dd3b1bff45e1e9","src/sys/epoll.rs":"49ce070f560c8ac7a6f338b4b182f70049303c7d895320a7186fb98b666cafa9","src/sys/event.rs":"3e6e737a880f802644b7c5656a6579d747a66b595ba26ab6cb59df1141ac6eda","src/sys/eventfd.rs":"244ec41689cf90ba0527dd3501ea9f2623873b35cb66577dfc652c35e8492fe4","src/sys/fanotify.rs":"075e0ee9807d28ccfaedd0542fb8ba30a653c81326c41dadf801da359c19d9ca","src/sys/inotify.rs":"5ce6d83beb2f328c33acf0dd3639a1bdd7b5c2e362745b3cb0fa4c549a641e90","src/sys/ioctl/bsd.rs":"e6affc2babd4fa4539574426e416b330b7e32ba4fd2821899a67417261e7089e","src/sys/ioctl/linux.rs":"8c8bdfc239aa175efb4fc2f666a6ecc799b7d614f85e9143595fff05d37f76f0","src/sys/ioctl/mod.rs":"304a959e9eb24dccfd3fc6153719b417367d9208dc7e6859239fb020c407d103","src/sys/memfd.rs":"a7c2c446143f1dda5537a4342a84b83bb536072215ca973de71f87a33ed8bd37","src/sys/mman.rs":"e75b3ae89c18f541ba8fed01b9147661078f9d035eeb4eaf792ba0e4ff1167fe","src/sys/mod.rs":"30057a1c687859394f27581247ae9e412f5f68d4484bd5196797c1bc1939a6c7","src/sys/personality.rs":"f7fa4e97de0943aa6a969465ca7d2d69ac98015f7c339fdbb88d83ffe26db4ce","src/sys/prctl.rs":"c134d3a5c6fc08c028682d39b1765672681caf91a113b0668db1f499e31f9df0","src/sys/pthread.rs":"258cdf7ff0b61a4afa6d228109e4cb4fb88d859bb8dfe6c959d95130fb010906","src/sys/ptrace/bsd.rs":"54b92e1ffe6455a545f807ed7de9011be05251adfdc71a5823b1965579650939","src/sys/ptrace/linux.rs":"f59edb76635fb13925ea33a31eca407926f78b0e644513760b6f875d8d690aef","src/sys/ptrace/mod.rs":"a9aefa2b10cc63c8b40adcd3e7dd612a8f4677bf6f37420cdd09e7129ba02c95","src/sys/quota.rs":"1638e34bddd955c7f98f1814d239eb76647101295c8a1ae40c78dd7dd7638f20","src/sys/reboot.rs":"b748217e4877c94c1870885407b9ab1ab9e059c9fb7d04818a1b29477eac81c6","src/sys/resource.rs":"5353e1991de1347b2ff32d8101af1d3beb9e9d62a6a9dda2e9ead098dfa500b1","src/sys/select.rs":"9cfcb3a9d15a46b2f209e66cbaf136dab6894c711031313557bc58534ecedc70","src/sys/sendfile.rs":"fc7ac628424eb1132674c73bbe19f0d82a28d6752b0beffbf111965ea3885760","src/sys/signal.rs":"fdf50b9d4e271754948d1f76ee0c42c66639e3c6b6d9481b9c1eea3721e29eb2","src/sys/signalfd.rs":"53f03d6298761181b6b6cd2fb402f7bd6acce1e770145d590303ca3e7bf7ffaf","src/sys/socket/addr.rs":"e621f332cb99f8804d458166d522f1691aba6e0a70b06206e64cf9032256648d","src/sys/socket/mod.rs":"d6c83b61abfca1981dfd831a8c0fe7c1b894e0ee63dd6b40acb9f7cc48bc4b70","src/sys/socket/sockopt.rs":"83865578a2b8e18b092216a90e0205f2c58b503f99149aa16cc5e33a412045a1","src/sys/stat.rs":"074401a0b0fe74d9516640e0790fe67b7727213115accfdb331a9767ae20064c","src/sys/statfs.rs":"991370ce27196f8721a03a88c3b906cc248f46f147ebd6524d45c61433dc0239","src/sys/statvfs.rs":"526c2e69b640f49331e8ca7a2e59cdb803887c91a53fa41f866364fec93bce24","src/sys/sysinfo.rs":"93ccfc746128dfcf8fbc2775ceefac6ddcefe154b6e5f7db96de8f29ad869b85","src/sys/termios.rs":"dd68b78e4a87786d22334c014d258e43d12f4e9370acda61209eb2c9ed176c86","src/sys/time.rs":"a63f6b5cf67a9323ccc3a225ffec88bb078c5dcf22d0eba78ae071db67aefc53","src/sys/timer.rs":"8c10f0e7cfac857ad00460be30bc68b957909cc9296e70718d3b5d4a0babafde","src/sys/timerfd.rs":"569d662725018427b517ffcfa78d8d03e150a344b8b8533d3f16e3bfd5c762da","src/sys/uio.rs":"d0886bf517e9b21af8ad6a25d332003fe9e132fed43cd642ec61b32d27622bd6","src/sys/utsname.rs":"e1f81d363621445633101800ba34debdb222eaf3a25553f8b486f74d49e4be41","src/sys/wait.rs":"338235d42a2ec29633cf64dada7b9b1d434ed0005776bffdecfd5c69922eed89","src/time.rs":"30038bbe683857469d106631cea13ee1e43f149cb4c947a8353824270ee4267c","src/ucontext.rs":"b8f2e04757a9c2bc38c3b1e259d3a013da8a730fe9bfbe5487637395681b43d3","src/unistd.rs":"c4cb141128856a133f7ed4cc5babdab9734ce534b118d7c9ffe2ff79aea9d719","test/common/mod.rs":"cb322163f65319b350882fccea8d540216c4ac43f0912f1e35efa7ea0305d23d","test/mount/mod.rs":"4aac842da29f063b6f653fc5ccb02e742283fc683d6281cbcc582f55004b9c0f","test/mount/test_mount.rs":"90820c9378690190bd576e22361d0cb9b932cd7002a099c5034772feefc4f8e6","test/mount/test_mount_apple.rs":"77055902167e85368291284c00ae67b83ec932eca425a17d69ceb867ea5a142d","test/mount/test_nmount.rs":"d6c112547bb80968170b5497cda4b6cbf69dabec6f51d494bd52298995ceff18","test/sys/mod.rs":"f08046850a4b7a9bbf203d8eba0ee3ae9c32b6bd4d9c7bf52ca29efb3eb74f35","test/sys/test_aio.rs":"a0c1315c2924a4eb4d419e08cdb00702061941170c4e3b4e53b383bf3475642d","test/sys/test_aio_drop.rs":"18974ef2ea0072d91e93489d9430725eda32582992f9c6a1f046b4d6be901a8c","test/sys/test_epoll.rs":"c30b08d665a1fe7d7a04fe51d50ec78fc74c2ac707ae0f95f82104d5c76ceaf2","test/sys/test_event.rs":"be4b1b1abd25f87f00b3d115105ef832b2c654fd7028c42f1a304a935935b479","test/sys/test_fanotify.rs":"3719547a2d11f8f7811be7f1a60d4239f0223f70143bbe0f54afbd180e89ae7e","test/sys/test_inotify.rs":"a141b9a995892547b51ceeb6761a70a6b86d37e8f38d13ea2c497b81b4b0f49f","test/sys/test_ioctl.rs":"07d08a46c4ac84161974b655a0d040e03efc9338e7a7505e0d16826b7653b5c2","test/sys/test_mman.rs":"f129659d6995fcada15e7c923cb943d8dd4c6e4aaa141c6cc5bacfa3257793f5","test/sys/test_prctl.rs":"0576ba8aeb6b80a91e6cfcf2d63c54fed32f4d64bf02a1ac584b754f0ba34b4e","test/sys/test_pthread.rs":"ace36a2f5587f1874854281b4fd84e4e4d892a1e3c5cc38ced57975739522ad6","test/sys/test_ptrace.rs":"f3c6fb377de01f0e3ad2c580815de76e84e3224378d5f001169f5e343b3fdbc7","test/sys/test_resource.rs":"aa58f566efb8132b42ae98be6e50b72fee86ef50c4bcc4a7bf49b275f6762008","test/sys/test_select.rs":"09fe9d020e4f1cdb0951ebd27a6c3f408b23471ce2c51d2f1e4708500fc15261","test/sys/test_signal.rs":"a1e4943e459e4bc79ac1e8929bbd4dab3c012935ed8084631fef4e973902a1c0","test/sys/test_signalfd.rs":"348aa82e161d99ffac0b70247441cc5b806ed7e0f23f32ecdfaa87ab2eb6c25c","test/sys/test_socket.rs":"ba1fa797fc8fa617a5283e93bcf1a7f6850c10d5d95353af3ba9e5cc095adc1b","test/sys/test_sockopt.rs":"a5664332c2c310f8c5f48a9fa6012f21c4ab573226307686d8f91b4a432ff831","test/sys/test_stat.rs":"6630a28217fd708bb84cd4f7e7101836b74f2420f9888923fdab664ccc331c1d","test/sys/test_statfs.rs":"90da08a3828b091482ee9be17c7f1aba32ffa598158b25ce3001d468fbc328c5","test/sys/test_statvfs.rs":"05cf8f1bcab0f0cd8fbefe8a2a72f9ac6d95aa760c355ac6d4b6f9c61649bc38","test/sys/test_sysinfo.rs":"ffd49bc96375914a2c4a4a59730cae8072f85771e2c4a80d3403df38d967e272","test/sys/test_termios.rs":"6c6897e0320d063a758f6702228c64ef2b459b4a5affa07ae7e76c1142432f0a","test/sys/test_time.rs":"aff97dd1bfc4aa9b616cc71e9cc11f25fb3ad983f1406c856648736847778c19","test/sys/test_timer.rs":"3ae20d364f075d2811f3ff94eda9886682cc21d8807656007d2464fe36d1e361","test/sys/test_timerfd.rs":"cfed3abf58118611d08f6985251a7739cff67108e11214222a1d2394a3a026ce","test/sys/test_uio.rs":"dda569818e3256ff45aa07b33cffb59828983c83b20266b864cdfa38103cffc9","test/sys/test_utsname.rs":"b8371dca02c9cdfc0c8e93df9b5cf5b5cb8a92b114977966854918abeb01ad73","test/sys/test_wait.rs":"c958e51b10a7d0396d0013e9d637a2848ad9d061d526408b40dfefb850c22beb","test/test.rs":"a4b08951e07e5011bd1809dc01a3ec6edd01cf3ad37ddba4ff06207af3e34c77","test/test_clearenv.rs":"45ca548035b3c20ec87314715feaba2be973709a635d85b8cde46fd1d9f1ecd4","test/test_dir.rs":"e6a100685f945b6007312d22575ac5e27363c649f3fed19fb10b18ac5d905449","test/test_errno.rs":"e7a1320e97350c2883368ffe9fc47fd041f4f9ecdee360d21d36254a63a305a3","test/test_fcntl.rs":"15d5a64f6cffe4fb45796bd6e55126cc77780f66501875614687ec15749face4","test/test_kmod/hello_mod/Makefile":"0219f7bce0603f97d997fb377ca071966c90333ecc665e78a54dfeb97a9c811b","test/test_kmod/hello_mod/hello.c":"bcac6b19c5bd807e1f3878c15e426acc85785a8ade9840c3bb4d068635c9188c","test/test_kmod/mod.rs":"b4ae25841c2f06f32de9f1acd8230eeccd7095721302ebe78ad454e4e4f9c783","test/test_mq.rs":"d8ec2a3f3acad4369851663b3f7fef03177d9f8395b585dee8e2c53f6a2a9b4a","test/test_net.rs":"ababee4623a5afb8548a1618efbdb43efa38e88d606bff8301245db6fa306078","test/test_nix_path.rs":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","test/test_poll.rs":"25b4fa094bbcda5a5317a25d2f292465965dbe3e066374b04a9b27a8d55897ac","test/test_pty.rs":"0fcf37cb5c60167552800447890726d6cb182b5cc2ac3332986155b9641da492","test/test_sched.rs":"c4579bd376fab8816e63b07fa9ace31dc08e63ebb7c855a2c450698090d1d1e8","test/test_sendfile.rs":"6f82e9f66359a85a7aa819ffd38c7c3326c1bb2384950d681085dc7823fc4a20","test/test_stat.rs":"dae37bd9b5e46e1a76696bed435d8bc4e98ecb91bb3476e7133a6197178d6644","test/test_time.rs":"6eb3536936c67bcfbc80a73a902b4a485943aab5375fc7e3880da6695a4eafce","test/test_unistd.rs":"96151e2101fba7cff2fcd125858be50567118e28935be1db76541b9ef0d24ebd"},"package":"71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"}
\ No newline at end of file
diff --git a/crates/nix/Android.bp b/crates/nix/Android.bp
index 0f7e25f..2a9c274 100644
--- a/crates/nix/Android.bp
+++ b/crates/nix/Android.bp
@@ -18,7 +18,7 @@
host_supported: true,
crate_name: "nix",
cargo_env_compat: true,
- cargo_pkg_version: "0.28.0",
+ cargo_pkg_version: "0.29.0",
crate_root: "src/lib.rs",
edition: "2021",
features: [
diff --git a/crates/nix/CHANGELOG.md b/crates/nix/CHANGELOG.md
index 37e4ab2..b673cac 100644
--- a/crates/nix/CHANGELOG.md
+++ b/crates/nix/CHANGELOG.md
@@ -3,6 +3,98 @@
# Change Log
+## [0.29.0] - 2024-05-24
+
+
+### Added
+
+- Add `getregset()/setregset()` for Linux/glibc/x86/x86_64/aarch64/riscv64 and
+ `getregs()/setregs()` for Linux/glibc/aarch64/riscv64
+ ([#2044](https://github.com/nix-rust/nix/pull/2044))
+- Add socket option Ipv6Ttl for apple targets.
+ ([#2287](https://github.com/nix-rust/nix/pull/2287))
+- Add socket option UtunIfname.
+ ([#2325](https://github.com/nix-rust/nix/pull/2325))
+- make SigAction repr(transparent) & can be converted to the libc raw type
+ ([#2326](https://github.com/nix-rust/nix/pull/2326))
+- Add `From` trait implementation for conversions between `sockaddr_in` and
+ `SockaddrIn`, `sockaddr_in6` and `SockaddrIn6`
+ ([#2328](https://github.com/nix-rust/nix/pull/2328))
+- Add socket option ReusePortLb for FreeBSD.
+ ([#2332](https://github.com/nix-rust/nix/pull/2332))
+- Added support for openat2 on linux.
+ ([#2339](https://github.com/nix-rust/nix/pull/2339))
+- Add if_indextoname function.
+ ([#2340](https://github.com/nix-rust/nix/pull/2340))
+- Add `mount` and `unmount` API for apple targets.
+ ([#2347](https://github.com/nix-rust/nix/pull/2347))
+- Added `_PC_MIN_HOLE_SIZE` for `pathconf` and `fpathconf`.
+ ([#2349](https://github.com/nix-rust/nix/pull/2349))
+- Added `impl AsFd for pty::PtyMaster`
+ ([#2355](https://github.com/nix-rust/nix/pull/2355))
+- Add `open` flag `O_SEARCH` to AIX, Empscripten, FreeBSD, Fuchsia, solarish,
+ WASI ([#2374](https://github.com/nix-rust/nix/pull/2374))
+- Add prctl function `prctl_set_vma_anon_name` for Linux/Android.
+ ([#2378](https://github.com/nix-rust/nix/pull/2378))
+- Add `sync(2)` for `apple_targets/solarish/haiku/aix/hurd`, `syncfs(2)` for
+ `hurd` and `fdatasync(2)` for `aix/hurd`
+ ([#2379](https://github.com/nix-rust/nix/pull/2379))
+- Add fdatasync support for Apple targets.
+ ([#2380](https://github.com/nix-rust/nix/pull/2380))
+- Add `fcntl::OFlag::O_PATH` for FreeBSD and Fuchsia
+ ([#2382](https://github.com/nix-rust/nix/pull/2382))
+- Added `PathconfVar::MIN_HOLE_SIZE` for apple_targets.
+ ([#2388](https://github.com/nix-rust/nix/pull/2388))
+- Add `open` flag `O_SEARCH` to apple_targets
+ ([#2391](https://github.com/nix-rust/nix/pull/2391))
+- `O_DSYNC` may now be used with `aio_fsync` and `fcntl` on FreeBSD.
+ ([#2404](https://github.com/nix-rust/nix/pull/2404))
+- Added `Flock::relock` for upgrading and downgrading locks.
+ ([#2407](https://github.com/nix-rust/nix/pull/2407))
+
+### Changed
+
+- Change the `ForkptyResult` type to the following repr so that the
+ uninitialized
+ `master` field won't be accessed in the child process:
+
+ ```rs
+ pub enum ForkptyResult {
+ Parent {
+ child: Pid,
+ master: OwnedFd,
+ },
+ Child,
+ }
+ ``` ([#2315](https://github.com/nix-rust/nix/pull/2315))
+- Updated `cfg_aliases` dependency from version 0.1 to 0.2
+ ([#2322](https://github.com/nix-rust/nix/pull/2322))
+- Change the signature of `ptrace::write` and `ptrace::write_user` to make them
+ safe ([#2324](https://github.com/nix-rust/nix/pull/2324))
+- Allow use of `SignalFd` through shared reference
+
+ Like with many other file descriptors, concurrent use of signalfds is safe.
+ Changing the signal mask of and reading signals from a signalfd can now be
+ done
+ with the `SignalFd` API even if other references to it exist.
+ ([#2367](https://github.com/nix-rust/nix/pull/2367))
+- Changed tee, splice and vmsplice RawFd arguments to AsFd.
+ ([#2387](https://github.com/nix-rust/nix/pull/2387))
+- Added I/O safety to the sys/aio module. Most functions that previously
+ accepted a `AsRawFd` argument now accept an `AsFd` instead.
+ ([#2401](https://github.com/nix-rust/nix/pull/2401))
+- `RecvMsg::cmsgs()` now returns a `Result`, and checks that cmsgs were not
+ truncated. ([#2413](https://github.com/nix-rust/nix/pull/2413))
+
+### Fixed
+
+- No longer panics when the `fanotify` queue overflows.
+ ([#2399](https://github.com/nix-rust/nix/pull/2399))
+- Fixed ControlMessageOwned::UdpGroSegments wrapped type from u16 to i32 to
+ reflect the used kernel's one.
+ ([#2406](https://github.com/nix-rust/nix/pull/2406))
+
+
## [0.28.0] - 2024-02-24
diff --git a/crates/nix/Cargo.toml b/crates/nix/Cargo.toml
index 34bc897..8b3405d 100644
--- a/crates/nix/Cargo.toml
+++ b/crates/nix/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.69"
name = "nix"
-version = "0.28.0"
+version = "0.29.0"
authors = ["The nix-rust Project Developers"]
include = [
"build.rs",
@@ -72,7 +72,7 @@
version = "1.0"
[dependencies.libc]
-version = "0.2.153"
+version = "0.2.155"
features = ["extra_traits"]
[dependencies.memoffset]
@@ -99,7 +99,7 @@
version = "3.7.1"
[build-dependencies.cfg_aliases]
-version = "0.1.1"
+version = "0.2"
[features]
acct = []
diff --git a/crates/nix/METADATA b/crates/nix/METADATA
index e30d992..b453f1f 100644
--- a/crates/nix/METADATA
+++ b/crates/nix/METADATA
@@ -1,17 +1,17 @@
name: "nix"
description: "Rust friendly bindings to *nix APIs"
third_party {
- version: "0.28.0"
+ version: "0.29.0"
license_type: NOTICE
last_upgrade_date {
- year: 2024
- month: 4
- day: 8
+ year: 2025
+ month: 3
+ day: 5
}
homepage: "https://crates.io/crates/nix"
identifier {
type: "Archive"
- value: "https://static.crates.io/crates/nix/nix-0.28.0.crate"
- version: "0.28.0"
+ value: "https://static.crates.io/crates/nix/nix-0.29.0.crate"
+ version: "0.29.0"
}
}
diff --git a/crates/nix/build.rs b/crates/nix/build.rs
index 4535af1..226a32c 100644
--- a/crates/nix/build.rs
+++ b/crates/nix/build.rs
@@ -14,12 +14,27 @@
solaris: { target_os = "solaris" },
watchos: { target_os = "watchos" },
tvos: { target_os = "tvos" },
+ visionos: { target_os = "visionos" },
- apple_targets: { any(ios, macos, watchos, tvos) },
+
+ // cfg aliases we would like to use
+ apple_targets: { any(ios, macos, watchos, tvos, visionos) },
bsd: { any(freebsd, dragonfly, netbsd, openbsd, apple_targets) },
+ bsd_without_apple: { any(freebsd, dragonfly, netbsd, openbsd) },
linux_android: { any(android, linux) },
freebsdlike: { any(dragonfly, freebsd) },
netbsdlike: { any(netbsd, openbsd) },
solarish: { any(illumos, solaris) },
}
+
+ // Below are Nix's custom cfg values that we need to let the compiler know
+ println!("cargo:rustc-check-cfg=cfg(apple_targets)");
+ println!("cargo:rustc-check-cfg=cfg(bsd)");
+ println!("cargo:rustc-check-cfg=cfg(bsd_without_apple)");
+ println!("cargo:rustc-check-cfg=cfg(linux_android)");
+ println!("cargo:rustc-check-cfg=cfg(freebsdlike)");
+ println!("cargo:rustc-check-cfg=cfg(netbsdlike)");
+ println!("cargo:rustc-check-cfg=cfg(solarish)");
+ println!("cargo:rustc-check-cfg=cfg(fbsd14)");
+ println!("cargo:rustc-check-cfg=cfg(qemu)");
}
diff --git a/crates/nix/src/dir.rs b/crates/nix/src/dir.rs
index ab70f06..20c5593 100644
--- a/crates/nix/src/dir.rs
+++ b/crates/nix/src/dir.rs
@@ -59,7 +59,7 @@
Dir::from_fd(fd.into_raw_fd())
}
- /// Converts from a file descriptor, closing it on success or failure.
+ /// Converts from a file descriptor, closing it on failure.
#[doc(alias("fdopendir"))]
pub fn from_fd(fd: RawFd) -> Result<Self> {
let d = ptr::NonNull::new(unsafe { libc::fdopendir(fd) }).ok_or_else(
diff --git a/crates/nix/src/fcntl.rs b/crates/nix/src/fcntl.rs
index ccefe95..cf87926 100644
--- a/crates/nix/src/fcntl.rs
+++ b/crates/nix/src/fcntl.rs
@@ -114,7 +114,7 @@
/// If the specified path isn't a directory, fail.
O_DIRECTORY;
/// Implicitly follow each `write()` with an `fdatasync()`.
- #[cfg(any(linux_android, apple_targets, netbsdlike))]
+ #[cfg(any(linux_android, apple_targets, target_os = "freebsd", netbsdlike))]
O_DSYNC;
/// Error out if a file was not created.
O_EXCL;
@@ -151,7 +151,7 @@
/// Obtain a file descriptor for low-level access.
///
/// The file itself is not opened and other file operations will fail.
- #[cfg(any(linux_android, target_os = "redox"))]
+ #[cfg(any(linux_android, target_os = "redox", target_os = "freebsd", target_os = "fuchsia"))]
O_PATH;
/// Only allow reading.
///
@@ -164,8 +164,18 @@
/// Similar to `O_DSYNC` but applies to `read`s instead.
#[cfg(any(target_os = "linux", netbsdlike))]
O_RSYNC;
- /// Skip search permission checks.
- #[cfg(target_os = "netbsd")]
+ /// Open directory for search only. Skip search permission checks on
+ /// later `openat()` calls using the obtained file descriptor.
+ #[cfg(any(
+ apple_targets,
+ solarish,
+ target_os = "netbsd",
+ target_os = "freebsd",
+ target_os = "fuchsia",
+ target_os = "emscripten",
+ target_os = "aix",
+ target_os = "wasi"
+ ))]
O_SEARCH;
/// Open with a shared file lock.
#[cfg(any(bsd, target_os = "redox"))]
@@ -242,6 +252,119 @@
Errno::result(fd)
}
+cfg_if::cfg_if! {
+ if #[cfg(target_os = "linux")] {
+ libc_bitflags! {
+ /// Path resolution flags.
+ ///
+ /// See [path resolution(7)](https://man7.org/linux/man-pages/man7/path_resolution.7.html)
+ /// for details of the resolution process.
+ pub struct ResolveFlag: libc::c_ulonglong {
+ /// Do not permit the path resolution to succeed if any component of
+ /// the resolution is not a descendant of the directory indicated by
+ /// dirfd. This causes absolute symbolic links (and absolute values of
+ /// pathname) to be rejected.
+ RESOLVE_BENEATH;
+
+ /// Treat the directory referred to by dirfd as the root directory
+ /// while resolving pathname.
+ RESOLVE_IN_ROOT;
+
+ /// Disallow all magic-link resolution during path resolution. Magic
+ /// links are symbolic link-like objects that are most notably found
+ /// in proc(5); examples include `/proc/[pid]/exe` and `/proc/[pid]/fd/*`.
+ ///
+ /// See symlink(7) for more details.
+ RESOLVE_NO_MAGICLINKS;
+
+ /// Disallow resolution of symbolic links during path resolution. This
+ /// option implies RESOLVE_NO_MAGICLINKS.
+ RESOLVE_NO_SYMLINKS;
+
+ /// Disallow traversal of mount points during path resolution (including
+ /// all bind mounts).
+ RESOLVE_NO_XDEV;
+ }
+ }
+
+ /// Specifies how [openat2] should open a pathname.
+ ///
+ /// See <https://man7.org/linux/man-pages/man2/open_how.2type.html>
+ #[repr(transparent)]
+ #[derive(Clone, Copy, Debug)]
+ pub struct OpenHow(libc::open_how);
+
+ impl OpenHow {
+ /// Create a new zero-filled `open_how`.
+ pub fn new() -> Self {
+ // safety: according to the man page, open_how MUST be zero-initialized
+ // on init so that unknown fields are also zeroed.
+ Self(unsafe {
+ std::mem::MaybeUninit::zeroed().assume_init()
+ })
+ }
+
+ /// Set the open flags used to open a file, completely overwriting any
+ /// existing flags.
+ pub fn flags(mut self, flags: OFlag) -> Self {
+ let flags = flags.bits() as libc::c_ulonglong;
+ self.0.flags = flags;
+ self
+ }
+
+ /// Set the file mode new files will be created with, overwriting any
+ /// existing flags.
+ pub fn mode(mut self, mode: Mode) -> Self {
+ let mode = mode.bits() as libc::c_ulonglong;
+ self.0.mode = mode;
+ self
+ }
+
+ /// Set resolve flags, completely overwriting any existing flags.
+ ///
+ /// See [ResolveFlag] for more detail.
+ pub fn resolve(mut self, resolve: ResolveFlag) -> Self {
+ let resolve = resolve.bits();
+ self.0.resolve = resolve;
+ self
+ }
+ }
+
+ // safety: default isn't derivable because libc::open_how must be zeroed
+ impl Default for OpenHow {
+ fn default() -> Self {
+ Self::new()
+ }
+ }
+
+ /// Open or create a file for reading, writing or executing.
+ ///
+ /// `openat2` is an extension of the [`openat`] function that allows the caller
+ /// to control how path resolution happens.
+ ///
+ /// # See also
+ ///
+ /// [openat2](https://man7.org/linux/man-pages/man2/openat2.2.html)
+ pub fn openat2<P: ?Sized + NixPath>(
+ dirfd: RawFd,
+ path: &P,
+ mut how: OpenHow,
+ ) -> Result<RawFd> {
+ let fd = path.with_nix_path(|cstr| unsafe {
+ libc::syscall(
+ libc::SYS_openat2,
+ dirfd,
+ cstr.as_ptr(),
+ &mut how as *mut OpenHow,
+ std::mem::size_of::<libc::open_how>(),
+ )
+ })?;
+
+ Errno::result(fd as RawFd)
+ }
+ }
+}
+
/// Change the name of a file.
///
/// The `renameat` function is equivalent to `rename` except in the case where either `old_path`
@@ -832,6 +955,30 @@
std::mem::forget(self);
Ok(inner)
}
+
+ /// Relock the file. This can upgrade or downgrade the lock type.
+ ///
+ /// # Example
+ /// ```
+ /// # use std::fs::File;
+ /// # use nix::fcntl::{Flock, FlockArg};
+ /// # use tempfile::tempfile;
+ /// let f: std::fs::File = tempfile().unwrap();
+ /// let locked_file = Flock::lock(f, FlockArg::LockExclusive).unwrap();
+ /// // Do stuff, then downgrade the lock
+ /// locked_file.relock(FlockArg::LockShared).unwrap();
+ /// ```
+ pub fn relock(&self, arg: FlockArg) -> Result<()> {
+ let flags = match arg {
+ FlockArg::LockShared => libc::LOCK_SH,
+ FlockArg::LockExclusive => libc::LOCK_EX,
+ FlockArg::LockSharedNonblock => libc::LOCK_SH | libc::LOCK_NB,
+ FlockArg::LockExclusiveNonblock => libc::LOCK_EX | libc::LOCK_NB,
+ #[allow(deprecated)]
+ FlockArg::Unlock | FlockArg::UnlockNonblock => return Err(Errno::EINVAL),
+ };
+ Errno::result(unsafe { libc::flock(self.as_raw_fd(), flags) }).map(drop)
+ }
}
// Safety: `File` is not [std::clone::Clone].
@@ -940,10 +1087,10 @@
/// # See Also
/// *[`splice`](https://man7.org/linux/man-pages/man2/splice.2.html)
#[cfg(linux_android)]
-pub fn splice(
- fd_in: RawFd,
+pub fn splice<Fd1: AsFd, Fd2: AsFd>(
+ fd_in: Fd1,
off_in: Option<&mut libc::loff_t>,
- fd_out: RawFd,
+ fd_out: Fd2,
off_out: Option<&mut libc::loff_t>,
len: usize,
flags: SpliceFFlags,
@@ -956,7 +1103,7 @@
.unwrap_or(ptr::null_mut());
let ret = unsafe {
- libc::splice(fd_in, off_in, fd_out, off_out, len, flags.bits())
+ libc::splice(fd_in.as_fd().as_raw_fd(), off_in, fd_out.as_fd().as_raw_fd(), off_out, len, flags.bits())
};
Errno::result(ret).map(|r| r as usize)
}
@@ -966,13 +1113,13 @@
/// # See Also
/// *[`tee`](https://man7.org/linux/man-pages/man2/tee.2.html)
#[cfg(linux_android)]
-pub fn tee(
- fd_in: RawFd,
- fd_out: RawFd,
+pub fn tee<Fd1: AsFd, Fd2: AsFd>(
+ fd_in: Fd1,
+ fd_out: Fd2,
len: usize,
flags: SpliceFFlags,
) -> Result<usize> {
- let ret = unsafe { libc::tee(fd_in, fd_out, len, flags.bits()) };
+ let ret = unsafe { libc::tee(fd_in.as_fd().as_raw_fd(), fd_out.as_fd().as_raw_fd(), len, flags.bits()) };
Errno::result(ret).map(|r| r as usize)
}
@@ -981,14 +1128,14 @@
/// # See Also
/// *[`vmsplice`](https://man7.org/linux/man-pages/man2/vmsplice.2.html)
#[cfg(linux_android)]
-pub fn vmsplice(
- fd: RawFd,
+pub fn vmsplice<F: AsFd>(
+ fd: F,
iov: &[std::io::IoSlice<'_>],
flags: SpliceFFlags,
) -> Result<usize> {
let ret = unsafe {
libc::vmsplice(
- fd,
+ fd.as_fd().as_raw_fd(),
iov.as_ptr().cast(),
iov.len(),
flags.bits(),
diff --git a/crates/nix/src/lib.rs b/crates/nix/src/lib.rs
index dffac29..c4c0fa5 100644
--- a/crates/nix/src/lib.rs
+++ b/crates/nix/src/lib.rs
@@ -362,3 +362,21 @@
self.as_os_str().with_nix_path(f)
}
}
+
+/// Like `NixPath::with_nix_path()`, but allow the `path` argument to be optional.
+///
+/// A NULL pointer will be provided if `path.is_none()`.
+#[cfg(any(
+ all(apple_targets, feature = "mount"),
+ all(linux_android, any(feature = "mount", feature = "fanotify"))
+))]
+pub(crate) fn with_opt_nix_path<P, T, F>(path: Option<&P>, f: F) -> Result<T>
+where
+ P: ?Sized + NixPath,
+ F: FnOnce(*const libc::c_char) -> T,
+{
+ match path {
+ Some(path) => path.with_nix_path(|p_str| f(p_str.as_ptr())),
+ None => Ok(f(ptr::null())),
+ }
+}
diff --git a/crates/nix/src/mount/apple.rs b/crates/nix/src/mount/apple.rs
new file mode 100644
index 0000000..ce0ab1e
--- /dev/null
+++ b/crates/nix/src/mount/apple.rs
@@ -0,0 +1,111 @@
+use crate::{Errno, NixPath, Result};
+use libc::c_int;
+
+libc_bitflags!(
+ /// Used with [`mount()`] and [`unmount()`].
+ pub struct MntFlags: c_int {
+ /// Do not interpret special files on the filesystem.
+ MNT_NODEV;
+ /// Enable data protection on the filesystem if the filesystem is configured for it.
+ MNT_CPROTECT;
+ /// file system is quarantined
+ MNT_QUARANTINE;
+ /// filesystem is stored locally
+ MNT_LOCAL;
+ /// quotas are enabled on filesystem
+ MNT_QUOTA;
+ /// identifies the root filesystem
+ MNT_ROOTFS;
+ /// file system is not appropriate path to user data
+ MNT_DONTBROWSE;
+ /// VFS will ignore ownership information on filesystem objects
+ MNT_IGNORE_OWNERSHIP;
+ /// filesystem was mounted by automounter
+ MNT_AUTOMOUNTED;
+ /// filesystem is journaled
+ MNT_JOURNALED;
+ /// Don't allow user extended attributes
+ MNT_NOUSERXATTR;
+ /// filesystem should defer writes
+ MNT_DEFWRITE;
+ /// don't block unmount if not responding
+ MNT_NOBLOCK;
+ /// file system is exported
+ MNT_EXPORTED;
+ /// file system written asynchronously
+ MNT_ASYNC;
+ /// Force a read-write mount even if the file system appears to be
+ /// unclean.
+ MNT_FORCE;
+ /// MAC support for objects.
+ MNT_MULTILABEL;
+ /// 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;
+ /// 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.
+ MNT_SNAPSHOT;
+ /// All I/O to the file system should be done synchronously.
+ MNT_SYNCHRONOUS;
+ /// Union with underlying fs.
+ MNT_UNION;
+ /// Indicates that the mount command is being applied to an already
+ /// mounted file system.
+ MNT_UPDATE;
+ }
+);
+
+/// Mount a file system.
+///
+/// # Arguments
+/// - `source` - Specifies the file system. e.g. `/dev/sd0`.
+/// - `target` - Specifies the destination. e.g. `/mnt`.
+/// - `flags` - Optional flags controlling the mount.
+/// - `data` - Optional file system specific data.
+///
+/// # see also
+/// [`mount`](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mount.2.html)
+pub fn mount<
+ P1: ?Sized + NixPath,
+ P2: ?Sized + NixPath,
+ P3: ?Sized + NixPath,
+>(
+ source: &P1,
+ target: &P2,
+ flags: MntFlags,
+ data: Option<&P3>,
+) -> Result<()> {
+ let res = source.with_nix_path(|s| {
+ target.with_nix_path(|t| {
+ crate::with_opt_nix_path(data, |d| unsafe {
+ libc::mount(
+ s.as_ptr(),
+ t.as_ptr(),
+ flags.bits(),
+ d.cast_mut().cast(),
+ )
+ })
+ })
+ })???;
+
+ Errno::result(res).map(drop)
+}
+
+/// Umount the file system mounted at `target`.
+pub fn unmount<P>(target: &P, flags: MntFlags) -> Result<()>
+where
+ P: ?Sized + NixPath,
+{
+ let res = target.with_nix_path(|cstr| unsafe {
+ libc::unmount(cstr.as_ptr(), flags.bits())
+ })?;
+
+ Errno::result(res).map(drop)
+}
diff --git a/crates/nix/src/mount/bsd.rs b/crates/nix/src/mount/bsd_without_apple.rs
similarity index 98%
rename from crates/nix/src/mount/bsd.rs
rename to crates/nix/src/mount/bsd_without_apple.rs
index 248e0ab..ae9eed7 100644
--- a/crates/nix/src/mount/bsd.rs
+++ b/crates/nix/src/mount/bsd_without_apple.rs
@@ -30,7 +30,7 @@
#[cfg(target_os = "freebsd")]
MNT_GJOURNAL;
/// MAC support for objects.
- #[cfg(any(apple_targets, target_os = "freebsd"))]
+ #[cfg(target_os = "freebsd")]
MNT_MULTILABEL;
/// Disable read clustering.
#[cfg(freebsdlike)]
@@ -58,7 +58,7 @@
/// Create a snapshot of the file system.
///
/// See [mksnap_ffs(8)](https://www.freebsd.org/cgi/man.cgi?query=mksnap_ffs)
- #[cfg(any(apple_targets, target_os = "freebsd"))]
+ #[cfg(target_os = "freebsd")]
MNT_SNAPSHOT;
/// Using soft updates.
#[cfg(any(freebsdlike, netbsdlike))]
@@ -71,7 +71,6 @@
MNT_SYNCHRONOUS;
/// Union with underlying fs.
#[cfg(any(
- apple_targets,
target_os = "freebsd",
target_os = "netbsd"
))]
diff --git a/crates/nix/src/mount/linux.rs b/crates/nix/src/mount/linux.rs
index aa166bc..3c27150 100644
--- a/crates/nix/src/mount/linux.rs
+++ b/crates/nix/src/mount/linux.rs
@@ -113,21 +113,10 @@
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| {
+ let res = crate::with_opt_nix_path(source, |s| {
target.with_nix_path(|t| {
- with_opt_nix_path(fstype, |ty| {
- with_opt_nix_path(data, |d| unsafe {
+ crate::with_opt_nix_path(fstype, |ty| {
+ crate::with_opt_nix_path(data, |d| unsafe {
libc::mount(
s,
t.as_ptr(),
diff --git a/crates/nix/src/mount/mod.rs b/crates/nix/src/mount/mod.rs
index 8caf27f..41e7b3e 100644
--- a/crates/nix/src/mount/mod.rs
+++ b/crates/nix/src/mount/mod.rs
@@ -5,8 +5,14 @@
#[cfg(linux_android)]
pub use self::linux::*;
-#[cfg(bsd)]
-mod bsd;
+#[cfg(bsd_without_apple)]
+mod bsd_without_apple;
-#[cfg(bsd)]
-pub use self::bsd::*;
+#[cfg(bsd_without_apple)]
+pub use self::bsd_without_apple::*;
+
+#[cfg(apple_targets)]
+mod apple;
+
+#[cfg(apple_targets)]
+pub use self::apple::*;
diff --git a/crates/nix/src/net/if_.rs b/crates/nix/src/net/if_.rs
index c66b5dc..5b6c2e7 100644
--- a/crates/nix/src/net/if_.rs
+++ b/crates/nix/src/net/if_.rs
@@ -3,9 +3,9 @@
//! Uses Linux and/or POSIX functions to resolve interface names like "eth0"
//! or "socan1" into device numbers.
-use std::fmt;
-use crate::{Error, NixPath, Result};
-use libc::c_uint;
+use std::{ffi::{CStr, CString}, fmt};
+use crate::{errno::Errno, Error, NixPath, Result};
+use libc::{c_uint, IF_NAMESIZE};
#[cfg(not(solarish))]
/// type alias for InterfaceFlags
@@ -14,7 +14,7 @@
/// type alias for InterfaceFlags
pub type IflagsType = libc::c_longlong;
-/// Resolve an interface into a interface number.
+/// Resolve an interface into an 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()) })?;
@@ -26,6 +26,19 @@
}
}
+/// Resolve an interface number into an interface.
+pub fn if_indextoname(index: c_uint) -> Result<CString> {
+ // We need to allocate this anyway, so doing it directly is faster.
+ let mut buf = vec![0u8; IF_NAMESIZE];
+
+ let return_buf = unsafe {
+ libc::if_indextoname(index, buf.as_mut_ptr().cast())
+ };
+
+ Errno::result(return_buf.cast())?;
+ Ok(CStr::from_bytes_until_nul(buf.as_slice()).unwrap().to_owned())
+}
+
libc_bitflags!(
/// Standard interface flags, used by `getifaddrs`
pub struct InterfaceFlags: IflagsType {
diff --git a/crates/nix/src/pty.rs b/crates/nix/src/pty.rs
index 74f8ecf..171bbfa 100644
--- a/crates/nix/src/pty.rs
+++ b/crates/nix/src/pty.rs
@@ -12,8 +12,6 @@
use crate::errno::Errno;
#[cfg(not(target_os = "aix"))]
use crate::sys::termios::Termios;
-#[cfg(feature = "process")]
-use crate::unistd::ForkResult;
#[cfg(all(feature = "process", not(target_os = "aix")))]
use crate::unistd::Pid;
use crate::{fcntl, unistd, Result};
@@ -31,15 +29,19 @@
feature! {
#![feature = "process"]
-/// Representation of a master with a forked pty
-///
-/// This is returned by [`forkpty`].
+/// A successful result of [`forkpty()`].
#[derive(Debug)]
-pub struct ForkptyResult {
- /// The master port in a virtual pty pair
- pub master: OwnedFd,
- /// Metadata about forked process
- pub fork_result: ForkResult,
+pub enum ForkptyResult {
+ /// This is the parent process of the underlying fork.
+ Parent {
+ /// The PID of the fork's child process
+ child: Pid,
+ /// A file descriptor referring to master side of the pseudoterminal of
+ /// the child process.
+ master: OwnedFd,
+ },
+ /// This is the child process of the underlying fork.
+ Child,
}
}
@@ -56,6 +58,12 @@
}
}
+impl AsFd for PtyMaster {
+ fn as_fd(&self) -> BorrowedFd<'_> {
+ self.0.as_fd()
+ }
+}
+
impl IntoRawFd for PtyMaster {
fn into_raw_fd(self) -> RawFd {
let fd = self.0;
@@ -300,9 +308,7 @@
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)).
+/// Create a new process operating in a pseudoterminal.
///
/// 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
@@ -319,6 +325,11 @@
/// 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
+///
+/// # Reference
+///
+/// * [FreeBSD](https://man.freebsd.org/cgi/man.cgi?query=forkpty)
+/// * [Linux](https://man7.org/linux/man-pages/man3/forkpty.3.html)
#[cfg(not(target_os = "aix"))]
pub unsafe fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b Termios>>>(
winsize: T,
@@ -343,14 +354,23 @@
let res = unsafe { 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) },
- })?;
+ let success_ret = Errno::result(res)?;
+ let forkpty_result = match success_ret {
+ // In the child process
+ 0 => ForkptyResult::Child,
+ // In the parent process
+ child_pid => {
+ // SAFETY:
+ // 1. The master buffer is guaranteed to be initialized in the parent process
+ // 2. OwnedFd::from_raw_fd won't panic as the fd is a valid file descriptor
+ let master = unsafe { OwnedFd::from_raw_fd( master.assume_init() ) };
+ ForkptyResult::Parent {
+ master,
+ child: Pid::from_raw(child_pid),
+ }
+ }
+ };
- Ok(ForkptyResult {
- master: unsafe { OwnedFd::from_raw_fd( master.assume_init() ) },
- fork_result,
- })
+ Ok(forkpty_result)
}
}
diff --git a/crates/nix/src/sys/aio.rs b/crates/nix/src/sys/aio.rs
index e9213c6..c7ba405 100644
--- a/crates/nix/src/sys/aio.rs
+++ b/crates/nix/src/sys/aio.rs
@@ -30,7 +30,7 @@
fmt::{self, Debug},
marker::{PhantomData, PhantomPinned},
mem,
- os::unix::io::RawFd,
+ os::unix::io::{AsFd, AsRawFd, BorrowedFd},
pin::Pin,
ptr, thread,
};
@@ -55,6 +55,7 @@
/// on supported operating systems only, do it like `fdatasync`
#[cfg(any(apple_targets,
target_os = "linux",
+ target_os = "freebsd",
netbsdlike))]
O_DSYNC
}
@@ -102,7 +103,7 @@
// provide polymorphism at the wrong level. Instead, the best place for
// polymorphism is at the level of `Futures`.
#[repr(C)]
-struct AioCb {
+struct AioCb<'a> {
aiocb: LibcAiocb,
/// Could this `AioCb` potentially have any in-kernel state?
// It would be really nice to perform the in-progress check entirely at
@@ -112,9 +113,10 @@
// that there's no way to write an AioCb constructor that neither boxes
// the object itself, nor moves it during return.
in_progress: bool,
+ _fd: PhantomData<BorrowedFd<'a>>,
}
-impl AioCb {
+impl<'a> AioCb<'a> {
pin_utils::unsafe_unpinned!(aiocb: LibcAiocb);
fn aio_return(mut self: Pin<&mut Self>) -> Result<usize> {
@@ -139,18 +141,23 @@
}
}
- fn common_init(fd: RawFd, prio: i32, sigev_notify: SigevNotify) -> Self {
+ fn common_init(
+ fd: BorrowedFd<'a>,
+ 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_fildes = fd.as_raw_fd();
a.aio_reqprio = prio;
a.aio_sigevent = SigEvent::new(sigev_notify).sigevent();
AioCb {
aiocb: LibcAiocb(a),
in_progress: false,
+ _fd: PhantomData,
}
}
@@ -186,7 +193,7 @@
}
}
-impl Debug for AioCb {
+impl<'a> Debug for AioCb<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("AioCb")
.field("aiocb", &self.aiocb.0)
@@ -195,7 +202,7 @@
}
}
-impl Drop for AioCb {
+impl<'a> Drop for AioCb<'a> {
/// 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) {
@@ -243,11 +250,11 @@
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
/// # use std::io::Write;
- /// # use std::os::unix::io::AsRawFd;
+ /// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// let wbuf = b"CDEF";
/// let mut f = tempfile().unwrap();
- /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
+ /// let mut aiocb = Box::pin(AioWrite::new(f.as_fd(),
/// 2, //offset
/// &wbuf[..],
/// 0, //priority
@@ -284,11 +291,11 @@
/// # use nix::sys::aio::*;
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
- /// # use std::os::unix::io::AsRawFd;
+ /// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// const WBUF: &[u8] = b"abcdef123456";
/// let mut f = tempfile().unwrap();
- /// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
+ /// let mut aiocb = Box::pin(AioWrite::new(f.as_fd(),
/// 2, //offset
/// WBUF,
/// 0, //priority
@@ -306,7 +313,7 @@
fn error(self: Pin<&mut Self>) -> Result<()>;
/// Returns the underlying file descriptor associated with the operation.
- fn fd(&self) -> RawFd;
+ fn fd(&self) -> BorrowedFd;
/// Does this operation currently have any in-kernel state?
///
@@ -321,10 +328,10 @@
/// # use nix::sys::aio::*;
/// # use nix::sys::signal::SigevNotify::SigevNone;
/// # use std::{thread, time};
- /// # use std::os::unix::io::AsRawFd;
+ /// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// let f = tempfile().unwrap();
- /// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC,
+ /// let mut aiof = Box::pin(AioFsync::new(f.as_fd(), AioFsyncMode::O_SYNC,
/// 0, SigevNone));
/// assert!(!aiof.as_mut().in_progress());
/// aiof.as_mut().submit().expect("aio_fsync failed early");
@@ -364,8 +371,10 @@
self.aiocb().error()
}
- fn fd(&self) -> RawFd {
- self.aiocb.aiocb.0.aio_fildes
+ fn fd(&self) -> BorrowedFd<'a> {
+ // safe because self's lifetime is the same as the original file
+ // descriptor.
+ unsafe { BorrowedFd::borrow_raw(self.aiocb.aiocb.0.aio_fildes) }
}
fn in_progress(&self) -> bool {
@@ -413,10 +422,10 @@
/// # use nix::sys::aio::*;
/// # use nix::sys::signal::SigevNotify::SigevNone;
/// # use std::{thread, time};
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// let f = tempfile().unwrap();
-/// let mut aiof = Box::pin(AioFsync::new(f.as_raw_fd(), AioFsyncMode::O_SYNC,
+/// let mut aiof = Box::pin(AioFsync::new(f.as_fd(), AioFsyncMode::O_SYNC,
/// 0, SigevNone));
/// aiof.as_mut().submit().expect("aio_fsync failed early");
/// while (aiof.as_mut().error() == Err(Errno::EINPROGRESS)) {
@@ -426,13 +435,13 @@
/// ```
#[derive(Debug)]
#[repr(transparent)]
-pub struct AioFsync {
- aiocb: AioCb,
+pub struct AioFsync<'a> {
+ aiocb: AioCb<'a>,
_pin: PhantomPinned,
}
-impl AioFsync {
- unsafe_pinned!(aiocb: AioCb);
+impl<'a> AioFsync<'a> {
+ unsafe_pinned!(aiocb: AioCb<'a>);
/// Returns the operation's fsync mode: data and metadata or data only?
pub fn mode(&self) -> AioFsyncMode {
@@ -451,7 +460,7 @@
/// * `sigev_notify`: Determines how you will be notified of event
/// completion.
pub fn new(
- fd: RawFd,
+ fd: BorrowedFd<'a>,
mode: AioFsyncMode,
prio: i32,
sigev_notify: SigevNotify,
@@ -469,7 +478,7 @@
}
}
-impl Aio for AioFsync {
+impl<'a> Aio for AioFsync<'a> {
type Output = ();
aio_methods!();
@@ -490,7 +499,7 @@
// AioFsync does not need AsMut, since it can't be used with lio_listio
-impl AsRef<libc::aiocb> for AioFsync {
+impl<'a> AsRef<libc::aiocb> for AioFsync<'a> {
fn as_ref(&self) -> &libc::aiocb {
&self.aiocb.aiocb.0
}
@@ -512,7 +521,7 @@
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
/// # use std::io::Write;
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// const INITIAL: &[u8] = b"abcdef123456";
/// const LEN: usize = 4;
@@ -522,7 +531,7 @@
/// {
/// let mut aior = Box::pin(
/// AioRead::new(
-/// f.as_raw_fd(),
+/// f.as_fd(),
/// 2, //offset
/// &mut rbuf,
/// 0, //priority
@@ -540,13 +549,13 @@
#[derive(Debug)]
#[repr(transparent)]
pub struct AioRead<'a> {
- aiocb: AioCb,
+ aiocb: AioCb<'a>,
_data: PhantomData<&'a [u8]>,
_pin: PhantomPinned,
}
impl<'a> AioRead<'a> {
- unsafe_pinned!(aiocb: AioCb);
+ unsafe_pinned!(aiocb: AioCb<'a>);
/// Returns the requested length of the aio operation in bytes
///
@@ -570,7 +579,7 @@
/// * `sigev_notify`: Determines how you will be notified of event
/// completion.
pub fn new(
- fd: RawFd,
+ fd: BorrowedFd<'a>,
offs: off_t,
buf: &'a mut [u8],
prio: i32,
@@ -629,7 +638,7 @@
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
/// # use std::io::{IoSliceMut, Write};
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// const INITIAL: &[u8] = b"abcdef123456";
/// let mut rbuf0 = vec![0; 4];
@@ -641,7 +650,7 @@
/// {
/// let mut aior = Box::pin(
/// AioReadv::new(
-/// f.as_raw_fd(),
+/// f.as_fd(),
/// 2, //offset
/// &mut rbufs,
/// 0, //priority
@@ -661,14 +670,14 @@
#[derive(Debug)]
#[repr(transparent)]
pub struct AioReadv<'a> {
- aiocb: AioCb,
+ aiocb: AioCb<'a>,
_data: PhantomData<&'a [&'a [u8]]>,
_pin: PhantomPinned,
}
#[cfg(target_os = "freebsd")]
impl<'a> AioReadv<'a> {
- unsafe_pinned!(aiocb: AioCb);
+ unsafe_pinned!(aiocb: AioCb<'a>);
/// Returns the number of buffers the operation will read into.
pub fn iovlen(&self) -> usize {
@@ -689,7 +698,7 @@
/// * `sigev_notify`: Determines how you will be notified of event
/// completion.
pub fn new(
- fd: RawFd,
+ fd: BorrowedFd<'a>,
offs: off_t,
bufs: &mut [IoSliceMut<'a>],
prio: i32,
@@ -750,13 +759,13 @@
/// # use nix::sys::aio::*;
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// const WBUF: &[u8] = b"abcdef123456";
/// let mut f = tempfile().unwrap();
/// let mut aiow = Box::pin(
/// AioWrite::new(
-/// f.as_raw_fd(),
+/// f.as_fd(),
/// 2, //offset
/// WBUF,
/// 0, //priority
@@ -772,13 +781,13 @@
#[derive(Debug)]
#[repr(transparent)]
pub struct AioWrite<'a> {
- aiocb: AioCb,
+ aiocb: AioCb<'a>,
_data: PhantomData<&'a [u8]>,
_pin: PhantomPinned,
}
impl<'a> AioWrite<'a> {
- unsafe_pinned!(aiocb: AioCb);
+ unsafe_pinned!(aiocb: AioCb<'a>);
/// Returns the requested length of the aio operation in bytes
///
@@ -802,7 +811,7 @@
/// * `sigev_notify`: Determines how you will be notified of event
/// completion.
pub fn new(
- fd: RawFd,
+ fd: BorrowedFd<'a>,
offs: off_t,
buf: &'a [u8],
prio: i32,
@@ -864,7 +873,7 @@
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
/// # use std::io::IoSlice;
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// const wbuf0: &[u8] = b"abcdef";
/// const wbuf1: &[u8] = b"123456";
@@ -873,7 +882,7 @@
/// let mut f = tempfile().unwrap();
/// let mut aiow = Box::pin(
/// AioWritev::new(
-/// f.as_raw_fd(),
+/// f.as_fd(),
/// 2, //offset
/// &wbufs,
/// 0, //priority
@@ -890,14 +899,14 @@
#[derive(Debug)]
#[repr(transparent)]
pub struct AioWritev<'a> {
- aiocb: AioCb,
+ aiocb: AioCb<'a>,
_data: PhantomData<&'a [&'a [u8]]>,
_pin: PhantomPinned,
}
#[cfg(target_os = "freebsd")]
impl<'a> AioWritev<'a> {
- unsafe_pinned!(aiocb: AioCb);
+ unsafe_pinned!(aiocb: AioCb<'a>);
/// Returns the number of buffers the operation will read into.
pub fn iovlen(&self) -> usize {
@@ -918,7 +927,7 @@
/// * `sigev_notify`: Determines how you will be notified of event
/// completion.
pub fn new(
- fd: RawFd,
+ fd: BorrowedFd<'a>,
offs: off_t,
bufs: &[IoSlice<'a>],
prio: i32,
@@ -983,17 +992,17 @@
/// # use nix::sys::signal::SigevNotify;
/// # use std::{thread, time};
/// # use std::io::Write;
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// let wbuf = b"CDEF";
/// let mut f = tempfile().unwrap();
-/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
+/// let mut aiocb = Box::pin(AioWrite::new(f.as_fd(),
/// 2, //offset
/// &wbuf[..],
/// 0, //priority
/// SigevNotify::SigevNone));
/// aiocb.as_mut().submit().unwrap();
-/// let cs = aio_cancel_all(f.as_raw_fd()).unwrap();
+/// let cs = aio_cancel_all(f.as_fd()).unwrap();
/// if cs == AioCancelStat::AioNotCanceled {
/// while (aiocb.as_mut().error() == Err(Errno::EINPROGRESS)) {
/// thread::sleep(time::Duration::from_millis(10));
@@ -1006,8 +1015,8 @@
/// # 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()) } {
+pub fn aio_cancel_all<F: AsFd>(fd: F) -> Result<AioCancelStat> {
+ match unsafe { libc::aio_cancel(fd.as_fd().as_raw_fd(), ptr::null_mut()) } {
libc::AIO_CANCELED => Ok(AioCancelStat::AioCanceled),
libc::AIO_NOTCANCELED => Ok(AioCancelStat::AioNotCanceled),
libc::AIO_ALLDONE => Ok(AioCancelStat::AioAllDone),
@@ -1028,18 +1037,18 @@
/// ```
/// # use nix::sys::aio::*;
/// # use nix::sys::signal::SigevNotify;
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use tempfile::tempfile;
/// const WBUF: &[u8] = b"abcdef123456";
/// let mut f = tempfile().unwrap();
-/// let mut aiocb = Box::pin(AioWrite::new(f.as_raw_fd(),
+/// let mut aiocb = Box::pin(AioWrite::new(f.as_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());
+/// assert_eq!(aiocb.as_mut().aio_return().unwrap(), WBUF.len());
/// ```
/// # References
///
@@ -1078,14 +1087,14 @@
/// 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 std::os::unix::io::AsFd;
/// # 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(),
+/// f.as_fd(),
/// 2, // offset
/// WBUF,
/// 0, // priority
@@ -1102,7 +1111,7 @@
/// technique for reducing overall context-switch overhead, especially when
/// combined with kqueue.
/// ```
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use std::thread;
/// # use std::time;
/// # use nix::errno::Errno;
@@ -1112,7 +1121,7 @@
/// const WBUF: &[u8] = b"abcdef123456";
/// let mut f = tempfile().unwrap();
/// let mut aiow = Box::pin(AioWrite::new(
-/// f.as_raw_fd(),
+/// f.as_fd(),
/// 2, // offset
/// WBUF,
/// 0, // priority
@@ -1136,7 +1145,7 @@
/// possibly resubmit some.
/// ```
/// # use libc::c_int;
-/// # use std::os::unix::io::AsRawFd;
+/// # use std::os::unix::io::AsFd;
/// # use std::sync::atomic::{AtomicBool, Ordering};
/// # use std::thread;
/// # use std::time;
@@ -1158,7 +1167,7 @@
/// const WBUF: &[u8] = b"abcdef123456";
/// let mut f = tempfile().unwrap();
/// let mut aiow = Box::pin(AioWrite::new(
-/// f.as_raw_fd(),
+/// f.as_fd(),
/// 2, // offset
/// WBUF,
/// 0, // priority
diff --git a/crates/nix/src/sys/fanotify.rs b/crates/nix/src/sys/fanotify.rs
index e217406..e22c527 100644
--- a/crates/nix/src/sys/fanotify.rs
+++ b/crates/nix/src/sys/fanotify.rs
@@ -96,9 +96,22 @@
/// final data.
FAN_CLASS_PRE_CONTENT;
- /// Remove the limit of 16384 events for the event queue.
+ /// Remove the limit on the number of events in the event queue.
+ ///
+ /// Prior to Linux kernel 5.13, this limit was hardcoded to 16384. After
+ /// 5.13, one can change it via file `/proc/sys/fs/fanotify/max_queued_events`.
+ ///
+ /// See `fanotify(7)` for details about this limit. Use of this flag
+ /// requires the `CAP_SYS_ADMIN` capability.
FAN_UNLIMITED_QUEUE;
- /// Remove the limit of 8192 marks.
+ /// Remove the limit on the number of fanotify marks per user.
+ ///
+ /// Prior to Linux kernel 5.13, this limit was hardcoded to 8192 (per
+ /// group, not per user). After 5.13, one can change it via file
+ /// `/proc/sys/fs/fanotify/max_user_marks`.
+ ///
+ /// See `fanotify(7)` for details about this limit. Use of this flag
+ /// requires the `CAP_SYS_ADMIN` capability.
FAN_UNLIMITED_MARKS;
/// Make `FanotifyEvent::pid` return pidfd. Since Linux 5.15.
@@ -236,6 +249,9 @@
impl Drop for FanotifyEvent {
fn drop(&mut self) {
+ if self.0.fd == libc::FAN_NOFD {
+ return;
+ }
let e = close(self.0.fd);
if !std::thread::panicking() && e == Err(Errno::EBADF) {
panic!("Closing an invalid file descriptor!");
@@ -313,18 +329,7 @@
dirfd: Option<RawFd>,
path: Option<&P>,
) -> 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(path, |p| unsafe {
+ let res = crate::with_opt_nix_path(path, |p| unsafe {
libc::fanotify_mark(
self.fd.as_raw_fd(),
flags.bits(),
diff --git a/crates/nix/src/sys/prctl.rs b/crates/nix/src/sys/prctl.rs
index 42324be..35b1ce1 100644
--- a/crates/nix/src/sys/prctl.rs
+++ b/crates/nix/src/sys/prctl.rs
@@ -9,9 +9,11 @@
use crate::sys::signal::Signal;
use crate::Result;
-use libc::{c_int, c_ulong};
+use libc::{c_int, c_ulong, c_void};
use std::convert::TryFrom;
use std::ffi::{CStr, CString};
+use std::num::NonZeroUsize;
+use std::ptr::NonNull;
libc_enum! {
/// The type of hardware memory corruption kill policy for the thread.
@@ -213,3 +215,14 @@
pub fn get_thp_disable() -> Result<bool> {
prctl_get_bool(libc::PR_GET_THP_DISABLE)
}
+
+/// Set an identifier (or reset it) to the address memory range.
+pub fn set_vma_anon_name(addr: NonNull<c_void>, length: NonZeroUsize, name: Option<&CStr>) -> Result<()> {
+ let nameref = match name {
+ Some(n) => n.as_ptr(),
+ _ => std::ptr::null()
+ };
+ let res = unsafe { libc::prctl(libc::PR_SET_VMA, libc::PR_SET_VMA_ANON_NAME, addr.as_ptr(), length, nameref) };
+
+ Errno::result(res).map(drop)
+}
diff --git a/crates/nix/src/sys/ptrace/linux.rs b/crates/nix/src/sys/ptrace/linux.rs
index 26544e1..8abaf4d 100644
--- a/crates/nix/src/sys/ptrace/linux.rs
+++ b/crates/nix/src/sys/ptrace/linux.rs
@@ -17,8 +17,10 @@
target_arch = "x86_64",
any(target_env = "gnu", target_env = "musl")
),
- all(target_arch = "x86", target_env = "gnu")
- )
+ all(target_arch = "x86", target_env = "gnu"),
+ all(target_arch = "aarch64", target_env = "gnu"),
+ all(target_arch = "riscv64", target_env = "gnu"),
+ ),
))]
use libc::user_regs_struct;
@@ -170,6 +172,92 @@
}
}
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
+))]
+libc_enum! {
+ #[repr(i32)]
+ /// Defines a specific register set, as used in `PTRACE_GETREGSET` and `PTRACE_SETREGSET`.
+ #[non_exhaustive]
+ pub enum RegisterSetValue {
+ NT_PRSTATUS,
+ NT_PRFPREG,
+ NT_PRPSINFO,
+ NT_TASKSTRUCT,
+ NT_AUXV,
+ }
+}
+
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
+))]
+/// Represents register set areas, such as general-purpose registers or
+/// floating-point registers.
+///
+/// # Safety
+///
+/// This trait is marked unsafe, since implementation of the trait must match
+/// ptrace's request `VALUE` and return data type `Regs`.
+pub unsafe trait RegisterSet {
+ /// Corresponding type of registers in the kernel.
+ const VALUE: RegisterSetValue;
+
+ /// Struct representing the register space.
+ type Regs;
+}
+
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
+))]
+/// Register sets used in [`getregset`] and [`setregset`]
+pub mod regset {
+ use super::*;
+
+ #[derive(Debug, Clone, Copy)]
+ /// General-purpose registers.
+ pub enum NT_PRSTATUS {}
+
+ unsafe impl RegisterSet for NT_PRSTATUS {
+ const VALUE: RegisterSetValue = RegisterSetValue::NT_PRSTATUS;
+ type Regs = user_regs_struct;
+ }
+
+ #[derive(Debug, Clone, Copy)]
+ /// Floating-point registers.
+ pub enum NT_PRFPREG {}
+
+ unsafe impl RegisterSet for NT_PRFPREG {
+ const VALUE: RegisterSetValue = RegisterSetValue::NT_PRFPREG;
+ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+ type Regs = libc::user_fpregs_struct;
+ #[cfg(target_arch = "aarch64")]
+ type Regs = libc::user_fpsimd_struct;
+ #[cfg(target_arch = "riscv64")]
+ type Regs = libc::__riscv_mc_d_ext_state;
+ }
+}
+
libc_bitflags! {
/// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
/// See `man ptrace` for more details.
@@ -217,6 +305,12 @@
}
/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
+///
+/// Note that since `PTRACE_GETREGS` are not available on all platforms (as in [ptrace(2)]),
+/// `ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, ...)` is used instead to achieve the same effect
+/// on aarch64 and riscv64.
+///
+/// [ptrace(2)]: https://www.man7.org/linux/man-pages/man2/ptrace.2.html
#[cfg(all(
target_os = "linux",
any(
@@ -231,7 +325,58 @@
ptrace_get_data::<user_regs_struct>(Request::PTRACE_GETREGS, pid)
}
+/// Get user registers, as with `ptrace(PTRACE_GETREGS, ...)`
+///
+/// Note that since `PTRACE_GETREGS` are not available on all platforms (as in [ptrace(2)]),
+/// `ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, ...)` is used instead to achieve the same effect
+/// on aarch64 and riscv64.
+///
+/// [ptrace(2)]: https://www.man7.org/linux/man-pages/man2/ptrace.2.html
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(target_arch = "aarch64", target_arch = "riscv64")
+))]
+pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
+ getregset::<regset::NT_PRSTATUS>(pid)
+}
+
+/// Get a particular set of user registers, as with `ptrace(PTRACE_GETREGSET, ...)`
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
+))]
+pub fn getregset<S: RegisterSet>(pid: Pid) -> Result<S::Regs> {
+ let request = Request::PTRACE_GETREGSET;
+ let mut data = mem::MaybeUninit::<S::Regs>::uninit();
+ let mut iov = libc::iovec {
+ iov_base: data.as_mut_ptr().cast(),
+ iov_len: mem::size_of::<S::Regs>(),
+ };
+ unsafe {
+ ptrace_other(
+ request,
+ pid,
+ S::VALUE as i32 as AddressType,
+ (&mut iov as *mut libc::iovec).cast(),
+ )?;
+ };
+ Ok(unsafe { data.assume_init() })
+}
+
/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
+///
+/// Note that since `PTRACE_SETREGS` are not available on all platforms (as in [ptrace(2)]),
+/// `ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, ...)` is used instead to achieve the same effect
+/// on aarch64 and riscv64.
+///
+/// [ptrace(2)]: https://www.man7.org/linux/man-pages/man2/ptrace.2.html
#[cfg(all(
target_os = "linux",
any(
@@ -248,12 +393,55 @@
Request::PTRACE_SETREGS as RequestType,
libc::pid_t::from(pid),
ptr::null_mut::<c_void>(),
- ®s as *const _ as *const c_void,
+ ®s as *const user_regs_struct as *const c_void,
)
};
Errno::result(res).map(drop)
}
+/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
+///
+/// Note that since `PTRACE_SETREGS` are not available on all platforms (as in [ptrace(2)]),
+/// `ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, ...)` is used instead to achieve the same effect
+/// on aarch64 and riscv64.
+///
+/// [ptrace(2)]: https://www.man7.org/linux/man-pages/man2/ptrace.2.html
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(target_arch = "aarch64", target_arch = "riscv64")
+))]
+pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
+ setregset::<regset::NT_PRSTATUS>(pid, regs)
+}
+
+/// Set a particular set of user registers, as with `ptrace(PTRACE_SETREGSET, ...)`
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
+))]
+pub fn setregset<S: RegisterSet>(pid: Pid, mut regs: S::Regs) -> Result<()> {
+ let mut iov = libc::iovec {
+ iov_base: (&mut regs as *mut S::Regs).cast(),
+ iov_len: mem::size_of::<S::Regs>(),
+ };
+ unsafe {
+ ptrace_other(
+ Request::PTRACE_SETREGSET,
+ pid,
+ S::VALUE as i32 as AddressType,
+ (&mut iov as *mut libc::iovec).cast(),
+ )?;
+ }
+ Ok(())
+}
+
/// 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
@@ -543,17 +731,15 @@
/// Writes a word into the processes memory at the given address, as with
/// ptrace(PTRACE_POKEDATA, ...)
-///
-/// # 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<()> {
- unsafe { ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data).map(drop) }
+#[allow(clippy::not_unsafe_ptr_arg_deref)]
+pub fn write(pid: Pid, addr: AddressType, data: c_long) -> Result<()> {
+ unsafe {
+ // Safety(not_unsafe_ptr_arg_deref):
+ // `ptrace_other` is a common abstract
+ // but in `PTRACE_POKEDATA` situation, `data` is exactly what will be wtitten
+ ptrace_other(Request::PTRACE_POKEDATA, pid, addr, data as *mut c_void)
+ .map(drop)
+ }
}
/// Reads a word from a user area at `offset`, as with ptrace(PTRACE_PEEKUSER, ...).
@@ -564,17 +750,13 @@
/// Writes a word to a user area at `offset`, as with ptrace(PTRACE_POKEUSER, ...).
/// 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<()> {
+#[allow(clippy::not_unsafe_ptr_arg_deref)]
+pub fn write_user(pid: Pid, offset: AddressType, data: c_long) -> Result<()> {
unsafe {
- ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data).map(drop)
+ // Safety(not_unsafe_ptr_arg_deref):
+ // `ptrace_other` is a common abstract
+ // but in `PTRACE_POKEDATA` situation, `data` is exactly what will be wtitten
+ ptrace_other(Request::PTRACE_POKEUSER, pid, offset, data as *mut c_void)
+ .map(drop)
}
}
diff --git a/crates/nix/src/sys/resource.rs b/crates/nix/src/sys/resource.rs
index 7131507..73d8a05 100644
--- a/crates/nix/src/sys/resource.rs
+++ b/crates/nix/src/sys/resource.rs
@@ -293,7 +293,9 @@
TimeVal::from(self.0.ru_stime)
}
- /// The resident set size at its peak, in kilobytes.
+ /// The resident set size at its peak,
+ #[cfg_attr(apple_targets, doc = " in bytes.")]
+ #[cfg_attr(not(apple_targets), doc = " in kilobytes.")]
pub fn max_rss(&self) -> c_long {
self.0.ru_maxrss
}
diff --git a/crates/nix/src/sys/signal.rs b/crates/nix/src/sys/signal.rs
index c9b593d..921fb28 100644
--- a/crates/nix/src/sys/signal.rs
+++ b/crates/nix/src/sys/signal.rs
@@ -597,7 +597,7 @@
target_os = "haiku",
target_os = "hurd",
target_os = "aix",
- target_os = "fushsia"
+ target_os = "fuchsia"
))]
#[doc(alias("sigsuspend"))]
pub fn suspend(&self) -> Result<()> {
@@ -753,11 +753,18 @@
}
/// Action to take on receipt of a signal. Corresponds to `sigaction`.
+#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SigAction {
sigaction: libc::sigaction
}
+impl From<SigAction> for libc::sigaction {
+ fn from(value: SigAction) -> libc::sigaction {
+ value.sigaction
+ }
+}
+
impl SigAction {
/// Creates a new action.
///
diff --git a/crates/nix/src/sys/signalfd.rs b/crates/nix/src/sys/signalfd.rs
index ccba774..4594f4d 100644
--- a/crates/nix/src/sys/signalfd.rs
+++ b/crates/nix/src/sys/signalfd.rs
@@ -105,11 +105,11 @@
Ok(SignalFd(fd))
}
- pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
+ pub fn set_mask(&self, mask: &SigSet) -> Result<()> {
self.update(mask, SfdFlags::empty())
}
- pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
+ pub fn read_signal(&self) -> Result<Option<siginfo>> {
let mut buffer = mem::MaybeUninit::<siginfo>::uninit();
let size = mem::size_of_val(&buffer);
diff --git a/crates/nix/src/sys/socket/addr.rs b/crates/nix/src/sys/socket/addr.rs
index f6800aa..aa89ba9 100644
--- a/crates/nix/src/sys/socket/addr.rs
+++ b/crates/nix/src/sys/socket/addr.rs
@@ -920,6 +920,19 @@
}
#[cfg(feature = "net")]
+impl From<SockaddrIn> for libc::sockaddr_in {
+ fn from(sin: SockaddrIn) -> libc::sockaddr_in {
+ sin.0
+ }
+}
+#[cfg(feature = "net")]
+impl From<libc::sockaddr_in> for SockaddrIn {
+ fn from(sin: libc::sockaddr_in) -> SockaddrIn {
+ SockaddrIn(sin)
+ }
+}
+
+#[cfg(feature = "net")]
impl std::str::FromStr for SockaddrIn {
type Err = net::AddrParseError;
@@ -970,6 +983,20 @@
}
#[cfg(feature = "net")]
+impl From<SockaddrIn6> for libc::sockaddr_in6 {
+ fn from(sin6: SockaddrIn6) -> libc::sockaddr_in6 {
+ sin6.0
+ }
+}
+
+#[cfg(feature = "net")]
+impl From<libc::sockaddr_in6> for SockaddrIn6 {
+ fn from(sin6: libc::sockaddr_in6) -> SockaddrIn6 {
+ SockaddrIn6(sin6)
+ }
+}
+
+#[cfg(feature = "net")]
impl private::SockaddrLikePriv for SockaddrIn6 {}
#[cfg(feature = "net")]
impl SockaddrLike for SockaddrIn6 {
@@ -2150,9 +2177,8 @@
}
#[cfg(not(any(target_os = "hurd", target_os = "redox")))]
+ #[allow(clippy::cast_ptr_alignment)]
mod link {
- #![allow(clippy::cast_ptr_alignment)]
-
#[cfg(any(apple_targets, solarish))]
use super::super::super::socklen_t;
use super::*;
diff --git a/crates/nix/src/sys/socket/mod.rs b/crates/nix/src/sys/socket/mod.rs
index 3d1651b..1f1869e 100644
--- a/crates/nix/src/sys/socket/mod.rs
+++ b/crates/nix/src/sys/socket/mod.rs
@@ -13,6 +13,7 @@
#[cfg(all(feature = "uio", not(target_os = "redox")))]
use libc::{
c_void, iovec, CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE,
+ MSG_CTRUNC,
};
#[cfg(not(target_os = "redox"))]
use std::io::{IoSlice, IoSliceMut};
@@ -599,13 +600,19 @@
}
impl<'a, S> RecvMsg<'a, '_, S> {
- /// Iterate over the valid control messages pointed to by this
- /// msghdr.
- pub fn cmsgs(&self) -> CmsgIterator {
- CmsgIterator {
+ /// Iterate over the valid control messages pointed to by this msghdr. If
+ /// allocated space for CMSGs was too small it is not safe to iterate,
+ /// instead return an `Error::ENOBUFS` error.
+ pub fn cmsgs(&self) -> Result<CmsgIterator> {
+
+ if self.mhdr.msg_flags & MSG_CTRUNC == MSG_CTRUNC {
+ return Err(Errno::ENOBUFS);
+ }
+
+ Ok(CmsgIterator {
cmsghdr: self.cmsghdr,
mhdr: &self.mhdr
- }
+ })
}
}
@@ -700,7 +707,7 @@
/// let mut iov = [IoSliceMut::new(&mut buffer)];
/// let r = recvmsg::<SockaddrIn>(in_socket.as_raw_fd(), &mut iov, Some(&mut cmsgspace), flags)
/// .unwrap();
- /// let rtime = match r.cmsgs().next() {
+ /// let rtime = match r.cmsgs().unwrap().next() {
/// Some(ControlMessageOwned::ScmTimestamp(rtime)) => rtime,
/// Some(_) => panic!("Unexpected control message"),
/// None => panic!("No control message")
@@ -773,7 +780,7 @@
#[cfg(target_os = "linux")]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
- UdpGroSegments(u16),
+ UdpGroSegments(i32),
/// SO_RXQ_OVFL indicates that an unsigned 32 bit value
/// ancilliary msg (cmsg) should be attached to recieved
@@ -949,7 +956,7 @@
#[cfg(target_os = "linux")]
#[cfg(feature = "net")]
(libc::SOL_UDP, libc::UDP_GRO) => {
- let gso_size: u16 = unsafe { ptr::read_unaligned(p as *const _) };
+ let gso_size: i32 = unsafe { ptr::read_unaligned(p as *const _) };
ControlMessageOwned::UdpGroSegments(gso_size)
},
#[cfg(any(linux_android, target_os = "fuchsia"))]
diff --git a/crates/nix/src/sys/socket/sockopt.rs b/crates/nix/src/sys/socket/sockopt.rs
index 4357695..f66b54e 100644
--- a/crates/nix/src/sys/socket/sockopt.rs
+++ b/crates/nix/src/sys/socket/sockopt.rs
@@ -5,7 +5,7 @@
use crate::Result;
use cfg_if::cfg_if;
use libc::{self, c_int, c_void, socklen_t};
-use std::ffi::{OsStr, OsString};
+use std::ffi::{CStr, CString, OsStr, OsString};
use std::mem::{self, MaybeUninit};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{AsFd, AsRawFd};
@@ -270,6 +270,16 @@
libc::SO_REUSEPORT,
bool
);
+#[cfg(target_os = "freebsd")]
+sockopt_impl!(
+ /// Enables incoming connections to be distributed among N sockets (up to 256)
+ /// via a Load-Balancing hash based algorithm.
+ ReusePortLb,
+ Both,
+ libc::SOL_SOCKET,
+ libc::SO_REUSEPORT_LB,
+ bool
+);
#[cfg(feature = "net")]
sockopt_impl!(
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -1026,7 +1036,7 @@
libc::IP_TTL,
libc::c_int
);
-#[cfg(any(linux_android, target_os = "freebsd"))]
+#[cfg(any(apple_targets, linux_android, target_os = "freebsd"))]
sockopt_impl!(
/// Set the unicast hop limit for the socket.
Ipv6Ttl,
@@ -1065,6 +1075,17 @@
libc::IPV6_DONTFRAG,
bool
);
+#[cfg(apple_targets)]
+#[cfg(feature = "net")]
+sockopt_impl!(
+ /// Get the utun interface name.
+ UtunIfname,
+ GetOnly,
+ libc::SYSPROTO_CONTROL,
+ libc::UTUN_OPT_IFNAME,
+ CString,
+ GetCString<[u8; libc::IFNAMSIZ]>
+);
#[allow(missing_docs)]
// Not documented by Linux!
@@ -1568,3 +1589,32 @@
}
}
+/// Getter for a `CString` value.
+struct GetCString<T: AsMut<[u8]>> {
+ len: socklen_t,
+ val: MaybeUninit<T>,
+}
+
+impl<T: AsMut<[u8]>> Get<CString> for GetCString<T> {
+ fn uninit() -> Self {
+ GetCString {
+ len: mem::size_of::<T>() as socklen_t,
+ val: MaybeUninit::uninit(),
+ }
+ }
+
+ fn ffi_ptr(&mut self) -> *mut c_void {
+ self.val.as_mut_ptr().cast()
+ }
+
+ fn ffi_len(&mut self) -> *mut socklen_t {
+ &mut self.len
+ }
+
+ unsafe fn assume_init(self) -> CString {
+ let mut v = unsafe { self.val.assume_init() };
+ CStr::from_bytes_until_nul(v.as_mut())
+ .expect("string should be null-terminated")
+ .to_owned()
+ }
+}
diff --git a/crates/nix/src/sys/sysinfo.rs b/crates/nix/src/sys/sysinfo.rs
index e8aa00b..a2bc093 100644
--- a/crates/nix/src/sys/sysinfo.rs
+++ b/crates/nix/src/sys/sysinfo.rs
@@ -1,4 +1,4 @@
-use libc::{self, SI_LOAD_SHIFT};
+use libc::SI_LOAD_SHIFT;
use std::time::Duration;
use std::{cmp, mem};
diff --git a/crates/nix/src/unistd.rs b/crates/nix/src/unistd.rs
index 4502766..58ede6e 100644
--- a/crates/nix/src/unistd.rs
+++ b/crates/nix/src/unistd.rs
@@ -1377,7 +1377,7 @@
/// Commit filesystem caches to disk
///
/// See also [sync(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sync.html)
-#[cfg(any(freebsdlike, linux_android, netbsdlike))]
+#[cfg(any(bsd, linux_android, solarish, target_os = "haiku", target_os = "aix", target_os = "hurd"))]
pub fn sync() {
unsafe { libc::sync() };
}
@@ -1386,7 +1386,7 @@
/// descriptor `fd` to disk
///
/// See also [syncfs(2)](https://man7.org/linux/man-pages/man2/sync.2.html)
-#[cfg(linux_android)]
+#[cfg(any(linux_android, target_os = "hurd"))]
pub fn syncfs(fd: RawFd) -> Result<()> {
let res = unsafe { libc::syncfs(fd) };
@@ -1411,13 +1411,27 @@
linux_android,
solarish,
netbsdlike,
+ apple_targets,
target_os = "freebsd",
target_os = "emscripten",
target_os = "fuchsia",
+ target_os = "aix",
+ target_os = "hurd",
))]
#[inline]
pub fn fdatasync(fd: RawFd) -> Result<()> {
- let res = unsafe { libc::fdatasync(fd) };
+ cfg_if! {
+ // apple libc supports fdatasync too, albeit not being present in its headers
+ // [fdatasync](https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/vfs/vfs_syscalls.c#L7728)
+ if #[cfg(apple_targets)] {
+ extern "C" {
+ fn fdatasync(fd: libc::c_int) -> libc::c_int;
+ }
+ } else {
+ use libc::fdatasync as fdatasync;
+ }
+ }
+ let res = unsafe { fdatasync(fd) };
Errno::result(res).map(drop)
}
@@ -2031,6 +2045,19 @@
/// 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,
+ #[cfg(any(
+ apple_targets,
+ solarish,
+ freebsdlike,
+ target_os = "netbsd",
+ ))]
+ /// If a file system supports the reporting of holes (see lseek(2)),
+ /// pathconf() and fpathconf() return a positive number that represents the
+ /// minimum hole size returned in bytes. The offsets of holes returned will
+ /// be aligned to this same value. A special value of 1 is returned if the
+ /// file system does not specify the minimum hole size but still reports
+ /// holes.
+ MIN_HOLE_SIZE = libc::_PC_MIN_HOLE_SIZE,
/// Maximum number of bytes in a filename (not including the terminating
/// null of a filename string).
NAME_MAX = libc::_PC_NAME_MAX,
diff --git a/crates/nix/test/common/mod.rs b/crates/nix/test/common/mod.rs
index db4aed2..ab0e746 100644
--- a/crates/nix/test/common/mod.rs
+++ b/crates/nix/test/common/mod.rs
@@ -37,8 +37,8 @@
#[macro_export]
macro_rules! require_mount {
($name:expr) => {
- use ::sysctl::{CtlValue, Sysctl};
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()
@@ -65,7 +65,7 @@
#[macro_export]
macro_rules! skip_if_jailed {
($name:expr) => {
- use ::sysctl::{CtlValue, Sysctl};
+ use sysctl::{CtlValue, Sysctl};
let ctl = ::sysctl::Ctl::new("security.jail.jailed").unwrap();
if let CtlValue::Int(1) = ctl.value().unwrap() {
diff --git a/crates/nix/test/mount/mod.rs b/crates/nix/test/mount/mod.rs
new file mode 100644
index 0000000..2764b83
--- /dev/null
+++ b/crates/nix/test/mount/mod.rs
@@ -0,0 +1,6 @@
+#[cfg(target_os = "linux")]
+mod test_mount;
+#[cfg(apple_targets)]
+mod test_mount_apple;
+#[cfg(target_os = "freebsd")]
+mod test_nmount;
diff --git a/crates/nix/test/test_mount.rs b/crates/nix/test/mount/test_mount.rs
similarity index 94%
rename from crates/nix/test/test_mount.rs
rename to crates/nix/test/mount/test_mount.rs
index a4f0903..9cb7741 100644
--- a/crates/nix/test/test_mount.rs
+++ b/crates/nix/test/mount/test_mount.rs
@@ -53,6 +53,8 @@
.unwrap_or_else(|e| panic!("read failed: {e}"));
assert_eq!(buf, SCRIPT_CONTENTS);
+ // while forking and unmounting prevent other child processes
+ let _m = FORK_MTX.lock();
// Verify execute.
assert_eq!(
EXPECTED_STATUS,
@@ -129,6 +131,8 @@
&test_path
);
+ // while forking and unmounting prevent other child processes
+ let _m = FORK_MTX.lock();
// EACCES: Permission denied
assert_eq!(
EACCES,
@@ -168,6 +172,8 @@
.and_then(|mut f| f.write(SCRIPT_CONTENTS))
.unwrap_or_else(|e| panic!("write failed: {e}"));
+ // wait for child processes to prevent EBUSY
+ let _m = FORK_MTX.lock();
umount(mount_point.path())
.unwrap_or_else(|e| panic!("umount failed: {e}"));
}
diff --git a/crates/nix/test/mount/test_mount_apple.rs b/crates/nix/test/mount/test_mount_apple.rs
new file mode 100644
index 0000000..f286850
--- /dev/null
+++ b/crates/nix/test/mount/test_mount_apple.rs
@@ -0,0 +1,8 @@
+use nix::errno::Errno;
+use nix::mount::{mount, MntFlags};
+
+#[test]
+fn test_mount() {
+ let res = mount::<str, str, str>("", "", MntFlags::empty(), None);
+ assert_eq!(res, Err(Errno::ENOENT));
+}
diff --git a/crates/nix/test/test_nmount.rs b/crates/nix/test/mount/test_nmount.rs
similarity index 100%
rename from crates/nix/test/test_nmount.rs
rename to crates/nix/test/mount/test_nmount.rs
diff --git a/crates/nix/test/sys/test_aio.rs b/crates/nix/test/sys/test_aio.rs
index ba5ad02..2f4494f 100644
--- a/crates/nix/test/sys/test_aio.rs
+++ b/crates/nix/test/sys/test_aio.rs
@@ -1,7 +1,7 @@
use std::{
io::{Read, Seek, Write},
ops::Deref,
- os::unix::io::AsRawFd,
+ os::unix::io::{AsFd, AsRawFd, BorrowedFd},
pin::Pin,
sync::atomic::{AtomicBool, Ordering},
thread, time,
@@ -45,8 +45,9 @@
#[test]
fn test_accessors() {
+ let f = tempfile().unwrap();
let aiocb = AioFsync::new(
- 1001,
+ f.as_fd(),
AioFsyncMode::O_SYNC,
42,
SigevNotify::SigevSignal {
@@ -54,7 +55,7 @@
si_value: 99,
},
);
- assert_eq!(1001, aiocb.fd());
+ assert_eq!(f.as_raw_fd(), aiocb.fd().as_raw_fd());
assert_eq!(AioFsyncMode::O_SYNC, aiocb.mode());
assert_eq!(42, aiocb.priority());
let sev = aiocb.sigevent().sigevent();
@@ -67,21 +68,17 @@
// Skip on Linux, because Linux's AIO implementation can't detect errors
// synchronously
#[test]
- #[cfg(any(target_os = "freebsd", apple_targets))]
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), ignore)]
fn error() {
use std::mem;
const INITIAL: &[u8] = b"abcdef123456";
// Create an invalid AioFsyncMode
- let mode = unsafe { mem::transmute(666) };
+ let mode = unsafe { mem::transmute::<i32, AioFsyncMode>(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 mut aiof =
+ Box::pin(AioFsync::new(f.as_fd(), mode, 0, SigevNotify::SigevNone));
let err = aiof.as_mut().submit();
err.expect_err("assertion failed");
}
@@ -92,9 +89,8 @@
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,
+ f.as_fd(),
AioFsyncMode::O_SYNC,
0,
SigevNotify::SigevNone,
@@ -110,9 +106,10 @@
#[test]
fn test_accessors() {
+ let f = tempfile().unwrap();
let mut rbuf = vec![0; 4];
let aiocb = AioRead::new(
- 1001,
+ f.as_fd(),
2, //offset
&mut rbuf,
42, //priority
@@ -121,7 +118,7 @@
si_value: 99,
},
);
- assert_eq!(1001, aiocb.fd());
+ assert_eq!(f.as_raw_fd(), aiocb.fd().as_raw_fd());
assert_eq!(4, aiocb.nbytes());
assert_eq!(2, aiocb.offset());
assert_eq!(42, aiocb.priority());
@@ -140,7 +137,7 @@
let mut rbuf = vec![0; 4];
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
- let fd = f.as_raw_fd();
+ let fd = f.as_fd();
let mut aior =
Box::pin(AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone));
aior.as_mut().submit().unwrap();
@@ -164,7 +161,7 @@
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
let mut aior = Box::pin(AioRead::new(
- f.as_raw_fd(),
+ f.as_fd(),
-1, //an invalid offset
&mut rbuf,
0, //priority
@@ -184,7 +181,7 @@
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
{
- let fd = f.as_raw_fd();
+ let fd = f.as_fd();
let mut aior = Box::pin(AioRead::new(
fd,
2,
@@ -211,7 +208,7 @@
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
{
- let fd = f.as_raw_fd();
+ let fd = f.as_fd();
let mut aior =
AioRead::new(fd, 2, &mut rbuf, 0, SigevNotify::SigevNone);
let mut aior = unsafe { Pin::new_unchecked(&mut aior) };
@@ -234,12 +231,13 @@
#[test]
fn test_accessors() {
+ let f = tempfile().unwrap();
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,
+ f.as_fd(),
2, //offset
&mut rbufs,
42, //priority
@@ -248,7 +246,7 @@
si_value: 99,
},
);
- assert_eq!(1001, aiocb.fd());
+ assert_eq!(f.as_raw_fd(), aiocb.fd().as_raw_fd());
assert_eq!(2, aiocb.iovlen());
assert_eq!(2, aiocb.offset());
assert_eq!(42, aiocb.priority());
@@ -270,7 +268,7 @@
let mut f = tempfile().unwrap();
f.write_all(INITIAL).unwrap();
{
- let fd = f.as_raw_fd();
+ let fd = f.as_fd();
let mut aior = Box::pin(AioReadv::new(
fd,
2,
@@ -297,9 +295,10 @@
#[test]
fn test_accessors() {
+ let f = tempfile().unwrap();
let wbuf = vec![0; 4];
let aiocb = AioWrite::new(
- 1001,
+ f.as_fd(),
2, //offset
&wbuf,
42, //priority
@@ -308,7 +307,7 @@
si_value: 99,
},
);
- assert_eq!(1001, aiocb.fd());
+ assert_eq!(f.as_raw_fd(), aiocb.fd().as_raw_fd());
assert_eq!(4, aiocb.nbytes());
assert_eq!(2, aiocb.offset());
assert_eq!(42, aiocb.priority());
@@ -327,7 +326,7 @@
let f = tempfile().unwrap();
let mut aiow = Box::pin(AioWrite::new(
- f.as_raw_fd(),
+ f.as_fd(),
0,
wbuf,
0,
@@ -356,18 +355,20 @@
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 mut aiow = Box::pin(AioWrite::new(
+ f.as_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());
+ 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();
@@ -386,19 +387,21 @@
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 mut aiow = AioWrite::new(
+ f.as_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());
+ 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();
@@ -411,12 +414,14 @@
// Skip on Linux, because Linux's AIO implementation can't detect errors
// synchronously
#[test]
- #[cfg(any(target_os = "freebsd", apple_targets))]
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), ignore)]
fn error() {
+ // Not I/O safe! Deliberately create an invalid fd.
+ let fd = unsafe { BorrowedFd::borrow_raw(666) };
let wbuf = "CDEF".to_string().into_bytes();
let mut aiow = Box::pin(AioWrite::new(
- 666, // An invalid file descriptor
- 0, //offset
+ fd,
+ 0, //offset
&wbuf,
0, //priority
SigevNotify::SigevNone,
@@ -435,11 +440,12 @@
#[test]
fn test_accessors() {
+ let f = tempfile().unwrap();
let wbuf0 = vec![0; 4];
let wbuf1 = vec![0; 8];
let wbufs = [IoSlice::new(&wbuf0), IoSlice::new(&wbuf1)];
let aiocb = AioWritev::new(
- 1001,
+ f.as_fd(),
2, //offset
&wbufs,
42, //priority
@@ -448,7 +454,7 @@
si_value: 99,
},
);
- assert_eq!(1001, aiocb.fd());
+ assert_eq!(f.as_raw_fd(), aiocb.fd().as_raw_fd());
assert_eq!(2, aiocb.iovlen());
assert_eq!(2, aiocb.offset());
assert_eq!(42, aiocb.priority());
@@ -472,18 +478,20 @@
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 mut aiow = Box::pin(AioWritev::new(
+ f.as_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);
+ 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();
@@ -521,22 +529,25 @@
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));
+ {
+ let mut aiow = Box::pin(AioWrite::new(
+ f.as_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());
}
- 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());
@@ -551,7 +562,7 @@
let f = tempfile().unwrap();
let mut aiocb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
+ f.as_fd(),
0, //offset
wbuf,
0, //priority
@@ -561,7 +572,7 @@
let err = aiocb.as_mut().error();
assert!(err == Ok(()) || err == Err(Errno::EINPROGRESS));
- aio_cancel_all(f.as_raw_fd()).unwrap();
+ aio_cancel_all(f.as_fd()).unwrap();
// Wait for aiocb to complete, but don't care whether it succeeded
let _ = poll_aio!(&mut aiocb);
@@ -579,7 +590,7 @@
f.write_all(INITIAL).unwrap();
let mut wcb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
+ f.as_fd(),
2, //offset
WBUF,
0, //priority
@@ -587,7 +598,7 @@
));
let mut rcb = Box::pin(AioRead::new(
- f.as_raw_fd(),
+ f.as_fd(),
8, //offset
&mut rbuf,
0, //priority
@@ -624,21 +635,23 @@
#[test]
fn casting() {
let sev = SigevNotify::SigevNone;
- let aiof = AioFsync::new(666, AioFsyncMode::O_SYNC, 0, sev);
+ // Only safe because we'll never await the futures
+ let fd = unsafe { BorrowedFd::borrow_raw(666) };
+ let aiof = AioFsync::new(fd, 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);
+ let aior = AioRead::new(fd, 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);
+ let aiow = AioWrite::new(fd, 0, &wbuf, 0, sev);
assert_eq!(
aiow.as_ref() as *const libc::aiocb,
&aiow as *const AioWrite as *const libc::aiocb
@@ -654,7 +667,9 @@
let mut rbuf = [];
let mut rbufs = [IoSliceMut::new(&mut rbuf)];
- let aiorv = AioReadv::new(666, 0, &mut rbufs[..], 0, sev);
+ // Only safe because we'll never await the futures
+ let fd = unsafe { BorrowedFd::borrow_raw(666) };
+ let aiorv = AioReadv::new(fd, 0, &mut rbufs[..], 0, sev);
assert_eq!(
aiorv.as_ref() as *const libc::aiocb,
&aiorv as *const AioReadv as *const libc::aiocb
@@ -662,7 +677,7 @@
let wbuf = [];
let wbufs = [IoSlice::new(&wbuf)];
- let aiowv = AioWritev::new(666, 0, &wbufs, 0, sev);
+ let aiowv = AioWritev::new(fd, 0, &wbufs, 0, sev);
assert_eq!(
aiowv.as_ref() as *const libc::aiocb,
&aiowv as *const AioWritev as *const libc::aiocb
diff --git a/crates/nix/test/sys/test_aio_drop.rs b/crates/nix/test/sys/test_aio_drop.rs
index 54106dd..47660cf 100644
--- a/crates/nix/test/sys/test_aio_drop.rs
+++ b/crates/nix/test/sys/test_aio_drop.rs
@@ -16,7 +16,7 @@
fn test_drop() {
use nix::sys::aio::*;
use nix::sys::signal::*;
- use std::os::unix::io::AsRawFd;
+ use std::os::unix::io::AsFd;
use tempfile::tempfile;
const WBUF: &[u8] = b"CDEF";
@@ -24,7 +24,7 @@
let f = tempfile().unwrap();
f.set_len(6).unwrap();
let mut aiocb = Box::pin(AioWrite::new(
- f.as_raw_fd(),
+ f.as_fd(),
2, //offset
WBUF,
0, //priority
diff --git a/crates/nix/test/sys/test_fanotify.rs b/crates/nix/test/sys/test_fanotify.rs
index 20226c2..13ec945 100644
--- a/crates/nix/test/sys/test_fanotify.rs
+++ b/crates/nix/test/sys/test_fanotify.rs
@@ -1,9 +1,10 @@
use crate::*;
+use nix::errno::Errno;
use nix::sys::fanotify::{
EventFFlags, Fanotify, FanotifyResponse, InitFlags, MarkFlags, MaskFlags,
Response,
};
-use std::fs::{read_link, File, OpenOptions};
+use std::fs::{read_link, read_to_string, File, OpenOptions};
use std::io::ErrorKind;
use std::io::{Read, Write};
use std::os::fd::AsRawFd;
@@ -16,6 +17,7 @@
test_fanotify_notifications();
test_fanotify_responses();
+ test_fanotify_overflow();
}
fn test_fanotify_notifications() {
@@ -147,3 +149,71 @@
file_thread.join().unwrap();
}
+
+fn test_fanotify_overflow() {
+ let max_events: usize =
+ read_to_string("/proc/sys/fs/fanotify/max_queued_events")
+ .unwrap()
+ .trim()
+ .parse()
+ .unwrap();
+
+ // make sure the kernel is configured with the default value,
+ // just so this test doesn't run forever
+ assert_eq!(max_events, 16384);
+
+ let group = Fanotify::init(
+ InitFlags::FAN_CLASS_NOTIF
+ | InitFlags::FAN_REPORT_TID
+ | InitFlags::FAN_NONBLOCK,
+ EventFFlags::O_RDONLY,
+ )
+ .unwrap();
+ let tempdir = tempfile::tempdir().unwrap();
+ let tempfile = tempdir.path().join("test");
+
+ OpenOptions::new()
+ .write(true)
+ .create_new(true)
+ .open(&tempfile)
+ .unwrap();
+
+ group
+ .mark(
+ MarkFlags::FAN_MARK_ADD,
+ MaskFlags::FAN_OPEN,
+ None,
+ Some(&tempfile),
+ )
+ .unwrap();
+
+ thread::scope(|s| {
+ // perform 10 more events to demonstrate some will be dropped
+ for _ in 0..(max_events + 10) {
+ s.spawn(|| {
+ File::open(&tempfile).unwrap();
+ });
+ }
+ });
+
+ // flush the queue until it's empty
+ let mut n = 0;
+ let mut last_event = None;
+ loop {
+ match group.read_events() {
+ Ok(events) => {
+ n += events.len();
+ if let Some(event) = events.last() {
+ last_event = Some(event.mask());
+ }
+ }
+ Err(e) if e == Errno::EWOULDBLOCK => break,
+ Err(e) => panic!("{e:?}"),
+ }
+ }
+
+ // make sure we read all we expected.
+ // the +1 is for the overflow event.
+ assert_eq!(n, max_events + 1);
+ assert_eq!(last_event, Some(MaskFlags::FAN_Q_OVERFLOW));
+}
diff --git a/crates/nix/test/sys/test_prctl.rs b/crates/nix/test/sys/test_prctl.rs
index 351213b..b409735 100644
--- a/crates/nix/test/sys/test_prctl.rs
+++ b/crates/nix/test/sys/test_prctl.rs
@@ -122,4 +122,38 @@
prctl::set_thp_disable(original).unwrap();
}
+
+ #[test]
+ fn test_set_vma_anon_name() {
+ use nix::errno::Errno;
+ use nix::sys::mman;
+ use std::num::NonZeroUsize;
+
+ const ONE_K: libc::size_t = 1024;
+ let sz = NonZeroUsize::new(ONE_K).unwrap();
+ let ptr = unsafe {
+ mman::mmap_anonymous(
+ None,
+ sz,
+ mman::ProtFlags::PROT_READ,
+ mman::MapFlags::MAP_SHARED,
+ )
+ .unwrap()
+ };
+ let err = prctl::set_vma_anon_name(
+ ptr,
+ sz,
+ Some(CStr::from_bytes_with_nul(b"[,$\0").unwrap()),
+ )
+ .unwrap_err();
+ assert_eq!(err, Errno::EINVAL);
+ // `CONFIG_ANON_VMA_NAME` kernel config might not be set
+ prctl::set_vma_anon_name(
+ ptr,
+ sz,
+ Some(CStr::from_bytes_with_nul(b"Nix\0").unwrap()),
+ )
+ .unwrap_or_default();
+ prctl::set_vma_anon_name(ptr, sz, None).unwrap_or_default();
+ }
}
diff --git a/crates/nix/test/sys/test_ptrace.rs b/crates/nix/test/sys/test_ptrace.rs
index 246b354..c99c676 100644
--- a/crates/nix/test/sys/test_ptrace.rs
+++ b/crates/nix/test/sys/test_ptrace.rs
@@ -1,7 +1,7 @@
#[cfg(all(
target_os = "linux",
- any(target_arch = "x86_64", target_arch = "x86"),
- target_env = "gnu"
+ target_env = "gnu",
+ any(target_arch = "x86_64", target_arch = "x86")
))]
use memoffset::offset_of;
use nix::errno::Errno;
@@ -179,8 +179,13 @@
// 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"
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
))]
#[test]
fn test_ptrace_syscall() {
@@ -226,12 +231,21 @@
let get_syscall_id =
|| ptrace::getregs(child).unwrap().orig_eax as libc::c_long;
+ #[cfg(target_arch = "aarch64")]
+ let get_syscall_id =
+ || ptrace::getregs(child).unwrap().regs[8] as libc::c_long;
+
+ #[cfg(target_arch = "riscv64")]
+ let get_syscall_id =
+ || ptrace::getregs(child).unwrap().a7 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);
+ #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
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;
@@ -246,6 +260,7 @@
Ok(WaitStatus::PtraceSyscall(child))
);
assert_eq!(get_syscall_id(), ::libc::SYS_kill);
+ #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill);
// kill exit
@@ -255,6 +270,7 @@
Ok(WaitStatus::PtraceSyscall(child))
);
assert_eq!(get_syscall_id(), ::libc::SYS_kill);
+ #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
assert_eq!(get_syscall_from_user_area(), ::libc::SYS_kill);
// receive signal
@@ -273,3 +289,85 @@
}
}
}
+
+#[cfg(all(
+ target_os = "linux",
+ target_env = "gnu",
+ any(
+ target_arch = "x86_64",
+ target_arch = "x86",
+ target_arch = "aarch64",
+ target_arch = "riscv64",
+ )
+))]
+#[test]
+fn test_ptrace_regsets() {
+ use nix::sys::ptrace::{self, getregset, regset, setregset};
+ use nix::sys::signal::*;
+ use nix::sys::wait::{waitpid, WaitStatus};
+ use nix::unistd::fork;
+ use nix::unistd::ForkResult::*;
+
+ require_capability!("test_ptrace_regsets", CAP_SYS_PTRACE);
+
+ let _m = crate::FORK_MTX.lock();
+
+ 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))
+ );
+ let mut regstruct =
+ getregset::<regset::NT_PRSTATUS>(child).unwrap();
+ let mut fpregstruct =
+ getregset::<regset::NT_PRFPREG>(child).unwrap();
+
+ #[cfg(target_arch = "x86_64")]
+ let (reg, fpreg) =
+ (&mut regstruct.r15, &mut fpregstruct.st_space[5]);
+ #[cfg(target_arch = "x86")]
+ let (reg, fpreg) =
+ (&mut regstruct.edx, &mut fpregstruct.st_space[5]);
+ #[cfg(target_arch = "aarch64")]
+ let (reg, fpreg) =
+ (&mut regstruct.regs[16], &mut fpregstruct.vregs[5]);
+ #[cfg(target_arch = "riscv64")]
+ let (reg, fpreg) = (&mut regstruct.t1, &mut fpregstruct.__f[5]);
+
+ *reg = 0xdeadbeefu32 as _;
+ *fpreg = 0xfeedfaceu32 as _;
+ let _ = setregset::<regset::NT_PRSTATUS>(child, regstruct);
+ regstruct = getregset::<regset::NT_PRSTATUS>(child).unwrap();
+ let _ = setregset::<regset::NT_PRFPREG>(child, fpregstruct);
+ fpregstruct = getregset::<regset::NT_PRFPREG>(child).unwrap();
+
+ #[cfg(target_arch = "x86_64")]
+ let (reg, fpreg) = (regstruct.r15, fpregstruct.st_space[5]);
+ #[cfg(target_arch = "x86")]
+ let (reg, fpreg) = (regstruct.edx, fpregstruct.st_space[5]);
+ #[cfg(target_arch = "aarch64")]
+ let (reg, fpreg) = (regstruct.regs[16], fpregstruct.vregs[5]);
+ #[cfg(target_arch = "riscv64")]
+ let (reg, fpreg) = (regstruct.t1, fpregstruct.__f[5]);
+ assert_eq!(reg, 0xdeadbeefu32 as _);
+ assert_eq!(fpreg, 0xfeedfaceu32 as _);
+
+ ptrace::cont(child, Some(Signal::SIGKILL)).unwrap();
+ match waitpid(child, None) {
+ Ok(WaitStatus::Signaled(pid, Signal::SIGKILL, _))
+ if pid == child => {}
+ _ => panic!("The process should have been killed"),
+ }
+ }
+ }
+}
diff --git a/crates/nix/test/sys/test_signal.rs b/crates/nix/test/sys/test_signal.rs
index bf60749..cd4bc3d 100644
--- a/crates/nix/test/sys/test_signal.rs
+++ b/crates/nix/test/sys/test_signal.rs
@@ -283,6 +283,7 @@
#[test]
#[cfg(not(target_os = "redox"))]
fn test_sigaction() {
+ let _m = crate::SIGNAL_MTX.lock();
thread::spawn(|| {
extern "C" fn test_sigaction_handler(_: libc::c_int) {}
extern "C" fn test_sigaction_action(
@@ -349,7 +350,7 @@
target_os = "haiku",
target_os = "hurd",
target_os = "aix",
- target_os = "fushsia"
+ target_os = "fuchsia"
))]
#[test]
fn test_sigsuspend() {
diff --git a/crates/nix/test/sys/test_signalfd.rs b/crates/nix/test/sys/test_signalfd.rs
index 4e0971a..d315848 100644
--- a/crates/nix/test/sys/test_signalfd.rs
+++ b/crates/nix/test/sys/test_signalfd.rs
@@ -28,7 +28,7 @@
};
let mask = SigSet::empty();
- let mut fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
+ let fd = SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK).unwrap();
let res = fd.read_signal();
assert!(res.unwrap().is_none());
@@ -47,7 +47,7 @@
mask.add(signal::SIGUSR1);
mask.thread_block().unwrap();
- let mut fd = SignalFd::new(&mask).unwrap();
+ let 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
@@ -72,7 +72,7 @@
// Block the SIGUSR1 signal from automatic processing for this thread
let mut mask = SigSet::empty();
- let mut fd = SignalFd::new(&mask).unwrap();
+ let fd = SignalFd::new(&mask).unwrap();
mask.add(signal::SIGUSR1);
mask.thread_block().unwrap();
diff --git a/crates/nix/test/sys/test_socket.rs b/crates/nix/test/sys/test_socket.rs
index 90b8a6f..79c97c8 100644
--- a/crates/nix/test/sys/test_socket.rs
+++ b/crates/nix/test/sys/test_socket.rs
@@ -55,7 +55,7 @@
.unwrap();
let mut ts = None;
- for c in recv.cmsgs() {
+ for c in recv.cmsgs().unwrap() {
if let ControlMessageOwned::ScmTimestampsns(timestamps) = c {
ts = Some(timestamps.system);
}
@@ -117,7 +117,7 @@
.unwrap();
let mut ts = None;
- for c in recv.cmsgs() {
+ for c in recv.cmsgs().unwrap() {
if let ControlMessageOwned::ScmRealtime(timeval) = c {
ts = Some(timeval);
}
@@ -179,7 +179,7 @@
.unwrap();
let mut ts = None;
- for c in recv.cmsgs() {
+ for c in recv.cmsgs().unwrap() {
if let ControlMessageOwned::ScmMonotonic(timeval) = c {
ts = Some(timeval);
}
@@ -889,7 +889,7 @@
)
.unwrap();
- for cmsg in msg.cmsgs() {
+ for cmsg in msg.cmsgs().unwrap() {
if let ControlMessageOwned::ScmRights(fd) = cmsg {
assert_eq!(received_r, None);
assert_eq!(fd.len(), 1);
@@ -1330,7 +1330,7 @@
.flags
.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- let mut cmsgs = msg.cmsgs();
+ let mut cmsgs = msg.cmsgs().unwrap();
match cmsgs.next() {
Some(ControlMessageOwned::ScmRights(fds)) => {
assert_eq!(
@@ -1399,7 +1399,7 @@
)
.unwrap();
- if msg.cmsgs().next().is_some() {
+ if msg.cmsgs().unwrap().next().is_some() {
panic!("unexpected cmsg");
}
assert!(!msg
@@ -1466,7 +1466,7 @@
.unwrap();
let mut received_cred = None;
- for cmsg in msg.cmsgs() {
+ for cmsg in msg.cmsgs().unwrap() {
let cred = match cmsg {
#[cfg(linux_android)]
ControlMessageOwned::ScmCredentials(cred) => cred,
@@ -1497,7 +1497,7 @@
#[test]
fn test_scm_credentials_and_rights() {
let space = cmsg_space!(libc::ucred, RawFd);
- test_impl_scm_credentials_and_rights(space);
+ test_impl_scm_credentials_and_rights(space).unwrap();
}
/// Ensure that passing a an oversized control message buffer to recvmsg
@@ -1509,11 +1509,23 @@
#[test]
fn test_too_large_cmsgspace() {
let space = vec![0u8; 1024];
- test_impl_scm_credentials_and_rights(space);
+ test_impl_scm_credentials_and_rights(space).unwrap();
}
#[cfg(linux_android)]
-fn test_impl_scm_credentials_and_rights(mut space: Vec<u8>) {
+#[test]
+fn test_too_small_cmsgspace() {
+ let space = vec![0u8; 4];
+ assert_eq!(
+ test_impl_scm_credentials_and_rights(space),
+ Err(nix::errno::Errno::ENOBUFS)
+ );
+}
+
+#[cfg(linux_android)]
+fn test_impl_scm_credentials_and_rights(
+ mut space: Vec<u8>,
+) -> Result<(), nix::errno::Errno> {
use libc::ucred;
use nix::sys::socket::sockopt::PassCred;
use nix::sys::socket::{
@@ -1573,9 +1585,9 @@
.unwrap();
let mut received_cred = None;
- assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
+ assert_eq!(msg.cmsgs()?.count(), 2, "expected 2 cmsgs");
- for cmsg in msg.cmsgs() {
+ for cmsg in msg.cmsgs()? {
match cmsg {
ControlMessageOwned::ScmRights(fds) => {
assert_eq!(received_r, None, "already received fd");
@@ -1606,6 +1618,8 @@
read(received_r.as_raw_fd(), &mut buf).unwrap();
assert_eq!(&buf[..], b"world");
close(received_r).unwrap();
+
+ Ok(())
}
// Test creating and using named unix domain sockets
@@ -1837,7 +1851,7 @@
.flags
.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- let mut cmsgs = msg.cmsgs();
+ let mut cmsgs = msg.cmsgs().unwrap();
if let Some(ControlMessageOwned::Ipv4PacketInfo(pktinfo)) = cmsgs.next()
{
let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
@@ -1929,11 +1943,11 @@
assert!(!msg
.flags
.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 2, "expected 2 cmsgs");
+ assert_eq!(msg.cmsgs().unwrap().count(), 2, "expected 2 cmsgs");
let mut rx_recvif = false;
let mut rx_recvdstaddr = false;
- for cmsg in msg.cmsgs() {
+ for cmsg in msg.cmsgs().unwrap() {
match cmsg {
ControlMessageOwned::Ipv4RecvIf(dl) => {
rx_recvif = true;
@@ -2027,10 +2041,10 @@
assert!(!msg
.flags
.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs");
+ assert_eq!(msg.cmsgs().unwrap().count(), 1, "expected 1 cmsgs");
let mut rx_recvorigdstaddr = false;
- for cmsg in msg.cmsgs() {
+ for cmsg in msg.cmsgs().unwrap() {
match cmsg {
ControlMessageOwned::Ipv4OrigDstAddr(addr) => {
rx_recvorigdstaddr = true;
@@ -2113,10 +2127,10 @@
assert!(!msg
.flags
.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- assert_eq!(msg.cmsgs().count(), 1, "expected 1 cmsgs");
+ assert_eq!(msg.cmsgs().unwrap().count(), 1, "expected 1 cmsgs");
let mut rx_recvorigdstaddr = false;
- for cmsg in msg.cmsgs() {
+ for cmsg in msg.cmsgs().unwrap() {
match cmsg {
ControlMessageOwned::Ipv6OrigDstAddr(addr) => {
rx_recvorigdstaddr = true;
@@ -2214,7 +2228,7 @@
.flags
.intersects(MsgFlags::MSG_TRUNC | MsgFlags::MSG_CTRUNC));
- let mut cmsgs = msg.cmsgs();
+ let mut cmsgs = msg.cmsgs().unwrap();
if let Some(ControlMessageOwned::Ipv6PacketInfo(pktinfo)) = cmsgs.next()
{
let i = if_nametoindex(lo_name.as_bytes()).expect("if_nametoindex");
@@ -2357,7 +2371,7 @@
flags,
)
.unwrap();
- let rtime = match r.cmsgs().next() {
+ let rtime = match r.cmsgs().unwrap().next() {
Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
Some(_) => panic!("Unexpected control message"),
None => panic!("No control message"),
@@ -2407,7 +2421,7 @@
// Receive the message
let mut buffer = vec![0u8; message.len()];
let cmsgspace = nix::cmsg_space!(TimeSpec);
- let mut iov = vec![[IoSliceMut::new(&mut buffer)]];
+ let mut iov = [[IoSliceMut::new(&mut buffer)]];
let mut data = MultiHeaders::preallocate(1, Some(cmsgspace));
let r: Vec<RecvMsg<()>> = recvmmsg(
in_socket.as_raw_fd(),
@@ -2418,7 +2432,7 @@
)
.unwrap()
.collect();
- let rtime = match r[0].cmsgs().next() {
+ let rtime = match r[0].cmsgs().unwrap().next() {
Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
Some(_) => panic!("Unexpected control message"),
None => panic!("No control message"),
@@ -2508,7 +2522,7 @@
MsgFlags::MSG_DONTWAIT,
) {
Ok(r) => {
- drop_counter = match r.cmsgs().next() {
+ drop_counter = match r.cmsgs().unwrap().next() {
Some(ControlMessageOwned::RxqOvfl(drop_counter)) => {
drop_counter
}
@@ -2687,7 +2701,7 @@
assert_eq!(msg.address, Some(sock_addr));
// Check for expected control message.
- let ext_err = match msg.cmsgs().next() {
+ let ext_err = match msg.cmsgs().unwrap().next() {
Some(cmsg) => testf(&cmsg),
None => panic!("No control message"),
};
@@ -2878,7 +2892,7 @@
#[cfg(not(any(qemu, target_arch = "aarch64")))]
let mut saw_time = false;
let mut recvd = 0;
- for cmsg in rmsg.cmsgs() {
+ for cmsg in rmsg.cmsgs().unwrap() {
if let ControlMessageOwned::ScmTimestampsns(timestamps) = cmsg {
let ts = timestamps.system;
diff --git a/crates/nix/test/sys/test_sockopt.rs b/crates/nix/test/sys/test_sockopt.rs
index a99d4e3..1da3f6a 100644
--- a/crates/nix/test/sys/test_sockopt.rs
+++ b/crates/nix/test/sys/test_sockopt.rs
@@ -828,3 +828,52 @@
Err(err) => panic!("{err:?}"),
}
}
+
+#[test]
+#[cfg(apple_targets)]
+fn test_utun_ifname() {
+ skip_if_not_root!("test_utun_ifname");
+
+ use nix::sys::socket::connect;
+ use nix::sys::socket::SysControlAddr;
+
+ let fd = socket(
+ AddressFamily::System,
+ SockType::Datagram,
+ SockFlag::empty(),
+ SockProtocol::KextControl,
+ )
+ .unwrap();
+
+ let unit = 123;
+ let addr = SysControlAddr::from_name(
+ fd.as_raw_fd(),
+ "com.apple.net.utun_control",
+ unit,
+ )
+ .unwrap();
+
+ connect(fd.as_raw_fd(), &addr).unwrap();
+
+ let name = getsockopt(&fd, sockopt::UtunIfname)
+ .expect("getting UTUN_OPT_IFNAME on a utun interface should succeed");
+
+ let expected_name = format!("utun{}", unit - 1);
+ assert_eq!(name.into_string(), Ok(expected_name));
+}
+
+#[test]
+#[cfg(target_os = "freebsd")]
+fn test_reuseport_lb() {
+ let fd = socket(
+ AddressFamily::Inet6,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None,
+ )
+ .unwrap();
+ setsockopt(&fd, sockopt::ReusePortLb, &false).unwrap();
+ assert!(!getsockopt(&fd, sockopt::ReusePortLb).unwrap());
+ setsockopt(&fd, sockopt::ReusePortLb, &true).unwrap();
+ assert!(getsockopt(&fd, sockopt::ReusePortLb).unwrap());
+}
diff --git a/crates/nix/test/sys/test_statfs.rs b/crates/nix/test/sys/test_statfs.rs
index 66b3f2c..ca7934e 100644
--- a/crates/nix/test/sys/test_statfs.rs
+++ b/crates/nix/test/sys/test_statfs.rs
@@ -44,7 +44,6 @@
// 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);
}
diff --git a/crates/nix/test/test.rs b/crates/nix/test/test.rs
index c723142..7401c95 100644
--- a/crates/nix/test/test.rs
+++ b/crates/nix/test/test.rs
@@ -3,7 +3,9 @@
#[cfg_attr(not(any(target_os = "redox", target_os = "haiku")), macro_use)]
extern crate nix;
+#[macro_use]
mod common;
+mod mount;
mod sys;
#[cfg(not(target_os = "redox"))]
mod test_dir;
@@ -11,20 +13,11 @@
mod test_fcntl;
#[cfg(linux_android)]
mod test_kmod;
-#[cfg(target_os = "linux")]
-mod test_mount;
-#[cfg(any(
- freebsdlike,
- target_os = "fushsia",
- target_os = "linux",
- target_os = "netbsd"
-))]
+#[cfg(any(freebsdlike, 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",
@@ -59,9 +52,10 @@
}
}
-/// Any test that creates child processes must grab this mutex, regardless
-/// of what it does with those children.
-pub static FORK_MTX: std::sync::Mutex<()> = std::sync::Mutex::new(());
+/// Any test that creates child processes or can be affected by child processes must grab this mutex, regardless
+/// of what it does with those children. It must hold the mutex until the
+/// child processes are waited upon.
+pub static FORK_MTX: Mutex<()> = Mutex::new(());
/// 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.
diff --git a/crates/nix/test/test_fcntl.rs b/crates/nix/test/test_fcntl.rs
index 6572e8a..5d32076 100644
--- a/crates/nix/test/test_fcntl.rs
+++ b/crates/nix/test/test_fcntl.rs
@@ -4,12 +4,15 @@
use nix::fcntl::{open, readlink, OFlag};
#[cfg(not(target_os = "redox"))]
use nix::fcntl::{openat, readlinkat, renameat};
+
+#[cfg(target_os = "linux")]
+use nix::fcntl::{openat2, OpenHow, ResolveFlag};
+
#[cfg(all(
target_os = "linux",
target_env = "gnu",
any(
target_arch = "x86_64",
- target_arch = "x32",
target_arch = "powerpc",
target_arch = "s390x"
)
@@ -58,6 +61,64 @@
}
#[test]
+#[cfg(target_os = "linux")]
+// 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_openat2() {
+ 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 = openat2(
+ dirfd,
+ tmp.path().file_name().unwrap(),
+ OpenHow::new()
+ .flags(OFlag::O_RDONLY)
+ .mode(Mode::empty())
+ .resolve(ResolveFlag::RESOLVE_BENEATH),
+ )
+ .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(target_os = "linux")]
+// 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_openat2_forbidden() {
+ let mut tmp = NamedTempFile::new().unwrap();
+ tmp.write_all(b"let me out").unwrap();
+
+ let dirfd =
+ open(tmp.path().parent().unwrap(), OFlag::empty(), Mode::empty())
+ .unwrap();
+
+ let escape_attempt =
+ tmp.path().parent().unwrap().join("../../../hello.txt");
+
+ let res = openat2(
+ dirfd,
+ &escape_attempt,
+ OpenHow::new()
+ .flags(OFlag::O_RDONLY)
+ .resolve(ResolveFlag::RESOLVE_BENEATH),
+ );
+ assert_eq!(Err(Errno::EXDEV), res);
+}
+
+#[test]
#[cfg(not(target_os = "redox"))]
fn test_renameat() {
let old_dir = tempfile::tempdir().unwrap();
@@ -84,7 +145,6 @@
target_env = "gnu",
any(
target_arch = "x86_64",
- target_arch = "x32",
target_arch = "powerpc",
target_arch = "s390x"
)
@@ -128,7 +188,6 @@
target_env = "gnu",
any(
target_arch = "x86_64",
- target_arch = "x32",
target_arch = "powerpc",
target_arch = "s390x"
)
@@ -176,7 +235,6 @@
target_env = "gnu",
any(
target_arch = "x86_64",
- target_arch = "x32",
target_arch = "powerpc",
target_arch = "s390x"
)
@@ -295,15 +353,9 @@
let (rd, wr) = pipe().unwrap();
let mut offset: loff_t = 5;
- let res = splice(
- tmp.as_raw_fd(),
- Some(&mut offset),
- wr.as_raw_fd(),
- None,
- 2,
- SpliceFFlags::empty(),
- )
- .unwrap();
+ let res =
+ splice(tmp, Some(&mut offset), wr, None, 2, SpliceFFlags::empty())
+ .unwrap();
assert_eq!(2, res);
@@ -319,9 +371,8 @@
let (rd2, wr2) = pipe().unwrap();
write(wr1, b"abc").unwrap();
- let res =
- tee(rd1.as_raw_fd(), wr2.as_raw_fd(), 2, SpliceFFlags::empty())
- .unwrap();
+ let res = tee(rd1.try_clone().unwrap(), wr2, 2, SpliceFFlags::empty())
+ .unwrap();
assert_eq!(2, res);
@@ -344,8 +395,7 @@
let buf2 = b"defghi";
let iovecs = [IoSlice::new(&buf1[0..3]), IoSlice::new(&buf2[0..3])];
- let res = vmsplice(wr.as_raw_fd(), &iovecs[..], SpliceFFlags::empty())
- .unwrap();
+ let res = vmsplice(wr, &iovecs[..], SpliceFFlags::empty()).unwrap();
assert_eq!(6, res);
@@ -636,7 +686,7 @@
/// Verify that `Flock::lock()` correctly obtains a lock, and subsequently unlocks upon drop.
#[test]
- fn verify_lock_and_drop() {
+ fn lock_and_drop() {
// Get 2 `File` handles to same underlying file.
let file1 = NamedTempFile::new().unwrap();
let file2 = file1.reopen().unwrap();
@@ -660,9 +710,32 @@
}
}
+ /// An exclusive lock can be downgraded
+ #[test]
+ fn downgrade() {
+ let file1 = NamedTempFile::new().unwrap();
+ let file2 = file1.reopen().unwrap();
+ let file1 = file1.into_file();
+
+ // Lock first handle
+ let lock1 = Flock::lock(file1, FlockArg::LockExclusive).unwrap();
+
+ // Attempt to lock second handle
+ let file2 = Flock::lock(file2, FlockArg::LockSharedNonblock)
+ .unwrap_err()
+ .0;
+
+ // Downgrade the lock
+ lock1.relock(FlockArg::LockShared).unwrap();
+
+ // Attempt to lock second handle again (but successfully)
+ Flock::lock(file2, FlockArg::LockSharedNonblock)
+ .expect("Expected locking to be successful.");
+ }
+
/// Verify that `Flock::unlock()` correctly obtains unlocks.
#[test]
- fn verify_unlock() {
+ fn unlock() {
// Get 2 `File` handles to same underlying file.
let file1 = NamedTempFile::new().unwrap();
let file2 = file1.reopen().unwrap();
@@ -679,4 +752,29 @@
panic!("Expected locking to be successful.");
}
}
+
+ /// A shared lock can be upgraded
+ #[test]
+ fn upgrade() {
+ let file1 = NamedTempFile::new().unwrap();
+ let file2 = file1.reopen().unwrap();
+ let file3 = file1.reopen().unwrap();
+ let file1 = file1.into_file();
+
+ // Lock first handle
+ let lock1 = Flock::lock(file1, FlockArg::LockShared).unwrap();
+
+ // Attempt to lock second handle
+ {
+ Flock::lock(file2, FlockArg::LockSharedNonblock)
+ .expect("Locking should've succeeded");
+ }
+
+ // Upgrade the lock
+ lock1.relock(FlockArg::LockExclusive).unwrap();
+
+ // Acquiring an additional shared lock should fail
+ Flock::lock(file3, FlockArg::LockSharedNonblock)
+ .expect_err("Should not have been able to lock the file");
+ }
}
diff --git a/crates/nix/test/test_net.rs b/crates/nix/test/test_net.rs
index faba850..46a3efd 100644
--- a/crates/nix/test/test_net.rs
+++ b/crates/nix/test/test_net.rs
@@ -13,3 +13,14 @@
fn test_if_nametoindex() {
if_nametoindex(LOOPBACK).expect("assertion failed");
}
+
+#[test]
+fn test_if_indextoname() {
+ let loopback_index = if_nametoindex(LOOPBACK).expect("assertion failed");
+ assert_eq!(
+ if_indextoname(loopback_index)
+ .expect("assertion failed")
+ .as_bytes(),
+ LOOPBACK
+ );
+}
diff --git a/crates/nix/test/test_pty.rs b/crates/nix/test/test_pty.rs
index 368ec12..bc618e0 100644
--- a/crates/nix/test/test_pty.rs
+++ b/crates/nix/test/test_pty.rs
@@ -8,6 +8,7 @@
use nix::pty::*;
use nix::sys::stat;
use nix::sys::termios::*;
+use nix::sys::wait::WaitStatus;
use nix::unistd::{pause, write};
/// Test equivalence of `ptsname` and `ptsname_r`
@@ -16,9 +17,10 @@
fn test_ptsname_equivalence() {
let _m = crate::PTSNAME_MTX.lock();
- // Open a new PTTY master
+ // Open a new PTY master
let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
assert!(master_fd.as_raw_fd() > 0);
+ assert!(master_fd.as_fd().as_raw_fd() == master_fd.as_raw_fd());
// Get the name of the slave
let slave_name = unsafe { ptsname(&master_fd) }.unwrap();
@@ -247,7 +249,6 @@
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
@@ -255,21 +256,22 @@
let string = "naninani\n";
let echoed_string = "naninani\r\n";
- let pty = unsafe { forkpty(None, None).unwrap() };
- match pty.fork_result {
- Child => {
+ let res = unsafe { forkpty(None, None).unwrap() };
+ match res {
+ ForkptyResult::Child => {
write(stdout(), string.as_bytes()).unwrap();
pause(); // we need the child to stay alive until the parent calls read
unsafe {
_exit(0);
}
}
- Parent { child } => {
+ ForkptyResult::Parent { child, master } => {
let mut buf = [0u8; 10];
assert!(child.as_raw() > 0);
- crate::read_exact(&pty.master, &mut buf);
+ crate::read_exact(&master, &mut buf);
kill(child, SIGTERM).unwrap();
- wait().unwrap(); // keep other tests using generic wait from getting our child
+ let status = wait().unwrap(); // keep other tests using generic wait from getting our child
+ assert_eq!(status, WaitStatus::Signaled(child, SIGTERM, false));
assert_eq!(&buf, echoed_string.as_bytes());
}
}
diff --git a/crates/nix/test/test_unistd.rs b/crates/nix/test/test_unistd.rs
index aa2e5e5..6ccf59f 100644
--- a/crates/nix/test/test_unistd.rs
+++ b/crates/nix/test/test_unistd.rs
@@ -313,12 +313,15 @@
// 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();
+ let mut group_list = getgrouplist(&user, group).unwrap();
assert!(group_list.contains(&group));
initgroups(&user, group).unwrap();
- let new_groups = getgroups().unwrap();
+ let mut new_groups = getgroups().unwrap();
+
+ new_groups.sort_by_key(|gid| gid.as_raw());
+ group_list.sort_by_key(|gid| gid.as_raw());
assert_eq!(new_groups, group_list);
// Revert back to the old groups
diff --git a/pseudo_crate/Cargo.lock b/pseudo_crate/Cargo.lock
index 11a543d..a5ad1ee 100644
--- a/pseudo_crate/Cargo.lock
+++ b/pseudo_crate/Cargo.lock
@@ -327,7 +327,7 @@
"mockall_derive",
"moveit",
"named-lock",
- "nix 0.28.0",
+ "nix 0.29.0",
"no-panic",
"nom",
"num-bigint",
diff --git a/pseudo_crate/Cargo.toml b/pseudo_crate/Cargo.toml
index e9af4eb..52dc8fe 100644
--- a/pseudo_crate/Cargo.toml
+++ b/pseudo_crate/Cargo.toml
@@ -237,7 +237,7 @@
mockall_derive = "=0.13.1"
moveit = "=0.6.0"
named-lock = "=0.3.0"
-nix = "=0.28.0"
+nix = "=0.29.0"
no-panic = "=0.1.33"
nom = "=7.1.3"
num-bigint = "=0.4.6"