Merge "Sync with upstream OpenBSD fts.c."
This commit is contained in:
commit
95a02366f2
@ -479,6 +479,7 @@ libc_upstream_openbsd_src_files := \
|
||||
upstream-openbsd/lib/libc/stdlib/getenv.c \
|
||||
upstream-openbsd/lib/libc/stdlib/insque.c \
|
||||
upstream-openbsd/lib/libc/stdlib/lsearch.c \
|
||||
upstream-openbsd/lib/libc/stdlib/reallocarray.c \
|
||||
upstream-openbsd/lib/libc/stdlib/remque.c \
|
||||
upstream-openbsd/lib/libc/stdlib/setenv.c \
|
||||
upstream-openbsd/lib/libc/stdlib/strtoimax.c \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: fts.c,v 1.46 2014/05/25 17:47:04 tedu Exp $ */
|
||||
/* $OpenBSD: fts.c,v 1.48 2014/11/20 04:14:15 guenther Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
@ -49,11 +49,12 @@ static size_t fts_maxarglen(char * const *);
|
||||
static void fts_padjust(FTS *, FTSENT *);
|
||||
static int fts_palloc(FTS *, size_t);
|
||||
static FTSENT *fts_sort(FTS *, FTSENT *, int);
|
||||
static u_short fts_stat(FTS *, FTSENT *, int);
|
||||
static u_short fts_stat(FTS *, FTSENT *, int, int);
|
||||
static int fts_safe_changedir(FTS *, FTSENT *, int, char *);
|
||||
|
||||
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
|
||||
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
|
||||
void* reallocarray(void*, size_t, size_t);
|
||||
|
||||
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
|
||||
|
||||
@ -119,7 +120,7 @@ fts_open(char * const *argv, int options,
|
||||
p->fts_level = FTS_ROOTLEVEL;
|
||||
p->fts_parent = parent;
|
||||
p->fts_accpath = p->fts_name;
|
||||
p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
|
||||
p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1);
|
||||
|
||||
/* Command-line "." and ".." are real directories. */
|
||||
if (p->fts_info == FTS_DOT)
|
||||
@ -273,7 +274,7 @@ fts_read(FTS *sp)
|
||||
|
||||
/* Any type of file may be re-visited; re-stat and re-turn. */
|
||||
if (instr == FTS_AGAIN) {
|
||||
p->fts_info = fts_stat(sp, p, 0);
|
||||
p->fts_info = fts_stat(sp, p, 0, -1);
|
||||
return (p);
|
||||
}
|
||||
|
||||
@ -285,7 +286,7 @@ fts_read(FTS *sp)
|
||||
*/
|
||||
if (instr == FTS_FOLLOW &&
|
||||
(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, -1);
|
||||
if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
|
||||
if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
|
||||
p->fts_errno = errno;
|
||||
@ -374,7 +375,7 @@ next: tmp = p;
|
||||
if (p->fts_instr == FTS_SKIP)
|
||||
goto next;
|
||||
if (p->fts_instr == FTS_FOLLOW) {
|
||||
p->fts_info = fts_stat(sp, p, 1);
|
||||
p->fts_info = fts_stat(sp, p, 1, -1);
|
||||
if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
|
||||
if ((p->fts_symfd =
|
||||
open(".", O_RDONLY, 0)) < 0) {
|
||||
@ -719,10 +720,11 @@ mem1: saved_errno = errno;
|
||||
if (ISSET(FTS_NOCHDIR)) {
|
||||
p->fts_accpath = p->fts_path;
|
||||
memmove(cp, p->fts_name, p->fts_namelen + 1);
|
||||
} else
|
||||
p->fts_info = fts_stat(sp, p, 0, dirfd(dirp));
|
||||
} else {
|
||||
p->fts_accpath = p->fts_name;
|
||||
/* Stat it. */
|
||||
p->fts_info = fts_stat(sp, p, 0);
|
||||
p->fts_info = fts_stat(sp, p, 0, -1);
|
||||
}
|
||||
|
||||
/* Decrement link count if applicable. */
|
||||
if (nlinks > 0 && (p->fts_info == FTS_D ||
|
||||
@ -789,13 +791,20 @@ mem1: saved_errno = errno;
|
||||
}
|
||||
|
||||
static u_short
|
||||
fts_stat(FTS *sp, FTSENT *p, int follow)
|
||||
fts_stat(FTS *sp, FTSENT *p, int follow, int dfd)
|
||||
{
|
||||
FTSENT *t;
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
struct stat *sbp, sb;
|
||||
int saved_errno;
|
||||
const char *path;
|
||||
|
||||
if (dfd == -1) {
|
||||
path = p->fts_accpath;
|
||||
dfd = AT_FDCWD;
|
||||
} else
|
||||
path = p->fts_name;
|
||||
|
||||
/* If user needs stat info, stat buffer already allocated. */
|
||||
sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
|
||||
@ -806,16 +815,16 @@ fts_stat(FTS *sp, FTSENT *p, int follow)
|
||||
* fail, set the errno from the stat call.
|
||||
*/
|
||||
if (ISSET(FTS_LOGICAL) || follow) {
|
||||
if (stat(p->fts_accpath, sbp)) {
|
||||
if (fstatat(dfd, path, sbp, 0)) {
|
||||
saved_errno = errno;
|
||||
if (!lstat(p->fts_accpath, sbp)) {
|
||||
if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
|
||||
errno = 0;
|
||||
return (FTS_SLNONE);
|
||||
}
|
||||
p->fts_errno = saved_errno;
|
||||
goto err;
|
||||
}
|
||||
} else if (lstat(p->fts_accpath, sbp)) {
|
||||
} else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {
|
||||
p->fts_errno = errno;
|
||||
err: memset(sbp, 0, sizeof(struct stat));
|
||||
return (FTS_NS);
|
||||
@ -873,8 +882,8 @@ fts_sort(FTS *sp, FTSENT *head, int nitems)
|
||||
struct _ftsent **a;
|
||||
|
||||
sp->fts_nitems = nitems + 40;
|
||||
if ((a = realloc(sp->fts_array,
|
||||
sp->fts_nitems * sizeof(FTSENT *))) == NULL) {
|
||||
if ((a = reallocarray(sp->fts_array,
|
||||
sp->fts_nitems, sizeof(FTSENT *))) == NULL) {
|
||||
if (sp->fts_array)
|
||||
free(sp->fts_array);
|
||||
sp->fts_array = NULL;
|
||||
|
@ -59,6 +59,9 @@
|
||||
/* We have OpenBSD's getentropy_linux.c, but we don't mention getentropy in any header. */
|
||||
__LIBC_HIDDEN__ extern int getentropy(void*, size_t);
|
||||
|
||||
/* OpenBSD has this as API, but we just use it internally. */
|
||||
__LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
|
||||
|
||||
/* LP32 NDK ctype.h contained references to these. */
|
||||
__LIBC64_HIDDEN__ extern const short* _tolower_tab_;
|
||||
__LIBC64_HIDDEN__ extern const short* _toupper_tab_;
|
||||
|
38
libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
Normal file
38
libc/upstream-openbsd/lib/libc/stdlib/reallocarray.c
Normal file
@ -0,0 +1,38 @@
|
||||
/* $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||
*/
|
||||
#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
|
||||
|
||||
void *
|
||||
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
Loading…
Reference in New Issue
Block a user