Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144485210
D50485.1774917189.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D50485.1774917189.diff
View Options
diff --git a/include/glob.h b/include/glob.h
--- a/include/glob.h
+++ b/include/glob.h
@@ -50,8 +50,15 @@
size_t gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
- /* Copy of errfunc parameter to glob. */
- int (*gl_errfunc)(const char *, int);
+ /* Copy of error callback parameter to glob. */
+ union {
+ int (*gl_errfunc)(const char *, int);
+#ifdef __BLOCKS__
+ int (^gl_errblk)(const char *, int);
+#else
+ void *gl_errblk;
+#endif
+ };
/*
* Alternate filesystem access methods for glob; replacement
@@ -90,6 +97,7 @@
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
#define GLOB_LIMIT 0x1000 /* limit number of returned paths */
+#define _GLOB_ERR_BLOCK 0x08000000 /* (internal) error callback is a block */
/* source compatibility, these are the old names */
#define GLOB_MAXPATH GLOB_LIMIT
@@ -99,6 +107,10 @@
__BEGIN_DECLS
int glob(const char * __restrict, int,
int (*)(const char *, int), glob_t * __restrict);
+#ifdef __BLOCKS__
+int glob_b(const char * __restrict, int,
+ int (^)(const char *, int), glob_t * __restrict);
+#endif
void globfree(glob_t *);
__END_DECLS
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -172,6 +172,7 @@
.if ${COMPILER_FEATURES:Mblocks}
CFLAGS.fts.c= -fblocks
+CFLAGS.glob.c= -fblocks
.endif
CFLAGS.arc4random.c= -I${SRCTOP}/sys -I${SRCTOP}/sys/crypto/chacha20
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -459,6 +459,7 @@
aio_write2;
execvpe;
fts_open_b;
+ glob_b;
psiginfo;
rtld_get_var;
rtld_set_var;
diff --git a/lib/libc/gen/glob.3 b/lib/libc/gen/glob.3
--- a/lib/libc/gen/glob.3
+++ b/lib/libc/gen/glob.3
@@ -27,11 +27,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd December 20, 2011
+.Dd June 02, 2025
.Dt GLOB 3
.Os
.Sh NAME
.Nm glob ,
+.Nm glob_b,
.Nm globfree
.Nd generate pathnames matching a pattern
.Sh LIBRARY
@@ -39,7 +40,9 @@
.Sh SYNOPSIS
.In glob.h
.Ft int
-.Fn glob "const char * restrict pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t * restrict pglob"
+.Fn glob "const char * restrict pattern" "int flags" "int (*errfunc)(const char *epath, int errno)" "glob_t * restrict pglob"
+.Ft int
+.Fn glob_b "const char * restrict pattern" "int flags" "int (^errblk)(const char *epath, int errno)" "glob_t * restrict pglob"
.Ft void
.Fn globfree "glob_t *pglob"
.Sh DESCRIPTION
@@ -272,10 +275,24 @@
.Pf non- Dv NULL ,
.Fn glob
calls
-.Fa \*(lp*errfunc\*(rp Ns ( Fa path , errno ) ,
+.Fa \*(lp*errfunc\*(rp Ns ( Fa path , errno ) .
+This may be unintuitive: a pattern like
+.Ql */Makefile
+will try to
+.Xr stat 2
+.Ql foo/Makefile
+even if
+.Ql foo
+is not a directory, resulting in a
+call to
+.Fa errfunc .
+The error routine can suppress this action by testing for
+.Er ENOENT
+and
+.Er ENOTDIR ;
however, the
.Dv GLOB_ERR
-flag will cause an immediate
+flag will still cause an immediate
return when this happens.
.Pp
If
@@ -307,16 +324,27 @@
returns zero, the error is ignored.
.Pp
The
+.Fn glob_b
+function is like
+.Fn glob
+except that the error callback is a block pointer instead of a function
+pointer.
+.Pp
+The
.Fn globfree
function frees any space associated with
.Fa pglob
from a previous call(s) to
-.Fn glob .
+.Fn glob
+or
+.Fn glob_b .
.Sh RETURN VALUES
On successful completion,
.Fn glob
-returns zero.
-In addition the fields of
+and
+.Fn glob_b
+return zero.
+In addition, the fields of
.Fa pglob
contain the values described below:
.Bl -tag -width GLOB_NOCHECK
@@ -324,12 +352,16 @@
contains the total number of matched pathnames so far.
This includes other matches from previous invocations of
.Fn glob
+or
+.Fn glob_b .
if
.Dv GLOB_APPEND
was specified.
.It Fa gl_matchc
contains the number of matched pathnames in the current invocation of
-.Fn glob .
+.Fn glob
+or
+.Fn glob_b .
.It Fa gl_flags
contains a copy of the
.Fa flags
@@ -352,6 +384,8 @@
.Pp
If
.Fn glob
+or
+.Fn glob_b
terminates due to an error, it sets errno and returns one of the
following non-zero constants, which are defined in the include
file
@@ -397,6 +431,14 @@
g.gl_pathv[1] = "-l";
execvp("ls", g.gl_pathv);
.Ed
+.Sh CAVEATS
+The
+.Fn glob
+and
+.Fn glob_b
+functions
+will not match filenames that begin with a period
+unless this is specifically requested (e.g., by ".*").
.Sh SEE ALSO
.Xr sh 1 ,
.Xr fnmatch 3 ,
@@ -435,6 +477,10 @@
.Fn globfree
functions first appeared in
.Bx 4.4 .
+The
+.Fn glob_b
+function first appeared in
+.Fx 15.0 .
.Sh BUGS
Patterns longer than
.Dv MAXPATHLEN
@@ -442,7 +488,9 @@
.Pp
The
.Fn glob
-argument
+and
+.Fn glob_b
+functions
may fail and set errno for any of the errors specified for the
library routines
.Xr stat 2 ,
diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c
--- a/lib/libc/gen/glob.c
+++ b/lib/libc/gen/glob.c
@@ -88,8 +88,11 @@
#include <unistd.h>
#include <wchar.h>
+#include "block_abi.h"
#include "collate.h"
+typedef DECLARE_BLOCK(int, glob_b_block, const char*, int);
+
/*
* glob(3) expansion limits. Stop the expansion if any of these limits
* is reached. This caps the runtime in the face of DoS attacks. See
@@ -179,9 +182,8 @@
static void qprintf(const char *, Char *);
#endif
-int
-glob(const char * __restrict pattern, int flags,
- int (*errfunc)(const char *, int), glob_t * __restrict pglob)
+static int
+__glob(const char *pattern, glob_t *pglob)
{
struct glob_limit limit = { 0, 0, 0, 0, 0 };
const char *patnext;
@@ -192,25 +194,23 @@
int too_long;
patnext = pattern;
- if (!(flags & GLOB_APPEND)) {
+ if (!(pglob->gl_flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
- if (!(flags & GLOB_DOOFFS))
+ if (!(pglob->gl_flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
- if (flags & GLOB_LIMIT) {
+ if (pglob->gl_flags & GLOB_LIMIT) {
limit.l_path_lim = pglob->gl_matchc;
if (limit.l_path_lim == 0)
limit.l_path_lim = GLOB_LIMIT_PATH;
}
- pglob->gl_flags = flags & ~GLOB_MAGCHAR;
- pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
bufnext = patbuf;
bufend = bufnext + MAXPATHLEN - 1;
too_long = 1;
- if (flags & GLOB_NOESCAPE) {
+ if (pglob->gl_flags & GLOB_NOESCAPE) {
memset(&mbs, 0, sizeof(mbs));
while (bufnext <= bufend) {
clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs);
@@ -250,15 +250,45 @@
return (err_nomatch(pglob, &limit, pattern));
*bufnext = EOS;
- if (flags & GLOB_BRACE)
+ if (pglob->gl_flags & GLOB_BRACE)
return (globexp0(patbuf, pglob, &limit, pattern));
else
return (glob0(patbuf, pglob, &limit, pattern));
}
+int
+glob(const char * __restrict pattern, int flags,
+ int (*errfunc)(const char *, int), glob_t * __restrict pglob)
+{
+ int rv;
+
+ pglob->gl_flags = flags & ~(GLOB_MAGCHAR | _GLOB_ERR_BLOCK);
+ pglob->gl_errfunc = errfunc;
+ rv = __glob(pattern, pglob);
+ pglob->gl_errfunc = NULL;
+
+ return (rv);
+}
+
+int
+glob_b(const char * __restrict pattern, int flags,
+ glob_b_block block, glob_t * __restrict pglob)
+{
+ int rv;
+
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_flags |= _GLOB_ERR_BLOCK;
+ pglob->gl_errblk = block;
+ rv = __glob(pattern, pglob);
+ pglob->gl_errblk = NULL;
+
+ return (rv);
+}
+
static int
globexp0(const Char *pattern, glob_t *pglob, struct glob_limit *limit,
- const char *origpat) {
+ const char *origpat)
+{
int rv;
size_t oldpathc;
@@ -724,7 +754,7 @@
return (GLOB_NOSPACE);
}
*pathend = EOS;
- if (pglob->gl_errfunc != NULL &&
+ if ((pglob->gl_errfunc != NULL || pglob->gl_errblk != NULL) &&
g_Ctoc(pathbuf, buf, sizeof(buf))) {
errno = E2BIG;
return (GLOB_NOSPACE);
@@ -1085,10 +1115,20 @@
}
static int
-err_aborted(glob_t *pglob, int err, char *buf) {
- if ((pglob->gl_errfunc != NULL && pglob->gl_errfunc(buf, err)) ||
- (pglob->gl_flags & GLOB_ERR))
+err_aborted(glob_t *pglob, int err, char *buf)
+{
+ int rv = 0;
+
+ if ((pglob->gl_flags & _GLOB_ERR_BLOCK) != 0) {
+ if (pglob->gl_errblk != NULL)
+ rv = CALL_BLOCK(pglob->gl_errblk, buf, errno);
+ } else if (pglob->gl_errfunc != NULL) {
+ rv = pglob->gl_errfunc(buf, errno);
+ }
+ /* GLOB_ERR is allowed to override the error callback function. */
+ if (rv != 0 || pglob->gl_flags & GLOB_ERR) {
return (GLOB_ABORTED);
+ }
return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 31, 12:33 AM (35 m, 43 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28232791
Default Alt Text
D50485.1774917189.diff (8 KB)
Attached To
Mode
D50485: glob: Add blocks support
Attached
Detach File
Event Timeline
Log In to Comment