Skip to content

Commit

Permalink
Merge branch 'nd/path-max-must-go'
Browse files Browse the repository at this point in the history
* nd/path-max-must-go:
  prep_exclude: remove the artificial PATH_MAX limit
  dir.h: move struct exclude declaration to top level
  dir.c: coding style fix
  • Loading branch information
Junio C Hamano committed Jul 22, 2014
2 parents 10b944b + aceb942 commit 4328190
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 46 deletions.
59 changes: 34 additions & 25 deletions dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,7 @@ int add_excludes_from_file_to_list(const char *fname,
buf = xrealloc(buf, size+1);
buf[size++] = '\n';
}
}
else {
} else {
size = xsize_t(st.st_size);
if (size == 0) {
close(fd);
Expand Down Expand Up @@ -793,17 +792,19 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)

group = &dir->exclude_list_group[EXC_DIRS];

/* Pop the exclude lists from the EXCL_DIRS exclude_list_group
/*
* Pop the exclude lists from the EXCL_DIRS exclude_list_group
* which originate from directories not in the prefix of the
* path being checked. */
* path being checked.
*/
while ((stk = dir->exclude_stack) != NULL) {
if (stk->baselen <= baselen &&
!strncmp(dir->basebuf, base, stk->baselen))
!strncmp(dir->basebuf.buf, base, stk->baselen))
break;
el = &group->el[dir->exclude_stack->exclude_ix];
dir->exclude_stack = stk->prev;
dir->exclude = NULL;
free((char *)el->src); /* see strdup() below */
free((char *)el->src); /* see strbuf_detach() below */
clear_exclude_list(el);
free(stk);
group->nr--;
Expand All @@ -813,17 +814,25 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
if (dir->exclude)
return;

/*
* Lazy initialization. All call sites currently just
* memset(dir, 0, sizeof(*dir)) before use. Changing all of
* them seems lots of work for little benefit.
*/
if (!dir->basebuf.buf)
strbuf_init(&dir->basebuf, PATH_MAX);

/* Read from the parent directories and push them down. */
current = stk ? stk->baselen : -1;
strbuf_setlen(&dir->basebuf, current < 0 ? 0 : current);
while (current < baselen) {
struct exclude_stack *stk = xcalloc(1, sizeof(*stk));
const char *cp;

if (current < 0) {
cp = base;
current = 0;
}
else {
} else {
cp = strchr(base + current + 1, '/');
if (!cp)
die("oops in prep_exclude");
Expand All @@ -833,48 +842,47 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
stk->baselen = cp - base;
stk->exclude_ix = group->nr;
el = add_exclude_list(dir, EXC_DIRS, NULL);
memcpy(dir->basebuf + current, base + current,
stk->baselen - current);
strbuf_add(&dir->basebuf, base + current, stk->baselen - current);
assert(stk->baselen == dir->basebuf.len);

/* Abort if the directory is excluded */
if (stk->baselen) {
int dt = DT_DIR;
dir->basebuf[stk->baselen - 1] = 0;
dir->basebuf.buf[stk->baselen - 1] = 0;
dir->exclude = last_exclude_matching_from_lists(dir,
dir->basebuf, stk->baselen - 1,
dir->basebuf + current, &dt);
dir->basebuf[stk->baselen - 1] = '/';
dir->basebuf.buf, stk->baselen - 1,
dir->basebuf.buf + current, &dt);
dir->basebuf.buf[stk->baselen - 1] = '/';
if (dir->exclude &&
dir->exclude->flags & EXC_FLAG_NEGATIVE)
dir->exclude = NULL;
if (dir->exclude) {
dir->basebuf[stk->baselen] = 0;
dir->exclude_stack = stk;
return;
}
}

/* Try to read per-directory file unless path is too long */
if (dir->exclude_per_dir &&
stk->baselen + strlen(dir->exclude_per_dir) < PATH_MAX) {
strcpy(dir->basebuf + stk->baselen,
dir->exclude_per_dir);
/* Try to read per-directory file */
if (dir->exclude_per_dir) {
/*
* dir->basebuf gets reused by the traversal, but we
* need fname to remain unchanged to ensure the src
* member of each struct exclude correctly
* back-references its source file. Other invocations
* of add_exclude_list provide stable strings, so we
* strdup() and free() here in the caller.
* strbuf_detach() and free() here in the caller.
*/
el->src = strdup(dir->basebuf);
add_excludes_from_file_to_list(dir->basebuf,
dir->basebuf, stk->baselen, el, 1);
struct strbuf sb = STRBUF_INIT;
strbuf_addbuf(&sb, &dir->basebuf);
strbuf_addstr(&sb, dir->exclude_per_dir);
el->src = strbuf_detach(&sb, NULL);
add_excludes_from_file_to_list(el->src, el->src,
stk->baselen, el, 1);
}
dir->exclude_stack = stk;
current = stk->baselen;
}
dir->basebuf[baselen] = '\0';
strbuf_setlen(&dir->basebuf, baselen);
}

/*
Expand Down Expand Up @@ -1671,4 +1679,5 @@ void clear_directory(struct dir_struct *dir)
free(stk);
stk = prev;
}
strbuf_release(&dir->basebuf);
}
44 changes: 23 additions & 21 deletions dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ struct dir_entry {
#define EXC_FLAG_MUSTBEDIR 8
#define EXC_FLAG_NEGATIVE 16

struct exclude {
/*
* This allows callers of last_exclude_matching() etc.
* to determine the origin of the matching pattern.
*/
struct exclude_list *el;

const char *pattern;
int patternlen;
int nowildcardlen;
const char *base;
int baselen;
int flags;

/*
* Counting starts from 1 for line numbers in ignore files,
* and from -1 decrementing for patterns from CLI args.
*/
int srcpos;
};

/*
* Each excludes file will be parsed into a fresh exclude_list which
* is appended to the relevant exclude_list_group (either EXC_DIRS or
Expand All @@ -32,26 +53,7 @@ struct exclude_list {
/* origin of list, e.g. path to filename, or descriptive string */
const char *src;

struct exclude {
/*
* This allows callers of last_exclude_matching() etc.
* to determine the origin of the matching pattern.
*/
struct exclude_list *el;

const char *pattern;
int patternlen;
int nowildcardlen;
const char *base;
int baselen;
int flags;

/*
* Counting starts from 1 for line numbers in ignore files,
* and from -1 decrementing for patterns from CLI args.
*/
int srcpos;
} **excludes;
struct exclude **excludes;
};

/*
Expand Down Expand Up @@ -117,7 +119,7 @@ struct dir_struct {
*/
struct exclude_stack *exclude_stack;
struct exclude *exclude;
char basebuf[PATH_MAX];
struct strbuf basebuf;
};

/*
Expand Down

0 comments on commit 4328190

Please sign in to comment.