Add Haiku support.
This replaces the use of a few BSD-specific functions, as well as the direct references to _open/_close et-al. BFS doesn't support the FTS_NOSTAT directory link count optimization, and no statfs() function is available, so we simply turn that off.
This commit is contained in:
parent
7de6d45ca2
commit
4b5a13ab81
@ -33,6 +33,8 @@
|
||||
#ifndef _FTS_H_
|
||||
#define _FTS_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
typedef struct {
|
||||
struct _ftsent *fts_cur; /* current node */
|
||||
struct _ftsent *fts_child; /* linked list of children */
|
||||
@ -52,7 +54,6 @@ typedef struct {
|
||||
#define FTS_PHYSICAL 0x010 /* physical walk */
|
||||
#define FTS_SEEDOT 0x020 /* return dot and dot-dot */
|
||||
#define FTS_XDEV 0x040 /* don't cross devices */
|
||||
#define FTS_WHITEOUT 0x080 /* return whiteout information */
|
||||
#define FTS_OPTIONMASK 0x0ff /* valid user option mask */
|
||||
|
||||
#define FTS_NAMEONLY 0x100 /* (private) child names only */
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef _FTW_H
|
||||
#define _FTW_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -36,6 +36,19 @@ static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fts.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
@ -53,6 +66,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "gen-private.h"
|
||||
#endif
|
||||
|
||||
static FTSENT *fts_alloc(FTS *, char *, size_t);
|
||||
static FTSENT *fts_build(FTS *, int);
|
||||
@ -86,11 +100,14 @@ static int fts_ufslinks(FTS *, const FTSENT *);
|
||||
*/
|
||||
struct _fts_private {
|
||||
FTS ftsp_fts;
|
||||
#ifndef __HAIKU__
|
||||
struct statfs ftsp_statfs;
|
||||
#endif
|
||||
dev_t ftsp_dev;
|
||||
int ftsp_linksreliable;
|
||||
};
|
||||
|
||||
#ifndef __HAIKU__
|
||||
/*
|
||||
* The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it
|
||||
* knows that a directory could not possibly have subdirectories. This
|
||||
@ -108,6 +125,7 @@ static const char *ufslike_filesystems[] = {
|
||||
"ext2fs",
|
||||
0
|
||||
};
|
||||
#endif /* !__HAIKU__ */
|
||||
|
||||
FTS *
|
||||
fts_open(argv, options, compar)
|
||||
@ -215,7 +233,7 @@ fts_open(argv, options, compar)
|
||||
* descriptor we run anyway, just more slowly.
|
||||
*/
|
||||
if (!ISSET(FTS_NOCHDIR) &&
|
||||
(sp->fts_rfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||
(sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||
SET(FTS_NOCHDIR);
|
||||
|
||||
return (sp);
|
||||
@ -281,7 +299,7 @@ fts_close(FTS *sp)
|
||||
/* Return to original directory, save errno if necessary. */
|
||||
if (!ISSET(FTS_NOCHDIR)) {
|
||||
saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
|
||||
(void)_close(sp->fts_rfd);
|
||||
(void)close(sp->fts_rfd);
|
||||
|
||||
/* Set errno and return. */
|
||||
if (saved_errno != 0) {
|
||||
@ -340,7 +358,7 @@ fts_read(FTS *sp)
|
||||
(p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
|
||||
p->fts_info = fts_stat(sp, p, 1);
|
||||
if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
|
||||
if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC,
|
||||
if ((p->fts_symfd = open(".", O_RDONLY | O_CLOEXEC,
|
||||
0)) < 0) {
|
||||
p->fts_errno = errno;
|
||||
p->fts_info = FTS_ERR;
|
||||
@ -356,7 +374,7 @@ fts_read(FTS *sp)
|
||||
if (instr == FTS_SKIP ||
|
||||
(ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
|
||||
if (p->fts_flags & FTS_SYMFOLLOW)
|
||||
(void)_close(p->fts_symfd);
|
||||
(void)close(p->fts_symfd);
|
||||
if (sp->fts_child) {
|
||||
fts_lfree(sp->fts_child);
|
||||
sp->fts_child = NULL;
|
||||
@ -432,7 +450,7 @@ next: tmp = p;
|
||||
p->fts_info = fts_stat(sp, p, 1);
|
||||
if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
|
||||
if ((p->fts_symfd =
|
||||
_open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) {
|
||||
open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) {
|
||||
p->fts_errno = errno;
|
||||
p->fts_info = FTS_ERR;
|
||||
} else
|
||||
@ -477,12 +495,12 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent);
|
||||
} else if (p->fts_flags & FTS_SYMFOLLOW) {
|
||||
if (FCHDIR(sp, p->fts_symfd)) {
|
||||
saved_errno = errno;
|
||||
(void)_close(p->fts_symfd);
|
||||
(void)close(p->fts_symfd);
|
||||
errno = saved_errno;
|
||||
SET(FTS_STOP);
|
||||
return (NULL);
|
||||
}
|
||||
(void)_close(p->fts_symfd);
|
||||
(void)close(p->fts_symfd);
|
||||
} else if (!(p->fts_flags & FTS_DONTCHDIR) &&
|
||||
fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
|
||||
SET(FTS_STOP);
|
||||
@ -568,14 +586,14 @@ fts_children(FTS *sp, int instr)
|
||||
ISSET(FTS_NOCHDIR))
|
||||
return (sp->fts_child = fts_build(sp, instr));
|
||||
|
||||
if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||
if ((fd = open(".", O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||
return (NULL);
|
||||
sp->fts_child = fts_build(sp, instr);
|
||||
if (fchdir(fd)) {
|
||||
(void)_close(fd);
|
||||
(void)close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
(void)_close(fd);
|
||||
(void)close(fd);
|
||||
return (sp->fts_child);
|
||||
}
|
||||
|
||||
@ -630,7 +648,10 @@ fts_build(FTS *sp, int type)
|
||||
DIR *dirp;
|
||||
void *oldaddr;
|
||||
char *cp;
|
||||
int cderrno, descend, oflag, saved_errno, nostat, doadjust;
|
||||
int cderrno, descend, saved_errno, nostat, doadjust;
|
||||
#ifdef FTS_WHITEOUT
|
||||
int oflag;
|
||||
#endif
|
||||
long level;
|
||||
long nlinks; /* has to be signed because -1 is a magic value */
|
||||
size_t dnamlen, len, maxlen, nitems;
|
||||
@ -700,7 +721,7 @@ fts_build(FTS *sp, int type)
|
||||
*/
|
||||
cderrno = 0;
|
||||
if (nlinks || type == BREAD) {
|
||||
if (fts_safe_changedir(sp, cur, _dirfd(dirp), NULL)) {
|
||||
if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
|
||||
if (nlinks && type == BREAD)
|
||||
cur->fts_errno = errno;
|
||||
cur->fts_flags |= FTS_DONTCHDIR;
|
||||
@ -737,7 +758,7 @@ fts_build(FTS *sp, int type)
|
||||
/* Read the directory, attaching each entry to the `link' pointer. */
|
||||
doadjust = 0;
|
||||
for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
|
||||
dnamlen = dp->d_namlen;
|
||||
dnamlen = strlen(dp->d_name);
|
||||
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
|
||||
continue;
|
||||
|
||||
@ -966,6 +987,7 @@ static FTSENT *
|
||||
fts_sort(FTS *sp, FTSENT *head, size_t nitems)
|
||||
{
|
||||
FTSENT **ap, *p;
|
||||
FTSENT **old_array;
|
||||
|
||||
/*
|
||||
* Construct an array of pointers to the structures and call qsort(3).
|
||||
@ -976,8 +998,10 @@ fts_sort(FTS *sp, FTSENT *head, size_t nitems)
|
||||
*/
|
||||
if (nitems > sp->fts_nitems) {
|
||||
sp->fts_nitems = nitems + 40;
|
||||
if ((sp->fts_array = reallocf(sp->fts_array,
|
||||
old_array = sp->fts_array;
|
||||
if ((sp->fts_array = realloc(old_array,
|
||||
sp->fts_nitems * sizeof(FTSENT *))) == NULL) {
|
||||
free(old_array);
|
||||
sp->fts_nitems = 0;
|
||||
return (head);
|
||||
}
|
||||
@ -1059,9 +1083,14 @@ fts_lfree(FTSENT *head)
|
||||
static int
|
||||
fts_palloc(FTS *sp, size_t more)
|
||||
{
|
||||
|
||||
char *old_path;
|
||||
sp->fts_pathlen += more + 256;
|
||||
sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen);
|
||||
|
||||
old_path = sp->fts_path;
|
||||
sp->fts_path = realloc(old_path, sp->fts_pathlen);
|
||||
if (sp->fts_path == NULL)
|
||||
free(old_path);
|
||||
|
||||
return (sp->fts_path == NULL);
|
||||
}
|
||||
|
||||
@ -1119,9 +1148,9 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path)
|
||||
newfd = fd;
|
||||
if (ISSET(FTS_NOCHDIR))
|
||||
return (0);
|
||||
if (fd < 0 && (newfd = _open(path, O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||
if (fd < 0 && (newfd = open(path, O_RDONLY | O_CLOEXEC, 0)) < 0)
|
||||
return (-1);
|
||||
if (_fstat(newfd, &sb)) {
|
||||
if (fstat(newfd, &sb)) {
|
||||
ret = -1;
|
||||
goto bail;
|
||||
}
|
||||
@ -1134,7 +1163,7 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path)
|
||||
bail:
|
||||
oerrno = errno;
|
||||
if (fd < 0)
|
||||
(void)_close(newfd);
|
||||
(void)close(newfd);
|
||||
errno = oerrno;
|
||||
return (ret);
|
||||
}
|
||||
@ -1146,7 +1175,9 @@ static int
|
||||
fts_ufslinks(FTS *sp, const FTSENT *ent)
|
||||
{
|
||||
struct _fts_private *priv;
|
||||
#ifndef __HAIKU__
|
||||
const char **cpp;
|
||||
#endif
|
||||
|
||||
priv = (struct _fts_private *)sp;
|
||||
/*
|
||||
@ -1156,6 +1187,7 @@ fts_ufslinks(FTS *sp, const FTSENT *ent)
|
||||
* avoidance.
|
||||
*/
|
||||
if (priv->ftsp_dev != ent->fts_dev) {
|
||||
#ifndef __HAIKU__
|
||||
if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) {
|
||||
priv->ftsp_dev = ent->fts_dev;
|
||||
priv->ftsp_linksreliable = 0;
|
||||
@ -1169,6 +1201,9 @@ fts_ufslinks(FTS *sp, const FTSENT *ent)
|
||||
} else {
|
||||
priv->ftsp_linksreliable = 0;
|
||||
}
|
||||
#else
|
||||
priv->ftsp_linksreliable = 0;
|
||||
#endif
|
||||
}
|
||||
return (priv->ftsp_linksreliable);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
// __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
//__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
Loading…
Reference in New Issue
Block a user