libroot: Fix issue reported in ticket #12291.

fts.c:
- Our fts functions were imported from FreeBSD and consequently did not
  use the same weak alias methodology that most of our glibc-derived
  POSIX functions do. These subsequently wound up clashing with the
  implementation of said functions in current versions of coreutils,
  resulting in assertion failures when e.g. running a program through
  stdbuf, since the BSD-derived functions had different flag constraints
  than their GNU peers. Consequently, this change adjusts the fts_*
  family of functions to similarly be exported as weak symbols so they
  can be preempted.
This commit is contained in:
Rene Gollent 2015-08-09 14:34:21 -04:00
parent 7cef8ca2fe
commit 422b0ec754

View File

@ -80,6 +80,18 @@ static int fts_stat(FTS *, FTSENT *, int);
static int fts_safe_changedir(FTS *, FTSENT *, int, char *);
static int fts_ufslinks(FTS *, const FTSENT *);
FTS * __fts_open(char * const *argv, int options, int (*compar)(
const FTSENT * const *, const FTSENT * const *));
int __fts_close(FTS *sp);
FTSENT * __fts_read(FTS *sp);
int __fts_set(FTS *sp, FTSENT *p, int instr);
FTSENT * __fts_children(FTS *sp, int instr);
void *(__fts_get_clientptr)(FTS *sp);
FTS * (__fts_get_stream)(FTSENT *p);
void __fts_set_clientptr(FTS *sp, void *clientptr);
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
#define CLR(opt) (sp->fts_options &= ~(opt))
@ -128,7 +140,7 @@ static const char *ufslike_filesystems[] = {
#endif /* !__HAIKU__ */
FTS *
fts_open(argv, options, compar)
__fts_open(argv, options, compar)
char * const *argv;
int options;
int (*compar)(const FTSENT * const *, const FTSENT * const *);
@ -245,6 +257,10 @@ mem1: free(sp);
return (NULL);
}
__weak_reference(__fts_open, fts_open);
static void
fts_load(FTS *sp, FTSENT *p)
{
@ -270,7 +286,7 @@ fts_load(FTS *sp, FTSENT *p)
}
int
fts_close(FTS *sp)
__fts_close(FTS *sp)
{
FTSENT *freep, *p;
int saved_errno;
@ -315,6 +331,10 @@ fts_close(FTS *sp)
return (0);
}
__weak_reference(__fts_close, fts_close);
/*
* Special case of "/" at the end of the path so that slashes aren't
* appended which would cause paths to be written as "....//foo".
@ -324,7 +344,7 @@ fts_close(FTS *sp)
? p->fts_pathlen - 1 : p->fts_pathlen)
FTSENT *
fts_read(FTS *sp)
__fts_read(FTS *sp)
{
FTSENT *p, *tmp;
int instr;
@ -510,6 +530,10 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
return (sp->fts_cur = p);
}
__weak_reference(__fts_read, fts_read);
/*
* Fts_set takes the stream as an argument although it's not used in this
* implementation; it would be necessary if anyone wanted to add global
@ -518,7 +542,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
*/
/* ARGSUSED */
int
fts_set(FTS *sp, FTSENT *p, int instr)
__fts_set(FTS *sp, FTSENT *p, int instr)
{
if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
instr != FTS_NOINSTR && instr != FTS_SKIP) {
@ -529,8 +553,12 @@ fts_set(FTS *sp, FTSENT *p, int instr)
return (0);
}
__weak_reference(__fts_set, fts_set);
FTSENT *
fts_children(FTS *sp, int instr)
__fts_children(FTS *sp, int instr)
{
FTSENT *p;
int fd;
@ -597,34 +625,50 @@ fts_children(FTS *sp, int instr)
return (sp->fts_child);
}
__weak_reference(__fts_children, fts_children);
#ifndef fts_get_clientptr
#error "fts_get_clientptr not defined"
#endif
void *
(fts_get_clientptr)(FTS *sp)
(__fts_get_clientptr)(FTS *sp)
{
return (fts_get_clientptr(sp));
}
__weak_reference(__fts_get_clientptr, fts_get_clientptr);
#ifndef fts_get_stream
#error "fts_get_stream not defined"
#endif
FTS *
(fts_get_stream)(FTSENT *p)
(__fts_get_stream)(FTSENT *p)
{
return (fts_get_stream(p));
}
__weak_reference(__fts_get_stream, fts_get_stream);
void
fts_set_clientptr(FTS *sp, void *clientptr)
__fts_set_clientptr(FTS *sp, void *clientptr)
{
sp->fts_clientptr = clientptr;
}
__weak_reference(__fts_set_clientptr, fts_set_clientptr);
/*
* This is the tricky part -- do not casually change *anything* in here. The
* idea is to build the linked list of entries that are used by fts_children