From cb56add1d876e7ed5cdbacb49b4318e4a5c807d0 Mon Sep 17 00:00:00 2001 From: sharkdp Date: Thu, 16 Apr 2020 09:41:24 +0200 Subject: [PATCH] Add new `--type socket` and `--type pipe` filters closes #511 --- CHANGELOG.md | 3 ++- doc/fd.1 | 4 ++++ src/app.rs | 10 ++++++++-- src/filesystem.rs | 22 +++++++++++++++++++++- src/filetypes.rs | 4 ++++ src/main.rs | 6 +++--- src/walk.rs | 8 +++++++- 7 files changed, 49 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccc1af6..a2e566f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,9 +12,10 @@ This can be useful to speed up searches in cases where you know that there are only N results. Using this option is also (slightly) faster than piping to `head -n ` where `fd` can only exit when it finds the search results ` + 1`. +- Add the alias `-1` for `--max-results=1`, see #561. (@SimplyDanny). +- Add new `--type socket` and `--type pipe` filters, see #511. - Add new `--min-depth ` and `--exact-depth ` options in addition to the existing option to limit the maximum depth. See #404. -- Add the alias `-1` for `--max-results=1`, see #561. (@SimplyDanny). - Support additional ANSI font styles in `LS_COLORS`: faint, slow blink, rapid blink, dimmed, hidden and strikethrough. ## Bugfixes diff --git a/doc/fd.1 b/doc/fd.1 index 6575c2a..3c31cd7 100644 --- a/doc/fd.1 +++ b/doc/fd.1 @@ -129,6 +129,10 @@ symbolic links executable (files) .IP "e, empty" empty files or directories +.IP "s, socket" +sockets +.IP "p, pipe" +named pipes (FIFOs) .RE .RS diff --git a/src/app.rs b/src/app.rs index 3b33d0e..7ca0271 100644 --- a/src/app.rs +++ b/src/app.rs @@ -228,11 +228,15 @@ pub fn build_app() -> App<'static, 'static> { "executable", "e", "empty", + "s", + "socket", + "p", + "pipe", ]) .hide_possible_values(true) .help( "Filter by type: file (f), directory (d), symlink (l),\nexecutable (x), \ - empty (e)", + empty (e), socket (s), pipe (p)", ) .long_help( "Filter the search by type (multiple allowable filetypes can be specified):\n \ @@ -240,7 +244,9 @@ pub fn build_app() -> App<'static, 'static> { 'd' or 'directory': directories\n \ 'l' or 'symlink': symbolic links\n \ 'x' or 'executable': executables\n \ - 'e' or 'empty': empty files or directories", + 'e' or 'empty': empty files or directories\n \ + 's' or 'socket': socket\n \ + 'p' or 'pipe': named pipe (FIFO)", ), ) .arg( diff --git a/src/filesystem.rs b/src/filesystem.rs index a43527f..a41fd58 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -4,7 +4,7 @@ use std::ffi::OsStr; use std::fs; use std::io; #[cfg(any(unix, target_os = "redox"))] -use std::os::unix::fs::PermissionsExt; +use std::os::unix::fs::{PermissionsExt, FileTypeExt}; use std::path::{Path, PathBuf}; use crate::walk; @@ -67,6 +67,26 @@ pub fn is_empty(entry: &walk::DirEntry) -> bool { } } +#[cfg(any(unix, target_os = "redox"))] +pub fn is_socket(ft: &fs::FileType) -> bool { + ft.is_socket() +} + +#[cfg(windows)] +pub fn is_socket(_: &fs::FileType) -> bool { + false +} + +#[cfg(any(unix, target_os = "redox"))] +pub fn is_pipe(ft: &fs::FileType) -> bool { + ft.is_fifo() +} + +#[cfg(windows)] +pub fn is_pipe(_: &fs::FileType) -> bool { + false +} + #[cfg(any(unix, target_os = "redox"))] pub fn osstr_to_bytes(input: &OsStr) -> Cow<[u8]> { use std::os::unix::ffi::OsStrExt; diff --git a/src/filetypes.rs b/src/filetypes.rs index f2703c8..1f445da 100644 --- a/src/filetypes.rs +++ b/src/filetypes.rs @@ -3,6 +3,8 @@ pub struct FileTypes { pub files: bool, pub directories: bool, pub symlinks: bool, + pub sockets: bool, + pub pipes: bool, pub executables_only: bool, pub empty_only: bool, } @@ -13,6 +15,8 @@ impl Default for FileTypes { files: false, directories: false, symlinks: false, + sockets: false, + pipes: false, executables_only: false, empty_only: false, } diff --git a/src/main.rs b/src/main.rs index 969ffbc..fb64e7a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -317,9 +317,9 @@ fn run() -> Result { file_types.executables_only = true; file_types.files = true; } - "e" | "empty" => { - file_types.empty_only = true; - } + "e" | "empty" => file_types.empty_only = true, + "s" | "socket" => file_types.sockets = true, + "p" | "pipe" => file_types.pipes = true, _ => unreachable!(), } } diff --git a/src/walk.rs b/src/walk.rs index 34b862c..93f20de 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -390,13 +390,19 @@ fn spawn_senders( if (!file_types.files && entry_type.is_file()) || (!file_types.directories && entry_type.is_dir()) || (!file_types.symlinks && entry_type.is_symlink()) + || (!file_types.sockets && filesystem::is_socket(entry_type)) + || (!file_types.pipes && filesystem::is_pipe(entry_type)) || (file_types.executables_only && !entry .metadata() .map(|m| filesystem::is_executable(&m)) .unwrap_or(false)) || (file_types.empty_only && !filesystem::is_empty(&entry)) - || !(entry_type.is_file() || entry_type.is_dir() || entry_type.is_symlink()) + || !(entry_type.is_file() + || entry_type.is_dir() + || entry_type.is_symlink() + || filesystem::is_socket(entry_type) + || filesystem::is_pipe(entry_type)) { return ignore::WalkState::Continue; }