Update glob(3) to add all the POSIX required options, specifically:

- add GLOB_NOMATCH return value and use it when we don't get a match
- rename GLOB_ABEND to GLOB_ABORTED and use it instead of returning 1
  in some places
- add GLOB_NOESCAPE flag and retire GLOB_QUOTE to compatibility
  section

Suggestions/advice on correct usage of POSIX defines: wollman
This commit is contained in:
Mike Heffner 2002-07-17 04:58:09 +00:00
parent fc7b12d6fc
commit 4a59c3ab55
3 changed files with 48 additions and 33 deletions

View File

@ -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 *);

View File

@ -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

View File

@ -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);
}