Revision: 934 http://trac.macosforge.org/projects/darwinbuild/changeset/934 Author: wsiegrist@apple.com Date: 2011-02-10 07:22:14 -0800 (Thu, 10 Feb 2011) Log Message: ----------- Merge PR-8817822 Modified Paths: -------------- trunk/darwinbuild.xcodeproj/project.pbxproj trunk/darwintrace/darwintrace.c trunk/darwinup/Depot.cpp trunk/darwinup/Digest.cpp trunk/darwinup/Digest.h trunk/darwinup/File.cpp trunk/darwinup/File.h trunk/darwinup/main.cpp trunk/testing/darwinup/run-tests.sh Added Paths: ----------- trunk/testing/darwintrace/ trunk/testing/darwintrace/close-test trunk/testing/darwintrace/exec trunk/testing/darwintrace/realpath trunk/testing/darwintrace/redirection-test trunk/testing/darwintrace/run-tests.sh trunk/testing/run-all-tests.sh Removed Paths: ------------- trunk/Makefile trunk/darwintrace/Makefile trunk/darwinup/redo_prebinding.h trunk/testing/darwintrace/close-test trunk/testing/darwintrace/exec trunk/testing/darwintrace/realpath trunk/testing/darwintrace/redirection-test trunk/testing/darwintrace/run-tests.sh Property Changed: ---------------- trunk/ Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/PR-4841388:399-419 /branches/PR-6358021:442-443 /branches/PR-6392966:423-427 /branches/PR-6398060:433-434 /branches/PR-6493844:460-461 /branches/PR-6497694:466-468,471 /branches/PR-6634286:632-650 /branches/PR-6688645:479-490 /branches/PR-6722857:495-499 /branches/PR-6729491:655-664 /branches/PR-6973110:804-813 /branches/PR-7250612:635-650 /branches/PR-7341154:682-694 /branches/PR-7431723:660-664 /branches/PR-7461534:650-664 /branches/PR-7482850:670-671 /branches/PR-7489777:676-731 /branches/PR-7529688:692-694 /branches/PR-7593824:739-772 /branches/PR-7598640:703-731 /branches/PR-7748469:777-785 /branches/PR-7765119:790-791 /branches/PR-7798586:796-799 /branches/PR-7872907:830-840 /branches/PR-7935095:819-821 /branches/PR-8116613:849 /branches/PR-8279204:854-862 /branches/PR-8416637:870-880 /branches/PR-8486662:885-889 /branches/PR-8488185:894-898 /branches/PR-8604911:903-905 /branches/PR-8908468:912 + /branches/PR-4841388:399-419 /branches/PR-6358021:442-443 /branches/PR-6392966:423-427 /branches/PR-6398060:433-434 /branches/PR-6493844:460-461 /branches/PR-6497694:466-468,471 /branches/PR-6634286:632-650 /branches/PR-6688645:479-490 /branches/PR-6722857:495-499 /branches/PR-6729491:655-664 /branches/PR-6973110:804-813 /branches/PR-7250612:635-650 /branches/PR-7341154:682-694 /branches/PR-7431723:660-664 /branches/PR-7461534:650-664 /branches/PR-7482850:670-671 /branches/PR-7489777:676-731 /branches/PR-7529688:692-694 /branches/PR-7593824:739-772 /branches/PR-7598640:703-731 /branches/PR-7748469:777-785 /branches/PR-7765119:790-791 /branches/PR-7798586:796-799 /branches/PR-7872907:830-840 /branches/PR-7935095:819-821 /branches/PR-8116613:849 /branches/PR-8279204:854-862 /branches/PR-8416637:870-880 /branches/PR-8486662:885-889 /branches/PR-8488185:894-898 /branches/PR-8604911:903-905 /branches/PR-8817822:917-933 /branches/PR-8908468:912 Deleted: trunk/Makefile =================================================================== --- trunk/Makefile 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/Makefile 2011-02-10 15:22:14 UTC (rev 934) @@ -1,26 +0,0 @@ -Project = darwinbuild -SubProjects = darwinbuild \ - darwintrace \ - darwinup \ - darwinxref - -Install_Flags = DESTDIR=$(DSTROOT) - -SUBDIRS= \ - darwinbuild \ - darwinxref \ - darwinup \ - darwintrace - -.PHONY: all clean install uninstall - -all clean install uninstall: - @$(foreach DIR,$(SUBDIRS), \ - (echo "*** Making $@ in $(DIR) ***" ; \ - make -C $(DIR) $@) || exit 1; ) - -installsrc: - tar czf - . | tar xzf - -C "$(SRCROOT)" --exclude=.svn --exclude=sqlite --exclude=www --exclude=darwinup/libredo.o --exclude=patches --exclude=plists --exclude=testing - -installhdrs: - @echo Nothing to be done for $@ Modified: trunk/darwinbuild.xcodeproj/project.pbxproj =================================================================== --- trunk/darwinbuild.xcodeproj/project.pbxproj 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinbuild.xcodeproj/project.pbxproj 2011-02-10 15:22:14 UTC (rev 934) @@ -37,17 +37,6 @@ name = darwinbuild_scripts; productName = darwinbuild_scripts; }; - 7227AC7E1098EF6400BE33D7 /* libredo_prebinding.a */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 7227AC841098EF8000BE33D7 /* Build configuration list for PBXAggregateTarget "libredo_prebinding.a" */; - buildPhases = ( - 7227AC7D1098EF6400BE33D7 /* ShellScript */, - ); - dependencies = ( - ); - name = libredo_prebinding.a; - productName = libredo_prebinding.a; - }; 725740981097B051008AD4D7 /* darwinxref_plugins */ = { isa = PBXAggregateTarget; buildConfigurationList = 725740A01097B08A008AD4D7 /* Build configuration list for PBXAggregateTarget "darwinxref_plugins" */; @@ -112,7 +101,6 @@ 7227AB67109899A600BE33D7 /* cfutils.h in Headers */ = {isa = PBXBuildFile; fileRef = 72C86BE910965E7500C66E90 /* cfutils.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7227AB68109899A600BE33D7 /* DBPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 72C86BED10965E7500C66E90 /* DBPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7227AB7510989F8D00BE33D7 /* manifest.c in Sources */ = {isa = PBXBuildFile; fileRef = 72C86C2E1096600B00C66E90 /* manifest.c */; }; - 7227ACA01098FCAA00BE33D7 /* libredo_prebinding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C86CDD10974C3A00C66E90 /* libredo_prebinding.a */; }; 7227AD1C109A05FA00BE33D7 /* buildlist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7227AB871098A7BF00BE33D7 /* buildlist */; }; 7227AD1D109A05FA00BE33D7 /* buildorder in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7227AB881098A7BF00BE33D7 /* buildorder */; }; 7227AD1E109A05FA00BE33D7 /* ditto in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7227AB891098A7BF00BE33D7 /* ditto */; }; @@ -607,13 +595,6 @@ remoteGlobalIDString = 72D05CAD11D267C400B33EDD; remoteInfo = query; }; - DFCB82D9109A2F9A00D2DB2F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 726DD14910965C5700D5AEAB /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7227AC7E1098EF6400BE33D7; - remoteInfo = libredo_prebinding.a; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -721,7 +702,6 @@ 72C86BE010965E4F00C66E90 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = File.cpp; path = darwinup/File.cpp; sourceTree = "<group>"; }; 72C86BE110965E4F00C66E90 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = darwinup/File.h; sourceTree = "<group>"; }; 72C86BE210965E4F00C66E90 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = darwinup/main.cpp; sourceTree = "<group>"; }; - 72C86BE310965E4F00C66E90 /* redo_prebinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = redo_prebinding.h; path = darwinup/redo_prebinding.h; sourceTree = "<group>"; }; 72C86BE410965E4F00C66E90 /* SerialSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SerialSet.cpp; path = darwinup/SerialSet.cpp; sourceTree = "<group>"; }; 72C86BE510965E4F00C66E90 /* SerialSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SerialSet.h; path = darwinup/SerialSet.h; sourceTree = "<group>"; }; 72C86BE610965E4F00C66E90 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Utils.cpp; path = darwinup/Utils.cpp; sourceTree = "<group>"; }; @@ -779,7 +759,6 @@ 72C86C381096607900C66E90 /* darwinbuild */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = darwinbuild; sourceTree = BUILT_PRODUCTS_DIR; }; 72C86C481096609500C66E90 /* darwinup */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = darwinup; sourceTree = BUILT_PRODUCTS_DIR; }; 72C86C52109660CA00C66E90 /* darwintrace.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = darwintrace.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - 72C86CDD10974C3A00C66E90 /* libredo_prebinding.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libredo_prebinding.a; path = /usr/local/lib/libredo_prebinding.a; sourceTree = "<absolute>"; }; 72C86CE310974CC800C66E90 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = /usr/lib/libsqlite3.dylib; sourceTree = "<absolute>"; }; 72D05CA911D2678F00B33EDD /* query.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = query.c; sourceTree = "<group>"; }; 72D05CB711D267C400B33EDD /* query.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.objfile"; includeInIndex = 0; path = query.so; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -985,7 +964,6 @@ buildActionMask = 2147483647; files = ( 72C86CE410974CC800C66E90 /* libsqlite3.dylib in Frameworks */, - 7227ACA01098FCAA00BE33D7 /* libredo_prebinding.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1014,7 +992,6 @@ 72C86BD610965DD000C66E90 /* darwinxref */, 72C86BD510965DC900C66E90 /* darwinbuild */, 72C86C391096607900C66E90 /* Products */, - 72C86CDD10974C3A00C66E90 /* libredo_prebinding.a */, 72C86CE310974CC800C66E90 /* libsqlite3.dylib */, 72574A0F10977F7A00B13BC3 /* CoreFoundation.framework */, 72574A1410977FAD00B13BC3 /* libtcl.dylib */, @@ -1085,7 +1062,6 @@ 72C86BE010965E4F00C66E90 /* File.cpp */, 72C86BE110965E4F00C66E90 /* File.h */, 72C86BE210965E4F00C66E90 /* main.cpp */, - 72C86BE310965E4F00C66E90 /* redo_prebinding.h */, 72C86BE410965E4F00C66E90 /* SerialSet.cpp */, 72C86BE510965E4F00C66E90 /* SerialSet.h */, 72C86BE610965E4F00C66E90 /* Utils.cpp */, @@ -1755,7 +1731,6 @@ buildRules = ( ); dependencies = ( - DFCB82DA109A2F9A00D2DB2F /* PBXTargetDependency */, ); name = darwinup; productName = darwinup; @@ -1858,7 +1833,6 @@ 7227AC151098D8DB00BE33D7 /* thinPackages */, 7227AC1E1098DB9200BE33D7 /* installXcode */, 7227AC271098DBDF00BE33D7 /* installXcode32 */, - 7227AC7E1098EF6400BE33D7 /* libredo_prebinding.a */, 720BE2EA120C90A700B3C4A5 /* digest */, ); }; @@ -2045,19 +2019,6 @@ shellPath = /bin/sh; shellScript = "/bin/cp $DERIVED_FILE_DIR/installXcode32 $BUILT_PRODUCTS_DIR/installXcode32"; }; - 7227AC7D1098EF6400BE33D7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -x\nBUILD=10A432\nHOST=src.macosforge.org\n\n# make sure we only run when needed\nif [ -f /usr/local/lib/libredo_prebinding.a ]; then\n\texit 0;\nfi\n\n/usr/bin/curl -kL http://$HOST/Roots/$BUILD/cctools_ofiles.root.tar.gz > $CONFIGURATION_TEMP_DIR/cctools_ofiles.root.tar.gz\n\n/bin/mkdir -p $BUILT_PRODUCTS_DIR\n\n/usr/bin/tar zxOf $CONFIGURATION_TEMP_DIR/cctools_ofiles.root.tar.gz ./usr/local/lib/libredo_prebinding.a > $BUILT_PRODUCTS_DIR/libredo_prebinding.a\n\n/bin/mkdir -p $DSTROOT/$PREFIX/lib/\n\n/bin/cp $BUILT_PRODUCTS_DIR/libredo_prebinding.a $DSTROOT/$PREFIX/lib/\n"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -2620,11 +2581,6 @@ target = 72D05CAD11D267C400B33EDD /* query */; targetProxy = 72D05CB911D2688D00B33EDD /* PBXContainerItemProxy */; }; - DFCB82DA109A2F9A00D2DB2F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 7227AC7E1098EF6400BE33D7 /* libredo_prebinding.a */; - targetProxy = DFCB82D9109A2F9A00D2DB2F /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -2865,27 +2821,6 @@ }; name = Release; }; - 7227AC7F1098EF6400BE33D7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = libredo_prebinding.a; - }; - name = Debug; - }; - 7227AC801098EF6400BE33D7 /* Public */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = libredo_prebinding.a; - }; - name = Public; - }; - 7227AC811098EF6400BE33D7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = libredo_prebinding.a; - }; - name = Release; - }; 72573F7C1097A488008AD4D7 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 72574B3E10979D6000B13BC3 /* c_plugins.xcconfig */; @@ -3777,16 +3712,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Public; }; - 7227AC841098EF8000BE33D7 /* Build configuration list for PBXAggregateTarget "libredo_prebinding.a" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7227AC7F1098EF6400BE33D7 /* Debug */, - 7227AC801098EF6400BE33D7 /* Public */, - 7227AC811098EF6400BE33D7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Public; - }; 72573F7B1097A488008AD4D7 /* Build configuration list for PBXNativeTarget "dependencies" */ = { isa = XCConfigurationList; buildConfigurations = ( Deleted: trunk/darwintrace/Makefile =================================================================== --- trunk/darwintrace/Makefile 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwintrace/Makefile 2011-02-10 15:22:14 UTC (rev 934) @@ -1,39 +0,0 @@ -include ../common.mk - -LIBS=$(shell if [ -e /usr/lib/libSystemStubs.a ]; then echo -lSystemStubs; fi) - -### -### Variables for the 'install' phase -### -DATDIR:=$(DATDIR)/darwinbuild - -all: darwintrace.dylib - -VERSION=$(shell uname -r | cut -f1 -d. ) -ifeq ($(VERSION), 8) -CFLAGS += -nostdlib -else -CFLAGS += -nodefaultlibs -endif - -darwintrace.dylib: darwintrace.c - cc -o $(OBJROOT)/$@ \ - $(CFLAGS) \ - -Wall -Werror -pedantic -std=c99 \ - -flat_namespace \ - -fno-common \ - $(CFLAGS) \ - -undefined suppress \ - -dynamiclib \ - $^ $(LIBS) -clean: - rm -f darwintrace.dylib - -install: all - [ -d $(DATDIR) ] || \ - $(INSTALL) -d $(INSTALL_DIR_FLAGS) $(DATDIR) - $(INSTALL) $(INSTALL_DOC_FLAGS) $(OBJROOT)/darwintrace.dylib $(DATDIR) - -uninstall: - rm -f $(DATDIR)/darwintrace.dylib - -rmdir $(DATDIR) Modified: trunk/darwintrace/darwintrace.c =================================================================== --- trunk/darwintrace/darwintrace.c 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwintrace/darwintrace.c 2011-02-10 15:22:14 UTC (rev 934) @@ -40,136 +40,171 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/param.h> -#include <sys/syscall.h> #include <sys/paths.h> #include <errno.h> #define DARWINTRACE_LOG_FULL_PATH 1 #define DARWINTRACE_DEBUG_OUTPUT 0 +#define DARWINTRACE_START_FD 101 +#define DARWINTRACE_STOP_FD 200 +#define DARWINTRACE_BUFFER_SIZE 1024 -#define START_FD 81 -static int __darwintrace_fd = -2; -#define BUFFER_SIZE 1024 - -static char __darwintrace_progname[BUFFER_SIZE]; -static pid_t __darwintrace_pid = -1; - #if DARWINTRACE_DEBUG_OUTPUT #define dprintf(...) fprintf(stderr, __VA_ARGS__) #else #define dprintf(...) #endif +#define DARWINTRACE_INTERPOSE(_replacement,_replacee) \ +__attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \ +__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee }; + +static int darwintrace_fd = -2; +static char darwintrace_progname[DARWINTRACE_BUFFER_SIZE]; +static pid_t darwintrace_pid = -1; + /** * Redirect file access */ -static char *__darwintrace_redirect = NULL; -static char *__darwintrace_buildroot = NULL; -static const char *__redirect_exceptions[] = {"/Developer/Library/Private", - "/Developer/Library/Frameworks", - "/Developer/usr/bin/../../Library/Private", - "/Developer/usr/bin/../../Library/Frameworks", - "/Developer/Library/Xcode", - "/Developer/Platforms/", - "/Developer/usr/bin/xcode", - "/System/Library/Frameworks/Carbon", - "/Volumes/BuildRoot_", - "/usr/bin/xcrun", - "/usr/bin/xcode", - "/usr/local/share/darwin", - "/usr/share/xcode", - "/var/folders/", - "/var/tmp/", - "/.vol/", - "/tmp/", - "/dev/"}; +static char *darwintrace_redirect = NULL; +static char *darwintrace_buildroot = NULL; +static const char *darwintrace_exceptions[] = { + "/Developer/Library/Private", + "/Developer/Library/Frameworks", + "/Developer/usr/bin/../../Library/Private", + "/Developer/usr/bin/../../Library/Frameworks", + "/Developer/Library/Xcode", + "/Developer/Platforms/", + "/Developer/usr/bin/xcode", + "/System/Library/Frameworks/Carbon", + "/Volumes/BuildRoot_", + "/usr/bin/xcrun", + "/usr/bin/xcode", + "/usr/local/share/darwin", + "/usr/share/xcode", + "/var/folders/", + "/var/tmp/", + "/.vol/", + "/tmp/", + "/dev/", +}; +/* store root paths so we can ignore them when logging */ +static char **darwintrace_ignores = NULL; +static size_t *darwintrace_ignore_lens = NULL; + /* check if str starts with one of the exceptions */ -static inline bool __except(const char *str) { - size_t i, __exception_count = sizeof(__redirect_exceptions)/sizeof(*__redirect_exceptions); - for (i = 0; i < __exception_count; i++) { - if (strncmp(__redirect_exceptions[i], str, strlen(__redirect_exceptions[i])) == 0) { +static inline bool darwintrace_except(const char *str) { + size_t c = sizeof(darwintrace_exceptions)/sizeof(*darwintrace_exceptions); + size_t i; + for (i = 0; i < c; i++) { + if (strncmp(darwintrace_exceptions[i], str, strlen(darwintrace_exceptions[i])) == 0) { return true; } } return false; } -/* create __darwintrace_path and write the potentially-redirected path to it */ -#define __redirect_path() \ - char *__darwintrace_path; \ - __darwintrace_path = (char *)path; \ - if (__darwintrace_redirect \ - && path[0] == '/' \ - && !__except(path) \ - && strncmp(__darwintrace_buildroot, path, strlen(__darwintrace_buildroot))!=0 \ - && strncmp(__darwintrace_redirect, path, strlen(__darwintrace_redirect))!=0 ) { \ - asprintf(&__darwintrace_path, "%s%s%s", __darwintrace_redirect, (*path == '/' ? "" : "/"), path); \ - dprintf("darwintrace: redirect %s -> %s\n", path, __darwintrace_path); \ +/* apply redirection heuristic to path */ +static inline char* darwintrace_redirect_path(const char* path) { + if (!darwintrace_redirect) return (char*)path; + + char *redirpath; + redirpath = (char *)path; + if (path[0] == '/' + && !darwintrace_except(path) + && strncmp(darwintrace_buildroot, path, strlen(darwintrace_buildroot))!=0 + && strncmp(darwintrace_redirect, path, strlen(darwintrace_redirect))!=0 ) { + asprintf(&redirpath, "%s%s%s", darwintrace_redirect, (*path == '/' ? "" : "/"), path); + dprintf("darwintrace: redirect %s -> %s\n", path, redirpath); } -#define __free_path() \ - if (__darwintrace_path != path) { \ - free(__darwintrace_path); \ - } + return redirpath; +} -static inline void __darwintrace_setup() { - if (__darwintrace_fd == -2) { - char* path = getenv("DARWINTRACE_LOG"); - if (path != NULL) { - int olderrno = errno; - int fd = open(path, - O_CREAT | O_WRONLY | O_APPEND, - DEFFILEMODE); - int newfd; - for(newfd = START_FD; newfd < START_FD + 21; newfd++) { - if(-1 == write(newfd, "", 0) && errno == EBADF) { - if(-1 != dup2(fd, newfd)) - __darwintrace_fd = newfd; - close(fd); - fcntl(__darwintrace_fd, F_SETFD, 1); /* close-on-exec */ - break; - } - } - errno = olderrno; - } +/* free path if not the same as test */ +static inline void darwintrace_free_path(char* path, const char* test) { + if (path != test) free(path); +} - /* read env vars needed for redirection */ - __darwintrace_redirect = getenv("DARWINTRACE_REDIRECT"); - __darwintrace_buildroot = getenv("DARWIN_BUILDROOT"); - } +static inline void darwintrace_setup() { + if (darwintrace_fd != -2) return; + + char* path = getenv("DARWINTRACE_LOG"); + if (path != NULL) { + int olderrno = errno; + int fd = open(path, + O_CREAT | O_WRONLY | O_APPEND, + DEFFILEMODE); + int newfd; + for(newfd = DARWINTRACE_START_FD; newfd < DARWINTRACE_STOP_FD; newfd++) { + if(-1 == write(newfd, "", 0) && errno == EBADF) { + if(-1 != dup2(fd, newfd)) darwintrace_fd = newfd; + close(fd); + fcntl(darwintrace_fd, F_SETFD, 1); /* close-on-exec */ + break; + } + } + errno = olderrno; + } - if (__darwintrace_pid == -1) { - __darwintrace_pid = getpid(); - char** progname = _NSGetProgname(); - if (progname && *progname) { - if (strlcpy(__darwintrace_progname, *progname, sizeof(__darwintrace_progname)) - >= sizeof(__darwintrace_progname)) { - dprintf("darwintrace: progname too long to copy: %s\n", *progname); - } - } - } -} + /* read env vars needed for redirection */ + darwintrace_redirect = getenv("DARWINTRACE_REDIRECT"); + darwintrace_buildroot = getenv("DARWIN_BUILDROOT"); -/* __darwintrace_setup must have been called already */ -static inline void __darwintrace_logpath(int fd, const char *procname, char *tag, const char *path) { -#pragma unused(procname) - char __darwintrace_buf[BUFFER_SIZE]; - int size; - - size = snprintf(__darwintrace_buf, sizeof(__darwintrace_buf), - "%s[%d]\t%s\t%s\n", - procname ? procname : __darwintrace_progname, __darwintrace_pid, - tag, path ); + darwintrace_pid = getpid(); + char** progname = _NSGetProgname(); + if (progname && *progname) { + if (strlcpy(darwintrace_progname, *progname, sizeof(darwintrace_progname)) >= sizeof(darwintrace_progname)) { + dprintf("darwintrace: progname too long to copy: %s\n", *progname); + } + } - write(fd, __darwintrace_buf, size); - fsync(fd); + /* create ignores list from root env vars */ + if (getenv("DARWINTRACE_IGNORE_ROOTS")) { + darwintrace_ignores = (char**)calloc(4, sizeof(char*)); + darwintrace_ignore_lens = (size_t*)calloc(4, sizeof(size_t)); + if (darwintrace_ignores && darwintrace_ignore_lens) { + darwintrace_ignores[0] = getenv("OBJROOT"); + if (darwintrace_ignores[0]) + darwintrace_ignore_lens[0] = strlen(darwintrace_ignores[0]); + darwintrace_ignores[1] = getenv("SRCROOT"); + if (darwintrace_ignores[1]) + darwintrace_ignore_lens[1] = strlen(darwintrace_ignores[1]); + darwintrace_ignores[2] = getenv("DSTROOT"); + if (darwintrace_ignores[2]) + darwintrace_ignore_lens[2] = strlen(darwintrace_ignores[2]); + darwintrace_ignores[3] = getenv("SYMROOT"); + if (darwintrace_ignores[3]) + darwintrace_ignore_lens[3] = strlen(darwintrace_ignores[3]); + } else { + dprintf("unable to allocate memory for darwintrace_ignores"); + } + } } +/* darwintrace_setup must have been called already */ +static inline void darwintrace_logpath(int fd, const char *procname, char *tag, const char *path) { + if (darwintrace_ignores) { + for (int i=0; i < 4; i++) { + if (darwintrace_ignores[i] + && strncmp(darwintrace_ignores[i], path, darwintrace_ignore_lens[i]) == 0) { + return; + } + } + } + char darwintrace_buf[DARWINTRACE_BUFFER_SIZE]; + int size = snprintf(darwintrace_buf, sizeof(darwintrace_buf), + "%s[%d]\t%s\t%s\n", + procname ? procname : darwintrace_progname, darwintrace_pid, + tag, path); + write(fd, darwintrace_buf, size); +} + /* remap resource fork access to the data fork. * do a partial realpath(3) to fix "foo//bar" to "foo/bar" */ -static inline void __darwintrace_cleanup_path(char *path) { +static inline void darwintrace_cleanup_path(char *path) { size_t pathlen, rsrclen; size_t i, shiftamount; enum { SAWSLASH, NOTHING } state = NOTHING; @@ -179,9 +214,9 @@ rsrclen = strlen(_PATH_RSRCFORKSPEC); if(pathlen > rsrclen && 0 == strncmp(path + pathlen - rsrclen, - _PATH_RSRCFORKSPEC, rsrclen)) { - path[pathlen - rsrclen] = '\0'; - pathlen -= rsrclen; + _PATH_RSRCFORKSPEC, rsrclen)) { + path[pathlen - rsrclen] = '\0'; + pathlen -= rsrclen; } /* for each position in string (including @@ -192,15 +227,15 @@ for(i=0, shiftamount=0; i <= pathlen; i++) { if(state == SAWSLASH) { if(path[i] == '/') { - /* consume it */ - shiftamount++; + /* consume it */ + shiftamount++; } else { - state = NOTHING; - path[i - shiftamount] = path[i]; + state = NOTHING; + path[i - shiftamount] = path[i]; } } else { if(path[i] == '/') { - state = SAWSLASH; + state = SAWSLASH; } path[i - shiftamount] = path[i]; } @@ -209,29 +244,26 @@ dprintf("darwintrace: cleanup resulted in %s\n", path); } -/* Log calls to open(2) into the file specified by DARWINTRACE_LOG. - Only logs if the DARWINTRACE_LOG environment variable is set. +/* Only logs files where the open succeeds. Only logs files opened for read access, without the O_CREAT flag set. The assumption is that any file that can be created isn't necessary to build the project. */ - -int open(const char* path, int flags, ...) { -#define open(x,y,z) syscall(SYS_open, (x), (y), (z)) +int darwintrace_open(const char* path, int flags, ...) { mode_t mode; int result; va_list args; - __redirect_path(); + char* redirpath = darwintrace_redirect_path(path); va_start(args, flags); mode = va_arg(args, int); va_end(args); - result = open(__darwintrace_path, flags, mode); - if (result >= 0 && (flags & (O_CREAT | O_WRONLY /*O_RDWR*/)) == 0 ) { - __darwintrace_setup(); - if (__darwintrace_fd >= 0) { + result = open(redirpath, flags, mode); + if (result >= 0 && (flags & (O_CREAT | O_WRONLY)) == 0 ) { + darwintrace_setup(); + if (darwintrace_fd >= 0) { char realpath[MAXPATHLEN]; #if DARWINTRACE_LOG_FULL_PATH int usegetpath = 1; @@ -239,76 +271,76 @@ int usegetpath = 0; #endif - dprintf("darwintrace: original open path is %s\n", __darwintrace_path); + dprintf("darwintrace: original open path is %s\n", redirpath); /* for volfs paths, we need to do a GETPATH anyway */ - if(!usegetpath && strncmp(__darwintrace_path, "/.vol/", 6) == 0) { + if(!usegetpath && strncmp(redirpath, "/.vol/", 6) == 0) { usegetpath = 1; } if(usegetpath) { - if(0 == fcntl(result, F_GETPATH, realpath)) { - dprintf("darwintrace: resolved %s to %s\n", __darwintrace_path, realpath); + if(0 == fcntl(result, F_GETPATH, realpath)) { + dprintf("darwintrace: resolved %s to %s\n", redirpath, realpath); } else { - /* use original path */ - dprintf("darwintrace: failed to resolve %s\n", __darwintrace_path); - if (strlcpy(realpath, __darwintrace_path, sizeof(realpath)) >= sizeof(realpath)) { - dprintf("darwintrace: in open: original path too long to copy: %s\n", __darwintrace_path); - } - } - } else { - if (strlcpy(realpath, __darwintrace_path, sizeof(realpath)) >= sizeof(realpath)) { - dprintf("darwintrace: in open (without getpath): path too long to copy: %s\n", __darwintrace_path); - } - } + /* use original path */ + dprintf("darwintrace: failed to resolve %s\n", redirpath); + if (strlcpy(realpath, redirpath, sizeof(realpath)) >= sizeof(realpath)) { + dprintf("darwintrace: in open: original path too long to copy: %s\n", redirpath); + } + } + } else { + if (strlcpy(realpath, redirpath, sizeof(realpath)) >= sizeof(realpath)) { + dprintf("darwintrace: in open (without getpath): path too long to copy: %s\n", redirpath); + } + } - __darwintrace_cleanup_path(realpath); - - __darwintrace_logpath(__darwintrace_fd, NULL, "open", realpath); + darwintrace_cleanup_path(realpath); + darwintrace_logpath(darwintrace_fd, NULL, "open", realpath); } } - __free_path(); + + darwintrace_free_path(redirpath, path); return result; } +DARWINTRACE_INTERPOSE(darwintrace_open, open) -/* Log calls to readlink(2) into the file specified by DARWINTRACE_LOG. - Only logs if the DARWINTRACE_LOG environment variable is set. + +/* Only logs files where the readlink succeeds. */ - -ssize_t readlink(const char * path, char * buf, size_t bufsiz) { -#define readlink(x,y,z) syscall(SYS_readlink, (x), (y), (z)) +ssize_t darwintrace_readlink(const char * path, char * buf, size_t bufsiz) { ssize_t result; - __redirect_path(); - result = readlink(__darwintrace_path, buf, bufsiz); + char* redirpath = darwintrace_redirect_path(path); + result = readlink(redirpath, buf, bufsiz); if (result >= 0) { - __darwintrace_setup(); - if (__darwintrace_fd >= 0) { + darwintrace_setup(); + if (darwintrace_fd >= 0) { char realpath[MAXPATHLEN]; - dprintf("darwintrace: original readlink path is %s\n", __darwintrace_path); + dprintf("darwintrace: original readlink path is %s\n", redirpath); - if (strlcpy(realpath, __darwintrace_path, sizeof(realpath)) >= sizeof(realpath)) { - dprintf("darwintrace: in readlink: path too long to copy: %s\n", __darwintrace_path); + if (strlcpy(realpath, redirpath, sizeof(realpath)) >= sizeof(realpath)) { + dprintf("darwintrace: in readlink: path too long to copy: %s\n", redirpath); } - __darwintrace_cleanup_path(realpath); - - __darwintrace_logpath(__darwintrace_fd, NULL, "readlink", realpath); + darwintrace_cleanup_path(realpath); + darwintrace_logpath(darwintrace_fd, NULL, "readlink", realpath); } } - __free_path(); + + darwintrace_free_path(redirpath, path); return result; } +DARWINTRACE_INTERPOSE(darwintrace_readlink, readlink) -int execve(const char* path, char* const argv[], char* const envp[]) { -#define execve(x,y,z) syscall(SYS_execve, (x), (y), (z)) + +int darwintrace_execve(const char* path, char* const argv[], char* const envp[]) { int result; - __redirect_path(); - __darwintrace_setup(); - if (__darwintrace_fd >= 0) { + char* redirpath = darwintrace_redirect_path(path); + darwintrace_setup(); + if (darwintrace_fd >= 0) { struct stat sb; char realpath[MAXPATHLEN]; int printorig = 0; @@ -320,15 +352,15 @@ int usegetpath = 0; #endif - dprintf("darwintrace: original execve path is %s\n", __darwintrace_path); + dprintf("darwintrace: original execve path is %s\n", redirpath); /* for symlinks, we wan't to capture * both the original path and the modified one, * since for /usr/bin/gcc -> gcc-4.0, * both "gcc_select" and "gcc" are contributors */ - if (lstat(__darwintrace_path, &sb) == 0) { - if(__darwintrace_path[0] != '/') { + if (lstat(redirpath, &sb) == 0) { + if(redirpath[0] != '/') { /* for relative paths, only print full path */ printreal = 1; printorig = 0; @@ -343,15 +375,15 @@ } if(printorig) { - if (strlcpy(realpath, __darwintrace_path, sizeof(realpath)) >= sizeof(realpath)) { - dprintf("darwintrace: in execve: path too long to copy: %s\n", __darwintrace_path); + if (strlcpy(realpath, redirpath, sizeof(realpath)) >= sizeof(realpath)) { + dprintf("darwintrace: in execve: path too long to copy: %s\n", redirpath); } - __darwintrace_cleanup_path(realpath); - __darwintrace_logpath(__darwintrace_fd, NULL, "execve", realpath); + darwintrace_cleanup_path(realpath); + darwintrace_logpath(darwintrace_fd, NULL, "execve", realpath); } - fd = open(__darwintrace_path, O_RDONLY, 0); + fd = open(redirpath, O_RDONLY, 0); if (fd != -1) { char buffer[MAXPATHLEN]; @@ -359,86 +391,89 @@ /* once we have an open fd, if a full path was requested, do it */ if(printreal) { - - if(usegetpath) { - if(0 == fcntl(fd, F_GETPATH, realpath)) { - dprintf("darwintrace: resolved execve path %s to %s\n", __darwintrace_path, realpath); - } else { - dprintf("darwintrace: failed to resolve %s\n", __darwintrace_path); - if (strlcpy(realpath, __darwintrace_path, sizeof(realpath)) >= sizeof(realpath)) { - dprintf("darwintrace: in execve: original path too long to copy: %s\n", __darwintrace_path); - } - } - } else { - if (strlcpy(realpath, __darwintrace_path, sizeof(realpath)) >= sizeof(realpath)) { - dprintf("darwintrace: in execve (without getpath): path too long to copy: %s\n", __darwintrace_path); - } - } - __darwintrace_cleanup_path(realpath); - __darwintrace_logpath(__darwintrace_fd, NULL, "execve", realpath); + if(usegetpath) { + if(0 == fcntl(fd, F_GETPATH, realpath)) { + dprintf("darwintrace: resolved execve path %s to %s\n", redirpath, realpath); + } else { + dprintf("darwintrace: failed to resolve %s\n", redirpath); + if (strlcpy(realpath, redirpath, sizeof(realpath)) >= sizeof(realpath)) { + dprintf("darwintrace: in execve: original path too long to copy: %s\n", redirpath); + } + } + } else { + if (strlcpy(realpath, redirpath, sizeof(realpath)) >= sizeof(realpath)) { + dprintf("darwintrace: in execve (without getpath): path too long to copy: %s\n", redirpath); + } + } + + darwintrace_cleanup_path(realpath); + darwintrace_logpath(darwintrace_fd, NULL, "execve", realpath); } bzero(buffer, sizeof(buffer)); bytes_read = read(fd, buffer, MAXPATHLEN); if (bytes_read > 2 && - buffer[0] == '#' && buffer[1] == '!') { - char* interp = &buffer[2]; - int i; - /* skip past leading whitespace */ - for (i = 2; i < bytes_read; ++i) { - if (buffer[i] != ' ' && buffer[i] != '\t') { - interp = &buffer[i]; - break; - } - } - /* found interpreter (or ran out of data) - skip until next whitespace, then terminate the string */ - for (; i < bytes_read; ++i) { - if (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n') { - buffer[i] = 0; - break; - } - } - /* we have liftoff */ - if (interp && interp[0] != '\0') { - const char* procname = NULL; + buffer[0] == '#' && buffer[1] == '!') { + char* interp = &buffer[2]; + int i; + /* skip past leading whitespace */ + for (i = 2; i < bytes_read; ++i) { + if (buffer[i] != ' ' && buffer[i] != '\t') { + interp = &buffer[i]; + break; + } + } + /* found interpreter (or ran out of data) + skip until next whitespace, then terminate the string */ + for (; i < bytes_read; ++i) { + if (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n') { + buffer[i] = 0; + break; + } + } + /* we have liftoff */ + if (interp && interp[0] != '\0') { + const char* procname = NULL; - /* look for slash to get the basename */ - procname = strrchr(argv[0], '/'); - if (procname == NULL) { - /* no slash found, so assume whole string is basename */ - procname = argv[0]; - } else { - /* advance pointer to just after slash */ - procname++; - } + /* look for slash to get the basename */ + procname = strrchr(argv[0], '/'); + if (procname == NULL) { + /* no slash found, so assume whole string is basename */ + procname = argv[0]; + } else { + /* advance pointer to just after slash */ + procname++; + } - __darwintrace_cleanup_path(interp); - - __darwintrace_logpath(__darwintrace_fd, procname, "execve", interp); - } + darwintrace_cleanup_path(interp); + darwintrace_logpath(darwintrace_fd, procname, "execve", interp); + } } + close(fd); } } } - result = execve(__darwintrace_path, argv, envp); - __free_path(); + + result = execve(redirpath, argv, envp); + darwintrace_free_path(redirpath, path); return result; } +DARWINTRACE_INTERPOSE(darwintrace_execve, execve) -/* if darwintrace has been initialized, trap + +/* + if darwintrace has been initialized, trap attempts to close our file descriptor */ -int close(int fd) { -#define close(x) syscall(SYS_close, (x)) - - if(__darwintrace_fd != -2 && fd == __darwintrace_fd) { +int darwintrace_close(int fd) { + if(darwintrace_fd != -2 && fd == darwintrace_fd) { errno = EBADF; return -1; } return close(fd); } +DARWINTRACE_INTERPOSE(darwintrace_close, close) Modified: trunk/darwinup/Depot.cpp =================================================================== --- trunk/darwinup/Depot.cpp 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/Depot.cpp 2011-02-10 15:22:14 UTC (rev 934) @@ -695,7 +695,9 @@ if (INFO_TEST(file->info(), FILE_INFO_INSTALL_DATA)) { ++context->files_modified; - res = file->install(context->depot->m_archives_path, context->depot->m_prefix); + res = file->install(context->depot->m_archives_path, + context->depot->m_prefix, + context->reverse_files); } else { res = file->install_info(context->depot->m_prefix); } @@ -947,11 +949,13 @@ S_ISDIR(preceding->mode())) { // use rename instead of mkdir so children are restored res = preceding->dirrename(context->depot->m_archives_path, - context->depot->m_prefix); + context->depot->m_prefix, + context->reverse_files); } else { res = preceding->install(context->depot->m_archives_path, - context->depot->m_prefix); + context->depot->m_prefix, + context->reverse_files); } } } else if (INFO_TEST(flags, FILE_INFO_MODE_DIFFERS) || Modified: trunk/darwinup/Digest.cpp =================================================================== --- trunk/darwinup/Digest.cpp 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/Digest.cpp 2011-02-10 15:22:14 UTC (rev 934) @@ -40,15 +40,6 @@ #include <string.h> #include <unistd.h> -// For SHA1DigestMachO -#include <mach/mach_init.h> -#include <mach/vm_map.h> -extern "C" { -// <rdar://problem/4319807> redo_prebinding.h should use extern "C" -//#include <mach-o/redo_prebinding.h> // from cctools_ofiles -#include "redo_prebinding.h" -} - uint8_t* Digest::data() { return m_data; } uint32_t Digest::size() { return m_size; } @@ -123,45 +114,6 @@ CC_SHA1((const void*)data, (CC_LONG)size, md); } -SHA1DigestMachO::SHA1DigestMachO(const char* filename) { - char* error = NULL; - - // Check for Mach-O - int type = object_file_type(filename, NULL, &error); - if (type == OFT_EXECUTABLE || - type == OFT_DYLIB || - type == OFT_BUNDLE) { - // XXX - type == OFT_ARCHIVE? - void* block = NULL; - unsigned long blocklen = 0; - int ret = unprebind(filename, - NULL, - NULL, - &error, - 1, - NULL, - 0, - &block, - &blocklen); - if (ret == REDO_PREBINDING_SUCCESS && block != NULL) { - digest(m_data, (uint8_t*)block, blocklen); - } else { - //fprintf(stderr, "%s:%d: unexpected unprebind result: %s: %s (%d)\n", __FILE__, __LINE__, filename, error, ret); - int fd = open(filename, O_RDONLY); - digest(m_data, fd); - close(fd); - } - if (block != NULL) { - kern_return_t ret = vm_deallocate(mach_task_self(), (vm_address_t)block, (vm_size_t)blocklen); - assert(ret == 0); - } - } else { - int fd = open(filename, O_RDONLY); - digest(m_data, fd); - close(fd); - } -} - SHA1DigestSymlink::SHA1DigestSymlink(const char* filename) { char link[PATH_MAX]; int res = readlink(filename, link, PATH_MAX); Modified: trunk/darwinup/Digest.h =================================================================== --- trunk/darwinup/Digest.h 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/Digest.h 2011-02-10 15:22:14 UTC (rev 934) @@ -111,18 +111,6 @@ }; //// -// SHA1DigestMachO -// Digests of canonicalized Mach-O file formats. -//// -struct SHA1DigestMachO : SHA1Digest { - // Computes the SHA-1 digest of the data in the file. - // If the file is a Mach-O executable or dynamic library, - // the SHA-1 digest is computed from its canonical - // representation. - SHA1DigestMachO(const char* filename); -}; - -//// // SHA1DigestSymlink // Digests of the target of a symlink. //// Modified: trunk/darwinup/File.cpp =================================================================== --- trunk/darwinup/File.cpp 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/File.cpp 2011-02-10 15:22:14 UTC (rev 934) @@ -147,7 +147,7 @@ free(dig); } -int File::install(const char* prefix, const char* dest) { +int File::install(const char* prefix, const char* dest, bool uninstall) { extern uint32_t force; int res = 0; Archive* archive = this->archive(); @@ -160,6 +160,10 @@ char* dstpath; join_path(&dstpath, dest, path); + // object changes are expected for some uninstall operations, + // otherwise require force flag + bool allow_change = (uninstall || force); + if (dirpath) { ssize_t len = snprintf(srcpath, sizeof(srcpath), "%s/%s", dirpath, path); if ((size_t)len > sizeof(srcpath)) { @@ -176,7 +180,7 @@ if (is_directory(dirpath) == 0) { IF_DEBUG("[install] File::install on-demand archive expansion\n"); res = archive->expand_directory(prefix); - if (res == 0) res = this->install(prefix, dest); + if (res == 0) res = this->install(prefix, dest, uninstall); } else { // archive was already expanded, so // the file is truly missing (worry). @@ -184,13 +188,13 @@ fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, srcpath, strerror(errno), errno); } - } else if (force && errno == ENOTDIR) { + } else if (allow_change && errno == ENOTDIR) { // a) some part of destination path does not exist // b) from is a directory, but to is not IF_DEBUG("[install] File::install ENOTDIR\n"); fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno); - } else if (force && errno == EISDIR) { + } else if (allow_change && errno == EISDIR) { // to is a directory, but from is not IF_DEBUG("[install] replacing directory with a file\n"); IF_DEBUG("[install] removefile(%s)\n", dstpath); @@ -206,7 +210,7 @@ if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno); - } else if (force && errno == ENOTEMPTY) { + } else if (allow_change && errno == ENOTEMPTY) { // to is a directory and is not empty IF_DEBUG("[install] File::install ENOTEMPTY\n"); fprintf(stderr, "%s:%d: %s: %s (%d)\n", @@ -228,7 +232,7 @@ return res; } -int File::dirrename(const char* prefix, const char* dest) { +int File::dirrename(const char* prefix, const char* dest, bool uninstall) { // only used for directories assert(0); } @@ -266,14 +270,14 @@ : File(serial, archive, info, path, mode, uid, gid, size, digest) {} Regular::Regular(Archive* archive, FTSENT* ent) : File(archive, ent) { - m_digest = new SHA1DigestMachO(ent->fts_accpath); + m_digest = new SHA1Digest(ent->fts_accpath); } Regular::Regular(uint64_t serial, Archive* archive, uint32_t info, const char* path, mode_t mode, uid_t uid, gid_t gid, off_t size, Digest* digest) : File(serial, archive, info, path, mode, uid, gid, size, digest) { if (digest == NULL || serial == 0) { - m_digest = new SHA1DigestMachO(path); + m_digest = new SHA1Digest(path); } } @@ -345,15 +349,15 @@ Digest* digest) : File(serial, archive, info, path, mode, uid, gid, size, digest) {}; -int Directory::install(const char* prefix, const char* dest) { - return this->_install(prefix, dest, false); +int Directory::install(const char* prefix, const char* dest, bool uninstall) { + return this->_install(prefix, dest, uninstall, false); } -int Directory::dirrename(const char* prefix, const char* dest) { - return this->_install(prefix, dest, true); +int Directory::dirrename(const char* prefix, const char* dest, bool uninstall) { + return this->_install(prefix, dest, uninstall, true); } -int Directory::_install(const char* prefix, const char* dest, bool use_rename) { +int Directory::_install(const char* prefix, const char* dest, bool uninstall, bool use_rename) { // We create a new directory instead of renaming the // existing one, since that would move the entire // sub-tree, and lead to a lot of ENOENT errors. @@ -362,6 +366,10 @@ char* dstpath; join_path(&dstpath, dest, this->path()); + // object changes are expected for some uninstall operations, + // otherwise require force flag + bool allow_change = (uninstall || force); + mode_t mode = this->mode() & ALLPERMS; uid_t uid = this->uid(); gid_t gid = this->gid(); @@ -403,7 +411,7 @@ if (res == -1) fprintf(stderr, "%s:%d: %s: %s (%d)\n", __FILE__, __LINE__, dstpath, strerror(errno), errno); - } else if (force) { + } else if (allow_change) { // this could be bad, so require the force option IF_DEBUG("[install] original node is a file, we need to replace " \ "with a directory \n"); @@ -415,7 +423,7 @@ __FILE__, __LINE__, dstpath, strerror(errno), errno); } - } else if (force && res == -1 && errno == ENOTDIR) { + } else if (allow_change && res == -1 && errno == ENOTDIR) { // some part of destination path is not a directory IF_DEBUG("[install] Directory::install ENOTDIR \n"); } else if (res == -1) { Modified: trunk/darwinup/File.h =================================================================== --- trunk/darwinup/File.h 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/File.h 2011-02-10 15:22:14 UTC (rev 934) @@ -172,9 +172,9 @@ // Installs the file from the archive into the prefix // i.e., for regular files: // rename(prefix + this->archive()->uuid() + this->path(), dest + this->path()); - virtual int install(const char* prefix, const char* dest); + virtual int install(const char* prefix, const char* dest, bool uninstall); // only used for directories - virtual int dirrename(const char* prefix, const char* dest); + virtual int dirrename(const char* prefix, const char* dest, bool uninstall); // Sets the mode, uid, and gid of the file in the dest path // XXX: rename as repair()? @@ -243,9 +243,9 @@ struct Directory : File { Directory(Archive* archive, FTSENT* ent); Directory(uint64_t serial, Archive* archive, uint32_t info, const char* path, mode_t mode, uid_t uid, gid_t gid, off_t size, Digest* digest); - virtual int install(const char* prefix, const char* dest); - virtual int dirrename(const char* prefix, const char* dest); - int _install(const char* prefix, const char* dest, bool use_rename); + virtual int install(const char* prefix, const char* dest, bool uninstall); + virtual int dirrename(const char* prefix, const char* dest, bool uninstall); + int _install(const char* prefix, const char* dest, bool uninstall, bool use_rename); virtual int remove(); }; Modified: trunk/darwinup/main.cpp =================================================================== --- trunk/darwinup/main.cpp 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/main.cpp 2011-02-10 15:22:14 UTC (rev 934) @@ -245,10 +245,6 @@ res = depot->process_archive(argv[0], argv[i]); } else if (strcmp(argv[0], "uninstall") == 0) { if (i==1 && depot->initialize(true)) exit(15); - // uninstall is always in force mode so it can - // uninstall archives that were installed under - // force mode - force = 1; res = depot->process_archive(argv[0], argv[i]); } else if (strcmp(argv[0], "verify") == 0) { if (i==1 && depot->initialize(true)) exit(16); Deleted: trunk/darwinup/redo_prebinding.h =================================================================== --- trunk/darwinup/redo_prebinding.h 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/darwinup/redo_prebinding.h 2011-02-10 15:22:14 UTC (rev 934) @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2005-2010 Apple Computer, Inc. All rights reserved. - * - * @APPLE_BSD_LICENSE_HEADER_START@ - * - * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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. - * - * @APPLE_BSD_LICENSE_HEADER_END@ - */ -#define REDO_PREBINDING_VERSION 2 -#include <mach/machine.h> -/* - * For all APIs in this file the parameters program_name and error_message - * are used the same. For unrecoverable resource errors like being unable to - * allocate memory each API prints a message to stderr precede with program_name - * then calls exit(2) with the value EXIT_FAILURE. If an API is unsuccessful - * and if error_message pass to it is not NULL it is set to a malloc(3)'ed - * buffer with a NULL terminated string with the error message. For all APIs - * when they return they release all resources (memory, open file descriptors, - * etc). - * - * The file_name parameter for these APIs may be of the form "foo(bar)" which is - * NOT interpreted as an archive name and a member name in that archive. As - * these API deal with prebinding and prebound binaries ready for execution - * can't be in archives. - * - * If the executable_path parameter for these APIs is not NULL it is used for - * any dependent library has a path that starts with "@executable_path". Then - * "@executable_path" is replaced with executable_path. - * - * If the root_dir parameter is not NULL it is prepended to all the rooted - * dependent library paths. - */ - -/* - * dependent_libs() takes a file_name of a binary and returns a malloc(3)'ed - * array of pointers (NULL terminated) to names (also malloc(3)'ed and '\0' - * terminated names) of all the dependent libraries for that binary (not - * recursive) for all of the architectures of that binary. If successful - * dependent_libs() returns a non NULL value (at minimum a pointer to one NULL - * pointer). If unsuccessful dependent_libs() returns NULL. - */ -extern -char ** -dependent_libs( -const char *file_name, -const char *program_name, -char **error_message); - -/* - * install_name() takes a file_name of a binary and returns a malloc(3)'ed - * pointer to a NULL terminated string containing the install_name value for - * the binary. If unsuccessful install_name() returns NULL. In particular, - * NULL is returned if the binary is not a dylib and there is no error_message - * set. If the all of the arch's are dylibs but all the install names don't - * match NULL is returned and a error_message is set. If some but not all of - * the archs are dylibs NULL is returned and a error_message is set. - */ -extern -char * -install_name( -const char *file_name, -const char *program_name, -char **error_message); - -/* return values for redo_prebinding() */ -enum redo_prebinding_retval { - REDO_PREBINDING_SUCCESS, - REDO_PREBINDING_FAILURE, - /* the following can only be returned if the parameter only_if_needed set */ - REDO_PREBINDING_NOT_NEEDED, - REDO_PREBINDING_NOT_PREBOUND, - REDO_PREBINDING_NEEDS_REBUILDING -}; - -/* - * redo_prebinding() takes a file_name of a binary and redoes the prebinding on - * it. If output_file is not NULL the update file is written to output_file, - * if not it is written to file_name. If redo_prebinding() is successful it - * returns REDO_PREBINDING_SUCCESS otherwise it returns REDO_PREBINDING_FAILURE. - * If the parameter allow_missing_architectures is zero and not all - * architectures can be updated it is not successful and nothing is done and - * this returns REDO_PREBINDING_FAILURE. If the parameter - * allow_missing_architectures is non-zero then only problems with missing - * architectures for the architecure of the cputype specified by - * allow_missing_architectures will cause this call to fail. Other - * architectures that could not be prebound due to missing architectures in - * depending libraries will not have their prebinding updated but will not - * cause this call to fail. - * If the slide_to_address parameter is non-zero and the binary is a - * dynamic library it is relocated to have that has its prefered address. If - * only_if_needed is non-zero the prebinding is checked first and only done if - * needed. The checking includes checking the prefered address against the - * slide_to_address value if it is non-zero. If only_if_needed is non-zero - * and the prebinding does not have to be redone REDO_PREBINDING_NOT_NEEDED is - * returned, if the binary is not prebound REDO_PREBINDING_NOT_PREBOUND is - * returned and if the new load commands do not fit in the binary and it needs - * to be rebuilt REDO_PREBINDING_NEEDS_REBUILDING is returned. - * If zero_out_prebind_checksum is non-zero then the cksum field of the - * LC_PREBIND_CKSUM load command (if any) is set to zero on output (this should - * always be set by B&I tools and never set by the update_prebinding(1) - * command). - * If throttle is non-NULL it points to a value of the maximum bytes per second - * to use for writting the output. If the value is ULONG_MAX then the actual - * bytes per second is returned indirectly through *throttle. - */ -extern -enum redo_prebinding_retval -redo_prebinding( -const char *file_name, -const char *executable_path, -const char *root_dir, -const char *output_file, -const char *program_name, -char **error_message, -unsigned long slide_to_address, -int only_if_needed, -int zero_out_prebind_checksum, -cpu_type_t allow_missing_architectures, -unsigned long *throttle); - - -/* return values for needs_redo_prebinding() */ -enum needs_redo_prebinding_retval { - PREBINDING_UPTODATE, /* a binary who's prebinding is up todate */ - PREBINDING_OUTOFDATE, /* a binary who's prebinding is out of date */ - NOT_PREBOUND, /* a binary, but not built prebound */ - NOT_PREBINDABLE, /* not a binary or statically linked, - prebinding does not apply */ - PREBINDING_UNKNOWN /* a binary who's prebinding can't be determined - because it is malformed, a library it depends - on is missing, etc. */ -}; - -/* - * needs_redo_prebinding() takes a file_name and determines if it is a binary - * and if its prebinding is uptodate. It returns one of the return values - * above depending on the state of the binary and libraries. If the parameter - * allow_missing_architectures is zero then the value returned is based on the - * first architecture for fat files. If the parameter - * allow_missing_architectures is non-zero then the value returned is based on - * the cputype specified by allow_missing_architectures. If that architecture - * is not present then PREBINDING_UPTODATE is returned. If the parameter - * expected_address is not zero and the binary is a dynamic library then the - * library is checked to see if it is at the expected_address if not the - * prebinding is assumed to be out of date and PREBINDING_OUTOFDATE is returned. - */ -extern -enum needs_redo_prebinding_retval -needs_redo_prebinding( -const char *file_name, -const char *executable_path, -const char *root_dir, -const char *program_name, -char **error_message, -unsigned long expected_address, -cpu_type_t allow_missing_architectures); - - -/* - * unprebind() takes a file_name of a binary and resets or removes prebinding - * information from it. If inbuf is non-NULL, the memory pointed to by inbuf is - * used as the input file contents. Otherwise, the contents are loaded from - * the file at path file_name. Even if inbuf is non-NULL, a file_name - * parameter should be specified for error reporting. Similarly, if outbuf is - * non-NULL, upon return, outbuf will point to a buffer containing the - * unprebound binary and outlen will point to the length of the output buffer. - * This buffer is vm_allocate'd and therefore should be vm_deallocate'd when it - * is no longer needed. If outbuf is NULL, and output_file is not NULL the - * update file is written to output_file, if outbuf is NULL and output_file is - * NULL, it is written to file_name. - * If unprebind() is successful it returns REDO_PREBINDING_SUCCESS otherwise it - * returns REDO_PREBINDING_FAILURE If the binary is already unprebound (i.e. it - * has the MH_PREBINDABLE flag set) then REDO_PREBINDING_NOT_NEEDED is returned. - * If the binary is not prebound and not prebindable, - * REDO_PREBINDING_NOT_PREBOUND is returned. If zero_checksum is non-zero then - * the cksum field the LC_PREBIND_CKSUM load command (if any) is set to zero on - * output, otherwise it is left alone. - * Unprebinding slides dynamic libraries to address zero, resets prebound - * symbols to address zero and type undefined, resets symbol pointers, removes - * LC_PREBOUND_DYLIB commands, resets library timestamps, resets two-level hints - * and updates relocation entries if necessary. Unprebound binaries have - * the MH_PREBINDABLE flag set, but not MH_PREBOUND. It will also set the the - * MH_ALLMODSBOUND flag if all two-level libraries were used and all modules - * were found to be bound in the LC_PREBOUND_DYLIB commands. - * As unprebinding is intended to produce a canonical Mach-O - * binary, bundles and non-prebound executables and dylibs are acceptable - * as input. For these files, the unprebind operation will zero library - * time stamps and version numbers and zero entries in the two-level hints - * table. These files will not gain the MH_PREBINDABLE flag. - * All resulting binaries successfully processed by unprebind() will have - * the MH_CANONICAL flag. - */ -extern -enum redo_prebinding_retval -unprebind( -const char *file_name, -const char *output_file, -const char *program_name, -char **error_message, -int zero_checksum, -void *inbuf, -unsigned long inlen, -void **outbuf, -unsigned long *outlen); - -enum object_file_type_retval { - OFT_OTHER, - OFT_EXECUTABLE, - OFT_DYLIB, - OFT_BUNDLE, - OFT_ARCHIVE, - OFT_INCONSISTENT, - OFT_FILE_ERROR -}; - -/* - * object_file_type() takes a file_name and determines what type of object - * file it is. If it is a fat file and the architectures are not of the same - * type then OFT_INCONSISTENT is returned. If the file_name can't be opened, - * read or malformed then OFT_FILE_ERROR is returned. - */ -extern -enum object_file_type_retval -object_file_type( -const char *file_name, -const char *program_name, -char **error_message); - -struct prebind_cksum_arch { - cpu_type_t cputype; /* cpu specifier */ - cpu_subtype_t cpusubtype; /* machine specifier */ - unsigned long has_cksum; /* 1 if the arch as an LC_PREBIND_CKSUM */ - unsigned long cksum; /* value of the cksum in LC_PREBIND_CKSUM */ -}; - -/* - * get_prebind_cksums() takes a file_name that is a Mach-O file or fat file - * containing Mach-O files and returns a malloc(3)'ed array of - * prebind_cksum_arch structs indirectly through the cksums parameter. The - * number of prebind_cksum_arch structs is returned indirectly through the - * ncksums parameter. If successful it returns zero else it returns non-zero. - */ -extern -int -get_prebind_cksums( -const char *file_name, -struct prebind_cksum_arch **cksums, -unsigned long *ncksums, -const char *program_name, -char **error_message); Deleted: trunk/testing/darwintrace/close-test =================================================================== --- branches/PR-8817822/testing/darwintrace/close-test 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/testing/darwintrace/close-test 2011-02-10 15:22:14 UTC (rev 934) @@ -1,16 +0,0 @@ -#!/usr/bin/env python -import os -for i in range(101,200): - print " ... trying to close(%s)" % i - try: - os.close(i) - print " ... closed %s" % i - exit(1) - except Exception, e: - # test for EBADF - if e.errno == 9: - print " ... got EBADF as expected" - else: - print " ... got wrong error back: %s" % e - exit(2) -exit(0) Copied: trunk/testing/darwintrace/close-test (from rev 933, branches/PR-8817822/testing/darwintrace/close-test) =================================================================== --- trunk/testing/darwintrace/close-test (rev 0) +++ trunk/testing/darwintrace/close-test 2011-02-10 15:22:14 UTC (rev 934) @@ -0,0 +1,16 @@ +#!/usr/bin/env python +import os +for i in range(101,200): + print " ... trying to close(%s)" % i + try: + os.close(i) + print " ... closed %s" % i + exit(1) + except Exception, e: + # test for EBADF + if e.errno == 9: + print " ... got EBADF as expected" + else: + print " ... got wrong error back: %s" % e + exit(2) +exit(0) Deleted: trunk/testing/darwintrace/exec =================================================================== --- branches/PR-8817822/testing/darwintrace/exec 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/testing/darwintrace/exec 2011-02-10 15:22:14 UTC (rev 934) @@ -1,3 +0,0 @@ -#!/usr/bin/env python -import subprocess, sys -subprocess.call(sys.argv[1:]) Copied: trunk/testing/darwintrace/exec (from rev 933, branches/PR-8817822/testing/darwintrace/exec) =================================================================== --- trunk/testing/darwintrace/exec (rev 0) +++ trunk/testing/darwintrace/exec 2011-02-10 15:22:14 UTC (rev 934) @@ -0,0 +1,3 @@ +#!/usr/bin/env python +import subprocess, sys +subprocess.call(sys.argv[1:]) Deleted: trunk/testing/darwintrace/realpath =================================================================== --- branches/PR-8817822/testing/darwintrace/realpath 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/testing/darwintrace/realpath 2011-02-10 15:22:14 UTC (rev 934) @@ -1,4 +0,0 @@ -#!/usr/bin/env python -import os -import sys -print os.path.realpath(sys.argv[1]) Copied: trunk/testing/darwintrace/realpath (from rev 933, branches/PR-8817822/testing/darwintrace/realpath) =================================================================== --- trunk/testing/darwintrace/realpath (rev 0) +++ trunk/testing/darwintrace/realpath 2011-02-10 15:22:14 UTC (rev 934) @@ -0,0 +1,4 @@ +#!/usr/bin/env python +import os +import sys +print os.path.realpath(sys.argv[1]) Deleted: trunk/testing/darwintrace/redirection-test =================================================================== --- branches/PR-8817822/testing/darwintrace/redirection-test 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/testing/darwintrace/redirection-test 2011-02-10 15:22:14 UTC (rev 934) @@ -1,5 +0,0 @@ -#!/bin/bash -PREFIX=$1 -ROOT=$PREFIX/root - -/bin/cat $PREFIX/datafile Copied: trunk/testing/darwintrace/redirection-test (from rev 933, branches/PR-8817822/testing/darwintrace/redirection-test) =================================================================== --- trunk/testing/darwintrace/redirection-test (rev 0) +++ trunk/testing/darwintrace/redirection-test 2011-02-10 15:22:14 UTC (rev 934) @@ -0,0 +1,5 @@ +#!/bin/bash +PREFIX=$1 +ROOT=$PREFIX/root + +/bin/cat $PREFIX/datafile Deleted: trunk/testing/darwintrace/run-tests.sh =================================================================== --- branches/PR-8817822/testing/darwintrace/run-tests.sh 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/testing/darwintrace/run-tests.sh 2011-02-10 15:22:14 UTC (rev 934) @@ -1,130 +0,0 @@ -#!/bin/bash -# -# Run test suite for darwintrace -# -set -e -set -x -pushd $(dirname $0) >> /dev/null - -PREFIX=/tmp/testing/darwintrace -LOGS=$PREFIX/logs -ROOT=$PREFIX/root -BIN=$PREFIX/bin - -DARWINTRACE="/usr/local/share/darwinbuild/darwintrace.dylib" -export DYLD_INSERT_LIBRARIES=$DARWINTRACE -export DARWINTRACE_LOG="${LOGS}/trace.log" - -echo "INFO: Cleaning up testing area ..." -rm -rf $PREFIX -mkdir -p $PREFIX -mkdir -p $ROOT -mkdir -p $LOGS -mkdir -p $BIN - -REALPATH=$BIN/realpath -cp realpath $REALPATH - -EXEC=$BIN/exec -cp exec $EXEC - -CLOSETEST=$BIN/close-test -cp close-test $CLOSETEST - -REDIRECTIONTEST=$BIN/redirection-test -cp redirection-test $REDIRECTIONTEST - - -echo "========== TEST: execve() Trace ==========" -for FILE in cp echo chmod date df expr hostname ls ps pwd test; -do - # some of these commands will error out when run without arguments, - # so just ignore that since all we want is the execve() call to happen - set +e - $EXEC /bin/$FILE 2>&1 >> /dev/null - set -e - LOGPAT="Python\[[0-9]+\][[:space:]]execve[[:space:]]/bin/${FILE}" - C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) - test $C -eq 1 -done -set -e - - -echo "========== TEST: close() Safety ==========" -$CLOSETEST - - -echo "========== TEST: open() Trace ==========" -for FILE in /System/Library/LaunchDaemons/*.plist; -do - cat $FILE >> /dev/null; - RP=$($REALPATH $FILE); - LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" - C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) - test $C -eq 1 -done - - -echo "========== TEST: readlink() Trace ==========" -for FILE in $(find /System/Library/Frameworks/*Foundation.framework -type l | xargs); -do - readlink $FILE - LOGPAT="readlink\[[0-9]+\][[:space:]]readlink[[:space:]]${FILE}" - C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) - test $C -eq 1 -done - - -echo "========== TEST: ROOT Ignores ==========" -export DARWINTRACE_IGNORE_ROOTS="" -export DSTROOT="/System/Library/LaunchAgents" -for FILE in /var/log/*.log; -do - cat $FILE >> /dev/null; - RP=$($REALPATH $FILE); - LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" - C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) - test $C -eq 1 -done - -for FILE in /System/Library/LaunchAgents/com.apple.*; -do - cat $FILE >> /dev/null; - RP=$($REALPATH $FILE); - LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" - set +e - C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) - set -e - test $C -eq 0 -done -unset DARWINTRACE_IGNORE_ROOTS -unset DSTROOT - - -echo "========== TEST: Redirection ==========" -mkdir -p $ROOT/$PREFIX -mkdir -p $ROOT/usr/lib -cp /usr/lib/libSystem.B.dylib $ROOT/usr/lib/libSystem.B.dylib -mkdir -p $ROOT/bin -cp /bin/cat $ROOT/bin/cat -echo "Outside of root" > $PREFIX/datafile -echo "Inside of root" > $ROOT/$PREFIX/datafile -export DARWINTRACE_REDIRECT="${ROOT}" -export DARWIN_BUILDROOT="${ROOT}" -$REDIRECTIONTEST $PREFIX -unset DARWINTRACE_REDIRECT -unset DARWIN_BUILDROOT -# test that execve(/bin/cat) was redirected -RP=$($REALPATH ${ROOT}/bin/cat) -LOGPAT="bash\[[0-9]+\][[:space:]]execve[[:space:]]${RP}" -C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) -test $C -eq 1 -# test that open(/tmp/.../datafile) does not get redirected -# since /tmp/ is one of the redirection exceptions -RP=$($REALPATH ${PREFIX}/datafile) -LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" -C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) -test $C -eq 1 - -popd >> /dev/null -echo "INFO: Done testing!" Copied: trunk/testing/darwintrace/run-tests.sh (from rev 933, branches/PR-8817822/testing/darwintrace/run-tests.sh) =================================================================== --- trunk/testing/darwintrace/run-tests.sh (rev 0) +++ trunk/testing/darwintrace/run-tests.sh 2011-02-10 15:22:14 UTC (rev 934) @@ -0,0 +1,130 @@ +#!/bin/bash +# +# Run test suite for darwintrace +# +set -e +set -x +pushd $(dirname $0) >> /dev/null + +PREFIX=/tmp/testing/darwintrace +LOGS=$PREFIX/logs +ROOT=$PREFIX/root +BIN=$PREFIX/bin + +DARWINTRACE="/usr/local/share/darwinbuild/darwintrace.dylib" +export DYLD_INSERT_LIBRARIES=$DARWINTRACE +export DARWINTRACE_LOG="${LOGS}/trace.log" + +echo "INFO: Cleaning up testing area ..." +rm -rf $PREFIX +mkdir -p $PREFIX +mkdir -p $ROOT +mkdir -p $LOGS +mkdir -p $BIN + +REALPATH=$BIN/realpath +cp realpath $REALPATH + +EXEC=$BIN/exec +cp exec $EXEC + +CLOSETEST=$BIN/close-test +cp close-test $CLOSETEST + +REDIRECTIONTEST=$BIN/redirection-test +cp redirection-test $REDIRECTIONTEST + + +echo "========== TEST: execve() Trace ==========" +for FILE in cp echo chmod date df expr hostname ls ps pwd test; +do + # some of these commands will error out when run without arguments, + # so just ignore that since all we want is the execve() call to happen + set +e + $EXEC /bin/$FILE 2>&1 >> /dev/null + set -e + LOGPAT="Python\[[0-9]+\][[:space:]]execve[[:space:]]/bin/${FILE}" + C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) + test $C -eq 1 +done +set -e + + +echo "========== TEST: close() Safety ==========" +$CLOSETEST + + +echo "========== TEST: open() Trace ==========" +for FILE in /System/Library/LaunchDaemons/*.plist; +do + cat $FILE >> /dev/null; + RP=$($REALPATH $FILE); + LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" + C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) + test $C -eq 1 +done + + +echo "========== TEST: readlink() Trace ==========" +for FILE in $(find /System/Library/Frameworks/*Foundation.framework -type l | xargs); +do + readlink $FILE + LOGPAT="readlink\[[0-9]+\][[:space:]]readlink[[:space:]]${FILE}" + C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) + test $C -eq 1 +done + + +echo "========== TEST: ROOT Ignores ==========" +export DARWINTRACE_IGNORE_ROOTS="" +export DSTROOT="/System/Library/LaunchAgents" +for FILE in /var/log/*.log; +do + cat $FILE >> /dev/null; + RP=$($REALPATH $FILE); + LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" + C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) + test $C -eq 1 +done + +for FILE in /System/Library/LaunchAgents/com.apple.*; +do + cat $FILE >> /dev/null; + RP=$($REALPATH $FILE); + LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" + set +e + C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) + set -e + test $C -eq 0 +done +unset DARWINTRACE_IGNORE_ROOTS +unset DSTROOT + + +echo "========== TEST: Redirection ==========" +mkdir -p $ROOT/$PREFIX +mkdir -p $ROOT/usr/lib +cp /usr/lib/libSystem.B.dylib $ROOT/usr/lib/libSystem.B.dylib +mkdir -p $ROOT/bin +cp /bin/cat $ROOT/bin/cat +echo "Outside of root" > $PREFIX/datafile +echo "Inside of root" > $ROOT/$PREFIX/datafile +export DARWINTRACE_REDIRECT="${ROOT}" +export DARWIN_BUILDROOT="${ROOT}" +$REDIRECTIONTEST $PREFIX +unset DARWINTRACE_REDIRECT +unset DARWIN_BUILDROOT +# test that execve(/bin/cat) was redirected +RP=$($REALPATH ${ROOT}/bin/cat) +LOGPAT="bash\[[0-9]+\][[:space:]]execve[[:space:]]${RP}" +C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) +test $C -eq 1 +# test that open(/tmp/.../datafile) does not get redirected +# since /tmp/ is one of the redirection exceptions +RP=$($REALPATH ${PREFIX}/datafile) +LOGPAT="cat\[[0-9]+\][[:space:]]open[[:space:]]${RP}" +C=$(grep -cE $LOGPAT $DARWINTRACE_LOG) +test $C -eq 1 + +popd >> /dev/null +echo "INFO: Done testing!" Modified: trunk/testing/darwinup/run-tests.sh =================================================================== --- trunk/testing/darwinup/run-tests.sh 2011-02-10 15:12:58 UTC (rev 933) +++ trunk/testing/darwinup/run-tests.sh 2011-02-10 15:22:14 UTC (rev 934) @@ -97,6 +97,18 @@ done fi +echo "========== TEST: Test uninstall build check safety ==========" +$DARWINUP install $PREFIX/root2 +sqlite3 $DEST/.DarwinDepot/Database-V100 "UPDATE archives SET osbuild = '$(sw_vers -buildVersion)X'" +set +e +$DARWINUP uninstall root2 +if [ $? -eq 0 ]; then exit 1; fi +set -e +$DARWINUP -f uninstall root2 +echo "DIFF: diffing original test files to dest (should be no diffs) ..." +$DIFF $ORIG $DEST 2>&1 + + echo "========== TEST: Try installing a symlink-to-directory ==========" ln -s root2 $PREFIX/root_link # test without trailing slash Copied: trunk/testing/run-all-tests.sh (from rev 933, branches/PR-8817822/testing/run-all-tests.sh) =================================================================== --- trunk/testing/run-all-tests.sh (rev 0) +++ trunk/testing/run-all-tests.sh 2011-02-10 15:22:14 UTC (rev 934) @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +pushd $(dirname $0) >> /dev/null + +for X in *; +do + if [ -d $X ]; then + $X/run-tests.sh + fi +done + +echo "INFO: All testing completed!"
participants (1)
-
source_changes@macosforge.org