|
1606 | 1606 | <span id="1604">1604</span>
|
1607 | 1607 | <span id="1605">1605</span>
|
1608 | 1608 | <span id="1606">1606</span>
|
| 1609 | +<span id="1607">1607</span> |
| 1610 | +<span id="1608">1608</span> |
| 1611 | +<span id="1609">1609</span> |
| 1612 | +<span id="1610">1610</span> |
| 1613 | +<span id="1611">1611</span> |
| 1614 | +<span id="1612">1612</span> |
| 1615 | +<span id="1613">1613</span> |
| 1616 | +<span id="1614">1614</span> |
| 1617 | +<span id="1615">1615</span> |
| 1618 | +<span id="1616">1616</span> |
| 1619 | +<span id="1617">1617</span> |
| 1620 | +<span id="1618">1618</span> |
| 1621 | +<span id="1619">1619</span> |
| 1622 | +<span id="1620">1620</span> |
| 1623 | +<span id="1621">1621</span> |
| 1624 | +<span id="1622">1622</span> |
| 1625 | +<span id="1623">1623</span> |
| 1626 | +<span id="1624">1624</span> |
| 1627 | +<span id="1625">1625</span> |
| 1628 | +<span id="1626">1626</span> |
| 1629 | +<span id="1627">1627</span> |
| 1630 | +<span id="1628">1628</span> |
| 1631 | +<span id="1629">1629</span> |
| 1632 | +<span id="1630">1630</span> |
| 1633 | +<span id="1631">1631</span> |
| 1634 | +<span id="1632">1632</span> |
| 1635 | +<span id="1633">1633</span> |
| 1636 | +<span id="1634">1634</span> |
| 1637 | +<span id="1635">1635</span> |
| 1638 | +<span id="1636">1636</span> |
1609 | 1639 | </pre><pre class="rust"><code><span class="attribute">#![<span class="ident">allow</span>(<span class="ident">clippy::missing_safety_doc</span>)]</span>
|
1610 | 1640 |
|
1611 | 1641 | <span class="comment">// This file is part of the uutils coreutils package.</span>
|
|
1638 | 1668 |
|
1639 | 1669 | <span class="kw">use</span> <span class="ident">clap</span>::{<span class="ident">crate_version</span>, <span class="ident">App</span>, <span class="ident">AppSettings</span>, <span class="ident">Arg</span>, <span class="ident">ArgMatches</span>};
|
1640 | 1670 | <span class="kw">use</span> <span class="ident">filetime::FileTime</span>;
|
| 1671 | +<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
| 1672 | +<span class="kw">use</span> <span class="ident">libc::mkfifo</span>; |
1641 | 1673 | <span class="kw">use</span> <span class="ident">quick_error::ResultExt</span>;
|
1642 | 1674 | <span class="kw">use</span> <span class="ident">std::collections::HashSet</span>;
|
1643 | 1675 | <span class="kw">use</span> <span class="ident">std::env</span>;
|
|
1651 | 1683 | <span class="kw">use</span> <span class="ident">std::io</span>;
|
1652 | 1684 | <span class="kw">use</span> <span class="ident">std::io</span>::{<span class="ident">stdin</span>, <span class="ident">stdout</span>, <span class="ident">Write</span>};
|
1653 | 1685 | <span class="kw">use</span> <span class="ident">std::mem</span>;
|
| 1686 | +<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
| 1687 | +<span class="kw">use</span> <span class="ident">std::os::unix::ffi::OsStrExt</span>; |
| 1688 | +<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
| 1689 | +<span class="kw">use</span> <span class="ident">std::os::unix::fs</span>::{<span class="ident">FileTypeExt</span>, <span class="ident">PermissionsExt</span>}; |
1654 | 1690 | <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">"linux"</span>)]</span>
|
1655 | 1691 | <span class="kw">use</span> <span class="ident">std::os::unix::io::AsRawFd</span>;
|
1656 | 1692 | <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">windows</span>)]</span>
|
|
1663 | 1699 | <span class="kw">use</span> <span class="ident">uucore::fs</span>::{<span class="ident">canonicalize</span>, <span class="ident">MissingHandling</span>, <span class="ident">ResolveMode</span>};
|
1664 | 1700 | <span class="kw">use</span> <span class="ident">walkdir::WalkDir</span>;
|
1665 | 1701 |
|
1666 |
| -<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
1667 |
| -<span class="kw">use</span> <span class="ident">std::os::unix::fs::PermissionsExt</span>; |
1668 |
| - |
1669 | 1702 | <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">"linux"</span>)]</span>
|
1670 | 1703 | <span class="macro">ioctl!</span>(<span class="ident">write</span> <span class="ident">ficlone</span> <span class="ident">with</span> <span class="number">0x94</span>, <span class="number">9</span>; <span class="ident">std::os::raw::c_int</span>);
|
1671 | 1704 |
|
|
1758 | 1791 | <span class="kw">pub</span> <span class="kw">type</span> <span class="ident">TargetSlice</span> <span class="op">=</span> <span class="ident">Path</span>;
|
1759 | 1792 |
|
1760 | 1793 | <span class="doccomment">/// Specifies whether when overwrite files</span>
|
1761 |
| -<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span> |
| 1794 | +<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Copy</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span> |
1762 | 1795 | <span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">ClobberMode</span> {
|
1763 | 1796 | <span class="ident">Force</span>,
|
1764 | 1797 | <span class="ident">RemoveDestination</span>,
|
1765 | 1798 | <span class="ident">Standard</span>,
|
1766 | 1799 | }
|
1767 | 1800 |
|
1768 | 1801 | <span class="doccomment">/// Specifies whether when overwrite files</span>
|
1769 |
| -<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span> |
| 1802 | +<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Copy</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span> |
1770 | 1803 | <span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">OverwriteMode</span> {
|
1771 | 1804 | <span class="doccomment">/// [Default] Always overwrite existing files</span>
|
1772 | 1805 | <span class="ident">Clobber</span>(<span class="ident">ClobberMode</span>),
|
|
2999 | 3032 | <span class="kw">let</span> <span class="ident">parent</span> <span class="op">=</span> <span class="ident">dest</span>.<span class="ident">parent</span>().<span class="ident">unwrap_or</span>(<span class="ident">dest</span>);
|
3000 | 3033 | <span class="ident">fs::create_dir_all</span>(<span class="ident">parent</span>)<span class="question-mark">?</span>;
|
3001 | 3034 | }
|
3002 |
| - <span class="kw">let</span> <span class="ident">is_symlink</span> <span class="op">=</span> <span class="ident">fs::symlink_metadata</span>(<span class="kw-2">&</span><span class="ident">source</span>)<span class="question-mark">?</span>.<span class="ident">file_type</span>().<span class="ident">is_symlink</span>(); |
| 3035 | + |
| 3036 | + <span class="kw">let</span> <span class="ident">file_type</span> <span class="op">=</span> <span class="ident">fs::symlink_metadata</span>(<span class="kw-2">&</span><span class="ident">source</span>)<span class="question-mark">?</span>.<span class="ident">file_type</span>(); |
| 3037 | + <span class="kw">let</span> <span class="ident">is_symlink</span> <span class="op">=</span> <span class="ident">file_type</span>.<span class="ident">is_symlink</span>(); |
| 3038 | + |
| 3039 | + <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
| 3040 | + <span class="kw">let</span> <span class="ident">is_fifo</span> <span class="op">=</span> <span class="ident">file_type</span>.<span class="ident">is_fifo</span>(); |
| 3041 | + <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">not</span>(<span class="ident">unix</span>))]</span> |
| 3042 | + <span class="kw">let</span> <span class="ident">is_fifo</span> <span class="op">=</span> <span class="bool-val">false</span>; |
| 3043 | + |
3003 | 3044 | <span class="kw">if</span> <span class="ident">source</span>.<span class="ident">as_os_str</span>() <span class="op">==</span> <span class="string">"/dev/null"</span> {
|
3004 | 3045 | <span class="comment">/* workaround a limitation of fs::copy
|
3005 | 3046 | * https://github.com/rust-lang/rust/issues/79390
|
3006 | 3047 | */</span>
|
3007 | 3048 | <span class="ident">File::create</span>(<span class="ident">dest</span>).<span class="ident">context</span>(<span class="ident">dest</span>.<span class="ident">display</span>().<span class="ident">to_string</span>())<span class="question-mark">?</span>;
|
| 3049 | + } <span class="kw">else</span> <span class="kw">if</span> <span class="ident">is_fifo</span> <span class="op">&&</span> <span class="ident">options</span>.<span class="ident">recursive</span> { |
| 3050 | + <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
| 3051 | + <span class="ident">copy_fifo</span>(<span class="ident">dest</span>, <span class="ident">options</span>.<span class="ident">overwrite</span>)<span class="question-mark">?</span>; |
3008 | 3052 | } <span class="kw">else</span> <span class="kw">if</span> <span class="ident">is_symlink</span> {
|
3009 | 3053 | <span class="ident">copy_link</span>(<span class="ident">source</span>, <span class="ident">dest</span>, <span class="ident">symlinked_files</span>)<span class="question-mark">?</span>;
|
3010 | 3054 | } <span class="kw">else</span> <span class="kw">if</span> <span class="ident">options</span>.<span class="ident">reflink_mode</span> <span class="op">!</span><span class="op">=</span> <span class="ident">ReflinkMode::Never</span> {
|
|
3024 | 3068 | <span class="prelude-val">Ok</span>(())
|
3025 | 3069 | }
|
3026 | 3070 |
|
| 3071 | +<span class="comment">// "Copies" a FIFO by creating a new one. This workaround is because Rust's</span> |
| 3072 | +<span class="comment">// built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390).</span> |
| 3073 | +<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span> |
| 3074 | +<span class="kw">fn</span> <span class="ident">copy_fifo</span>(<span class="ident">dest</span>: <span class="kw-2">&</span><span class="ident">Path</span>, <span class="ident">overwrite</span>: <span class="ident">OverwriteMode</span>) -> <span class="ident">CopyResult</span><span class="op"><</span>()<span class="op">></span> { |
| 3075 | + <span class="kw">if</span> <span class="ident">dest</span>.<span class="ident">exists</span>() { |
| 3076 | + <span class="ident">overwrite</span>.<span class="ident">verify</span>(<span class="ident">dest</span>)<span class="question-mark">?</span>; |
| 3077 | + <span class="ident">fs::remove_file</span>(<span class="kw-2">&</span><span class="ident">dest</span>)<span class="question-mark">?</span>; |
| 3078 | + } |
| 3079 | + |
| 3080 | + <span class="kw">let</span> <span class="ident">name</span> <span class="op">=</span> <span class="ident">CString::new</span>(<span class="ident">dest</span>.<span class="ident">as_os_str</span>().<span class="ident">as_bytes</span>()).<span class="ident">unwrap</span>(); |
| 3081 | + <span class="kw">let</span> <span class="ident">err</span> <span class="op">=</span> <span class="kw">unsafe</span> { <span class="ident">mkfifo</span>(<span class="ident">name</span>.<span class="ident">as_ptr</span>(), <span class="number">0o666</span>) }; |
| 3082 | + <span class="kw">if</span> <span class="ident">err</span> <span class="op">==</span> <span class="op">-</span><span class="number">1</span> { |
| 3083 | + <span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="macro">format!</span>(<span class="string">"cannot create fifo {}: File exists"</span>, <span class="ident">dest</span>.<span class="ident">quote</span>()).<span class="ident">into</span>()); |
| 3084 | + } |
| 3085 | + <span class="prelude-val">Ok</span>(()) |
| 3086 | +} |
| 3087 | + |
3027 | 3088 | <span class="kw">fn</span> <span class="ident">copy_link</span>(
|
3028 | 3089 | <span class="ident">source</span>: <span class="kw-2">&</span><span class="ident">Path</span>,
|
3029 | 3090 | <span class="ident">dest</span>: <span class="kw-2">&</span><span class="ident">Path</span>,
|
|
3107 | 3168 | <span class="comment">// Extract paths in a form suitable to be passed to a syscall.</span>
|
3108 | 3169 | <span class="comment">// The unwrap() is safe because they come from the command-line and so contain non nul</span>
|
3109 | 3170 | <span class="comment">// character.</span>
|
3110 |
| - <span class="kw">use</span> <span class="ident">std::os::unix::ffi::OsStrExt</span>; |
3111 | 3171 | <span class="kw">let</span> <span class="ident">src</span> <span class="op">=</span> <span class="ident">CString::new</span>(<span class="ident">source</span>.<span class="ident">as_os_str</span>().<span class="ident">as_bytes</span>()).<span class="ident">unwrap</span>();
|
3112 | 3172 | <span class="kw">let</span> <span class="ident">dst</span> <span class="op">=</span> <span class="ident">CString::new</span>(<span class="ident">dest</span>.<span class="ident">as_os_str</span>().<span class="ident">as_bytes</span>()).<span class="ident">unwrap</span>();
|
3113 | 3173 |
|
|
0 commit comments