X-Git-Url: https://git.chrismorgan.info/symlink/blobdiff_plain/14c59628c8907cc6d603d2c4649e25b4f98539ac..HEAD:/README.md diff --git a/README.md b/README.md index 69c2e61..c7a4f86 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,13 @@ Rust’s standard library exposes platform-specific ways to create symlinks: - On Windows, `std::os::windows::fs::{symlink_file, symlink_dir}` (because Windows does file and directory symlinks differently); -- On Unixy platforms and Redox, `std::os::unix::fs::symlink` (because they don’t care about whether it’s a file or a directory). +- On Unix platforms, `std::os::unix::fs::symlink` (because they don’t care about whether it’s a file or a directory). -The situation is similar when removing symlinks: on Unixy platforms all symlinks are files and must be removed with `std::fs::remove_file`, but on Windows directory symlinks must be removed with `std::fs::remove_dir` instead. +There’s also `std::fs::soft_link`, deprecated because of the whole Windows situation, but potentially still useful: as I write, at the start of 2022, it’s the only stable way to create a symlink on the wasm32-wasi target (`std::os::wasi::fs::symlink_path` not yet being stable). -This is all a pain: as soon as you touch symlinks for Unix you need to add in lots of `#[cfg]` branches and other such messy things, or else lose Windows support for no good reason. +The situation is similar when removing symlinks: on most platforms all symlinks are files and must be removed with `std::fs::remove_file`, but on Windows directory symlinks must be removed with `std::fs::remove_dir` instead. + +This is all a pain: as soon as you touch symlinks for Unix you need to add in lots of `#[cfg]` branches and other such messy things, or else lose Windows support for no good reason, or use a deprecated function that makes directory symlinks not work on Windows. Enter the `symlink` crate. This crate gives you six cross-platform functions instead: @@ -21,11 +23,9 @@ Enter the `symlink` crate. This crate gives you six cross-platform functions ins - `remove_symlink_dir`, which removes a directory symlink on Windows and a perfectly ordinary symlink on other platforms; - `remove_symlink_auto`, which removes a file or directory symlink on Windows, depending on an examination of the path, and a perfectly ordinary symlink on other platforms. -“What about `std::fs::soft_link`?” I hear you say. Yeah, that one got deprecated in Rust 1.1.0 because it didn’t do anything clever on Windows, it just created a file symlink, which is often wrong. `symlink_auto` creates a file *or* directory symlink, depending on what the target is. (Unlike `symlink_file` and `symlink_dir`, it returns an error if the destination doesn’t exist or can’t be statted.) - -And there’s no good way to delete a symlink at all. +Back on the topic of `std::fs::soft_link`: it got deprecated in Rust 1.1.0 because it just created a file symlink on Windows, which is often wrong. `symlink_auto` creates a file *or* directory symlink, depending on what the target is. (But it’s also more fragile: unlike `symlink_file` and `symlink_dir`, it returns an error if the destination doesn’t exist or can’t be statted.) -So that’s why this crate exists. +And before this crate there was no good way to delete a symlink at all on Windows. Who knows, perhaps windows_file_type_ext will be stabilised eventually. But until then, there’s this crate. ## Best practices @@ -33,11 +33,11 @@ You should generally avoid `symlink_auto` and `remove_symlink_auto`, preferring **Make sure you use absolute paths for the destination.** I haven’t tested whether relative paths are treated consistently across platforms yet (whether they’re relative to the working directory or the symlink source path). TODO! -## Caution: this isn’t as useful as it looks +## Caution: symlinks are still less reliable on Windows -So now you can create or delete symlinks, right? Not so fast. Although Windows supports symlinks from Windows Vista onwards, it was viewed as a security or compatibility or something risk, and so prior to the Windows 10 Creators Update (due by mid-2017; currently available through the Windows Insider Program) it requires a special privilege, which basically means you’ve got to run a program as admin for it to be allowed to manipulate symlinks. +You can only reliably use symlinks from the Windows 10 Creators Update (mid-2017) onwards. -Also [Rust PR #38921](https://github.com/rust-lang/rust/pull/38921) needs to land before unprivileged symlink creation will work on the Windows 10 Creators Update. So we’re talking Rust 1.16 as the earliest. +Before that, manipulating symlinks required a special privilege which practically meant you had to run a program as admin to get it to work. And symlinks were new to Vista; XP and older didn’t support them. ## My goal: integration with Rust @@ -61,20 +61,30 @@ Note that despite the suggestions matching certain approaches for `symlink_auto` **Concerning `remove_*`**: I guess what’s done with the other three functions will guide what’s done with these three. -## Usage - -Cargo all the way: it’s the [`symlink` crate on crates.io](http://crates.io/crates/symlink). - ## Unsafe code in this library -On Windows only there is some unavoidable unsafe code in `remove_symlink_auto` to determine whether a symlink is a file symlink or a directory symlink, because this detail is not exposed in the standard library. +On Windows only there is some unavoidable unsafe code in `remove_symlink_auto` to determine whether a symlink is a file symlink or a directory symlink, because this detail is not exposed in a stable function in the standard library. ## Author -[Chris Morgan](http://chrismorgan.info/) ([chris-morgan](https://gitlab.com/chris-morgan)) is the primary author and maintainer of this library. +[Chris Morgan](https://chrismorgan.info/) is the author and maintainer of this library. ## License -This library is distributed under similar terms to Rust: dual licensed under the MIT license and the Apache license (version 2.0). +Copyright © 2017–2022 Chris Morgan + +This project is distributed under the terms of three different licenses, +at your choice: + +- Blue Oak Model License 1.0.0: https://blueoakcouncil.org/license/1.0.0 +- MIT License: https://opensource.org/licenses/MIT +- Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0 + +If you do not have particular cause to select the MIT or the Apache-2.0 +license, Chris Morgan recommends that you select BlueOak-1.0.0, which is +better and simpler than both MIT and Apache-2.0, which are only offered +due to their greater recognition and their conventional use in the Rust +ecosystem. (BlueOak-1.0.0 was only published in March 2019.) -See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details. +When using this code, ensure you comply with the terms of at least one of +these licenses.