summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2012-03-10 11:29:32 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2012-03-14 22:28:27 -0700
commitc6e3ea61d9f08aa0128a0eb13d31a2fbad376f99 (patch)
tree657c6157dd4b4c250a4bbdf770ef62cfb2062571 /lib
parent354516cd121a7cdbad1397662b718b04c349692a (diff)
downloadgrep-c6e3ea61d9f08aa0128a0eb13d31a2fbad376f99.tar.gz
grep: -r no longer follows symlinks; use fts
Change -r to follow only command-line symlinks, and by default to read only devices named on the command line. This is a simple way to get a more-useful behavior when searching random directories; the idea is to use 'find' if you want something fancy. -R acts as before and gets a new alias --dereference-recursive. The code now uses fts internally, so it is more robust and faster with large hierarchies. * .gitignore: Remove lib/savedir.c, lib/savedir.h. * tests/symlink: New file * Makefile.boot (LIB_OBJS_core): Remove isdir.o, savedir.o. Perhaps other changes are needed too, but I'm not sure what this makefile is for. * NEWS: Document changes. * doc/grep.texi (File and Directory Selection): Likewise. * bootstrap.conf (gnulib_modules): Remove dirent, dirname, isdir, open. Add fstatat, fts, openat-safer. * lib/Makefile.am (libgreputils_a_SOURCES): Remove savedir.c, savedir.h. * lib/savedir.c, lib/savedir.h: Remove. * po/POTFILES.in: Add lib/openat-die.c. * src/main.c: Include fcntl-safer.h, fts_.h. Don't include isdir.h, savedir.h. (struct stats, stats_base): Remove. (long_options, usage, main): Add --dereference-recursive and implement -r vs -R. (filename_prefix_len, fts_options): New static vars. (basic_fts_options, READ_COMMAND_LINE_DEVICES): New constants. (devices): Now defaults to READ_COMMAND_LINE_DEVICES. (reset, grep): Now takes just struct stat rather than file name and struct stats. All callers changed. (fillbuf): Now takes struct stat reather than struct stats. All callers changed. (grep): Don't worry about recursing too deeply; fts and grepdesc handle this now. (is_device_mode, grepdirent, grepdesc, grep_command_line_args): New functions. (grepfile): New args DIRDESC, FOLLOW, COMMAND_LINE. Remove struct stats arg. All callers changed. Use openat_safer rather than open. Use desc == STDIN_FILENO to tell whether we're reading "-". Don't worry about EINTR when closing -- not possible, since we're not catching signals. * tests/Makefile.am (TESTS): Add symlink. * tests/symlink: New file.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/savedir.c163
-rw-r--r--lib/savedir.h11
3 files changed, 1 insertions, 175 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 04ae51ea..527c6f54 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -32,7 +32,7 @@ INCLUDES = -I.. -I$(srcdir)
AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
libgreputils_a_SOURCES += \
- colorize.c colorize.h savedir.c savedir.h
+ colorize.c colorize.h
EXTRA_DIST += colorize-posix.c colorize-w32.c
diff --git a/lib/savedir.c b/lib/savedir.c
deleted file mode 100644
index 3f93c165..00000000
--- a/lib/savedir.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* savedir.c -- save the list of files in a directory in a string
- Copyright (C) 1990, 1997-2001, 2009-2012 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#include <config.h>
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#ifdef CLOSEDIR_VOID
-/* Fake a return value. */
-# define CLOSEDIR(d) (closedir (d), 0)
-#else
-# define CLOSEDIR(d) closedir (d)
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <fnmatch.h>
-#include "savedir.h"
-#include "xalloc.h"
-
-static char *path;
-static size_t pathlen;
-
-extern int isdir (const char *name);
-
-static int
-isdir1 (const char *dir, const char *file)
-{
- size_t dirlen = strlen (dir);
- size_t filelen = strlen (file);
-
- while (dirlen && dir[dirlen - 1] == '/')
- dirlen--;
-
- if ((dirlen + filelen + 2) > pathlen)
- {
- pathlen *= 2;
- if ((dirlen + filelen + 2) > pathlen)
- pathlen = dirlen + filelen + 2;
-
- path = xrealloc (path, pathlen);
- }
-
- memcpy (path, dir, dirlen);
- path[dirlen] = '/';
- strcpy (path + dirlen + 1, file);
- return isdir (path);
-}
-
-/* Return a freshly allocated string containing the filenames
- in directory DIR, separated by '\0' characters;
- the end is marked by two '\0' characters in a row.
- NAME_SIZE is the number of bytes to initially allocate
- for the string; it will be enlarged as needed.
- Return NULL if DIR cannot be opened or if out of memory. */
-char *
-savedir (const char *dir, off_t name_size, struct exclude *included_patterns,
- struct exclude *excluded_patterns, struct exclude *excluded_directory_patterns )
-{
- DIR *dirp;
- struct dirent *dp;
- char *name_space;
- char *namep;
-
- dirp = opendir (dir);
- if (dirp == NULL)
- return NULL;
-
- /* Be sure name_size is at least `1' so there's room for
- the final NUL byte. */
- if (name_size <= 0)
- name_size = 1;
-
- name_space = (char *) malloc (name_size);
- if (name_space == NULL)
- {
- closedir (dirp);
- return NULL;
- }
- namep = name_space;
-
- while ((dp = readdir (dirp)) != NULL)
- {
- /* Skip "." and ".." (some NFS file systems' directories lack them). */
- if (dp->d_name[0] != '.'
- || (dp->d_name[1] != '\0'
- && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
- {
- size_t namlen = strlen (dp->d_name);
- size_t size_needed = (namep - name_space) + namlen + 2;
-
- if ((included_patterns || excluded_patterns)
- && !isdir1 (dir, dp->d_name))
- {
- if (included_patterns
- && excluded_file_name (included_patterns, dp->d_name))
- continue;
- if (excluded_patterns
- && excluded_file_name (excluded_patterns, dp->d_name))
- continue;
- }
-
- if ( excluded_directory_patterns
- && isdir1 (dir, dp->d_name) )
- {
- if (excluded_directory_patterns
- && excluded_file_name (excluded_directory_patterns, dp->d_name))
- continue;
- }
-
- if (size_needed > name_size)
- {
- char *new_name_space;
-
- while (size_needed > name_size)
- name_size += 1024;
-
- new_name_space = realloc (name_space, name_size);
- if (new_name_space == NULL)
- {
- closedir (dirp);
- goto fail;
- }
- namep = new_name_space + (namep - name_space);
- name_space = new_name_space;
- }
- strcpy (namep, dp->d_name);
- namep += namlen + 1;
- }
- }
- *namep = '\0';
- if (CLOSEDIR (dirp))
- {
- fail:
- free (name_space);
- name_space = NULL;
- }
- if (path)
- {
- free (path);
- path = NULL;
- pathlen = 0;
- }
- return name_space;
-}
diff --git a/lib/savedir.h b/lib/savedir.h
deleted file mode 100644
index 00cb1a98..00000000
--- a/lib/savedir.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#if !defined SAVEDIR_H_
-# define SAVEDIR_H_
-
-#include "exclude.h"
-
-extern char *
-savedir (const char *dir, off_t name_size,
- struct exclude *, struct exclude *,
- struct exclude *);
-
-#endif