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