diff --git a/include/glob.h b/include/glob.h index d59db3b799e..694ac40589a 100644 --- a/include/glob.h +++ b/include/glob.h @@ -64,13 +64,24 @@ typedef struct { int (*gl_stat)(const char *, struct stat *); } glob_t; +#if __POSIX_VISIBLE >= 199209 +/* Believed to have been introduced in 1003.2-1992 */ #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ #define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ #define GLOB_ERR 0x0004 /* Return on error. */ #define GLOB_MARK 0x0008 /* Append / to matching directories. */ #define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ #define GLOB_NOSORT 0x0020 /* Don't sort. */ +#define GLOB_NOESCAPE 0x2000 /* Disable backslash escaping. */ +/* Error values returned by glob(3) */ +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK was not set. */ +#define GLOB_NOSYS (-4) /* Obsolete: source comptability only. */ +#endif /* __POSIX_VISIBLE >= 199209 */ + +#if __BSD_VISIBLE #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ #define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ @@ -79,11 +90,10 @@ typedef struct { #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ #define GLOB_LIMIT 0x1000 /* limit number of returned paths */ -/* backwards compatibility, this is the old name for this option */ +/* source compatibility, these are the old names */ #define GLOB_MAXPATH GLOB_LIMIT - -#define GLOB_NOSPACE (-1) /* Malloc call failed. */ -#define GLOB_ABEND (-2) /* Unignored error. */ +#define GLOB_ABEND GLOB_ABORTED +#endif /* __BSD_VISIBLE */ __BEGIN_DECLS int glob(const char *, int, int (*)(const char *, int), glob_t *); diff --git a/lib/libc/gen/glob.3 b/lib/libc/gen/glob.3 index daca64ed5d1..9aac9b0cc81 100644 --- a/lib/libc/gen/glob.3 +++ b/lib/libc/gen/glob.3 @@ -187,9 +187,15 @@ consisting of only .Fa pattern , with the number of total pathnames is set to 1, and the number of matched pathnames set to 0. +The effect of backslash escaping is present in the pattern returned. +.It Dv GLOB_NOESCAPE +By default, a backslash +.Pq Ql \e +character is used to escape the following character in the pattern, +avoiding any special interpretation of the character. If -.Dv GLOB_QUOTE -is set, its effect is present in the pattern returned. +.Dv GLOB_NOESCAPE +is set, backslash escaping is disabled. .It Dv GLOB_NOSORT By default, the pathnames are sorted in ascending .Tn ASCII @@ -250,12 +256,6 @@ if it does not contain any of the special characters ``*'', ``?'' or ``[''. is provided to simplify implementing the historic .Xr csh 1 globbing behavior and should probably not be used anywhere else. -.It Dv GLOB_QUOTE -Use the backslash -.Pq Ql \e -character for quoting: every occurrence of -a backslash followed by a character in the pattern is replaced by that -character, avoiding any special interpretation of the character. .It Dv GLOB_TILDE Expand patterns that start with .Ql ~ @@ -304,7 +304,7 @@ If returns non-zero, .Fn glob stops the scan and returns -.Dv GLOB_ABEND +.Dv GLOB_ABORTED after setting .Fa gl_pathc and @@ -386,12 +386,16 @@ was 0 was specified in the flags and .Fa pglob\->gl_matchc or more patterns were matched. -.It Dv GLOB_ABEND +.It Dv GLOB_ABORTED The scan was stopped because an error was encountered and either .Dv GLOB_ERR was set or .Fa \*(lp*errfunc\*(rp\*(lp\*(rp returned non-zero. +.It Dv GLOB_NOMATCH +The pattern did not match a pathname and +.Dv GLOB_NOCHECK +was not set. .El .Pp The arguments @@ -430,7 +434,6 @@ that the flags .Dv GLOB_LIMIT , .Dv GLOB_MAGCHAR , .Dv GLOB_NOMAGIC , -.Dv GLOB_QUOTE , and .Dv GLOB_TILDE , and the fields diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c index e50c11d3d71..5e159dd9ef9 100644 --- a/lib/libc/gen/glob.c +++ b/lib/libc/gen/glob.c @@ -182,7 +182,10 @@ glob(pattern, flags, errfunc, pglob) bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; - if (flags & GLOB_QUOTE) { + if (flags & GLOB_NOESCAPE) + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + else { /* Protect the quoted characters. */ while (bufnext < bufend && (c = *patnext++) != EOS) if (c == QUOTE) { @@ -195,9 +198,6 @@ glob(pattern, flags, errfunc, pglob) else *bufnext++ = c; } - else - while (bufnext < bufend && (c = *patnext++) != EOS) - *bufnext++ = c; *bufnext = EOS; if (flags & GLOB_BRACE) @@ -415,8 +415,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob) * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 - * if things went well, nonzero if errors occurred. It is not an error - * to find no matches. + * if things went well, nonzero if errors occurred. */ static int glob0(pattern, pglob, limit) @@ -493,12 +492,15 @@ glob0(pattern, pglob, limit) * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ - if (pglob->gl_pathc == oldpathc && - ((pglob->gl_flags & GLOB_NOCHECK) || - ((pglob->gl_flags & GLOB_NOMAGIC) && - !(pglob->gl_flags & GLOB_MAGCHAR)))) - return(globextend(pattern, pglob, limit)); - else if (!(pglob->gl_flags & GLOB_NOSORT)) + if (pglob->gl_pathc == oldpathc) { + if (((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR)))) + return(globextend(pattern, pglob, limit)); + else + return(GLOB_NOMATCH); + } + if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); @@ -557,7 +559,7 @@ glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit) (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) - return (1); + return (GLOB_ABORTED); *pathend++ = SEP; *pathend = EOS; } @@ -572,7 +574,7 @@ glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit) if (ismeta(*p)) anymeta = 1; if (q + 1 > pathend_last) - return (1); + return (GLOB_ABORTED); *q++ = *p++; } @@ -581,7 +583,7 @@ glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit) pattern = p; while (*pattern == SEP) { if (pathend + 1 > pathend_last) - return (1); + return (GLOB_ABORTED); *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ @@ -611,7 +613,7 @@ glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit) struct dirent *(*readdirfunc)(); if (pathend > pathend_last) - return (1); + return (GLOB_ABORTED); *pathend = EOS; errno = 0; @@ -619,10 +621,10 @@ glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit) /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { if (g_Ctoc(pathbuf, buf, sizeof(buf))) - return (GLOB_ABEND); + return (GLOB_ABORTED); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) - return (GLOB_ABEND); + return (GLOB_ABORTED); } return(0); }