You've already forked macports-base
mirror of
https://github.com/macports/macports-base.git
synced 2026-07-12 18:18:43 -07:00
Use clonefile(2) in more places
A lot of file copies that we create are not subsequently modified, especially in the destroot phase. This makes cloning a more efficient alternative. * Modified xinstall and 'file copy' Tcl commands to try cloning. * Created a vendored copy of install(1) that tries cloning. * Created a thin wrapper around cp(1) that adds the -c flag. * If the build directory is on a filesystem that supports cloning, the configure.install option defaults to our install(1), and the directory containing our install and cp commands is added to the front of PATH, currently only during the destroot phase. The code for all of the above is not built on systems that lack clonefile(2). If cloning fails, everything will fall back to creating a copy as previously done.
This commit is contained in:
+2
-1
@@ -32,7 +32,7 @@ src/darwintracelib1.0/sip_copy_proc.[ch]
|
||||
src/machista1.0/tests/libmachista-test
|
||||
src/port/*
|
||||
!src/port/*.tcl
|
||||
src/programs/daemondo/build/
|
||||
src/programs/*/build/
|
||||
src/**/*.o
|
||||
src/**/*.a
|
||||
src/**/*.dylib
|
||||
@@ -44,6 +44,7 @@ tests/test/trace/test.tcl
|
||||
|
||||
vendor/vendor-destroot/
|
||||
vendor/tclsh
|
||||
vendor/install/build/
|
||||
vendor/**/*.o
|
||||
vendor/**/*.a
|
||||
vendor/**/*.dylib
|
||||
|
||||
@@ -37,6 +37,7 @@ XCODEBUILD = @XCODEBUILD@
|
||||
INTREE_TCLSH = @INTREE_TCLSH@
|
||||
TCLSH = @TCLSH@
|
||||
TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
|
||||
TCL_PREFIX = @TCL_PREFIX@
|
||||
|
||||
DSCL = @DSCL@
|
||||
DSEDITGROUP = @DSEDITGROUP@
|
||||
|
||||
@@ -672,6 +672,7 @@ VENDOR_TCLX_SUBDIR
|
||||
VENDOR_DESTROOT
|
||||
VENDOR_TCL_INSTALL
|
||||
VENDOR_TCL_SUBDIR
|
||||
CLONEBIN_PATH
|
||||
localstatedir_expanded
|
||||
MPCONFIGDIR_EXPANDED
|
||||
DARWINTRACE_SIP_WORKAROUND_PATH
|
||||
@@ -689,6 +690,8 @@ HAVE_STRLCPY
|
||||
HAVE_STRLCAT
|
||||
HAVE_GETLINE
|
||||
HAVE_GETDELIM
|
||||
EXTRA_PROGS
|
||||
HAVE_CLONEFILE
|
||||
HAVE_TIMINGSAFE_BCMP
|
||||
HAVE_GETENTROPY
|
||||
HAVE_ARC4RANDOM_BUF
|
||||
@@ -704,7 +707,6 @@ RUNUSR
|
||||
DSTGRP
|
||||
DSTUSR
|
||||
MPCONFIGDIR
|
||||
EXTRA_PROGS
|
||||
HAVE_FUNCTION_CFNOTIFICATIONCENTERGETDARWINNOTIFYCENTER
|
||||
HAVE_FRAMEWORK_IOKIT
|
||||
HAVE_FRAMEWORK_SYSTEMCONFIGURATION
|
||||
@@ -7012,8 +7014,6 @@ printf %s "checking for whether we will build daemondo... " >&6; }
|
||||
printf "%s\n" "${result}" >&6; }
|
||||
|
||||
|
||||
|
||||
|
||||
# Check for paths
|
||||
|
||||
|
||||
@@ -7729,6 +7729,17 @@ HAVE_GETENTROPY=$ac_cv_func_getentropy
|
||||
HAVE_TIMINGSAFE_BCMP=$ac_cv_func_timingsafe_bcmp
|
||||
|
||||
|
||||
# For vendor/install
|
||||
HAVE_CLONEFILE=$ac_cv_func_clonefile
|
||||
|
||||
# For programs/cp
|
||||
if test x$ac_cv_func_clonefile = xyes; then
|
||||
EXTRA_PROGS="$EXTRA_PROGS cp"
|
||||
ac_config_files="$ac_config_files src/programs/cp/Makefile vendor/install/Makefile"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Check for library functions, replacements are in pextlib1.0/compat/
|
||||
ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline"
|
||||
if test "x$ac_cv_func_getline" = xyes
|
||||
@@ -8660,6 +8671,11 @@ eval "macports_libexec_dir=$macports_libexec_dir"
|
||||
prefix=$oldprefix
|
||||
exec_prefix=$oldexec_prefix
|
||||
|
||||
if test x$ac_cv_func_clonefile = xyes; then
|
||||
CLONEBIN_PATH="${macports_libexec_dir}/clonebin"
|
||||
fi
|
||||
|
||||
|
||||
## Tcl package
|
||||
mp_fn_var_prepend() {
|
||||
eval "$1=\"$2\$$1\""
|
||||
@@ -10448,6 +10464,8 @@ do
|
||||
case $ac_config_target in
|
||||
"src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
|
||||
"src/programs/daemondo/Makefile") CONFIG_FILES="$CONFIG_FILES src/programs/daemondo/Makefile" ;;
|
||||
"src/programs/cp/Makefile") CONFIG_FILES="$CONFIG_FILES src/programs/cp/Makefile" ;;
|
||||
"vendor/install/Makefile") CONFIG_FILES="$CONFIG_FILES vendor/install/Makefile" ;;
|
||||
"Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;;
|
||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||
"Mk/macports.autoconf.mk") CONFIG_FILES="$CONFIG_FILES Mk/macports.autoconf.mk" ;;
|
||||
|
||||
+14
-2
@@ -201,8 +201,6 @@ MP_COMPILER_ATTRIBUTE_UNUSED
|
||||
|
||||
MP_PROG_DAEMONDO
|
||||
|
||||
AC_SUBST(EXTRA_PROGS)
|
||||
|
||||
# Check for paths
|
||||
AC_PREFIX_DEFAULT(/opt/local)
|
||||
AC_ARG_WITH(
|
||||
@@ -269,6 +267,15 @@ AC_SUBST(HAVE_ARC4RANDOM_BUF, $ac_cv_func_arc4random_buf)
|
||||
AC_SUBST(HAVE_GETENTROPY, $ac_cv_func_getentropy)
|
||||
AC_SUBST(HAVE_TIMINGSAFE_BCMP, $ac_cv_func_timingsafe_bcmp)
|
||||
|
||||
# For vendor/install
|
||||
AC_SUBST(HAVE_CLONEFILE, $ac_cv_func_clonefile)
|
||||
# For programs/cp
|
||||
if test x$ac_cv_func_clonefile = xyes; then
|
||||
EXTRA_PROGS="$EXTRA_PROGS cp"
|
||||
AC_CONFIG_FILES([src/programs/cp/Makefile vendor/install/Makefile])
|
||||
fi
|
||||
AC_SUBST(EXTRA_PROGS)
|
||||
|
||||
# Check for library functions, replacements are in pextlib1.0/compat/
|
||||
AC_CHECK_FUNCS([getline getdelim strlcat strlcpy])
|
||||
AC_SUBST(HAVE_GETDELIM, $ac_cv_func_getdelim)
|
||||
@@ -347,6 +354,11 @@ eval "macports_libexec_dir=$macports_libexec_dir"
|
||||
prefix=$oldprefix
|
||||
exec_prefix=$oldexec_prefix
|
||||
|
||||
if test x$ac_cv_func_clonefile = xyes; then
|
||||
CLONEBIN_PATH="${macports_libexec_dir}/clonebin"
|
||||
fi
|
||||
AC_SUBST(CLONEBIN_PATH)
|
||||
|
||||
## Tcl package
|
||||
MP_CONFIG_SUBDIR([vendor/tcl/unix], [--prefix=${macports_libexec_dir} --enable-threads])
|
||||
VENDOR_TCL_SUBDIR=tcl/unix
|
||||
|
||||
@@ -49,7 +49,7 @@ package require mpcommon 1.0
|
||||
namespace eval macports {
|
||||
variable bootstrap_options [dict create]
|
||||
# Config file options with no special handling
|
||||
foreach opt [list binpath auto_path extra_env portdbformat \
|
||||
foreach opt [list binpath auto_path clonebin_path extra_env portdbformat \
|
||||
portarchivetype portimage_mode hfscompression portautoclean \
|
||||
porttrace portverbose keeplogs destroot_umask release_urls release_version_urls \
|
||||
rsync_server rsync_options rsync_dir \
|
||||
@@ -87,6 +87,9 @@ namespace eval macports {
|
||||
macosx_deployment_target packagemaker_path default_compilers sandbox_enable sandbox_network \
|
||||
delete_la_files cxx_stdlib pkg_post_unarchive_deletions {*}$user_options]
|
||||
|
||||
# Options set in the portfile interpreter but only in system_options
|
||||
variable portinterp_private_options [list clonebin_path]
|
||||
|
||||
# deferred options are only computed when needed.
|
||||
# they are not exported to the trace thread.
|
||||
# they are not exported to the interpreter in system_options array.
|
||||
@@ -985,6 +988,7 @@ proc mportinit {{up_ui_options {}} {up_options {}} {up_variations {}}} {
|
||||
macports::portarchive_hfscompression \
|
||||
macports::host_cache \
|
||||
macports::porturl_prefix_map \
|
||||
macports::clonebin_path \
|
||||
macports::ui_options \
|
||||
macports::global_options \
|
||||
macports::global_variations
|
||||
@@ -1486,6 +1490,15 @@ match macports.conf.default."
|
||||
set env(PATH) $binpath
|
||||
}
|
||||
|
||||
if {![info exists clonebin_path]} {
|
||||
if {![catch {fs_clone_capable [file join $portdbpath build]} result] && $result
|
||||
&& [file executable ${macports::autoconf::clonebin_path}/install]} {
|
||||
set clonebin_path ${macports::autoconf::clonebin_path}
|
||||
} else {
|
||||
set clonebin_path {}
|
||||
}
|
||||
}
|
||||
|
||||
# Set startupitem default type (can be overridden by portfile)
|
||||
if {![info exists startupitem_type]} {
|
||||
set startupitem_type default
|
||||
@@ -1896,6 +1909,7 @@ proc macports::copy_xcode_plist {target_homedir} {
|
||||
|
||||
proc macports::worker_init {workername portpath porturl portbuildpath options variations} {
|
||||
variable portinterp_options; variable portinterp_deferred_options
|
||||
variable portinterp_private_options
|
||||
variable ui_priorities; variable ui_options
|
||||
|
||||
# Hide any Tcl commands that should be inaccessible to port1.0 and Portfiles
|
||||
@@ -2044,6 +2058,15 @@ proc macports::worker_init {workername portpath porturl portbuildpath options va
|
||||
$workername eval [list set $opt ?]
|
||||
}
|
||||
|
||||
foreach opt $portinterp_private_options {
|
||||
if {![info exists $opt]} {
|
||||
variable $opt
|
||||
}
|
||||
if {[info exists $opt]} {
|
||||
$workername eval [list set system_options($opt) [set $opt]]
|
||||
}
|
||||
}
|
||||
|
||||
foreach {opt val} $options {
|
||||
$workername eval [list set user_options($opt) $val]
|
||||
$workername eval [list set $opt $val]
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace eval macports::autoconf {
|
||||
variable aa_path "@AA@"
|
||||
variable bzip2_path "@BZIP2_BIN@"
|
||||
variable chown_path "@CHOWN@"
|
||||
variable clonebin_path "@CLONEBIN_PATH@"
|
||||
variable gzip_path "@GZIP_BIN@"
|
||||
variable macports_conf_path "@MPCONFIGDIR_EXPANDED@"
|
||||
variable macports_keys_base "@prefix_expanded@/share/macports/keys/base"
|
||||
|
||||
@@ -47,6 +47,14 @@
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
/* For clonefile */
|
||||
#ifdef HAVE_SYS_ATTR_H
|
||||
#include <sys/attr.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_CLONEFILE_H
|
||||
#include <sys/clonefile.h>
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
@@ -131,6 +139,9 @@ static char *funcname;
|
||||
static int safecopy, docompare, dostrip, dobackup, dopreserve, nommap;
|
||||
static mode_t mode;
|
||||
|
||||
#ifdef HAVE_CLONEFILE
|
||||
static int clone(const char *, const char *, int, char *, size_t);
|
||||
#endif
|
||||
static int copy(Tcl_Interp *interp, int, const char *, int, const char *, off_t);
|
||||
static int compare(int, const char *, size_t, int, const char *, size_t);
|
||||
static int create_newfile(Tcl_Interp *interp, const char *, int, struct stat *);
|
||||
@@ -139,6 +150,7 @@ static int install(Tcl_Interp *interp, const char *, const char *, u_long, u_int
|
||||
static int install_dir(Tcl_Interp *interp, char *);
|
||||
static u_long numeric_id(Tcl_Interp *interp, const char *, const char *, int *rval);
|
||||
static void strip(const char *);
|
||||
static void tempfile_template(const char *, char *, size_t);
|
||||
static int trymmap(int);
|
||||
static void usage(Tcl_Interp *interp);
|
||||
|
||||
@@ -432,9 +444,14 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
|
||||
{
|
||||
struct stat from_sb, temp_sb, to_sb;
|
||||
struct timeval tvb[2];
|
||||
int devnull, files_match, from_fd = 0, serrno, target;
|
||||
int tempcopy, temp_fd, to_fd = 0;
|
||||
int devnull, files_match, from_fd = -1, serrno, target;
|
||||
int tempcopy, temp_fd = -1, to_fd = -1;
|
||||
char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
|
||||
#ifdef HAVE_CLONEFILE
|
||||
const int tryclone = 1;
|
||||
#else
|
||||
const int tryclone = 0;
|
||||
#endif
|
||||
|
||||
files_match = 0;
|
||||
|
||||
@@ -484,7 +501,7 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
|
||||
/* Only copy safe if the target exists. */
|
||||
tempcopy = safecopy && target;
|
||||
|
||||
if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) {
|
||||
if ((!tryclone || dostrip || docompare) && !devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) {
|
||||
char errmsg[255];
|
||||
|
||||
snprintf(errmsg, sizeof errmsg, "%s: Unable to open: %s, %s",
|
||||
@@ -517,6 +534,26 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
|
||||
}
|
||||
|
||||
if (!files_match) {
|
||||
int done_clone = 0;
|
||||
#ifdef HAVE_CLONEFILE
|
||||
if (tryclone && !devnull && !dostrip) {
|
||||
done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
|
||||
}
|
||||
if (done_clone &&
|
||||
(((to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0)) < 0)
|
||||
|| (!tempcopy && fstat(to_fd, &to_sb) == -1))) {
|
||||
(void)unlink(tempcopy ? tempfile : to_name);
|
||||
done_clone = 0;
|
||||
}
|
||||
if (!done_clone && from_fd < 0 && (from_fd = open(from_name, O_RDONLY, 0)) < 0) {
|
||||
char errmsg[255];
|
||||
snprintf(errmsg, sizeof errmsg, "%s: Unable to open: %s, %s",
|
||||
funcname, from_name, strerror(errno));
|
||||
Tcl_SetResult(interp, errmsg, TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#endif
|
||||
if (!done_clone) {
|
||||
if (tempcopy) {
|
||||
to_fd = create_tempfile(to_name, tempfile,
|
||||
sizeof(tempfile));
|
||||
@@ -539,8 +576,9 @@ install(Tcl_Interp *interp, const char *from_name, const char *to_name, u_long f
|
||||
}
|
||||
ui_info(interp, "%s: %s -> %s", funcname, from_name, to_name);
|
||||
}
|
||||
} /* !done_clone */
|
||||
if (!devnull) {
|
||||
if (copy(interp, from_fd, from_name, to_fd,
|
||||
if (!done_clone && copy(interp, from_fd, from_name, to_fd,
|
||||
tempcopy ? tempfile : to_name, from_sb.st_size) != TCL_OK)
|
||||
return TCL_ERROR;
|
||||
#if HAVE_COPYFILE
|
||||
@@ -838,12 +876,11 @@ compare(int from_fd, const char *from_name UNUSED, size_t from_len,
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* create_tempfile --
|
||||
* create a temporary file based on path and open it
|
||||
/* tempfile_template --
|
||||
* prepare a template filename for use with mktemp/mkstemp.
|
||||
*/
|
||||
static int
|
||||
create_tempfile(const char *path, char *temp, size_t tsize)
|
||||
static void
|
||||
tempfile_template(const char *path, char *temp, size_t tsize)
|
||||
{
|
||||
char *p;
|
||||
|
||||
@@ -855,6 +892,16 @@ create_tempfile(const char *path, char *temp, size_t tsize)
|
||||
p = temp;
|
||||
(void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
|
||||
temp[tsize - 1] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* create_tempfile --
|
||||
* create a temporary file based on path and open it
|
||||
*/
|
||||
static int
|
||||
create_tempfile(const char *path, char *temp, size_t tsize)
|
||||
{
|
||||
tempfile_template(path, temp, tsize);
|
||||
return (mkstemp(temp));
|
||||
}
|
||||
|
||||
@@ -993,6 +1040,24 @@ copy(Tcl_Interp *interp, int from_fd, const char *from_name, int to_fd, const ch
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* clone --
|
||||
* create a clone of a file
|
||||
*/
|
||||
#ifdef HAVE_CLONEFILE
|
||||
static int
|
||||
clone(const char *from_name, const char *to_name,
|
||||
int use_temp, char *temp_name, size_t tsize)
|
||||
{
|
||||
if (use_temp) {
|
||||
tempfile_template(to_name, temp_name, tsize);
|
||||
mktemp(temp_name);
|
||||
to_name = temp_name;
|
||||
}
|
||||
return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* strip --
|
||||
* use strip(1) to strip the target file
|
||||
|
||||
@@ -291,7 +291,7 @@ options configure.perl configure.python configure.ruby \
|
||||
default configure.perl {}
|
||||
default configure.python {}
|
||||
default configure.ruby {}
|
||||
default configure.install {${portutil::autoconf::install_command}}
|
||||
default configure.install {[expr {$system_options(clonebin_path) ne "" ? [file join $system_options(clonebin_path) install] : ${portutil::autoconf::install_command}}]}
|
||||
default configure.awk {}
|
||||
default configure.bison {}
|
||||
default configure.pkg_config {}
|
||||
|
||||
@@ -126,7 +126,19 @@ proc portdestroot::destroot_start {args} {
|
||||
}
|
||||
|
||||
proc portdestroot::destroot_main {args} {
|
||||
command_exec -callback portprogress::target_progress_callback destroot
|
||||
global system_options
|
||||
if {$system_options(clonebin_path) ne ""} {
|
||||
global env
|
||||
set saved_path $env(PATH)
|
||||
set env(PATH) $system_options(clonebin_path):$env(PATH)
|
||||
}
|
||||
try {
|
||||
command_exec -callback portprogress::target_progress_callback destroot
|
||||
} finally {
|
||||
if {[info exists saved_path]} {
|
||||
set env(PATH) $saved_path
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include ../../../Mk/macports.autoconf.mk
|
||||
|
||||
SRCS = cp.c
|
||||
OBJS = cp.o
|
||||
PROGRAM = build/cp
|
||||
|
||||
.PHONY: cp mkdirs
|
||||
|
||||
all: cp
|
||||
|
||||
cp: mkdirs ${PROGRAM}
|
||||
|
||||
${PROGRAM}: ${OBJS}
|
||||
${CC} ${CFLAGS} -o ${PROGRAM} ${LIBS} ${OBJS}
|
||||
|
||||
mkdirs:
|
||||
mkdir -p build
|
||||
|
||||
clean:
|
||||
rm -Rf build ${PROGRAM} ${OBJS}
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
install: cp
|
||||
${INSTALL} -d -m 755 "${DESTDIR}${TCL_PREFIX}/clonebin"
|
||||
${INSTALL} -o "${DSTUSR}" -g "${DSTGRP}" -m 555 "${PROGRAM}" "${DESTDIR}${TCL_PREFIX}/clonebin"
|
||||
|
||||
test:
|
||||
|
||||
codesign:: ${PROGRAM}
|
||||
../../codesign.sh $?
|
||||
@@ -0,0 +1,26 @@
|
||||
/* cp wrapper to add -c (clone) option */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *cp_path = "/bin/cp";
|
||||
const char *clone_arg = "-c";
|
||||
const char **new_argv = malloc(sizeof(char *) * (argc+1));
|
||||
if (new_argv) {
|
||||
new_argv[0] = cp_path;
|
||||
new_argv[1] = clone_arg;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
new_argv[i+1] = argv[i];
|
||||
}
|
||||
execve(cp_path, new_argv, environ);
|
||||
}
|
||||
/* something failed */
|
||||
perror("cp");
|
||||
return errno;
|
||||
}
|
||||
@@ -17,6 +17,8 @@ LIBS = -framework CoreFoundation \
|
||||
-framework IOKit
|
||||
PROGRAM = build/daemondo
|
||||
|
||||
.PHONY: daemondo mkdirs
|
||||
|
||||
all: daemondo
|
||||
|
||||
daemondo: mkdirs ${PROGRAM}
|
||||
|
||||
+28
-9
@@ -2,14 +2,15 @@ TCL_SUBDIR= @VENDOR_TCL_SUBDIR@
|
||||
TCLX_SUBDIR= @VENDOR_TCLX_SUBDIR@
|
||||
TCLLIB_SUBDIR= @VENDOR_TCLLIB_SUBDIR@
|
||||
SIGNIFY_SUBDIR= signify-osx
|
||||
INSTALL_SUBDIR= install
|
||||
|
||||
PREFIX= @prefix@
|
||||
DESTROOT= @abs_top_builddir@/vendor/vendor-destroot
|
||||
|
||||
.PHONY: all clean distclean install destroot test
|
||||
.PHONY: destroot-tcl destroot-tclx destroot-tcllib destroot-signify
|
||||
.PHONY: install-tcl install-tclx install-tcllib install-signify
|
||||
.PHONY: %-tcl %-tclx %-tcllib %-signify
|
||||
.PHONY: destroot-tcl destroot-tclx destroot-tcllib destroot-signify destroot-install
|
||||
.PHONY: install-tcl install-tclx install-tcllib install-signify install-install
|
||||
.PHONY: %-tcl %-tclx %-tcllib %-signify %-install
|
||||
|
||||
# for make all, run destroot (where destroot will depend on all of each
|
||||
# subpackage)
|
||||
@@ -37,33 +38,47 @@ all-tcllib: all-tcl
|
||||
@echo ===\> making $(@:%-signify=%) in ${DIRPRFX}${SIGNIFY_SUBDIR}
|
||||
@umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} $(@:%-signify=%)
|
||||
|
||||
%-install:
|
||||
@echo ===\> making $(@:%-install=%) in ${DIRPRFX}${INSTALL_SUBDIR}
|
||||
@umask 0022; $(MAKE) -C ${INSTALL_SUBDIR} $(@:%-install=%)
|
||||
|
||||
DESTROOT_TARGETS= destroot-tcl destroot-tclx destroot-tcllib
|
||||
ifneq (@OS_PLATFORM@,linux)
|
||||
DESTROOT_TARGETS+= destroot-signify
|
||||
endif
|
||||
ifeq (@HAVE_CLONEFILE@,yes)
|
||||
DESTROOT_TARGETS+= destroot-install
|
||||
endif
|
||||
|
||||
destroot: $(DESTROOT_TARGETS)
|
||||
destroot-tcl: all-tcl
|
||||
@echo ===\> staging to destroot in ${DIRPRFX}@VENDOR_TCL_SUBDIR@
|
||||
@umask 0022; $(MAKE) -C @VENDOR_TCL_SUBDIR@ DESTDIR=${DESTROOT} @VENDOR_TCL_INSTALL@
|
||||
@umask 0022; $(MAKE) -C @VENDOR_TCL_SUBDIR@ "DESTDIR=${DESTROOT}" @VENDOR_TCL_INSTALL@
|
||||
|
||||
destroot-tclx: all-tclx
|
||||
@echo ===\> staging to destroot in ${DIRPRFX}@VENDOR_TCLX_SUBDIR@
|
||||
@umask 0022; $(MAKE) -C @VENDOR_TCLX_SUBDIR@ DESTDIR=${DESTROOT} @VENDOR_TCLX_INSTALL@
|
||||
@umask 0022; $(MAKE) -C @VENDOR_TCLX_SUBDIR@ "DESTDIR=${DESTROOT}" @VENDOR_TCLX_INSTALL@
|
||||
|
||||
destroot-tcllib: all-tcllib
|
||||
@echo ===\> staging to destroot in ${DIRPRFX}@VENDOR_TCLLIB_SUBDIR@
|
||||
@umask 0022; $(MAKE) -C @VENDOR_TCLLIB_SUBDIR@ DESTDIR=${DESTROOT} TCLSH_PROG=@INTREE_TCLSH@ @VENDOR_TCLLIB_INSTALL@
|
||||
@umask 0022; $(MAKE) -C @VENDOR_TCLLIB_SUBDIR@ "DESTDIR=${DESTROOT}" TCLSH_PROG=@INTREE_TCLSH@ @VENDOR_TCLLIB_INSTALL@
|
||||
@chmod -R ugo+rX ${DESTROOT}${PREFIX}/libexec/macports/lib/tcllib*
|
||||
|
||||
destroot-signify:
|
||||
@echo ===\> staging to destroot in ${DIRPRFX}${SIGNIFY_SUBDIR}
|
||||
@umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} install PREFIX=${DESTROOT}${PREFIX}/libexec/macports
|
||||
@umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} install "PREFIX=${DESTROOT}${PREFIX}/libexec/macports"
|
||||
|
||||
destroot-install:
|
||||
@echo ===\> staging to destroot in ${DIRPRFX}${INSTALL_SUBDIR}
|
||||
@umask 0022; $(MAKE) -C ${INSTALL_SUBDIR} install "DESTDIR=${DESTROOT}"
|
||||
|
||||
INSTALL_TARGETS= install-tcl install-tclx install-tcllib
|
||||
ifneq (@OS_PLATFORM@,linux)
|
||||
INSTALL_TARGETS+= install-signify
|
||||
endif
|
||||
ifeq (@HAVE_CLONEFILE@,yes)
|
||||
INSTALL_TARGETS+= install-install
|
||||
endif
|
||||
|
||||
install: $(INSTALL_TARGETS)
|
||||
|
||||
@@ -106,12 +121,16 @@ install-signify:
|
||||
@echo ===\> making $(@:%-signify=%) in ${DIRPRFX}${SIGNIFY_SUBDIR}
|
||||
@umask 0022; $(MAKE) -C ${SIGNIFY_SUBDIR} install PREFIX=$(DESTDIR)${PREFIX}/libexec/macports
|
||||
|
||||
install-install:
|
||||
@echo ===\> making $(@:%-install=%) in ${DIRPRFX}${INSTALL_SUBDIR}
|
||||
@umask 0022; $(MAKE) -C ${INSTALL_SUBDIR} install
|
||||
|
||||
test:
|
||||
|
||||
clean: clean-tcl clean-tcllib clean-tclx clean-signify
|
||||
clean: clean-tcl clean-tcllib clean-tclx clean-signify clean-install
|
||||
rm -rf ${DESTROOT}
|
||||
|
||||
distclean: distclean-tcl distclean-tcllib distclean-tclx distclean-signify
|
||||
distclean: distclean-tcl distclean-tcllib distclean-tclx distclean-signify distclean-install
|
||||
rm -f Makefile
|
||||
rm -rf vendor-destroot
|
||||
rm -f tclsh
|
||||
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include ../../Mk/macports.autoconf.mk
|
||||
|
||||
SRCS = xinstall.c
|
||||
OBJS = xinstall.o
|
||||
PROGRAM = build/install
|
||||
|
||||
.PHONY: xinstall mkdirs
|
||||
|
||||
all: xinstall
|
||||
|
||||
xinstall: mkdirs ${PROGRAM}
|
||||
|
||||
${PROGRAM}: ${OBJS}
|
||||
${CC} ${CFLAGS} -o ${PROGRAM} ${LIBS} ${OBJS}
|
||||
|
||||
mkdirs:
|
||||
mkdir -p build
|
||||
|
||||
clean:
|
||||
rm -Rf build ${PROGRAM} ${OBJS}
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
install: xinstall
|
||||
${INSTALL} -d -m 755 "${DESTDIR}${TCL_PREFIX}/clonebin"
|
||||
${INSTALL} -m 555 "${PROGRAM}" "${DESTDIR}${TCL_PREFIX}/clonebin"
|
||||
|
||||
test: xinstall
|
||||
if which -s kyua > /dev/null ; then \
|
||||
cd tests && env "PATH=../build:$$PATH" kyua test ; \
|
||||
fi
|
||||
|
||||
codesign:: ${PROGRAM}
|
||||
../../codesign.sh $?
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
syntax(2)
|
||||
test_suite('install')
|
||||
atf_test_program{name='install_test.sh'}
|
||||
+448
@@ -0,0 +1,448 @@
|
||||
#! /usr/bin/env atf-sh
|
||||
#
|
||||
# Copyright (c) 2016 Jilles Tjoelker
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
copy_to_nonexistent_with_opts() {
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
atf_check install "$@" testf copyf
|
||||
cmp testf copyf || atf_fail "bad copy"
|
||||
[ ! testf -nt copyf ] || atf_fail "bad timestamp"
|
||||
[ ! -e copyf.bak ] || atf_fail "no backup expected"
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent
|
||||
copy_to_nonexistent_body() {
|
||||
copy_to_nonexistent_with_opts
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent_safe
|
||||
copy_to_nonexistent_safe_body() {
|
||||
copy_to_nonexistent_with_opts -S
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent_comparing
|
||||
copy_to_nonexistent_comparing_body() {
|
||||
copy_to_nonexistent_with_opts -C
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent_safe_comparing
|
||||
copy_to_nonexistent_safe_comparing_body() {
|
||||
copy_to_nonexistent_with_opts -S -C
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent_backup
|
||||
copy_to_nonexistent_backup_body() {
|
||||
copy_to_nonexistent_with_opts -b -B.bak
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent_backup_safe
|
||||
copy_to_nonexistent_backup_safe_body() {
|
||||
copy_to_nonexistent_with_opts -b -B.bak -S
|
||||
}
|
||||
|
||||
atf_test_case copy_to_nonexistent_preserving
|
||||
copy_to_nonexistent_preserving_body() {
|
||||
copy_to_nonexistent_with_opts -p
|
||||
[ ! testf -ot copyf ] || atf_fail "bad timestamp 2"
|
||||
}
|
||||
|
||||
copy_self_with_opts() {
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
printf 'test\n123\r456\r\n789\0z' >testf2
|
||||
atf_check -s not-exit:0 -o empty -e match:. install "$@" testf testf
|
||||
cmp testf testf2 || atf_fail "file changed after self-copy attempt"
|
||||
}
|
||||
|
||||
atf_test_case copy_self
|
||||
copy_self_body() {
|
||||
copy_self_with_opts
|
||||
}
|
||||
|
||||
atf_test_case copy_self_safe
|
||||
copy_self_safe_body() {
|
||||
copy_self_with_opts -S
|
||||
}
|
||||
|
||||
atf_test_case copy_self_comparing
|
||||
copy_self_comparing_body() {
|
||||
copy_self_with_opts -C
|
||||
}
|
||||
|
||||
atf_test_case copy_self_safe_comparing
|
||||
copy_self_safe_comparing_body() {
|
||||
copy_self_with_opts -S -C
|
||||
}
|
||||
|
||||
overwrite_with_opts() {
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
printf 'test\n123\r456\r\n789\0w' >otherf
|
||||
atf_check install "$@" testf otherf
|
||||
cmp testf otherf || atf_fail "bad overwrite"
|
||||
[ ! testf -nt otherf ] || atf_fail "bad timestamp"
|
||||
}
|
||||
|
||||
atf_test_case overwrite
|
||||
overwrite_body() {
|
||||
overwrite_with_opts
|
||||
}
|
||||
|
||||
atf_test_case overwrite_safe
|
||||
overwrite_safe_body() {
|
||||
overwrite_with_opts -S
|
||||
}
|
||||
|
||||
atf_test_case overwrite_comparing
|
||||
overwrite_comparing_body() {
|
||||
overwrite_with_opts -C
|
||||
}
|
||||
|
||||
atf_test_case overwrite_safe_comparing
|
||||
overwrite_safe_comparing_body() {
|
||||
overwrite_with_opts -S -C
|
||||
}
|
||||
|
||||
overwrite_eq_with_opts() {
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
printf 'test\n123\r456\r\n789\0z' >otherf
|
||||
atf_check install "$@" testf otherf
|
||||
cmp testf otherf || atf_fail "bad overwrite"
|
||||
[ ! testf -nt otherf ] || atf_fail "bad timestamp"
|
||||
}
|
||||
|
||||
atf_test_case overwrite_eq
|
||||
overwrite_eq_body() {
|
||||
overwrite_eq_with_opts
|
||||
}
|
||||
|
||||
atf_test_case overwrite_eq_safe
|
||||
overwrite_eq_safe_body() {
|
||||
overwrite_eq_with_opts -S
|
||||
}
|
||||
|
||||
atf_test_case overwrite_eq_comparing
|
||||
overwrite_eq_comparing_body() {
|
||||
overwrite_eq_with_opts -C
|
||||
}
|
||||
|
||||
atf_test_case overwrite_eq_safe_comparing
|
||||
overwrite_eq_safe_comparing_body() {
|
||||
overwrite_eq_with_opts -S -C
|
||||
}
|
||||
|
||||
overwrite_backup_with_opts() {
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
printf 'test\n123\r456\r\n789\0w' >otherf
|
||||
printf 'test\n123\r456\r\n789\0w' >otherf2
|
||||
atf_check install -b -B.bak "$@" testf otherf
|
||||
cmp testf otherf || atf_fail "bad overwrite"
|
||||
[ ! testf -nt otherf ] || atf_fail "bad timestamp"
|
||||
cmp otherf.bak otherf2 || atf_fail "bad backup"
|
||||
}
|
||||
|
||||
atf_test_case overwrite_backup
|
||||
overwrite_backup_body() {
|
||||
overwrite_backup_with_opts
|
||||
}
|
||||
|
||||
atf_test_case overwrite_backup_safe
|
||||
overwrite_backup_safe_body() {
|
||||
overwrite_backup_with_opts -S
|
||||
}
|
||||
|
||||
atf_test_case overwrite_backup_comparing
|
||||
overwrite_backup_comparing_body() {
|
||||
overwrite_backup_with_opts -C
|
||||
}
|
||||
|
||||
atf_test_case overwrite_backup_safe_comparing
|
||||
overwrite_backup_safe_comparing_body() {
|
||||
overwrite_backup_with_opts -S -C
|
||||
}
|
||||
|
||||
setup_stripbin() {
|
||||
cat <<\STRIPBIN >stripbin
|
||||
#!/bin/sh
|
||||
[ "$1" = "-o" ] && dst="$2" && shift 2
|
||||
[ "$1" = "--" ] && shift
|
||||
[ -z "$dst" ] && dst="$1"
|
||||
STRIPBIN
|
||||
[ "$1" = "true" ] && cmd="cat" || cmd="tr z @"
|
||||
echo $cmd '<"$1" >"$1.new" && mv -- "$1.new" "$dst"' >>stripbin
|
||||
chmod 755 stripbin
|
||||
export STRIPBIN="$PWD/stripbin"
|
||||
}
|
||||
|
||||
strip_changing_with_opts() {
|
||||
setup_stripbin
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
atf_check install -s "$@" testf copyf
|
||||
[ ! testf -nt copyf ] || atf_fail "bad timestamp"
|
||||
printf 'test\n123\r456\r\n789\0@' >otherf
|
||||
cmp otherf copyf || atf_fail "bad stripped copy"
|
||||
}
|
||||
|
||||
# atf_test_case strip_changing
|
||||
# strip_changing_body() {
|
||||
# strip_changing_with_opts
|
||||
# }
|
||||
#
|
||||
# atf_test_case strip_changing_comparing
|
||||
# strip_changing_comparing_body() {
|
||||
# strip_changing_with_opts -C
|
||||
# }
|
||||
|
||||
strip_changing_overwrite_with_opts() {
|
||||
setup_stripbin
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
printf 'test\n123\r456\r\n789\0w' >copyf
|
||||
atf_check install -s "$@" testf copyf
|
||||
[ ! testf -nt copyf ] || atf_fail "bad timestamp"
|
||||
printf 'test\n123\r456\r\n789\0@' >otherf
|
||||
cmp otherf copyf || atf_fail "bad stripped copy"
|
||||
}
|
||||
|
||||
# atf_test_case strip_changing_overwrite
|
||||
# strip_changing_overwrite_body() {
|
||||
# strip_changing_overwrite_with_opts
|
||||
# }
|
||||
#
|
||||
# atf_test_case strip_changing_overwrite_comparing
|
||||
# strip_changing_overwrite_comparing_body() {
|
||||
# strip_changing_overwrite_with_opts -C
|
||||
# }
|
||||
|
||||
strip_changing_overwrite_eq_with_opts() {
|
||||
setup_stripbin
|
||||
printf 'test\n123\r456\r\n789\0z' >testf
|
||||
printf 'test\n123\r456\r\n789\0@' >copyf
|
||||
atf_check install -s "$@" testf copyf
|
||||
[ ! testf -nt copyf ] || atf_fail "bad timestamp"
|
||||
printf 'test\n123\r456\r\n789\0@' >otherf
|
||||
cmp otherf copyf || atf_fail "bad stripped copy"
|
||||
}
|
||||
|
||||
# atf_test_case strip_changing_overwrite_eq
|
||||
# strip_changing_overwrite_eq_body() {
|
||||
# strip_changing_overwrite_eq_with_opts
|
||||
# }
|
||||
#
|
||||
# atf_test_case strip_changing_overwrite_eq_comparing
|
||||
# strip_changing_overwrite_eq_comparing_body() {
|
||||
# strip_changing_overwrite_eq_with_opts -C
|
||||
# }
|
||||
|
||||
# atf_test_case strip_noop
|
||||
# strip_noop_body() {
|
||||
# setup_stripbin true
|
||||
# printf 'test\n123\r456\r\n789\0z' >testf
|
||||
# atf_check install -s testf copyf
|
||||
# [ ! testf -nt copyf ] || atf_fail "bad timestamp"
|
||||
# printf 'test\n123\r456\r\n789\0z' >otherf
|
||||
# cmp otherf copyf || atf_fail "bad stripped copy"
|
||||
# }
|
||||
|
||||
#atf_test_case hard_link
|
||||
#hard_link_body() {
|
||||
# printf 'test\n123\r456\r\n789\0z' >testf
|
||||
# atf_check install -l h testf copyf
|
||||
# [ testf -ef copyf ] || atf_fail "not same file"
|
||||
# [ ! -L copyf ] || atf_fail "copy is symlink"
|
||||
#}
|
||||
|
||||
#atf_test_case symbolic_link
|
||||
#symbolic_link_body() {
|
||||
# printf 'test\n123\r456\r\n789\0z' >testf
|
||||
# atf_check install -l s testf copyf
|
||||
# [ testf -ef copyf ] || atf_fail "not same file"
|
||||
# [ -L copyf ] || atf_fail "copy is not symlink"
|
||||
#}
|
||||
|
||||
#atf_test_case symbolic_link_absolute
|
||||
#symbolic_link_absolute_body() {
|
||||
# printf 'test\n123\r456\r\n789\0z' >testf
|
||||
# atf_check install -l sa testf copyf
|
||||
# [ testf -ef copyf ] || atf_fail "not same file"
|
||||
# [ -L copyf ] || atf_fail "copy is not symlink"
|
||||
# copyf_path=$(readlink copyf)
|
||||
# testf_path="$(pwd -P)/testf"
|
||||
# if [ "$copyf_path" != "$testf_path" ]; then
|
||||
# atf_fail "unexpected symlink contents ('$copyf_path' != '$testf_path')"
|
||||
# fi
|
||||
#}
|
||||
|
||||
#atf_test_case symbolic_link_relative
|
||||
#symbolic_link_relative_body() {
|
||||
# printf 'test\n123\r456\r\n789\0z' >testf
|
||||
# atf_check install -l sr testf copyf
|
||||
# [ testf -ef copyf ] || atf_fail "not same file"
|
||||
# [ -L copyf ] || atf_fail "copy is not symlink"
|
||||
# copyf_path=$(readlink copyf)
|
||||
# testf_path="testf"
|
||||
# if [ "$copyf_path" != "$testf_path" ]; then
|
||||
# atf_fail "unexpected symlink contents ('$copyf_path' != '$testf_path')"
|
||||
# fi
|
||||
#}
|
||||
|
||||
# atf_test_case symbolic_link_relative_absolute_source_and_dest1
|
||||
# symbolic_link_relative_absolute_source_and_dest1_head() {
|
||||
# atf_set "descr" "Verify -l rs with absolute paths (.../copyf -> .../a/b/c/testf)"
|
||||
# }
|
||||
# symbolic_link_relative_absolute_source_and_dest1_body() {
|
||||
# src_path=a/b/c/testf
|
||||
# src_path_prefixed=$PWD/$src_path
|
||||
# dest_path=$PWD/copyf
|
||||
#
|
||||
# atf_check mkdir -p a/b/c
|
||||
# atf_check touch $src_path
|
||||
# atf_check install -l sr $src_path_prefixed $dest_path
|
||||
# [ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
|
||||
# [ -L $dest_path ] || atf_fail "copy is not symlink"
|
||||
# dest_path_relative=$(readlink $dest_path)
|
||||
# src_path_relative="$src_path"
|
||||
# if [ "$src_path_relative" != "$dest_path_relative" ]; then
|
||||
# atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
|
||||
# fi
|
||||
# }
|
||||
|
||||
# atf_test_case symbolic_link_relative_absolute_source_and_dest1_double_slash
|
||||
# symbolic_link_relative_absolute_source_and_dest1_double_slash_head() {
|
||||
# atf_set "descr" "Verify -l rs with absolute paths (.../copyf -> .../a/b/c/testf), using double-slashes"
|
||||
# }
|
||||
# symbolic_link_relative_absolute_source_and_dest1_double_slash_body() {
|
||||
# src_path=a//b//c//testf
|
||||
# src_path_prefixed=$PWD/$src_path
|
||||
# dest_path=$PWD/copyf
|
||||
#
|
||||
# atf_check mkdir -p a/b/c
|
||||
# atf_check touch $src_path
|
||||
# atf_check install -l sr $src_path_prefixed $dest_path
|
||||
# [ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
|
||||
# [ -L $dest_path ] || atf_fail "copy is not symlink"
|
||||
# dest_path_relative=$(readlink $dest_path)
|
||||
# src_path_relative="$(echo $src_path | sed -e 's,//,/,g')"
|
||||
# if [ "$src_path_relative" != "$dest_path_relative" ]; then
|
||||
# atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
|
||||
# fi
|
||||
# }
|
||||
|
||||
# atf_test_case symbolic_link_relative_absolute_source_and_dest2
|
||||
# symbolic_link_relative_absolute_source_and_dest2_head() {
|
||||
# atf_set "descr" "Verify -l rs with absolute paths (.../a/b/c/copyf -> .../testf)"
|
||||
# }
|
||||
# symbolic_link_relative_absolute_source_and_dest2_body() {
|
||||
# src_path=testf
|
||||
# src_path_prefixed=$PWD/$src_path
|
||||
# dest_path=$PWD/a/b/c/copyf
|
||||
#
|
||||
# atf_check mkdir -p a/b/c
|
||||
# atf_check touch $src_path
|
||||
# atf_check install -l sr $src_path_prefixed $dest_path
|
||||
# [ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
|
||||
# [ -L $dest_path ] || atf_fail "copy is not symlink"
|
||||
# dest_path_relative=$(readlink $dest_path)
|
||||
# src_path_relative="../../../$src_path"
|
||||
# if [ "$src_path_relative" != "$dest_path_relative" ]; then
|
||||
# atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
|
||||
# fi
|
||||
# }
|
||||
|
||||
atf_test_case mkdir_simple
|
||||
mkdir_simple_body() {
|
||||
atf_check install -d dir1/dir2
|
||||
[ -d dir1 ] || atf_fail "dir1 missing"
|
||||
[ -d dir1/dir2 ] || atf_fail "dir2 missing"
|
||||
atf_check install -d dir1/dir2/dir3
|
||||
[ -d dir1/dir2/dir3 ] || atf_fail "dir3 missing"
|
||||
atf_check install -d dir1
|
||||
atf_check install -d dir1/dir2/dir3
|
||||
}
|
||||
|
||||
# atf_test_case symbolic_link_relative_absolute_common
|
||||
# symbolic_link_relative_absolute_common_head() {
|
||||
# atf_set "descr" "Verify -l rs with absolute paths having common components"
|
||||
# }
|
||||
# symbolic_link_relative_absolute_common_body() {
|
||||
# filename=foo.so
|
||||
# src_path=lib
|
||||
# src_path_prefixed=$PWD/$src_path
|
||||
# dest_path=$PWD/libexec/
|
||||
# src_file=$src_path_prefixed/$filename
|
||||
# dest_file=$dest_path/$filename
|
||||
#
|
||||
# atf_check mkdir $src_path_prefixed $dest_path
|
||||
# atf_check touch $src_file
|
||||
# atf_check install -l sr $src_file $dest_path
|
||||
#
|
||||
# dest_path_relative=$(readlink $dest_file)
|
||||
# src_path_relative="../lib/$filename"
|
||||
# if [ "$src_path_relative" != "$dest_path_relative" ]; then
|
||||
# atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
|
||||
# fi
|
||||
# }
|
||||
|
||||
atf_init_test_cases() {
|
||||
atf_add_test_case copy_to_nonexistent
|
||||
atf_add_test_case copy_to_nonexistent_safe
|
||||
atf_add_test_case copy_to_nonexistent_comparing
|
||||
atf_add_test_case copy_to_nonexistent_safe_comparing
|
||||
atf_add_test_case copy_to_nonexistent_backup
|
||||
atf_add_test_case copy_to_nonexistent_backup_safe
|
||||
atf_add_test_case copy_to_nonexistent_preserving
|
||||
atf_add_test_case copy_self
|
||||
atf_add_test_case copy_self_safe
|
||||
atf_add_test_case copy_self_comparing
|
||||
atf_add_test_case copy_self_safe_comparing
|
||||
atf_add_test_case overwrite
|
||||
atf_add_test_case overwrite_safe
|
||||
atf_add_test_case overwrite_comparing
|
||||
atf_add_test_case overwrite_safe_comparing
|
||||
atf_add_test_case overwrite_eq
|
||||
atf_add_test_case overwrite_eq_safe
|
||||
atf_add_test_case overwrite_eq_comparing
|
||||
atf_add_test_case overwrite_eq_safe_comparing
|
||||
atf_add_test_case overwrite_backup
|
||||
atf_add_test_case overwrite_backup_safe
|
||||
atf_add_test_case overwrite_backup_comparing
|
||||
atf_add_test_case overwrite_backup_safe_comparing
|
||||
#atf_add_test_case strip_changing
|
||||
#atf_add_test_case strip_changing_comparing
|
||||
#atf_add_test_case strip_changing_overwrite
|
||||
#atf_add_test_case strip_changing_overwrite_comparing
|
||||
#atf_add_test_case strip_changing_overwrite_eq
|
||||
#atf_add_test_case strip_changing_overwrite_eq_comparing
|
||||
#atf_add_test_case strip_noop
|
||||
#atf_add_test_case hard_link
|
||||
#atf_add_test_case symbolic_link
|
||||
#atf_add_test_case symbolic_link_absolute
|
||||
#atf_add_test_case symbolic_link_relative
|
||||
#atf_add_test_case symbolic_link_relative_absolute_source_and_dest1
|
||||
#atf_add_test_case symbolic_link_relative_absolute_source_and_dest1_double_slash
|
||||
#atf_add_test_case symbolic_link_relative_absolute_source_and_dest2
|
||||
#atf_add_test_case symbolic_link_relative_absolute_common
|
||||
atf_add_test_case mkdir_simple
|
||||
}
|
||||
Vendored
+878
File diff suppressed because it is too large
Load Diff
+129
@@ -0,0 +1,129 @@
|
||||
Applied to original from file_cmds-430.140.2
|
||||
|
||||
--- xinstall.c.orig 2024-08-20 16:07:42
|
||||
+++ xinstall.c 2024-08-27 16:58:56
|
||||
@@ -70,9 +70,9 @@
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#include <copyfile.h>
|
||||
+#include <sys/attr.h>
|
||||
+#include <sys/clonefile.h>
|
||||
#endif /* __APPLE__ */
|
||||
-
|
||||
-#include "pathnames.h"
|
||||
|
||||
/* Bootstrap aid - this doesn't exist in most older releases */
|
||||
#ifndef MAP_FAILED
|
||||
@@ -92,6 +92,7 @@
|
||||
mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
char *suffix = BACKUP_SUFFIX;
|
||||
|
||||
+static int clone __P((const char *, const char *, int, char *, size_t));
|
||||
void copy __P((int, char *, int, char *, off_t));
|
||||
int compare __P((int, const char *, size_t, int, const char *, size_t));
|
||||
int create_newfile __P((char *, int, struct stat *));
|
||||
@@ -100,6 +101,7 @@
|
||||
void install_dir __P((char *));
|
||||
u_long numeric_id __P((char *, char *));
|
||||
void strip __P((char *));
|
||||
+static void tempfile_template __P((const char *, char *, size_t));
|
||||
int trymmap __P((int));
|
||||
void usage __P((void));
|
||||
|
||||
@@ -276,9 +278,10 @@
|
||||
{
|
||||
struct stat from_sb, temp_sb, to_sb;
|
||||
struct utimbuf utb;
|
||||
- int devnull, files_match, from_fd=0, serrno, target;
|
||||
- int tempcopy, temp_fd, to_fd=0;
|
||||
+ int devnull, files_match, from_fd=-1, serrno, target;
|
||||
+ int tempcopy, temp_fd=-1, to_fd=-1;
|
||||
char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
|
||||
+ const int tryclone = 1;
|
||||
|
||||
files_match = 0;
|
||||
|
||||
@@ -334,6 +337,17 @@
|
||||
}
|
||||
|
||||
if (!files_match) {
|
||||
+ int done_clone = 0;
|
||||
+ if (tryclone && !devnull && !dostrip) {
|
||||
+ done_clone = (clone(from_name, to_name, tempcopy, tempfile, sizeof(tempfile)) == 0);
|
||||
+ }
|
||||
+ if (done_clone &&
|
||||
+ (((to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0)) < 0)
|
||||
+ || (!tempcopy && fstat(to_fd, &to_sb) == -1))) {
|
||||
+ (void)unlink(tempcopy ? tempfile : to_name);
|
||||
+ done_clone = 0;
|
||||
+ }
|
||||
+ if (!done_clone) {
|
||||
if (tempcopy) {
|
||||
to_fd = create_tempfile(to_name, tempfile,
|
||||
sizeof(tempfile));
|
||||
@@ -350,6 +364,7 @@
|
||||
if (!devnull)
|
||||
copy(from_fd, from_name, to_fd,
|
||||
tempcopy ? tempfile : to_name, from_sb.st_size);
|
||||
+ } /* !done_clone */
|
||||
}
|
||||
|
||||
if (dostrip) {
|
||||
@@ -592,11 +607,11 @@
|
||||
}
|
||||
|
||||
/*
|
||||
- * create_tempfile --
|
||||
- * create a temporary file based on path and open it
|
||||
+ * tempfile_template --
|
||||
+ * prepare a template filename for use with mktemp/mkstemp.
|
||||
*/
|
||||
-int
|
||||
-create_tempfile(char *path,
|
||||
+static void
|
||||
+tempfile_template(const char *path,
|
||||
char *temp,
|
||||
size_t tsize)
|
||||
{
|
||||
@@ -610,6 +625,18 @@
|
||||
p = temp;
|
||||
(void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p);
|
||||
temp[tsize - 1] = '\0';
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * create_tempfile --
|
||||
+ * create a temporary file based on path and open it
|
||||
+ */
|
||||
+int
|
||||
+create_tempfile(char *path,
|
||||
+ char *temp,
|
||||
+ size_t tsize)
|
||||
+{
|
||||
+ tempfile_template(path, temp, tsize);
|
||||
return (mkstemp(temp));
|
||||
}
|
||||
|
||||
@@ -736,6 +763,22 @@
|
||||
}
|
||||
|
||||
/*
|
||||
+ * clone --
|
||||
+ * create a clone of a file
|
||||
+ */
|
||||
+static int
|
||||
+clone(const char *from_name, const char *to_name,
|
||||
+ int use_temp, char *temp_name, size_t tsize)
|
||||
+{
|
||||
+ if (use_temp) {
|
||||
+ tempfile_template(to_name, temp_name, tsize);
|
||||
+ mktemp(temp_name);
|
||||
+ to_name = temp_name;
|
||||
+ }
|
||||
+ return clonefile(from_name, to_name, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* strip --
|
||||
* use strip(1) to strip the target file
|
||||
*/
|
||||
Vendored
+112
@@ -0,0 +1,112 @@
|
||||
diff --git a/vendor/tcl8.6.14/unix/configure b/vendor/tcl8.6.14/unix/configure
|
||||
index 87dc84d1e..a161fed43 100755
|
||||
--- a/vendor/tcl8.6.14/unix/configure
|
||||
+++ b/vendor/tcl8.6.14/unix/configure
|
||||
@@ -17439,7 +17439,7 @@ fi
|
||||
done
|
||||
|
||||
|
||||
-for ac_header in copyfile.h
|
||||
+for ac_header in sys/clonefile.h copyfile.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||
@@ -17589,7 +17589,7 @@ fi
|
||||
done
|
||||
|
||||
|
||||
-for ac_func in copyfile
|
||||
+for ac_func in clonefile copyfile
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
diff --git a/vendor/tcl8.6.14/unix/tclUnixFCmd.c b/vendor/tcl8.6.14/unix/tclUnixFCmd.c
|
||||
index 26429df73..82da6d433 100644
|
||||
--- a/vendor/tcl8.6.14/unix/tclUnixFCmd.c
|
||||
+++ b/vendor/tcl8.6.14/unix/tclUnixFCmd.c
|
||||
@@ -51,6 +51,18 @@
|
||||
#ifdef HAVE_FTS
|
||||
#include <fts.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SYS_CLONEFILE_H
|
||||
+#include <sys/clonefile.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_CLONEFILE
|
||||
+#if defined(__APPLE__) && \
|
||||
+ defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
|
||||
+ MAC_OS_X_VERSION_MIN_REQUIRED < 101200
|
||||
+#define MayUseCloneFile() (clonefile != NULL)
|
||||
+#else
|
||||
+#define MayUseCloneFile() (1)
|
||||
+#endif
|
||||
+#endif /* HAVE_CLONEFILE */
|
||||
|
||||
/*
|
||||
* The following constants specify the type of callback when
|
||||
@@ -526,14 +538,50 @@ DoCopyFile(
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
-
|
||||
+
|
||||
+/*
|
||||
+ *----------------------------------------------------------------------
|
||||
+ *
|
||||
+ * TclUnixCloneFile -
|
||||
+ *
|
||||
+ * Helper function for TclUnixCopyFile. Clones one regular file, using
|
||||
+ * clonefile().
|
||||
+ *
|
||||
+ * Results:
|
||||
+ * A standard Tcl result.
|
||||
+ *
|
||||
+ * Side effects:
|
||||
+ * A file is cloned.
|
||||
+ *
|
||||
+ *----------------------------------------------------------------------
|
||||
+ */
|
||||
+#ifdef HAVE_CLONEFILE
|
||||
+int
|
||||
+TclUnixCloneFile(
|
||||
+ const char *src, /* Pathname of file to clone (native). */
|
||||
+ const char *dst, /* Pathname of file to create (native). */
|
||||
+ const Tcl_StatBuf *statBufPtr,
|
||||
+ /* Used to copy attributes. */
|
||||
+ int dontCopyAtts) /* If flag set, don't copy attributes. */
|
||||
+{
|
||||
+ if (clonefile(src, dst, CLONE_NOFOLLOW|CLONE_NOOWNERCOPY) == 0) {
|
||||
+ if (dontCopyAtts || CopyFileAtts(src, dst, statBufPtr) == TCL_OK) {
|
||||
+ return TCL_OK;
|
||||
+ }
|
||||
+ }
|
||||
+ unlink(dst); /* INTL: Native. */
|
||||
+ return TCL_ERROR;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclUnixCopyFile -
|
||||
*
|
||||
* Helper function for TclpCopyFile. Copies one regular file, using
|
||||
- * read() and write().
|
||||
+ * read() and write(), or clones it with TclUnixCloneFile() if
|
||||
+ * supported.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
@@ -558,6 +606,13 @@ TclUnixCopyFile(
|
||||
char *buffer; /* Data buffer for copy */
|
||||
size_t nread;
|
||||
|
||||
+#ifdef HAVE_CLONEFILE
|
||||
+ if (MayUseCloneFile() &&
|
||||
+ TclUnixCloneFile(src, dst, statBufPtr, dontCopyAtts) == TCL_OK) {
|
||||
+ return TCL_OK;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
#ifdef DJGPP
|
||||
#define BINMODE |O_BINARY
|
||||
#else
|
||||
Vendored
+2
-2
@@ -17439,7 +17439,7 @@ fi
|
||||
done
|
||||
|
||||
|
||||
for ac_header in copyfile.h
|
||||
for ac_header in sys/clonefile.h copyfile.h
|
||||
do
|
||||
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
if eval "test \"\${$as_ac_Header+set}\" = set"; then
|
||||
@@ -17589,7 +17589,7 @@ fi
|
||||
done
|
||||
|
||||
|
||||
for ac_func in copyfile
|
||||
for ac_func in clonefile copyfile
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user