Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157533892
D2877.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D2877.diff
View Options
Index: include/err.h
===================================================================
--- include/err.h
+++ include/err.h
@@ -59,6 +59,9 @@
void vwarnx(const char *, __va_list) __printflike(1, 0);
void err_set_file(void *);
void err_set_exit(void (*)(int));
+#ifdef __BLOCKS__
+void err_set_exit_b(void (^)(int));
+#endif /* __BLOCKS__ */
__END_DECLS
#endif /* !_ERR_H_ */
Index: include/fts.h
===================================================================
--- include/fts.h
+++ include/fts.h
@@ -44,8 +44,12 @@
int fts_rfd; /* fd for root */
__size_t fts_pathlen; /* sizeof(path) */
__size_t fts_nitems; /* elements in the sort array */
- int (*fts_compar) /* compare function */
- (const struct _ftsent * const *, const struct _ftsent * const *);
+ union {
+ int (*fts_compar) /* compare function */
+ (const struct _ftsent * const *,
+ const struct _ftsent * const *);
+ void *fts_compar_b; /* compare block */
+ };
#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */
#define FTS_LOGICAL 0x002 /* logical walk */
@@ -59,6 +63,7 @@
#define FTS_NAMEONLY 0x100 /* (private) child names only */
#define FTS_STOP 0x200 /* (private) unrecoverable error */
+#define FTS_COMPAR_B 0x400 /* (private) use block compare */
int fts_options; /* fts_open options, global flags */
void *fts_clientptr; /* thunk for sort function */
} FTS;
@@ -128,6 +133,10 @@
#define fts_get_stream(ftsent) ((ftsent)->fts_fts)
FTS *fts_open(char * const *, int,
int (*)(const FTSENT * const *, const FTSENT * const *));
+#ifdef __BLOCKS__
+FTS *fts_open_b(char * const *, int,
+ int (^)(const FTSENT * const *, const FTSENT * const *));
+#endif /* __BLOCKS__ */
FTSENT *fts_read(FTS *);
int fts_set(FTS *, FTSENT *, int);
void fts_set_clientptr(FTS *, void *);
Index: include/glob.h
===================================================================
--- include/glob.h
+++ include/glob.h
@@ -51,8 +51,12 @@
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 errfunc/errblock parameter to
+ glob/glob_b.*/
+ union {
+ int (*gl_errfunc)(const char *, int);
+ void *gl_errblk;
+ };
/*
* Alternate filesystem access methods for glob; replacement
@@ -92,6 +96,8 @@
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
#define GLOB_LIMIT 0x1000 /* limit number of returned paths */
+#define _GLOB_ERRBLK 0x80000000 /* (private) err callback is block */
+
/* source compatibility, these are the old names */
#define GLOB_MAXPATH GLOB_LIMIT
#define GLOB_ABEND GLOB_ABORTED
@@ -100,6 +106,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 /* __BLOCKS__ */
void globfree(glob_t *);
__END_DECLS
Index: lib/libc/gen/Makefile.inc
===================================================================
--- lib/libc/gen/Makefile.inc
+++ lib/libc/gen/Makefile.inc
@@ -319,6 +319,7 @@
dlopen.3 dlfunc.3 \
dlopen.3 dlsym.3
MLINKS+=err.3 err_set_exit.3 \
+ err.3 err_set_exit_b.3 \
err.3 err_set_file.3 \
err.3 errc.3 \
err.3 errx.3 \
@@ -349,6 +350,7 @@
MLINKS+=fts.3 fts_children.3 \
fts.3 fts_close.3 \
fts.3 fts_open.3 \
+ fts.3 fts_open_b.3 \
fts.3 fts_read.3 \
fts.3 fts_set.3 \
fts.3 fts_set_clientptr.3 \
@@ -413,7 +415,8 @@
getutxent.3 setutxdb.3 \
getutxent.3 setutxent.3 \
getutxent.3 utmpx.3
-MLINKS+=glob.3 globfree.3
+MLINKS+=glob.3 globfree.3 \
+ glob.3 glob_b.3
MLINKS+=isgreater.3 isgreaterequal.3 \
isgreater.3 isless.3 \
isgreater.3 islessequal.3 \
Index: lib/libc/gen/Symbol.map
===================================================================
--- lib/libc/gen/Symbol.map
+++ lib/libc/gen/Symbol.map
@@ -410,6 +410,9 @@
};
FBSD_1.4 {
+ err_set_exit_b;
+ fts_open_b;
+ glob_b;
scandir_b;
};
Index: lib/libc/gen/err.3
===================================================================
--- lib/libc/gen/err.3
+++ lib/libc/gen/err.3
@@ -28,7 +28,7 @@
.\" From: @(#)err.3 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
-.Dd March 29, 2012
+.Dd June 25, 2015
.Dt ERR 3
.Os
.Sh NAME
@@ -45,6 +45,7 @@
.Nm warnx ,
.Nm vwarnx ,
.Nm err_set_exit ,
+.Nm err_set_exit_b ,
.Nm err_set_file
.Nd formatted error messages
.Sh LIBRARY
@@ -54,8 +55,10 @@
.Ft void
.Fn err "int eval" "const char *fmt" "..."
.Ft void
-.Fn err_set_exit "void (*exitf)(int)"
+.Fn err_set_exit "void (*exitfunc)(int)"
.Ft void
+.Fn err_set_exit_b "void (^exitblock)(int)"
+.Ft void
.Fn err_set_file "void *vfp"
.Ft void
.Fn errc "int eval" "int code" "const char *fmt" "..."
@@ -162,10 +165,23 @@
.Fn err_set_exit
function can be used to specify a function which is called before
.Xr exit 3
-to perform any necessary cleanup; passing a null function pointer for
-.Va exitf
+to perform any necessary cleanup.
+Passing a null function pointer for
+.Va exitfunc
resets the hook to do nothing.
The
+.Fn err_set_exit_b
+function is like
+.Fn err_set_exit ,
+except it takes the block pointer,
+.Va exitblock ,
+instead of a function pointer.
+Note that the
+.Fn Block_copy
+function is used by
+.Fn err_set_exit_b
+to make a copy in case the block is freed or goes out of scope.
+The
.Fn err_set_file
function sets the output stream used by the other functions.
Its
@@ -243,3 +259,8 @@
.Fn warnc
functions first appeared in
.Fx 3.0 .
+The
+.Fn err_set_exit_b
+function first appeared in Mac OS X. This implementation was
+created by Stacey Son for
+.Fx 11.0 .
Index: lib/libc/gen/err.c
===================================================================
--- lib/libc/gen/err.c
+++ lib/libc/gen/err.c
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "block_abi.h"
#include "un-namespace.h"
#include "libc_private.h"
@@ -46,6 +47,7 @@
static FILE *err_file; /* file to use for error output */
static void (*err_exit)(int);
+typedef DECLARE_BLOCK(void, err_exit_block_t, int);
/*
* This is declared to take a `void *' so that the caller is not required
@@ -67,6 +69,17 @@
err_exit = ef;
}
+/*
+ * Register a block to be executed at error exit.
+ */
+void
+err_set_exit_b(err_exit_block_t block)
+{
+
+ if (_Block_copy != 0)
+ err_exit = (void(*)(int))GET_BLOCK_FUNCTION(_Block_copy(block));
+}
+
__weak_reference(_err, err);
void
Index: lib/libc/gen/fts.3
===================================================================
--- lib/libc/gen/fts.3
+++ lib/libc/gen/fts.3
@@ -28,7 +28,7 @@
.\" @(#)fts.3 8.5 (Berkeley) 4/16/94
.\" $FreeBSD$
.\"
-.Dd January 12, 2014
+.Dd May 5, 2014
.Dt FTS 3
.Os
.Sh NAME
@@ -40,6 +40,8 @@
.In fts.h
.Ft FTS *
.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const FTSENT * const *, const FTSENT * const *)"
+.Ft FTS *
+.Fn fts_open_b "char * const *path_argv" "int options" "int (^compar)(const FTSENT * const *, const FTSENT * const *)"
.Ft FTSENT *
.Fn fts_read "FTS *ftsp"
.Ft FTSENT *
@@ -62,7 +64,9 @@
file hierarchies.
A simple overview is that the
.Fn fts_open
-function returns a
+and
+.Fn fts_open_b
+functions return a
.Dq handle
on a file hierarchy, which is then supplied to
the other
@@ -189,6 +193,8 @@
.Ql ..\&
which was not specified as a file name to
.Fn fts_open
+or
+.Fn fts_open_b
(see
.Dv FTS_SEEDOT ) .
.It Dv FTS_DP
@@ -237,6 +243,8 @@
The path for the file relative to the root of the traversal.
This path contains the path specified to
.Fn fts_open
+or
+.Fn fts_open_b
as a prefix.
.It Fa fts_pathlen
The length of the string referenced by
@@ -521,6 +529,14 @@
.Fa path_argv
for the root paths, and in the order listed in the directory for
everything else.
+.Sh FTS_OPEN_B
+.Fn fts_open_b
+is a block-based version of
+.Fn fts_open
+where
+.Fa compar
+is a block pointer that is passed to
+.Xr qsort_b 3 .
.Sh FTS_READ
The
.Fn fts_read
@@ -775,7 +791,8 @@
.Xr chdir 2 ,
.Xr stat 2 ,
.Xr ftw 3 ,
-.Xr qsort 3
+.Xr qsort 3 ,
+.Xr qsort_b 3
.Sh HISTORY
The
.Nm
@@ -791,10 +808,17 @@
principally to provide for alternative interfaces to the
.Nm
functionality using different data structures.
+The
+.Fn fts_open_b
+function first appeared in Mac OS X.
+This implementation was created by Stacey Son for
+.Fx 11.0 .
.Sh BUGS
The
.Fn fts_open
-function will automatically set the
+and
+.Fn fts_open_b
+functions will automatically set the
.Dv FTS_NOCHDIR
option if the
.Dv FTS_LOGICAL
Index: lib/libc/gen/fts.c
===================================================================
--- lib/libc/gen/fts.c
+++ lib/libc/gen/fts.c
@@ -50,10 +50,15 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include "block_abi.h"
#include "un-namespace.h"
#include "gen-private.h"
+/* fts_block_t */
+typedef DECLARE_BLOCK(int, fts_block_t, const FTSENT * const *,
+ const FTSENT * const *);
+
static FTSENT *fts_alloc(FTS *, char *, size_t);
static FTSENT *fts_build(FTS *, int);
static void fts_lfree(FTSENT *);
@@ -109,37 +114,16 @@
0
};
-FTS *
-fts_open(argv, options, compar)
+static FTS *
+_fts_open_common(argv, priv)
char * const *argv;
- int options;
- int (*compar)(const FTSENT * const *, const FTSENT * const *);
+ struct _fts_private *priv;
{
- struct _fts_private *priv;
- FTS *sp;
+ FTS *sp = &priv->ftsp_fts;
FTSENT *p, *root;
FTSENT *parent, *tmp;
size_t len, nitems;
- /* Options check. */
- if (options & ~FTS_OPTIONMASK) {
- errno = EINVAL;
- return (NULL);
- }
-
- /* fts_open() requires at least one path */
- if (*argv == NULL) {
- errno = EINVAL;
- return (NULL);
- }
-
- /* Allocate/initialize the stream. */
- if ((priv = calloc(1, sizeof(*priv))) == NULL)
- return (NULL);
- sp = &priv->ftsp_fts;
- sp->fts_compar = compar;
- sp->fts_options = options;
-
/* Shush, GCC. */
tmp = NULL;
@@ -177,7 +161,7 @@
* If comparison routine supplied, traverse in sorted
* order; otherwise traverse in the order specified.
*/
- if (compar) {
+ if (sp->fts_compar) {
p->fts_link = root;
root = p;
} else {
@@ -190,7 +174,7 @@
}
}
}
- if (compar && nitems > 1)
+ if (sp->fts_compar && nitems > 1)
root = fts_sort(sp, root, nitems);
/*
@@ -223,6 +207,66 @@
return (NULL);
}
+static int
+_fts_open_argcheck(char * const *argv, int options)
+{
+
+ /*
+ * Check for illegal options and for at least one path.
+ */
+ if (options & ~FTS_OPTIONMASK || *argv == NULL)
+ return (EINVAL);
+
+ return (0);
+}
+
+FTS *
+fts_open(char * const *argv, int options, int (*compar)(const FTSENT * const *,
+ const FTSENT * const *))
+{
+ FTS *sp;
+ struct _fts_private *priv;
+
+ /* Check arguments. */
+ if ((errno = _fts_open_argcheck(argv, options)) != 0)
+ return (NULL);
+
+ /* Allocate/initialize the stream. */
+ if ((priv = calloc(1, sizeof(*priv))) == NULL)
+ return (NULL);
+ sp = &priv->ftsp_fts;
+ sp->fts_compar = compar;
+ sp->fts_options = options;
+
+ return (_fts_open_common(argv, priv));
+}
+
+FTS *
+fts_open_b(char * const *argv, int options, fts_block_t compar)
+{
+ FTS *sp;
+ struct _fts_private *priv;
+
+ /* Check arguments. */
+ if ((errno = _fts_open_argcheck(argv, options)) != 0)
+ return (NULL);
+
+ /* Check to make sure we have the block runtime. */
+ if (_Block_copy == 0) {
+ errno = ENOSYS;
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream. */
+ if ((priv = calloc(1, sizeof(*priv))) == NULL)
+ return (NULL);
+ sp = &priv->ftsp_fts;
+ sp->fts_compar_b = _Block_copy(compar);
+ sp->fts_options = options | FTS_COMPAR_B;
+
+ return (_fts_open_common(argv, priv));
+}
+
static void
fts_load(FTS *sp, FTSENT *p)
{
@@ -274,6 +318,11 @@
free(sp->fts_array);
free(sp->fts_path);
+ /* Free block pointer, if any. */
+ if (ISSET(FTS_COMPAR_B) && sp->fts_compar_b != NULL &&
+ _Block_release != 0)
+ _Block_release(sp->fts_compar_b);
+
/* Return to original directory, save errno if necessary. */
if (!ISSET(FTS_NOCHDIR)) {
saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
@@ -973,6 +1022,17 @@
return (*parent->fts_compar)(a, b);
}
+static int
+fts_compar_b(void *thunk, const void *a, const void *b)
+{
+ FTS *sp = (FTS *)thunk;
+ int (*funcp)(const void *, const void *);
+
+ funcp = (int (*)(const void *, const void *))
+ GET_BLOCK_FUNCTION(sp->fts_compar_b);
+ return (*funcp)(a, b);
+}
+
static FTSENT *
fts_sort(FTS *sp, FTSENT *head, size_t nitems)
{
@@ -995,7 +1055,11 @@
}
for (ap = sp->fts_array, p = head; p; p = p->fts_link)
*ap++ = p;
- qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar);
+ if (ISSET(FTS_COMPAR_B))
+ qsort_r(sp->fts_array, nitems, sizeof(FTSENT *),
+ sp->fts_compar_b, fts_compar_b);
+ else
+ qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar);
for (head = *(ap = sp->fts_array); --nitems; ++ap)
ap[0]->fts_link = ap[1];
ap[0]->fts_link = NULL;
Index: lib/libc/gen/glob.3
===================================================================
--- lib/libc/gen/glob.3
+++ lib/libc/gen/glob.3
@@ -30,11 +30,12 @@
.\" @(#)glob.3 8.3 (Berkeley) 4/16/94
.\" $FreeBSD$
.\"
-.Dd December 20, 2011
+.Dd May 5, 2014
.Dt GLOB 3
.Os
.Sh NAME
.Nm glob ,
+.Nm glob_b ,
.Nm globfree
.Nd generate pathnames matching a pattern
.Sh LIBRARY
@@ -43,6 +44,8 @@
.In glob.h
.Ft int
.Fn glob "const char * restrict pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t * restrict pglob"
+.Ft int
+.Fn glob_b "const char * restrict pattern" "int flags" "int (^errblock)(const char *, int)" "glob_t * restrict pglob"
.Ft void
.Fn globfree "glob_t *pglob"
.Sh DESCRIPTION
@@ -72,7 +75,7 @@
is a pointer to a pathname pattern to be expanded.
The
.Fn glob
-argument
+function
matches all accessible pathnames against the pattern and creates
a list of the pathnames that match.
In order to have access to a pathname,
@@ -88,7 +91,7 @@
.Pp
The
.Fn glob
-argument
+function
stores the number of matched pathnames into the
.Fa gl_pathc
field, and a pointer to a list of pointers to pathnames into the
@@ -323,6 +326,12 @@
.Fa errfunc
returns zero, the error is ignored.
.Pp
+.Fn glob_b
+is a block-based version of
+.Fn glob .
+where the error callback is the block pointer,
+.Fa errblock .
+.Pp
The
.Fn globfree
function frees any space associated with
@@ -332,7 +341,9 @@
.Sh RETURN VALUES
On successful completion,
.Fn glob
-returns zero.
+and
+.Fn glob_b
+return zero.
In addition the fields of
.Fa pglob
contain the values described below:
@@ -341,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
@@ -369,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
@@ -452,6 +469,11 @@
.Fn globfree
functions first appeared in
.Bx 4.4 .
+The
+.Fn glob_b
+function first appeared in Mac OS X.
+This implementation was created by Stacey Son for
+.Fx 11.0 .
.Sh BUGS
Patterns longer than
.Dv MAXPATHLEN
@@ -459,7 +481,9 @@
.Pp
The
.Fn glob
-argument
+or
+.Fn glob_b
+function
may fail and set errno for any of the errors specified for the
library routines
.Xr stat 2 ,
Index: lib/libc/gen/glob.c
===================================================================
--- lib/libc/gen/glob.c
+++ lib/libc/gen/glob.c
@@ -92,8 +92,12 @@
#include <unistd.h>
#include <wchar.h>
+#include "block_abi.h"
#include "collate.h"
+/* errblock_t */
+typedef DECLARE_BLOCK(int, errblock_t, 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
@@ -189,9 +193,9 @@
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_common(const char * __restrict pattern, int flags,
+ glob_t * __restrict pglob)
{
struct glob_limit limit = { 0, 0, 0, 0, 0 };
const char *patnext;
@@ -212,8 +216,6 @@
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;
@@ -258,6 +260,28 @@
return (glob0(patbuf, pglob, &limit));
}
+int
+glob(const char * __restrict pattern, int flags,
+ int (*errfunc)(const char *, int), glob_t * __restrict pglob)
+{
+
+ pglob->gl_flags = flags & ~(GLOB_MAGCHAR | _GLOB_ERRBLK);
+ pglob->gl_errfunc = errfunc;
+ return (_glob_common(pattern, flags, pglob));
+}
+
+int
+glob_b(const char * __restrict pattern, int flags, errblock_t errblock,
+ glob_t * __restrict pglob)
+{
+
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_flags |= _GLOB_ERRBLK;
+ pglob->gl_errblk = (void *)errblock;
+
+ return (_glob_common(pattern, flags, pglob));
+}
+
/*
* Expand recursively a glob {} pattern. When there is no more expansion
* invoke the standard globbing routine to glob the rest of the magic
@@ -649,6 +673,7 @@
DIR *dirp;
int err;
char buf[MAXPATHLEN];
+ int (*errfunc)(const char *, int);
/*
* The readdirfunc declaration can't be prototyped, because it is
@@ -668,7 +693,13 @@
if (pglob->gl_errfunc) {
if (g_Ctoc(pathbuf, buf, sizeof(buf)))
return (GLOB_ABORTED);
- if (pglob->gl_errfunc(buf, errno) ||
+printf("glob3: %p %d\n", buf, errno);
+ if (pglob->gl_flags & _GLOB_ERRBLK)
+ errfunc = (int (*)(const char *, int))
+ GET_BLOCK_FUNCTION(pglob->gl_errblk);
+ else
+ errfunc = pglob->gl_errfunc;
+ if ((*errfunc)(buf, errno) ||
pglob->gl_flags & GLOB_ERR)
return (GLOB_ABORTED);
}
Index: lib/libc/include/block_abi.h
===================================================================
--- lib/libc/include/block_abi.h
+++ lib/libc/include/block_abi.h
@@ -26,6 +26,8 @@
* $FreeBSD$
*/
+#include <sys/cdefs.h>
+
#ifdef __BLOCKS__
/**
* Declares a block variable. This macro is defined in the trivial way for
@@ -61,3 +63,9 @@
int reserved;\
void (*invoke)(void *, ...);\
}*)(void*)x)->invoke)
+
+/*
+ * _Block_copy() and _Block_release() are provided by libBlocksRuntime.
+ */
+__weak_symbol void *_Block_copy(void *);
+__weak_symbol void _Block_release(void *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 23, 12:52 PM (14 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33446794
Default Alt Text
D2877.diff (18 KB)
Attached To
Mode
D2877: More Apple-block function support
Attached
Detach File
Event Timeline
Log In to Comment