You've already forked uutils.github.io
mirror of
https://github.com/uutils/uutils.github.io.git
synced 2026-06-10 16:12:28 -07:00
deploy: b3ede5bce1
This commit is contained in:
+4
-4
File diff suppressed because one or more lines are too long
+216
-72
@@ -140,6 +140,78 @@
|
||||
<span id="138">138</span>
|
||||
<span id="139">139</span>
|
||||
<span id="140">140</span>
|
||||
<span id="141">141</span>
|
||||
<span id="142">142</span>
|
||||
<span id="143">143</span>
|
||||
<span id="144">144</span>
|
||||
<span id="145">145</span>
|
||||
<span id="146">146</span>
|
||||
<span id="147">147</span>
|
||||
<span id="148">148</span>
|
||||
<span id="149">149</span>
|
||||
<span id="150">150</span>
|
||||
<span id="151">151</span>
|
||||
<span id="152">152</span>
|
||||
<span id="153">153</span>
|
||||
<span id="154">154</span>
|
||||
<span id="155">155</span>
|
||||
<span id="156">156</span>
|
||||
<span id="157">157</span>
|
||||
<span id="158">158</span>
|
||||
<span id="159">159</span>
|
||||
<span id="160">160</span>
|
||||
<span id="161">161</span>
|
||||
<span id="162">162</span>
|
||||
<span id="163">163</span>
|
||||
<span id="164">164</span>
|
||||
<span id="165">165</span>
|
||||
<span id="166">166</span>
|
||||
<span id="167">167</span>
|
||||
<span id="168">168</span>
|
||||
<span id="169">169</span>
|
||||
<span id="170">170</span>
|
||||
<span id="171">171</span>
|
||||
<span id="172">172</span>
|
||||
<span id="173">173</span>
|
||||
<span id="174">174</span>
|
||||
<span id="175">175</span>
|
||||
<span id="176">176</span>
|
||||
<span id="177">177</span>
|
||||
<span id="178">178</span>
|
||||
<span id="179">179</span>
|
||||
<span id="180">180</span>
|
||||
<span id="181">181</span>
|
||||
<span id="182">182</span>
|
||||
<span id="183">183</span>
|
||||
<span id="184">184</span>
|
||||
<span id="185">185</span>
|
||||
<span id="186">186</span>
|
||||
<span id="187">187</span>
|
||||
<span id="188">188</span>
|
||||
<span id="189">189</span>
|
||||
<span id="190">190</span>
|
||||
<span id="191">191</span>
|
||||
<span id="192">192</span>
|
||||
<span id="193">193</span>
|
||||
<span id="194">194</span>
|
||||
<span id="195">195</span>
|
||||
<span id="196">196</span>
|
||||
<span id="197">197</span>
|
||||
<span id="198">198</span>
|
||||
<span id="199">199</span>
|
||||
<span id="200">200</span>
|
||||
<span id="201">201</span>
|
||||
<span id="202">202</span>
|
||||
<span id="203">203</span>
|
||||
<span id="204">204</span>
|
||||
<span id="205">205</span>
|
||||
<span id="206">206</span>
|
||||
<span id="207">207</span>
|
||||
<span id="208">208</span>
|
||||
<span id="209">209</span>
|
||||
<span id="210">210</span>
|
||||
<span id="211">211</span>
|
||||
<span id="212">212</span>
|
||||
</pre><pre class="rust">
|
||||
<span class="comment">// * This file is part of the uutils coreutils package.</span>
|
||||
<span class="comment">// *</span>
|
||||
@@ -154,8 +226,11 @@
|
||||
<span class="kw">extern</span> <span class="kw">crate</span> <span class="ident">uucore</span>;
|
||||
|
||||
<span class="kw">use</span> <span class="ident">clap</span>::{<span class="ident">crate_version</span>, <span class="ident">App</span>, <span class="ident">Arg</span>};
|
||||
<span class="kw">use</span> <span class="ident">std::fs</span>;
|
||||
<span class="kw">use</span> <span class="ident">std::fs</span>::{<span class="ident">read_dir</span>, <span class="ident">remove_dir</span>};
|
||||
<span class="kw">use</span> <span class="ident">std::io</span>;
|
||||
<span class="kw">use</span> <span class="ident">std::path::Path</span>;
|
||||
<span class="kw">use</span> <span class="ident">uucore::error</span>::{<span class="ident">set_exit_code</span>, <span class="ident">strip_errno</span>, <span class="ident">UResult</span>};
|
||||
<span class="kw">use</span> <span class="ident">uucore::util_name</span>;
|
||||
|
||||
<span class="kw">static</span> <span class="ident">ABOUT</span>: <span class="kw-2">&</span><span class="ident">str</span> <span class="op">=</span> <span class="string">"Remove the DIRECTORY(ies), if they are empty."</span>;
|
||||
<span class="kw">static</span> <span class="ident">OPT_IGNORE_FAIL_NON_EMPTY</span>: <span class="kw-2">&</span><span class="ident">str</span> <span class="op">=</span> <span class="string">"ignore-fail-on-non-empty"</span>;
|
||||
@@ -164,35 +239,158 @@
|
||||
|
||||
<span class="kw">static</span> <span class="ident">ARG_DIRS</span>: <span class="kw-2">&</span><span class="ident">str</span> <span class="op">=</span> <span class="string">"dirs"</span>;
|
||||
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span>
|
||||
<span class="kw">static</span> <span class="ident">ENOTDIR</span>: <span class="ident">i32</span> <span class="op">=</span> <span class="number">20</span>;
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">windows</span>)]</span>
|
||||
<span class="kw">static</span> <span class="ident">ENOTDIR</span>: <span class="ident">i32</span> <span class="op">=</span> <span class="number">267</span>;
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">usage</span>() <span class="op">-</span><span class="op">></span> <span class="ident">String</span> {
|
||||
<span class="macro">format!</span>(<span class="string">"{0} [OPTION]... DIRECTORY..."</span>, <span class="ident">uucore::execution_phrase</span>())
|
||||
}
|
||||
|
||||
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">uumain</span>(<span class="ident">args</span>: <span class="kw">impl</span> <span class="ident">uucore::Args</span>) <span class="op">-</span><span class="op">></span> <span class="ident">i32</span> {
|
||||
<span class="attribute">#[<span class="ident">uucore_procs::gen_uumain</span>]</span>
|
||||
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">uumain</span>(<span class="ident">args</span>: <span class="kw">impl</span> <span class="ident">uucore::Args</span>) <span class="op">-</span><span class="op">></span> <span class="ident">UResult</span><span class="op"><</span>()<span class="op">></span> {
|
||||
<span class="kw">let</span> <span class="ident">usage</span> <span class="op">=</span> <span class="ident">usage</span>();
|
||||
|
||||
<span class="kw">let</span> <span class="ident">matches</span> <span class="op">=</span> <span class="ident">uu_app</span>().<span class="ident">usage</span>(<span class="kw-2">&</span><span class="ident">usage</span>[..]).<span class="ident">get_matches_from</span>(<span class="ident">args</span>);
|
||||
|
||||
<span class="kw">let</span> <span class="ident">dirs</span>: <span class="ident">Vec</span><span class="op"><</span><span class="ident">String</span><span class="op">></span> <span class="op">=</span> <span class="ident">matches</span>
|
||||
.<span class="ident">values_of</span>(<span class="ident">ARG_DIRS</span>)
|
||||
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">v</span><span class="op">|</span> <span class="ident">v</span>.<span class="ident">map</span>(<span class="ident">ToString::to_string</span>).<span class="ident">collect</span>())
|
||||
.<span class="ident">unwrap_or_default</span>();
|
||||
<span class="kw">let</span> <span class="ident">opts</span> <span class="op">=</span> <span class="ident">Opts</span> {
|
||||
<span class="ident">ignore</span>: <span class="ident">matches</span>.<span class="ident">is_present</span>(<span class="ident">OPT_IGNORE_FAIL_NON_EMPTY</span>),
|
||||
<span class="ident">parents</span>: <span class="ident">matches</span>.<span class="ident">is_present</span>(<span class="ident">OPT_PARENTS</span>),
|
||||
<span class="ident">verbose</span>: <span class="ident">matches</span>.<span class="ident">is_present</span>(<span class="ident">OPT_VERBOSE</span>),
|
||||
};
|
||||
|
||||
<span class="kw">let</span> <span class="ident">ignore</span> <span class="op">=</span> <span class="ident">matches</span>.<span class="ident">is_present</span>(<span class="ident">OPT_IGNORE_FAIL_NON_EMPTY</span>);
|
||||
<span class="kw">let</span> <span class="ident">parents</span> <span class="op">=</span> <span class="ident">matches</span>.<span class="ident">is_present</span>(<span class="ident">OPT_PARENTS</span>);
|
||||
<span class="kw">let</span> <span class="ident">verbose</span> <span class="op">=</span> <span class="ident">matches</span>.<span class="ident">is_present</span>(<span class="ident">OPT_VERBOSE</span>);
|
||||
<span class="kw">for</span> <span class="ident">path</span> <span class="kw">in</span> <span class="ident">matches</span>
|
||||
.<span class="ident">values_of_os</span>(<span class="ident">ARG_DIRS</span>)
|
||||
.<span class="ident">unwrap_or_default</span>()
|
||||
.<span class="ident">map</span>(<span class="ident">Path::new</span>)
|
||||
{
|
||||
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Err</span>(<span class="ident">error</span>) <span class="op">=</span> <span class="ident">remove</span>(<span class="ident">path</span>, <span class="ident">opts</span>) {
|
||||
<span class="kw">let</span> <span class="ident">Error</span> { <span class="ident">error</span>, <span class="ident">path</span> } <span class="op">=</span> <span class="ident">error</span>;
|
||||
|
||||
<span class="kw">match</span> <span class="ident">remove</span>(<span class="ident">dirs</span>, <span class="ident">ignore</span>, <span class="ident">parents</span>, <span class="ident">verbose</span>) {
|
||||
<span class="prelude-val">Ok</span>(()) <span class="op">=</span><span class="op">></span> ( <span class="comment">/* pass */</span> ),
|
||||
<span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span><span class="op">></span> <span class="kw">return</span> <span class="ident">e</span>,
|
||||
<span class="kw">if</span> <span class="ident">opts</span>.<span class="ident">ignore</span> <span class="op">&&</span> <span class="ident">dir_not_empty</span>(<span class="kw-2">&</span><span class="ident">error</span>, <span class="ident">path</span>) {
|
||||
<span class="kw">continue</span>;
|
||||
}
|
||||
|
||||
<span class="ident">set_exit_code</span>(<span class="number">1</span>);
|
||||
|
||||
<span class="comment">// If `foo` is a symlink to a directory then `rmdir foo/` may give</span>
|
||||
<span class="comment">// a "not a directory" error. This is confusing as `rm foo/` says</span>
|
||||
<span class="comment">// "is a directory".</span>
|
||||
<span class="comment">// This differs from system to system. Some don't give an error.</span>
|
||||
<span class="comment">// Windows simply allows calling RemoveDirectory on symlinks so we</span>
|
||||
<span class="comment">// don't need to worry about it here.</span>
|
||||
<span class="comment">// GNU rmdir seems to print "Symbolic link not followed" if:</span>
|
||||
<span class="comment">// - It has a trailing slash</span>
|
||||
<span class="comment">// - It's a symlink</span>
|
||||
<span class="comment">// - It either points to a directory or dangles</span>
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">unix</span>)]</span>
|
||||
{
|
||||
<span class="kw">use</span> <span class="ident">std::ffi::OsStr</span>;
|
||||
<span class="kw">use</span> <span class="ident">std::os::unix::ffi::OsStrExt</span>;
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">is_symlink</span>(<span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span>) <span class="op">-</span><span class="op">></span> <span class="ident">io::Result</span><span class="op"><</span><span class="ident">bool</span><span class="op">></span> {
|
||||
<span class="prelude-val">Ok</span>(<span class="ident">path</span>.<span class="ident">symlink_metadata</span>()<span class="question-mark">?</span>.<span class="ident">file_type</span>().<span class="ident">is_symlink</span>())
|
||||
}
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">points_to_directory</span>(<span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span>) <span class="op">-</span><span class="op">></span> <span class="ident">io::Result</span><span class="op"><</span><span class="ident">bool</span><span class="op">></span> {
|
||||
<span class="prelude-val">Ok</span>(<span class="ident">path</span>.<span class="ident">metadata</span>()<span class="question-mark">?</span>.<span class="ident">file_type</span>().<span class="ident">is_dir</span>())
|
||||
}
|
||||
|
||||
<span class="kw">let</span> <span class="ident">path</span> <span class="op">=</span> <span class="ident">path</span>.<span class="ident">as_os_str</span>().<span class="ident">as_bytes</span>();
|
||||
<span class="kw">if</span> <span class="ident">error</span>.<span class="ident">raw_os_error</span>() <span class="op">=</span><span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">libc::ENOTDIR</span>) <span class="op">&&</span> <span class="ident">path</span>.<span class="ident">ends_with</span>(<span class="string">b"/"</span>) {
|
||||
<span class="comment">// Strip the trailing slash or .symlink_metadata() will follow the symlink</span>
|
||||
<span class="kw">let</span> <span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span> <span class="op">=</span> <span class="ident">OsStr::from_bytes</span>(<span class="kw-2">&</span><span class="ident">path</span>[..<span class="ident">path</span>.<span class="ident">len</span>() <span class="op">-</span> <span class="number">1</span>]).<span class="ident">as_ref</span>();
|
||||
<span class="kw">if</span> <span class="ident">is_symlink</span>(<span class="ident">path</span>).<span class="ident">unwrap_or</span>(<span class="bool-val">false</span>)
|
||||
<span class="op">&&</span> <span class="ident">points_to_directory</span>(<span class="ident">path</span>).<span class="ident">unwrap_or</span>(<span class="bool-val">true</span>)
|
||||
{
|
||||
<span class="macro">show_error!</span>(
|
||||
<span class="string">"failed to remove '{}/': Symbolic link not followed"</span>,
|
||||
<span class="ident">path</span>.<span class="ident">display</span>()
|
||||
);
|
||||
<span class="kw">continue</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="macro">show_error!</span>(
|
||||
<span class="string">"failed to remove '{}': {}"</span>,
|
||||
<span class="ident">path</span>.<span class="ident">display</span>(),
|
||||
<span class="ident">strip_errno</span>(<span class="kw-2">&</span><span class="ident">error</span>)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
<span class="number">0</span>
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="kw">struct</span> <span class="ident">Error</span><span class="op"><</span><span class="lifetime">'a</span><span class="op">></span> {
|
||||
<span class="ident">error</span>: <span class="ident">io::Error</span>,
|
||||
<span class="ident">path</span>: <span class="kw-2">&</span><span class="lifetime">'a</span> <span class="ident">Path</span>,
|
||||
}
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">remove</span>(<span class="kw-2">mut</span> <span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span>, <span class="ident">opts</span>: <span class="ident">Opts</span>) <span class="op">-</span><span class="op">></span> <span class="prelude-ty">Result</span><span class="op"><</span>(), <span class="ident">Error</span><span class="op"><</span><span class="lifetime">'_</span><span class="op">></span><span class="op">></span> {
|
||||
<span class="ident">remove_single</span>(<span class="ident">path</span>, <span class="ident">opts</span>)<span class="question-mark">?</span>;
|
||||
<span class="kw">if</span> <span class="ident">opts</span>.<span class="ident">parents</span> {
|
||||
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">new</span>) <span class="op">=</span> <span class="ident">path</span>.<span class="ident">parent</span>() {
|
||||
<span class="ident">path</span> <span class="op">=</span> <span class="ident">new</span>;
|
||||
<span class="kw">if</span> <span class="ident">path</span>.<span class="ident">as_os_str</span>() <span class="op">=</span><span class="op">=</span> <span class="string">""</span> {
|
||||
<span class="kw">break</span>;
|
||||
}
|
||||
<span class="ident">remove_single</span>(<span class="ident">path</span>, <span class="ident">opts</span>)<span class="question-mark">?</span>;
|
||||
}
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">remove_single</span>(<span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span>, <span class="ident">opts</span>: <span class="ident">Opts</span>) <span class="op">-</span><span class="op">></span> <span class="prelude-ty">Result</span><span class="op"><</span>(), <span class="ident">Error</span><span class="op"><</span><span class="lifetime">'_</span><span class="op">></span><span class="op">></span> {
|
||||
<span class="kw">if</span> <span class="ident">opts</span>.<span class="ident">verbose</span> {
|
||||
<span class="macro">println!</span>(<span class="string">"{}: removing directory, '{}'"</span>, <span class="ident">util_name</span>(), <span class="ident">path</span>.<span class="ident">display</span>());
|
||||
}
|
||||
<span class="ident">remove_dir</span>(<span class="ident">path</span>).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">error</span><span class="op">|</span> <span class="ident">Error</span> { <span class="ident">error</span>, <span class="ident">path</span> })
|
||||
}
|
||||
|
||||
<span class="comment">// POSIX: https://pubs.opengroup.org/onlinepubs/009696799/functions/rmdir.html</span>
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">not</span>(<span class="ident">windows</span>))]</span>
|
||||
<span class="kw">const</span> <span class="ident">NOT_EMPTY_CODES</span>: <span class="kw-2">&</span>[<span class="ident">i32</span>] <span class="op">=</span> <span class="kw-2">&</span>[<span class="ident">libc::ENOTEMPTY</span>, <span class="ident">libc::EEXIST</span>];
|
||||
|
||||
<span class="comment">// 145 is ERROR_DIR_NOT_EMPTY, determined experimentally.</span>
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">windows</span>)]</span>
|
||||
<span class="kw">const</span> <span class="ident">NOT_EMPTY_CODES</span>: <span class="kw-2">&</span>[<span class="ident">i32</span>] <span class="op">=</span> <span class="kw-2">&</span>[<span class="number">145</span>];
|
||||
|
||||
<span class="comment">// Other error codes you might get for directories that could be found and are</span>
|
||||
<span class="comment">// not empty.</span>
|
||||
<span class="comment">// This is a subset of the error codes listed in rmdir(2) from the Linux man-pages</span>
|
||||
<span class="comment">// project. Maybe other systems have additional codes that apply?</span>
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">not</span>(<span class="ident">windows</span>))]</span>
|
||||
<span class="kw">const</span> <span class="ident">PERHAPS_EMPTY_CODES</span>: <span class="kw-2">&</span>[<span class="ident">i32</span>] <span class="op">=</span> <span class="kw-2">&</span>[<span class="ident">libc::EACCES</span>, <span class="ident">libc::EBUSY</span>, <span class="ident">libc::EPERM</span>, <span class="ident">libc::EROFS</span>];
|
||||
|
||||
<span class="comment">// Probably incomplete, I can't find a list of possible errors for</span>
|
||||
<span class="comment">// RemoveDirectory anywhere.</span>
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">windows</span>)]</span>
|
||||
<span class="kw">const</span> <span class="ident">PERHAPS_EMPTY_CODES</span>: <span class="kw-2">&</span>[<span class="ident">i32</span>] <span class="op">=</span> <span class="kw-2">&</span>[
|
||||
<span class="number">5</span>, <span class="comment">// ERROR_ACCESS_DENIED, found experimentally.</span>
|
||||
];
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">dir_not_empty</span>(<span class="ident">error</span>: <span class="kw-2">&</span><span class="ident">io::Error</span>, <span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span>) <span class="op">-</span><span class="op">></span> <span class="ident">bool</span> {
|
||||
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">code</span>) <span class="op">=</span> <span class="ident">error</span>.<span class="ident">raw_os_error</span>() {
|
||||
<span class="kw">if</span> <span class="ident">NOT_EMPTY_CODES</span>.<span class="ident">contains</span>(<span class="kw-2">&</span><span class="ident">code</span>) {
|
||||
<span class="kw">return</span> <span class="bool-val">true</span>;
|
||||
}
|
||||
<span class="comment">// If --ignore-fail-on-non-empty is used then we want to ignore all errors</span>
|
||||
<span class="comment">// for non-empty directories, even if the error was e.g. because there's</span>
|
||||
<span class="comment">// no permission. So we do an additional check.</span>
|
||||
<span class="kw">if</span> <span class="ident">PERHAPS_EMPTY_CODES</span>.<span class="ident">contains</span>(<span class="kw-2">&</span><span class="ident">code</span>) {
|
||||
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="kw-2">mut</span> <span class="ident">iterator</span>) <span class="op">=</span> <span class="ident">read_dir</span>(<span class="ident">path</span>) {
|
||||
<span class="kw">if</span> <span class="ident">iterator</span>.<span class="ident">next</span>().<span class="ident">is_some</span>() {
|
||||
<span class="kw">return</span> <span class="bool-val">true</span>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="bool-val">false</span>
|
||||
}
|
||||
|
||||
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Copy</span>, <span class="ident">Debug</span>)]</span>
|
||||
<span class="kw">struct</span> <span class="ident">Opts</span> {
|
||||
<span class="ident">ignore</span>: <span class="ident">bool</span>,
|
||||
<span class="ident">parents</span>: <span class="ident">bool</span>,
|
||||
<span class="ident">verbose</span>: <span class="ident">bool</span>,
|
||||
}
|
||||
|
||||
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">uu_app</span>() <span class="op">-</span><span class="op">></span> <span class="ident">App</span><span class="op"><</span><span class="lifetime">'static</span>, <span class="lifetime">'static</span><span class="op">></span> {
|
||||
@@ -227,59 +425,5 @@
|
||||
.<span class="ident">required</span>(<span class="bool-val">true</span>),
|
||||
)
|
||||
}
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">remove</span>(<span class="ident">dirs</span>: <span class="ident">Vec</span><span class="op"><</span><span class="ident">String</span><span class="op">></span>, <span class="ident">ignore</span>: <span class="ident">bool</span>, <span class="ident">parents</span>: <span class="ident">bool</span>, <span class="ident">verbose</span>: <span class="ident">bool</span>) <span class="op">-</span><span class="op">></span> <span class="prelude-ty">Result</span><span class="op"><</span>(), <span class="ident">i32</span><span class="op">></span> {
|
||||
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">r</span> <span class="op">=</span> <span class="prelude-val">Ok</span>(());
|
||||
|
||||
<span class="kw">for</span> <span class="ident">dir</span> <span class="kw">in</span> <span class="kw-2">&</span><span class="ident">dirs</span> {
|
||||
<span class="kw">let</span> <span class="ident">path</span> <span class="op">=</span> <span class="ident">Path::new</span>(<span class="kw-2">&</span><span class="ident">dir</span>[..]);
|
||||
<span class="ident">r</span> <span class="op">=</span> <span class="ident">remove_dir</span>(<span class="ident">path</span>, <span class="ident">ignore</span>, <span class="ident">verbose</span>).<span class="ident">and</span>(<span class="ident">r</span>);
|
||||
<span class="kw">if</span> <span class="ident">parents</span> {
|
||||
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">p</span> <span class="op">=</span> <span class="ident">path</span>;
|
||||
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">new_p</span>) <span class="op">=</span> <span class="ident">p</span>.<span class="ident">parent</span>() {
|
||||
<span class="ident">p</span> <span class="op">=</span> <span class="ident">new_p</span>;
|
||||
<span class="kw">match</span> <span class="ident">p</span>.<span class="ident">as_os_str</span>().<span class="ident">to_str</span>() {
|
||||
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">></span> <span class="kw">break</span>,
|
||||
<span class="prelude-val">Some</span>(<span class="ident">s</span>) <span class="op">=</span><span class="op">></span> <span class="kw">match</span> <span class="ident">s</span> {
|
||||
<span class="string">""</span> <span class="op">|</span> <span class="string">"."</span> <span class="op">|</span> <span class="string">"/"</span> <span class="op">=</span><span class="op">></span> <span class="kw">break</span>,
|
||||
<span class="kw">_</span> <span class="op">=</span><span class="op">></span> (),
|
||||
},
|
||||
};
|
||||
<span class="ident">r</span> <span class="op">=</span> <span class="ident">remove_dir</span>(<span class="ident">p</span>, <span class="ident">ignore</span>, <span class="ident">verbose</span>).<span class="ident">and</span>(<span class="ident">r</span>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="ident">r</span>
|
||||
}
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">remove_dir</span>(<span class="ident">path</span>: <span class="kw-2">&</span><span class="ident">Path</span>, <span class="ident">ignore</span>: <span class="ident">bool</span>, <span class="ident">verbose</span>: <span class="ident">bool</span>) <span class="op">-</span><span class="op">></span> <span class="prelude-ty">Result</span><span class="op"><</span>(), <span class="ident">i32</span><span class="op">></span> {
|
||||
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">read_dir</span> <span class="op">=</span> <span class="ident">fs::read_dir</span>(<span class="ident">path</span>).<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
|
||||
<span class="kw">if</span> <span class="ident">e</span>.<span class="ident">raw_os_error</span>() <span class="op">=</span><span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">ENOTDIR</span>) {
|
||||
<span class="macro">show_error!</span>(<span class="string">"failed to remove '{}': Not a directory"</span>, <span class="ident">path</span>.<span class="ident">display</span>());
|
||||
} <span class="kw">else</span> {
|
||||
<span class="macro">show_error!</span>(<span class="string">"reading directory '{}': {}"</span>, <span class="ident">path</span>.<span class="ident">display</span>(), <span class="ident">e</span>);
|
||||
}
|
||||
<span class="number">1</span>
|
||||
})<span class="question-mark">?</span>;
|
||||
|
||||
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">r</span> <span class="op">=</span> <span class="prelude-val">Ok</span>(());
|
||||
|
||||
<span class="kw">if</span> <span class="ident">read_dir</span>.<span class="ident">next</span>().<span class="ident">is_none</span>() {
|
||||
<span class="kw">match</span> <span class="ident">fs::remove_dir</span>(<span class="ident">path</span>) {
|
||||
<span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span><span class="op">></span> {
|
||||
<span class="macro">show_error!</span>(<span class="string">"removing directory '{}': {}"</span>, <span class="ident">path</span>.<span class="ident">display</span>(), <span class="ident">e</span>);
|
||||
<span class="ident">r</span> <span class="op">=</span> <span class="prelude-val">Err</span>(<span class="number">1</span>);
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) <span class="kw">if</span> <span class="ident">verbose</span> <span class="op">=</span><span class="op">></span> <span class="macro">println!</span>(<span class="string">"removing directory, '{}'"</span>, <span class="ident">path</span>.<span class="ident">display</span>()),
|
||||
<span class="kw">_</span> <span class="op">=</span><span class="op">></span> (),
|
||||
}
|
||||
} <span class="kw">else</span> <span class="kw">if</span> <span class="op">!</span><span class="ident">ignore</span> {
|
||||
<span class="macro">show_error!</span>(<span class="string">"failed to remove '{}': Directory not empty"</span>, <span class="ident">path</span>.<span class="ident">display</span>());
|
||||
<span class="ident">r</span> <span class="op">=</span> <span class="prelude-val">Err</span>(<span class="number">1</span>);
|
||||
}
|
||||
|
||||
<span class="ident">r</span>
|
||||
}
|
||||
</pre></div>
|
||||
</section><section id="search" class="content hidden"></section><div id="rustdoc-vars" data-root-path="../../" data-current-crate="uu_rmdir" data-search-index-js="../../search-index.js" data-search-js="../../search.js"></div><script src="../../main.js"></script><script src="../../source-script.js"></script><script src="../../source-files.js"></script></body></html>
|
||||
@@ -1972,21 +1972,6 @@
|
||||
<span id="1970">1970</span>
|
||||
<span id="1971">1971</span>
|
||||
<span id="1972">1972</span>
|
||||
<span id="1973">1973</span>
|
||||
<span id="1974">1974</span>
|
||||
<span id="1975">1975</span>
|
||||
<span id="1976">1976</span>
|
||||
<span id="1977">1977</span>
|
||||
<span id="1978">1978</span>
|
||||
<span id="1979">1979</span>
|
||||
<span id="1980">1980</span>
|
||||
<span id="1981">1981</span>
|
||||
<span id="1982">1982</span>
|
||||
<span id="1983">1983</span>
|
||||
<span id="1984">1984</span>
|
||||
<span id="1985">1985</span>
|
||||
<span id="1986">1986</span>
|
||||
<span id="1987">1987</span>
|
||||
</pre><pre class="rust">
|
||||
<span class="comment">// * This file is part of the uutils coreutils package.</span>
|
||||
<span class="comment">// *</span>
|
||||
@@ -2035,7 +2020,7 @@
|
||||
<span class="kw">use</span> <span class="ident">std::path::PathBuf</span>;
|
||||
<span class="kw">use</span> <span class="ident">std::str::Utf8Error</span>;
|
||||
<span class="kw">use</span> <span class="ident">unicode_width::UnicodeWidthStr</span>;
|
||||
<span class="kw">use</span> <span class="ident">uucore::error</span>::{<span class="ident">set_exit_code</span>, <span class="ident">UError</span>, <span class="ident">UResult</span>, <span class="ident">USimpleError</span>, <span class="ident">UUsageError</span>};
|
||||
<span class="kw">use</span> <span class="ident">uucore::error</span>::{<span class="ident">set_exit_code</span>, <span class="ident">strip_errno</span>, <span class="ident">UError</span>, <span class="ident">UResult</span>, <span class="ident">USimpleError</span>, <span class="ident">UUsageError</span>};
|
||||
<span class="kw">use</span> <span class="ident">uucore::parse_size</span>::{<span class="ident">parse_size</span>, <span class="ident">ParseSizeError</span>};
|
||||
<span class="kw">use</span> <span class="ident">uucore::version_cmp::version_cmp</span>;
|
||||
<span class="kw">use</span> <span class="ident">uucore::InvalidEncodingHandling</span>;
|
||||
@@ -2187,27 +2172,17 @@ Valid options are: MbdfhnRrV. They override the global options for this key.&quo
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
}
|
||||
<span class="ident">SortError::OpenFailed</span> { <span class="ident">path</span>, <span class="ident">error</span> } <span class="op">=</span><span class="op">></span> <span class="macro">write!</span>(
|
||||
<span class="ident">f</span>,
|
||||
<span class="string">"open failed: {}: {}"</span>,
|
||||
<span class="ident">path</span>,
|
||||
<span class="ident">strip_errno</span>(<span class="kw-2">&</span><span class="ident">error</span>.<span class="ident">to_string</span>())
|
||||
),
|
||||
<span class="ident">SortError::OpenFailed</span> { <span class="ident">path</span>, <span class="ident">error</span> } <span class="op">=</span><span class="op">></span> {
|
||||
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">"open failed: {}: {}"</span>, <span class="ident">path</span>, <span class="ident">strip_errno</span>(<span class="ident">error</span>))
|
||||
}
|
||||
<span class="ident">SortError::ParseKeyError</span> { <span class="ident">key</span>, <span class="ident">msg</span> } <span class="op">=</span><span class="op">></span> {
|
||||
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">"failed to parse key `{}`: {}"</span>, <span class="ident">key</span>, <span class="ident">msg</span>)
|
||||
}
|
||||
<span class="ident">SortError::ReadFailed</span> { <span class="ident">path</span>, <span class="ident">error</span> } <span class="op">=</span><span class="op">></span> <span class="macro">write!</span>(
|
||||
<span class="ident">f</span>,
|
||||
<span class="string">"cannot read: {}: {}"</span>,
|
||||
<span class="ident">path</span>,
|
||||
<span class="ident">strip_errno</span>(<span class="kw-2">&</span><span class="ident">error</span>.<span class="ident">to_string</span>())
|
||||
),
|
||||
<span class="ident">SortError::ReadFailed</span> { <span class="ident">path</span>, <span class="ident">error</span> } <span class="op">=</span><span class="op">></span> {
|
||||
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">"cannot read: {}: {}"</span>, <span class="ident">path</span>, <span class="ident">strip_errno</span>(<span class="ident">error</span>))
|
||||
}
|
||||
<span class="ident">SortError::OpenTmpFileFailed</span> { <span class="ident">error</span> } <span class="op">=</span><span class="op">></span> {
|
||||
<span class="macro">write!</span>(
|
||||
<span class="ident">f</span>,
|
||||
<span class="string">"failed to open temporary file: {}"</span>,
|
||||
<span class="ident">strip_errno</span>(<span class="kw-2">&</span><span class="ident">error</span>.<span class="ident">to_string</span>())
|
||||
)
|
||||
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">"failed to open temporary file: {}"</span>, <span class="ident">strip_errno</span>(<span class="ident">error</span>))
|
||||
}
|
||||
<span class="ident">SortError::CompressProgExecutionFailed</span> { <span class="ident">code</span> } <span class="op">=</span><span class="op">></span> {
|
||||
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">"couldn't execute compress program: errno {}"</span>, <span class="ident">code</span>)
|
||||
@@ -3804,11 +3779,6 @@ With no FILE, or when FILE is -, read standard input."</span>,
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Strips the trailing " (os error XX)" from io error strings.</span>
|
||||
<span class="kw">fn</span> <span class="ident">strip_errno</span>(<span class="ident">err</span>: <span class="kw-2">&</span><span class="ident">str</span>) <span class="op">-</span><span class="op">></span> <span class="kw-2">&</span><span class="ident">str</span> {
|
||||
<span class="kw-2">&</span><span class="ident">err</span>[..<span class="ident">err</span>.<span class="ident">find</span>(<span class="string">" (os error "</span>).<span class="ident">unwrap_or</span>(<span class="ident">err</span>.<span class="ident">len</span>())]
|
||||
}
|
||||
|
||||
<span class="kw">fn</span> <span class="ident">open</span>(<span class="ident">path</span>: <span class="kw">impl</span> <span class="ident">AsRef</span><span class="op"><</span><span class="ident">OsStr</span><span class="op">></span>) <span class="op">-</span><span class="op">></span> <span class="ident">UResult</span><span class="op"><</span><span class="ident">Box</span><span class="op"><</span><span class="kw">dyn</span> <span class="ident">Read</span> <span class="op">+</span> <span class="ident">Send</span><span class="op">></span><span class="op">></span> {
|
||||
<span class="kw">let</span> <span class="ident">path</span> <span class="op">=</span> <span class="ident">path</span>.<span class="ident">as_ref</span>();
|
||||
<span class="kw">if</span> <span class="ident">path</span> <span class="op">=</span><span class="op">=</span> <span class="string">"-"</span> {
|
||||
|
||||
@@ -551,6 +551,15 @@
|
||||
<span id="549">549</span>
|
||||
<span id="550">550</span>
|
||||
<span id="551">551</span>
|
||||
<span id="552">552</span>
|
||||
<span id="553">553</span>
|
||||
<span id="554">554</span>
|
||||
<span id="555">555</span>
|
||||
<span id="556">556</span>
|
||||
<span id="557">557</span>
|
||||
<span id="558">558</span>
|
||||
<span id="559">559</span>
|
||||
<span id="560">560</span>
|
||||
</pre><pre class="rust">
|
||||
<span class="doccomment">//! All utils return exit with an exit code. Usually, the following scheme is used:</span>
|
||||
<span class="doccomment">//! * `0`: succeeded</span>
|
||||
@@ -963,6 +972,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Strip the trailing " (os error XX)" from io error strings.</span>
|
||||
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">strip_errno</span>(<span class="ident">err</span>: <span class="kw-2">&</span><span class="ident">std::io::Error</span>) <span class="op">-</span><span class="op">></span> <span class="ident">String</span> {
|
||||
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">err</span>.<span class="ident">to_string</span>();
|
||||
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">pos</span>) <span class="op">=</span> <span class="ident">msg</span>.<span class="ident">find</span>(<span class="string">" (os error "</span>) {
|
||||
<span class="ident">msg</span>.<span class="ident">drain</span>(<span class="ident">pos</span>..);
|
||||
}
|
||||
<span class="ident">msg</span>
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to</span>
|
||||
<span class="doccomment">/// [`UResult`].</span>
|
||||
<span class="kw">pub</span> <span class="kw">trait</span> <span class="ident">FromIo</span><span class="op"><</span><span class="ident">T</span><span class="op">></span> {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
initSidebarItems({"fn":[["get_exit_code","Get the last exit code set with [`set_exit_code`]. The default value is `0`."],["set_exit_code","Set the exit code for the program if `uumain` returns `Ok(())`."]],"struct":[["ExitCode","A special error type that does not print any message when returned from `uumain`. Especially useful for porting utilities to using [`UResult`]."],["UIoError","Wrapper type around [`std::io::Error`]."],["USimpleError","A simple error type with an exit code and a message that implements [`UError`]."],["UUsageError",""]],"trait":[["FromIo","Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to [`UResult`]."],["UError","Custom errors defined by the utils and `uucore`."]],"type":[["UResult","Result type that should be returned by all utils."]]});
|
||||
initSidebarItems({"fn":[["get_exit_code","Get the last exit code set with [`set_exit_code`]. The default value is `0`."],["set_exit_code","Set the exit code for the program if `uumain` returns `Ok(())`."],["strip_errno","Strip the trailing “ (os error XX)“ from io error strings."]],"struct":[["ExitCode","A special error type that does not print any message when returned from `uumain`. Especially useful for porting utilities to using [`UResult`]."],["UIoError","Wrapper type around [`std::io::Error`]."],["USimpleError","A simple error type with an exit code and a message that implements [`UError`]."],["UUsageError",""]],"trait":[["FromIo","Enables the conversion from [`std::io::Error`] to [`UError`] and from [`std::io::Result`] to [`UResult`]."],["UError","Custom errors defined by the utils and `uucore`."]],"type":[["UResult","Result type that should be returned by all utils."]]});
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user