+ if (pat[i] == '/') {
+ if (overflow) return 0;
+ in_bracket = 0;
+ pat += i+1;
+ i = -1;
+ pos += j+1;
+ j = -1;
+ }
+ /* Only store a character if it fits in the buffer, but if
+ * a potential bracket expression is open, the overflow
+ * must be remembered and handled later only if the bracket
+ * is unterminated (and thereby a literal), so as not to
+ * disallow long bracket expressions with short matches. */
+ if (pos+(j+1) < PATH_MAX) {
+ buf[pos+j++] = pat[i];
+ } else if (in_bracket) {
+ overflow = 1;
+ } else {
+ return 0;
+ }
+ /* If we consume any new components, the caller-passed type
+ * or dummy type from above is no longer valid. */
+ type = 0;
+ }
+ buf[pos] = 0;
+ if (!*pat) {
+ /* If we consumed any components above, or if GLOB_MARK is
+ * requested and we don't yet know if the match is a dir,
+ * we must confirm the file exists and/or determine its type.
+ *
+ * If marking dirs, symlink type is inconclusive; we need the
+ * type for the symlink target, and therefore must try stat
+ * first unless type is known not to be a symlink. Otherwise,
+ * or if that fails, use lstat for determining existence to
+ * avoid false negatives in the case of broken symlinks. */
+ struct stat st;
+ if ((flags & GLOB_MARK) && (!type||type==DT_LNK) && !stat(buf, &st)) {
+ if (S_ISDIR(st.st_mode)) type = DT_DIR;
+ else type = DT_REG;
+ }
+ if (!type && lstat(buf, &st)) {
+ if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR)))
+ return GLOB_ABORTED;
+ return 0;
+ }
+ if (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR))
+ return GLOB_NOSPACE;