Skip to content

Commit

Permalink
Add support for a --one-device flag
Browse files Browse the repository at this point in the history
  • Loading branch information
umanwizard committed Jan 11, 2015
1 parent 684a812 commit 8daa0c5
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 4 deletions.
9 changes: 8 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,14 @@ int main(int argc, char **argv) {
log_debug("searching path %s for %s", paths[i], opts.query);
symhash = NULL;
ignores *ig = init_ignore(root_ignores, "", 0);
search_dir(ig, base_paths[i], paths[i], 0);
struct stat s = {.st_dev = 0};
/* The device is ignored if opts.one_dev is false, so it's fine
* to leave it at the default 0
*/
if (opts.one_dev && lstat(paths[i], &s) == -1) {
log_err("Failed to get device information for path %s. Skipping...", paths[i]);
}
search_dir(ig, base_paths[i], paths[i], 0, s.st_dev);
cleanup_ignore(ig);
}
pthread_mutex_lock(&work_queue_mtx);
Expand Down
3 changes: 3 additions & 0 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Search Options:\n\
(literal file/directory names also allowed)\n\
--ignore-dir NAME Alias for --ignore for compatibility with ack.\n\
-m --max-count NUM Skip the rest of a file after NUM matches (Default: 10,000)\n\
--one-device Don't follow links to other devices.\n\
-p --path-to-agignore STRING\n\
Use .agignore file at STRING\n\
-Q --literal Don't parse PATTERN as a regular expression\n\
Expand Down Expand Up @@ -125,6 +126,7 @@ void init_options(void) {
opts.color_match = ag_strdup(color_match);
opts.color_line_number = ag_strdup(color_line_number);
opts.use_thread_affinity = TRUE;
opts.one_dev = FALSE;
}

void cleanup_options(void) {
Expand Down Expand Up @@ -230,6 +232,7 @@ void parse_options(int argc, char **argv, char **base_paths[], char **paths[]) {
{ "nopager", no_argument, NULL, 0 },
{ "null", no_argument, NULL, '0' },
{ "only-matching", no_argument, NULL, 'o' },
{ "one-device", no_argument, &opts.one_dev, 1 },
{ "pager", required_argument, NULL, 0 },
{ "parallel", no_argument, &opts.parallel, 1 },
{ "passthrough", no_argument, &opts.passthrough, 1 },
Expand Down
1 change: 1 addition & 0 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ typedef struct {
int literal_ends_wordchar;
size_t max_matches_per_file;
int max_search_depth;
int one_dev;
int only_matching;
char path_sep;
char *path_to_agignore;
Expand Down
17 changes: 15 additions & 2 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,8 @@ static int check_symloop_leave(dirkey_t *dirkey) {
/* TODO: Append matches to some data structure instead of just printing them out.
* Then ag can have sweet summaries of matches/files scanned/time/etc.
*/
void search_dir(ignores *ig, const char *base_path, const char *path, const int depth) {
void search_dir(ignores *ig, const char *base_path, const char *path, const int depth,
dev_t original_dev) {
struct dirent **dir_list = NULL;
struct dirent *dir = NULL;
scandir_baton_t scandir_baton;
Expand Down Expand Up @@ -445,6 +446,17 @@ void search_dir(ignores *ig, const char *base_path, const char *path, const int
queue_item = NULL;
dir = dir_list[i];
ag_asprintf(&dir_full_path, "%s/%s", path, dir->d_name);
if (opts.one_dev) {
struct stat s;
if (lstat(dir_full_path, &s) != 0) {
log_err("Failed to get device information for %s. Skipping...", dir->d_name);
goto cleanup;
}
if (s.st_dev != original_dev) {
log_debug("File %s crosses a device boundary (is probably a mount point.) Skipping...", dir->d_name);
goto cleanup;
}
}

/* If a link points to a directory then we need to treat it as a directory. */
if (!opts.follow_symlinks && is_symlink(path, dir)) {
Expand Down Expand Up @@ -491,7 +503,8 @@ void search_dir(ignores *ig, const char *base_path, const char *path, const int
// #else
// child_ig = init_ignore(ig, dir->d_name, dir->d_namlen);
// #endif
search_dir(child_ig, base_path, dir_full_path, depth + 1);
search_dir(child_ig, base_path, dir_full_path, depth + 1,
original_dev);
cleanup_ignore(child_ig);
} else {
if (opts.max_search_depth == DEFAULT_MAX_SEARCH_DEPTH) {
Expand Down
2 changes: 1 addition & 1 deletion src/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ void search_file(const char *file_full_path);

void *search_file_worker(void *i);

void search_dir(ignores *ig, const char *base_path, const char *path, const int depth);
void search_dir(ignores *ig, const char *base_path, const char *path, const int depth, dev_t original_dev);

#endif

0 comments on commit 8daa0c5

Please sign in to comment.