diff options
Diffstat (limited to 'updater')
-rw-r--r-- | updater/Android.mk | 38 | ||||
-rw-r--r-- | updater/install.c | 73 | ||||
-rw-r--r-- | updater/updater.c | 6 |
3 files changed, 113 insertions, 4 deletions
diff --git a/updater/Android.mk b/updater/Android.mk index 897b9d74c..d4a4e332d 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -18,11 +18,47 @@ LOCAL_MODULE_TAGS := eng LOCAL_SRC_FILES := $(updater_src_files) -LOCAL_STATIC_LIBRARIES := libapplypatch libedify libmtdutils libminzip libz +LOCAL_STATIC_LIBRARIES := $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) +LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz LOCAL_STATIC_LIBRARIES += libmincrypt libbz LOCAL_STATIC_LIBRARIES += libcutils libstdc++ libc LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. +# Each library in TARGET_RECOVERY_UPDATER_LIBS should have a function +# named "Register_<libname>()". Here we emit a little C function that +# gets #included by updater.c. It calls all those registration +# functions. + +# Devices can also add libraries to TARGET_RECOVERY_UPDATER_EXTRA_LIBS. +# These libs are also linked in with updater, but we don't try to call +# any sort of registration function for these. Use this variable for +# any subsidiary static libraries required for your registered +# extension libs. + +inc := $(call intermediates-dir-for,PACKAGING,updater_extensions)/register.inc + +# During the first pass of reading the makefiles, we dump the list of +# extension libs to a temp file, then copy that to the ".list" file if +# it is different than the existing .list (if any). The register.inc +# file then uses the .list as a prerequisite, so it is only rebuilt +# (and updater.o recompiled) when the list of extension libs changes. + +junk := $(shell mkdir -p $(dir $(inc));\ + echo $(TARGET_RECOVERY_UPDATER_LIBS) > $(inc).temp;\ + diff -q $(inc).temp $(inc).list || cp -f $(inc).temp $(inc).list) + +$(inc) : libs := $(TARGET_RECOVERY_UPDATER_LIBS) +$(inc) : $(inc).list + $(hide) mkdir -p $(dir $@) + $(hide) echo "" > $@ + $(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@) + $(hide) echo "void RegisterDeviceExtensions() {" >> $@ + $(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@) + $(hide) echo "}" >> $@ + +$(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc) +LOCAL_C_INCLUDES += $(dir $(inc)) + LOCAL_MODULE := updater LOCAL_FORCE_STATIC_EXECUTABLE := true diff --git a/updater/install.c b/updater/install.c index c4f5e0341..aa80d7576 100644 --- a/updater/install.c +++ b/updater/install.c @@ -23,6 +23,7 @@ #include <sys/mount.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/wait.h> #include <unistd.h> #include "cutils/misc.h" @@ -85,6 +86,8 @@ char* MountFn(const char* name, State* state, int argc, Expr* argv[]) { } else { if (mount(location, mount_point, type, MS_NOATIME | MS_NODEV | MS_NODIRATIME, "") < 0) { + fprintf(stderr, "%s: failed to mount %s at %s: %s\n", + name, location, mount_point, strerror(errno)); result = strdup(""); } else { result = mount_point; @@ -347,6 +350,7 @@ char* PackageExtractFileFn(const char* name, State* state, // symlink target src1 src2 ... +// unlinks any previously existing src1, src2, etc before creating symlinks. char* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc == 0) { return ErrorAbort(state, "%s() expects 1+ args, got %d", name, argc); @@ -363,7 +367,16 @@ char* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { int i; for (i = 0; i < argc-1; ++i) { - symlink(target, srcs[i]); + if (unlink(srcs[i]) < 0) { + if (errno != ENOENT) { + fprintf(stderr, "%s: failed to remove %s: %s\n", + name, srcs[i], strerror(errno)); + } + } + if (symlink(target, srcs[i]) < 0) { + fprintf(stderr, "%s: failed to symlink %s to %s: %s\n", + name, srcs[i], target, strerror(errno)); + } free(srcs[i]); } free(srcs); @@ -423,8 +436,14 @@ char* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) { } for (i = 3; i < argc; ++i) { - chown(args[i], uid, gid); - chmod(args[i], mode); + if (chown(args[i], uid, gid) < 0) { + fprintf(stderr, "%s: chown of %s to %d %d failed: %s\n", + name, args[i], uid, gid, strerror(errno)); + } + if (chmod(args[i], mode) < 0) { + fprintf(stderr, "%s: chmod of %s to %o failed: %s\n", + name, args[i], mode, strerror(errno)); + } } } result = strdup(""); @@ -759,6 +778,52 @@ char* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) { return buffer; } +char* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) { + if (argc < 1) { + return ErrorAbort(state, "%s() expects at least 1 arg", name); + } + char** args = ReadVarArgs(state, argc, argv); + if (args == NULL) { + return NULL; + } + + char** args2 = malloc(sizeof(char*) * (argc+1)); + memcpy(args2, args, sizeof(char*) * argc); + args2[argc] = NULL; + + fprintf(stderr, "about to run program [%s] with %d args\n", args2[0], argc); + + pid_t child = fork(); + if (child == 0) { + execv(args2[0], args2); + fprintf(stderr, "run_program: execv failed: %s\n", strerror(errno)); + _exit(1); + } + int status; + waitpid(child, &status, 0); + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) { + fprintf(stderr, "run_program: child exited with status %d\n", + WEXITSTATUS(status)); + } + } else if (WIFSIGNALED(status)) { + fprintf(stderr, "run_program: child terminated by signal %d\n", + WTERMSIG(status)); + } + + int i; + for (i = 0; i < argc; ++i) { + free(args[i]); + } + free(args); + free(args2); + + char buffer[20]; + sprintf(buffer, "%d", status); + + return strdup(buffer); +} + void RegisterInstallFunctions() { RegisterFunction("mount", MountFn); @@ -785,4 +850,6 @@ void RegisterInstallFunctions() { RegisterFunction("apply_patch_space", ApplyPatchFn); RegisterFunction("ui_print", UIPrintFn); + + RegisterFunction("run_program", RunProgramFn); } diff --git a/updater/updater.c b/updater/updater.c index 31d93ae96..1aa277c7f 100644 --- a/updater/updater.c +++ b/updater/updater.c @@ -23,6 +23,11 @@ #include "install.h" #include "minzip/Zip.h" +// Generated by the makefile, this function defines the +// RegisterDeviceExtensions() function, which calls all the +// registration functions for device-specific extensions. +#include "register.inc" + // Where in the package we expect to find the edify script to execute. // (Note it's "updateR-script", not the older "update-script".) #define SCRIPT_NAME "META-INF/com/google/android/updater-script" @@ -76,6 +81,7 @@ int main(int argc, char** argv) { RegisterBuiltins(); RegisterInstallFunctions(); + RegisterDeviceExtensions(); FinishRegistration(); // Parse the script. |