From 3cad9d11fc1fd697f8f569e24abefe45609e98d4 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 21 Aug 2017 09:08:50 +0200 Subject: [PATCH] Add support for LFS Signed-off-by: Igor Gnatenko --- ...port-of-LFS-compatible-fts-functions.patch | 468 ++++++++++++++++++ fakechroot.spec | 12 +- 2 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 0001-Add-support-of-LFS-compatible-fts-functions.patch diff --git a/0001-Add-support-of-LFS-compatible-fts-functions.patch b/0001-Add-support-of-LFS-compatible-fts-functions.patch new file mode 100644 index 0000000..f780d4e --- /dev/null +++ b/0001-Add-support-of-LFS-compatible-fts-functions.patch @@ -0,0 +1,468 @@ +From 46f5da05629638d9ea67782d4afc0b0f5154e7b9 Mon Sep 17 00:00:00 2001 +From: Gleb Fotengauer-Malinovskiy +Date: Wed, 16 Aug 2017 19:20:03 +0300 +Subject: [PATCH] Add support of LFS-compatible fts functions + +Since glibc 2.23, fts has LFS support. +--- + configure.ac | 15 ++++-- + src/Makefile.am | 1 + + src/fts.c | 147 +++++++++++++++++++++++++++++++++----------------------- + src/fts64.c | 33 +++++++++++++ + 4 files changed, 132 insertions(+), 64 deletions(-) + create mode 100644 src/fts64.c + +diff --git a/configure.ac b/configure.ac +index 30557a4..e87ce94 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -190,6 +190,7 @@ AC_CHECK_FUNCS(m4_normalize([ + fts_children + fts_open + fts_read ++ fts64_open + ftw + ftw64 + futimesat +@@ -315,11 +316,19 @@ m4_foreach_w([function], [getpeername getsockname], + + ACX_CHECK_FUNC_ARGTYPES([fts_open], + [], [sys/types.h sys/stat.h fts.h], +- [[FTS *], [char * const *_], [int], [int (*_)(const FTSENT **, const FTSENT **)]], +- [[FTS *]], ++ [[FTSOBJ *], [char * const *_], [int], [int (*_)(const FTSENTRY **, const FTSENTRY **)]], ++ [[FTSOBJ *]], + [[char * const *_]], + [[int _]], +- [[int (*_)(const FTSENT * const *, const FTSENT * const *)], [int (*_)(const FTSENT **, const FTSENT **)]]) ++ [[int (*_)(const FTSENTRY * const *, const FTSENTRY * const *)], [int (*_)(const FTSENTRY **, const FTSENTRY **)]]) ++ ++ACX_CHECK_FUNC_ARGTYPES([fts64_open], ++ [], [sys/types.h sys/stat.h fts.h], ++ [[FTSOBJ *], [char * const *_], [int], [int (*_)(const FTSENTRY **, const FTSENTRY **)]], ++ [[FTSOBJ *]], ++ [[char * const *_]], ++ [[int _]], ++ [[int (*_)(const FTSENTRY * const *, const FTSENTRY * const *)], [int (*_)(const FTSENTRY **, const FTSENTRY **)]]) + + ACX_CHECK_FUNC_ARGTYPES([readlink], + [ +diff --git a/src/Makefile.am b/src/Makefile.am +index 01fc652..8af41eb 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -62,6 +62,7 @@ libfakechroot_la_SOURCES = \ + freopen.c \ + freopen64.c \ + fts.c \ ++ fts64.c \ + ftw.c \ + ftw64.c \ + futimesat.c \ +diff --git a/src/fts.c b/src/fts.c +index 61ac032..e69e1b7 100644 +--- a/src/fts.c ++++ b/src/fts.c +@@ -32,10 +32,13 @@ + + #include + ++#if !defined FTS64_C__ || (defined FTS64_C__ && HAVE_FTS64_OPEN) ++ + #define _ATFILE_SOURCE + #define _BSD_SOURCE + #define _XOPEN_SOURCE 500 + #define _DEFAULT_SOURCE ++#define _LARGEFILE64_SOURCE + #include + #include + +@@ -80,16 +83,34 @@ + # endif + #endif + +-static FTSENT *fts_alloc(FTS *, char *, size_t); +-static FTSENT *fts_build(FTS *, int); +-static void fts_lfree(FTSENT *); +-static void fts_load(FTS *, FTSENT *); ++/* Support for the LFS API version. */ ++#ifndef FTS_OPEN ++/* functions */ ++# define FTS_OPEN fts_open ++# define FTS_CLOSE fts_close ++# define FTS_READ fts_read ++# define FTS_SET fts_set ++# define FTS_CHILDREN fts_children ++/* types */ ++# define FTSOBJ FTS ++# define _FTSENT _ftsent ++# define FTSENTRY FTSENT ++# define INO_T ino_t ++# define STAT stat ++# define FSTAT fstat ++# define LSTAT lstat ++#endif ++ ++static FTSENTRY *fts_alloc(FTSOBJ *, char *, size_t); ++static FTSENTRY *fts_build(FTSOBJ *, int); ++static void fts_lfree(FTSENTRY *); ++static void fts_load(FTSOBJ *, FTSENTRY *); + 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 int fts_safe_changedir(FTS *, FTSENT *, int, char *); ++static void fts_padjust(FTSOBJ *, FTSENTRY *); ++static int fts_palloc(FTSOBJ *, size_t); ++static FTSENTRY *fts_sort(FTSOBJ *, FTSENTRY *, int); ++static u_short fts_stat(FTSOBJ *, FTSENTRY *, int); ++static int fts_safe_changedir(FTSOBJ *, FTSENTRY *, int, char *); + + #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) + +@@ -104,14 +125,14 @@ static int fts_safe_changedir(FTS *, FTSENT *, int, char *); + #define BNAMES 2 /* fts_children, names only */ + #define BREAD 3 /* fts_read */ + +-FTS * +-fts_open(char * const *argv, int options, ++FTSOBJ * ++FTS_OPEN(char * const *argv, int options, + FTS_OPEN_TYPE_ARG3(compar)) + { +- FTS *sp; +- FTSENT *p, *root; ++ FTSOBJ *sp; ++ FTSENTRY *p, *root; + int nitems; +- FTSENT *parent, *tmp = NULL; ++ FTSENTRY *parent, *tmp = NULL; + size_t len; + + debug("fts_open({\"%s\", ...}, %d, &compar)", **argv, options); +@@ -123,7 +144,7 @@ fts_open(char * const *argv, int options, + } + + /* Allocate/initialize the stream */ +- if ((sp = calloc(1, sizeof(FTS))) == NULL) ++ if ((sp = calloc(1, sizeof(FTSOBJ))) == NULL) + return (NULL); + sp->fts_compar = (void *)compar; + sp->fts_options = options; +@@ -216,7 +237,7 @@ mem1: free(sp); + } + + static void +-fts_load(FTS *sp, FTSENT *p) ++fts_load(FTSOBJ *sp, FTSENTRY *p) + { + size_t len; + char *cp; +@@ -240,9 +261,9 @@ fts_load(FTS *sp, FTSENT *p) + } + + int +-fts_close(FTS *sp) ++FTS_CLOSE(FTSOBJ *sp) + { +- FTSENT *freep, *p; ++ FTSENTRY *freep, *p; + int rfd, error = 0; + + debug("fts_close(&sp)"); +@@ -292,10 +313,10 @@ fts_close(FTS *sp) + (p->fts_path[p->fts_pathlen - 1] == '/' \ + ? p->fts_pathlen - 1 : p->fts_pathlen) + +-FTSENT * +-fts_read(FTS *sp) ++FTSENTRY * ++FTS_READ(FTSOBJ *sp) + { +- FTSENT *p, *tmp; ++ FTSENTRY *p, *tmp; + int instr; + char *t; + int saved_errno; +@@ -490,7 +511,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); + */ + /* ARGSUSED */ + int +-fts_set(FTS *sp, FTSENT *p, int instr) ++FTS_SET(FTSOBJ *sp, FTSENTRY *p, int instr) + { + debug("fts_set(&sp, &p, %d)", instr); + if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW && +@@ -502,10 +523,10 @@ fts_set(FTS *sp, FTSENT *p, int instr) + return (0); + } + +-FTSENT * +-fts_children(FTS *sp, int instr) ++FTSENTRY * ++FTS_CHILDREN(FTSOBJ *sp, int instr) + { +- FTSENT *p; ++ FTSENTRY *p; + int fd; + + debug("fts_children(&sp, %d)", instr); +@@ -586,12 +607,12 @@ fts_children(FTS *sp, int instr) + * directories and for any files after the subdirectories in the directory have + * been found, cutting the stat calls by about 2/3. + */ +-static FTSENT * +-fts_build(FTS *sp, int type) ++static FTSENTRY * ++fts_build(FTSOBJ *sp, int type) + { + struct dirent *dp; +- FTSENT *p, *head; +- FTSENT *cur, *tail; ++ FTSENTRY *p, *head; ++ FTSENTRY *cur, *tail; + DIR *dirp; + void *oldaddr; + size_t len, maxlen; +@@ -834,12 +855,12 @@ mem1: saved_errno = errno; + } + + static u_short +-fts_stat(FTS *sp, FTSENT *p, int follow) ++fts_stat(FTSOBJ *sp, FTSENTRY *p, int follow) + { +- FTSENT *t; ++ FTSENTRY *t; + dev_t dev; +- ino_t ino; +- struct stat *sbp, sb; ++ INO_T ino; ++ struct STAT *sbp, sb; + int saved_errno; + + /* If user needs stat info, stat buffer already allocated. */ +@@ -851,18 +872,18 @@ 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 (STAT(p->fts_accpath, sbp)) { + saved_errno = errno; +- if (!lstat(p->fts_accpath, sbp)) { ++ if (!LSTAT(p->fts_accpath, sbp)) { + errno = 0; + return (FTS_SLNONE); + } + p->fts_errno = saved_errno; + goto err; + } +- } else if (lstat(p->fts_accpath, sbp)) { ++ } else if (LSTAT(p->fts_accpath, sbp)) { + p->fts_errno = errno; +-err: memset(sbp, 0, sizeof(struct stat)); ++err: memset(sbp, 0, sizeof(struct STAT)); + return (FTS_NS); + } + +@@ -902,10 +923,10 @@ err: memset(sbp, 0, sizeof(struct stat)); + return (FTS_DEFAULT); + } + +-static FTSENT * +-fts_sort(FTS *sp, FTSENT *head, int nitems) ++static FTSENTRY * ++fts_sort(FTSOBJ *sp, FTSENTRY *head, int nitems) + { +- FTSENT **ap, *p; ++ FTSENTRY **ap, *p; + + /* + * Construct an array of pointers to the structures and call qsort(3). +@@ -915,11 +936,11 @@ fts_sort(FTS *sp, FTSENT *head, int nitems) + * 40 so don't realloc one entry at a time. + */ + if (nitems > sp->fts_nitems) { +- struct _ftsent **a; ++ struct _FTSENT **a; + + sp->fts_nitems = nitems + 40; + if ((a = realloc(sp->fts_array, +- sp->fts_nitems * sizeof(FTSENT *))) == NULL) { ++ sp->fts_nitems * sizeof(FTSENTRY *))) == NULL) { + if (sp->fts_array) + free(sp->fts_array); + sp->fts_array = NULL; +@@ -930,33 +951,33 @@ fts_sort(FTS *sp, FTSENT *head, int nitems) + } + for (ap = sp->fts_array, p = head; p; p = p->fts_link) + *ap++ = p; +- qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), (void *)sp->fts_compar); ++ qsort((void *)sp->fts_array, nitems, sizeof(FTSENTRY *), (void *)sp->fts_compar); + for (head = *(ap = sp->fts_array); --nitems; ++ap) + ap[0]->fts_link = ap[1]; + ap[0]->fts_link = NULL; + return (head); + } + +-static FTSENT * +-fts_alloc(FTS *sp, char *name, size_t namelen) ++static FTSENTRY * ++fts_alloc(FTSOBJ *sp, char *name, size_t namelen) + { +- FTSENT *p; ++ FTSENTRY *p; + size_t len; + + #ifdef HAVE_STRUCT__FTSENT_FTS_NAME_TYPE_CHAR_P + struct ftsent_withstat { +- FTSENT ent; ++ FTSENTRY ent; + struct stat statbuf; + }; + + /* + * The file name is a variable length array and no stat structure is +- * necessary if the user has set the nostat bit. Allocate the FTSENT ++ * necessary if the user has set the nostat bit. Allocate the FTSENTRY + * structure, the file name and the stat structure in one chunk, but + * be careful that the stat structure is reasonably aligned. + */ + if (ISSET(FTS_NOSTAT)) +- len = sizeof(FTSENT) + namelen + 1; ++ len = sizeof(FTSENTRY) + namelen + 1; + else + len = sizeof(struct ftsent_withstat) + namelen + 1; + +@@ -985,15 +1006,15 @@ fts_alloc(FTS *sp, char *name, size_t namelen) + #else + /* + * The file name is a variable length array and no stat structure is +- * necessary if the user has set the nostat bit. Allocate the FTSENT ++ * necessary if the user has set the nostat bit. Allocate the FTSENTRY + * structure, the file name and the stat structure in one chunk, but + * be careful that the stat structure is reasonably aligned. Since the + * fts_name field is declared to be of size 1, the fts_name pointer is + * namelen + 2 before the first possible address of the stat structure. + */ +- len = sizeof(FTSENT) + namelen; ++ len = sizeof(FTSENTRY) + namelen; + if (!ISSET(FTS_NOSTAT)) +- len += sizeof(struct stat) + ALIGNBYTES; ++ len += sizeof(struct STAT) + ALIGNBYTES; + if ((p = malloc(len)) == NULL) + return (NULL); + +@@ -1002,7 +1023,7 @@ fts_alloc(FTS *sp, char *name, size_t namelen) + p->fts_namelen = namelen; + p->fts_instr = FTS_NOINSTR; + if (!ISSET(FTS_NOSTAT)) +- p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2); ++ p->fts_statp = (struct STAT *)ALIGN(p->fts_name + namelen + 2); + memcpy(p->fts_name, name, namelen); + #endif + +@@ -1010,9 +1031,9 @@ fts_alloc(FTS *sp, char *name, size_t namelen) + } + + static void +-fts_lfree(FTSENT *head) ++fts_lfree(FTSENTRY *head) + { +- FTSENT *p; ++ FTSENTRY *p; + + /* Free a linked list of structures. */ + while ((p = head)) { +@@ -1028,7 +1049,7 @@ fts_lfree(FTSENT *head) + * plus 256 bytes so don't realloc the path 2 bytes at a time. + */ + static int +-fts_palloc(FTS *sp, size_t more) ++fts_palloc(FTSOBJ *sp, size_t more) + { + char *p; + +@@ -1060,9 +1081,9 @@ fts_palloc(FTS *sp, size_t more) + * already returned. + */ + static void +-fts_padjust(FTS *sp, FTSENT *head) ++fts_padjust(FTSOBJ *sp, FTSENTRY *head) + { +- FTSENT *p; ++ FTSENTRY *p; + char *addr = sp->fts_path; + + #define ADJUST(p) { \ +@@ -1100,17 +1121,17 @@ fts_maxarglen(char * const *argv) + * Assumes p->fts_dev and p->fts_ino are filled in. + */ + static int +-fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) ++fts_safe_changedir(FTSOBJ *sp, FTSENTRY *p, int fd, char *path) + { + int ret, oerrno, newfd; +- struct stat sb; ++ struct STAT sb; + + newfd = fd; + if (ISSET(FTS_NOCHDIR)) + return (0); + if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0) + return (-1); +- if (fstat(newfd, &sb)) { ++ if (FSTAT(newfd, &sb)) { + ret = -1; + goto bail; + } +@@ -1127,3 +1148,7 @@ bail: + errno = oerrno; + return (ret); + } ++ ++#else ++typedef int empty_translation_unit; ++#endif +diff --git a/src/fts64.c b/src/fts64.c +new file mode 100644 +index 0000000..ba98805 +--- /dev/null ++++ b/src/fts64.c +@@ -0,0 +1,33 @@ ++/* File tree traversal functions LFS version. ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FTS64_C__ ++#define FTS_OPEN fts64_open ++#define FTS_CLOSE fts64_close ++#define FTS_READ fts64_read ++#define FTS_SET fts64_set ++#define FTS_CHILDREN fts64_children ++#define FTSOBJ FTS64 ++#define FTSENTRY FTSENT64 ++#define _FTSENT _ftsent64 ++#define INO_T ino64_t ++#define STAT stat64 ++#define FSTAT fstat64 ++#define LSTAT lstat64 ++ ++#include "fts.c" +-- +2.14.1 + diff --git a/fakechroot.spec b/fakechroot.spec index 48badc2..9ce3b54 100644 --- a/fakechroot.spec +++ b/fakechroot.spec @@ -1,12 +1,18 @@ Name: fakechroot Version: 2.19 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Gives a fake chroot environment License: LGPLv2+ URL: https://github.com/dex4er/fakechroot Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz +# https://github.com/dex4er/fakechroot/pull/50 +Patch0: 0001-Add-support-of-LFS-compatible-fts-functions.patch Requires: %{name}-libs%{?_isa} = %{version}-%{release} +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +BuildRequires: gcc # Required for manpage BuildRequires: /usr/bin/pod2man BuildRequires: perl-generators @@ -32,6 +38,7 @@ This package contains the libraries required by %{name}. chmod -x scripts/{relocatesymlinks,restoremode,savemode}.sh %build +autoreconf -vfi %configure --disable-static --disable-silent-rules %make_build @@ -61,6 +68,9 @@ make %{?_smp_mflags} check %{_libdir}/%{name}/ %changelog +* Mon Aug 21 2017 Igor Gnatenko - 2.19-4 +- Add support for LFS + * Wed Aug 02 2017 Fedora Release Engineering - 2.19-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild