|
C-Menu 0.2.9
A User Interface Toolkit
|
list files based on matching criteria More...
#include "cm.h"#include <argp.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <grp.h>#include <linux/limits.h>#include <pthread.h>#include <pwd.h>#include <regex.h>#include <stdatomic.h>#include <stdbool.h>#include <stdint.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/syscall.h>#include <sys/sysinfo.h>#include <sys/types.h>#include <sys/wait.h>#include <time.h>#include <unistd.h>Go to the source code of this file.
Macros | |
| #define | _GNU_SOURCE |
| #define | ARENA_MAX_NODES (32 * 1024 * 1024) |
| #define | CACHE_LINE_SIZE 64 |
| #define | DIR_BUF_SIZE 262144 |
| #define | DT_LNK_DIR 14 |
| #define | MAX_DEPTH 64 |
| #define | MAX_PATH_LEN _POSIX_PATH_MAX |
| #define | print_file_type(mask, lf_type, dt_type, name) |
| #define | QUEUE_CAPACITY 16384 |
| #define | QUEUE_MASK (QUEUE_CAPACITY - 1) |
Typedefs | |
| typedef struct CycleNode | CycleNode |
| typedef struct QueuePayload | QueuePayload |
Enumerations | |
| enum | TerminationStatus { TS_SUCCESS = 0 , TS_ERROR = 1 , TS_MATCH = 2 , TS_MATCH_PLUS_ERROR = 3 , TS_SUCCESS = 0 , TS_ERROR = 1 , TS_MATCH = 2 , TS_MATCH_PLUS_ERROR = 3 } |
| enum | TerminationStatus { TS_SUCCESS = 0 , TS_ERROR = 1 , TS_MATCH = 2 , TS_MATCH_PLUS_ERROR = 3 , TS_SUCCESS = 0 , TS_ERROR = 1 , TS_MATCH = 2 , TS_MATCH_PLUS_ERROR = 3 } |
Functions | |
| bool | append_output_buffer (LfContext *lf, OutputBuffer *output, const char *path, size_t path_len, bool append_slash) |
| Append a path to the output buffer, flushing if necessary. | |
| bool | build_full_path (char *dst, size_t dst_size, const char *dir_path, const char *name, size_t *out_len) |
| Build a full file path by concatenating a directory path and a file name. | |
| void | cycle_arena_destroy (void) |
| Destroy the cycle arena and release allocated resources. | |
| void | cycle_arena_init (void) |
| Initialize the cycle arena for tracking visited directories. | |
| void | debug_out (LfContext *lf, int argc, char **argv) |
| Output debug information to stderr. | |
| int | err_out (LfContext *lf, const char *format,...) |
| Thread-safe error output function that writes formatted error messages to the specified error file or stderr. | |
| void * | finder (LfContext *lf, QueuePayload *current_node, QueuePayload *child_node) |
| Process a directory and its entries, applying filters and enqueuing subdirectories. | |
| void | flush_output_buffer (LfContext *lf, OutputBuffer *output) |
| Flush the output buffer to stdout in a thread-safe manner. | |
| bool | init_lf (LfContext *lf, int argc, char **argv) |
| Initialize the file search process. | |
| bool | is_dirsys (const char *) |
| bool | is_hidden (const char *) |
| bool | is_link_cycle (dev_t dev, ino_t ino, CycleNode *parent) |
| int | main (int argc, char **argv) |
| bool | mpmc_dequeue (LfContext *lf, QueuePayload *out_node) |
| Dequeue a task from the MPMCQueue. | |
| bool | mpmc_enqueue (LfContext *lf, const QueuePayload *child_node) |
| Enqueue a task into the MPMCQueue. | |
| MPMCQueue * | mpmc_queue_init () |
| Initialize the MPMCQueue. | |
| int | scan_file (const char *file_spec, const size_t *path_len, LfContext *lf, const unsigned char effective_type, const struct stat *cached_sb, OutputBuffer *output) |
| Scan a file or directory and apply filters based on the LfContext. | |
| int | sort_lf_output (LfContext *lf, int argc, char **argv) |
| Sort the output of the lf command using the system's sort utility. | |
| void * | worker (void *arg) |
| Worker thread function that processes tasks from the MPMCQueue. | |
Variables | |
| const char * | argp_program_bug_address = "billxwaller@gmail.com" |
| const char * | argp_program_version = CM_VERSION |
| char * | debug_p |
| const char | doc [] = _("lf list files\nIf specified, DIRECTORY is the top-level\n directory to search. REGULAR_EXPRESSION is a properly\nformatted regular expression for which matching files\nwill be listed.") |
| char * | exec |
| char * | file_types_p |
| unsigned char const | lf_mask [15] |
| int | lfargc |
| char * | lfargs [3] |
| char * | perms_p |
| TerminationStatus | termination_status |
| struct tm | tm_info |
| #define print_file_type | ( | mask, | |
| lf_type, | |||
| dt_type, | |||
| name ) |
Definition at line 92 of file lf.c.
| #define QUEUE_MASK (QUEUE_CAPACITY - 1) |
| enum TerminationStatus |
| Enumerator | |
|---|---|
| TS_SUCCESS | |
| TS_ERROR | |
| TS_MATCH | |
| TS_MATCH_PLUS_ERROR | |
| TS_SUCCESS | |
| TS_ERROR | |
| TS_MATCH | |
| TS_MATCH_PLUS_ERROR | |
Definition at line 77 of file lf.c.
| enum TerminationStatus |
| Enumerator | |
|---|---|
| TS_SUCCESS | |
| TS_ERROR | |
| TS_MATCH | |
| TS_MATCH_PLUS_ERROR | |
| TS_SUCCESS | |
| TS_ERROR | |
| TS_MATCH | |
| TS_MATCH_PLUS_ERROR | |
Definition at line 77 of file lf.c.
| bool append_output_buffer | ( | LfContext * | lf, |
| OutputBuffer * | output, | ||
| const char * | path, | ||
| size_t | path_len, | ||
| bool | append_slash ) |
Append a path to the output buffer, flushing if necessary.
| lf | A pointer to the LfContext struct containing the output mutex. |
| output | A pointer to the OutputBuffer struct where the path will be appended. |
| path | The path string to append to the output buffer. |
| path_len | The length of the path string. |
| append_slash | A boolean indicating whether to append a slash after the path. |
This function appends a given path to an output buffer. If the buffer is full, it flushes the buffer to stdout. If the path is too long to fit in the buffer, it prints it directly to stdout. The function uses a mutex to ensure thread-safe access to stdout when printing directly.
Definition at line 941 of file lf.c.
References flush_output_buffer().
Referenced by scan_file().
| bool build_full_path | ( | char * | dst, |
| size_t | dst_size, | ||
| const char * | dir_path, | ||
| const char * | name, | ||
| size_t * | out_len ) |
Build a full file path by concatenating a directory path and a file name.
| dst | A pointer to the destination buffer where the full path will be stored. |
| dst_size | The size of the destination buffer. |
| dir_path | The directory path to be concatenated. |
| name | The file name to be concatenated. |
| out_len | A pointer to a size_t variable where the length of the resulting full path will be stored (optional). |
This function constructs a full file path by concatenating the provided directory path and file name. It ensures that there is a single '/' separator between the directory and file name, and it checks for sufficient buffer size before performing the concatenation. If successful, it null-terminates the resulting string and optionally returns its length.
Definition at line 893 of file lf.c.
Referenced by finder().
| void cycle_arena_destroy | ( | void | ) |
Destroy the cycle arena and release allocated resources.
This function releases the resources allocated for the global cycle arena structure. It unmaps the virtual memory space reserved for the arena using munmap, allowing the operating system to reclaim the memory. This function should be called when the cycle arena is no longer needed to prevent memory leaks.
| void cycle_arena_init | ( | void | ) |
Initialize the cycle arena for tracking visited directories.
This function initializes a global cycle arena structure that is used to track visited directories during the file search process. It reserves virtual memory space for the arena using mmap, allowing for efficient allocation of CycleNode structures without immediate physical memory allocation. The arena is designed to handle a maximum number of nodes defined by ARENA_MAX_NODES.
Definition at line 828 of file lf.c.
Referenced by init_lf().
| void debug_out | ( | LfContext * | lf, |
| int | argc, | ||
| char ** | argv ) |
Output debug information to stderr.
| lf | A pointer to the LfContext struct containing the debug settings. |
| argc | The number of command-line arguments. |
| argv | An array of command-line argument strings. |
This function outputs debug information to stderr if debugging is enabled in the LfContext. It includes a timestamp, user information, IP addresses, command-line arguments, and various configuration settings. The output is formatted for readability and includes details about file types, permissions, regex patterns, and other relevant settings.
Definition at line 583 of file lf.c.
References format_local_timestamp(), get_ip_addresses(), get_local_timestamp(), get_user_str(), LF_BLK, LF_CHR, LF_DIR, LF_EXC_REGEX, LF_FIFO, LF_IRUSR, LF_ISGID, LF_ISUID, LF_IWUSR, LF_IXUSR, LF_LNK, LF_REG, LF_REGEX, LF_SOCK, LF_UNKNOWN, LF_USER, and ssnprintf().
Referenced by init_lf().
| int err_out | ( | LfContext * | lf, |
| const char * | format, | ||
| ... ) |
Thread-safe error output function that writes formatted error messages to the specified error file or stderr.
| lf | A pointer to the LfContext struct containing the output mutex and error file information. |
| format | A printf-style format string for the error message. |
| ... | Additional arguments corresponding to the format string. |
This function locks the output mutex to ensure that only one thread can write to the error output at a time. It checks if an error file has been specified; if not, it defaults to stderr. If an error file is specified but not yet opened, it attempts to open it in append mode. The function uses vfprintf to write the formatted error message and then unlocks the mutex before returning.
Definition at line 1479 of file lf.c.
References TS_ERROR.
Referenced by finder().
| void * finder | ( | LfContext * | lf, |
| QueuePayload * | current_node, | ||
| QueuePayload * | child_node ) |
Process a directory and its entries, applying filters and enqueuing subdirectories.
| lf | A pointer to the LfContext struct containing the queue and other context information. |
| current_node | A pointer to the QueuePayload struct representing the current directory to process. |
This function opens the specified directory, reads its entries, and processes each entry according to the specified filters (e.g., file types, hidden files, max depth). It uses fstatat to get metadata for each entry and determines the effective type. If an entry is a directory and meets the criteria, it is enqueued for further processing. The function handles errors gracefully, logging them if necessary, and ensures that output is written in a thread-safe manner.
Definition at line 1105 of file lf.c.
References build_full_path(), err_out(), finder(), flush_output_buffer(), mpmc_enqueue(), scan_file(), and ssnprintf().
Referenced by finder(), and worker().
| void flush_output_buffer | ( | LfContext * | lf, |
| OutputBuffer * | output ) |
Flush the output buffer to stdout in a thread-safe manner.
| lf | A pointer to the LfContext struct containing the output mutex. |
| output | A pointer to the OutputBuffer struct containing the data to be flushed. |
This function writes the contents of the output buffer to stdout using fwrite_unlocked for efficiency. It uses a mutex to ensure that only one thread can write to stdout at a time, preventing interleaved output from multiple threads. After flushing, it resets the length of the output buffer to zero.
Definition at line 921 of file lf.c.
Referenced by append_output_buffer(), and finder().
| bool init_lf | ( | LfContext * | lf, |
| int | argc, | ||
| char ** | argv ) |
Initialize the file search process.
| lf | A pointer to the LfContext struct containing the search settings. |
| argc | The number of command-line arguments. |
| argv | An array of command-line argument strings. |
This function initializes the file search process based on the provided settings in the LfContext struct. It sets up file type inclusion and suppression, compiles regular expressions if specified, and creates a multi-producer, multi-consumer queue for managing directory traversal tasks. It also initializes threads for concurrent processing of directory entries.
suppress file types that aren't included
Definition at line 722 of file lf.c.
References cycle_arena_init(), debug_out(), LF_EXC_REGEX, LF_HIDE, LF_REGEX, mpmc_enqueue(), mpmc_queue_init(), strnz__cpy(), termination_status, TS_ERROR, TS_SUCCESS, and worker().
Referenced by main(), and sort_lf_output().
| bool is_dirsys | ( | const char * | ) |
| bool is_hidden | ( | const char * | ) |
| bool is_link_cycle | ( | dev_t | dev, |
| ino_t | ino, | ||
| CycleNode * | parent ) |
| int main | ( | int | argc, |
| char ** | argv ) |
Definition at line 431 of file lf.c.
References expand_tilde(), init_lf(), is_directory(), is_symlink_to_dir(), is_valid_regex(), LF_HIDE, LF_REGEX, lfargc, lfargs, sort_lf_output(), strnz__cpy(), termination_status, TS_ERROR, and TS_SUCCESS.
| bool mpmc_dequeue | ( | LfContext * | lf, |
| QueuePayload * | out_node ) |
Dequeue a task from the MPMCQueue.
| lf | A pointer to the LfContext struct containing the queue. |
| task | A pointer to the QueuePayload struct where the dequeued task will be stored. |
This function attempts to dequeue a task from the MPMCQueue. It uses atomic operations to ensure thread-safe access to the queue's dequeue position and sequence numbers. If the queue is empty, it yields the processor to reduce contention. If the queue has been shut down, it returns false, allowing for graceful termination of worker threads.
Definition at line 1031 of file lf.c.
Referenced by worker().
| bool mpmc_enqueue | ( | LfContext * | lf, |
| const QueuePayload * | child_node ) |
Enqueue a task into the MPMCQueue.
| lf | A pointer to the LfContext struct containing the queue. |
| dir | A pointer to the QueuePayload struct representing the task to enqueue. |
This function attempts to enqueue a task into the MPMCQueue. It uses atomic operations to ensure thread-safe access to the queue's enqueue position and sequence numbers. If the queue is full, it returns false, allowing for potential recursion or other handling by the caller. The function also includes a spin-wait mechanism to reduce contention when multiple threads are trying to enqueue tasks simultaneously.
Definition at line 992 of file lf.c.
Referenced by finder(), and init_lf().
| MPMCQueue * mpmc_queue_init | ( | ) |
Initialize the MPMCQueue.
| q | A pointer to the MPMCQueue struct representing the queue. |
This function initializes the MPMCQueue by setting up the sequence numbers for each node in the queue and initializing the enqueue and dequeue indexes. It ensures that the queue is ready for concurrent access by multiple producer and consumer threads.
Definition at line 971 of file lf.c.
Referenced by init_lf().
| int scan_file | ( | const char * | file_spec, |
| const size_t * | path_len, | ||
| LfContext * | lf, | ||
| const unsigned char | effective_type, | ||
| const struct stat * | cached_sb, | ||
| OutputBuffer * | output ) |
Scan a file or directory and apply filters based on the LfContext.
| file_spec | The full path of the file or directory to scan. |
| lf | A pointer to the LfContext struct containing the search filters and options. |
| effective_type | The effective type of the file or directory (e.g., DT_REG, DT_DIR). |
| cached_sb | A pointer to a stat struct containing cached metadata for the file, or nullptr if not available. |
| output | A pointer to the OutputBuffer struct where matching paths will be appended. |
This function checks various conditions based on the search filters specified in the LfContext. It evaluates whether the file or directory should be included in the output based on type, regex matching, ownership, permissions, modification time, and size. If all conditions are met, it appends the path to the output buffer. The function also handles caching of stat information to avoid redundant system calls when possible.
Definition at line 1388 of file lf.c.
References append_output_buffer(), LF_EXC_REGEX, LF_IRUSR, LF_ISGID, LF_ISUID, LF_IWUSR, LF_IXUSR, lf_mask, LF_REGEX, LF_USER, termination_status, and TS_MATCH.
Referenced by finder().
| int sort_lf_output | ( | LfContext * | lf, |
| int | argc, | ||
| char ** | argv ) |
Sort the output of the lf command using the system's sort utility.
| lf | A pointer to the LfContext struct containing the search settings. |
| argc | The number of command-line arguments. |
| argv | An array of command-line argument strings. |
This function sets up a pipeline to sort the output of the lf command. It creates a pipe, forks a child process to execute the sort command, and redirects the standard input and output streams accordingly. The sort command is executed with optional flags for parallel processing and buffer size, as well as a reverse sort option if specified in the LfContext. The function waits for the child process to complete before returning.
Definition at line 532 of file lf.c.
References init_lf(), and TS_ERROR.
Referenced by main().
| void * worker | ( | void * | arg | ) |
Worker thread function that processes tasks from the MPMCQueue.
| arg | A pointer to the LfContext struct containing the queue and other context information. |
This function runs in a loop, dequeuing tasks from the MPMCQueue and processing them using the finder function. It decrements the active task count after processing each task. If the active task count reaches zero, it sets the shut_down flag to true, signaling other threads to terminate. The function exits when there are no more tasks to process or when a shutdown is detected.
Definition at line 1072 of file lf.c.
References finder(), and mpmc_dequeue().
Referenced by init_lf().
| const char* argp_program_version = CM_VERSION |
| char doc = _("lf list files\nIf specified, DIRECTORY is the top-level\n directory to search. REGULAR_EXPRESSION is a properly\nformatted regular expression for which matching files\nwill be listed.") |
| unsigned char const lf_mask |
Definition at line 161 of file lf.c.
Referenced by scan_file().
| TerminationStatus termination_status |
Definition at line 107 of file lf.c.
Referenced by init_lf(), main(), and scan_file().