Updater: automatically restart if possible

This commit is contained in:
Anton Makeev
2011-11-26 17:53:53 +01:00
parent bc347a812d
commit f2ce5df79f
9 changed files with 412 additions and 253 deletions
+10 -55
View File
@@ -2,65 +2,20 @@
#import <AppKit/AppKit.h>
@interface TerminationListener : NSObject
{
const char *executablePath;
pid_t parentProcessId;
}
int main(int argc, const char *argv[]) {
if (argc != 2) return EXIT_FAILURE;
- (void) relaunch;
unsigned int interval = 500; // check every 0.5 second
unsigned int slept = 0;
while (getppid() != 1) {
usleep(interval * 1000);
@end
@implementation TerminationListener
- (id) initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid
{
self = [super init];
if (self != nil) {
executablePath = execPath;
parentProcessId = ppid;
// This adds the input source required by the run loop
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
if (getppid() == 1) {
// ppid is launchd (1) => parent terminated already
[self relaunch];
}
slept += interval;
if (slept > 10 * 1000 /* wait for maximum 10 seconds */) return EXIT_FAILURE;
}
return self;
}
- (void) applicationDidTerminate:(NSNotification *)notification
{
if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) {
// parent just terminated
[self relaunch];
}
}
- (void) relaunch
{
// [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(actualLaunch) userInfo:nil repeats:NO];
// NSDate *future = [NSDate dateWithTimeIntervalSinceNow: 5.0 ];
// [NSThread sleepUntilDate:future];
[[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:executablePath]];
exit(0);
}
@end
int main (int argc, const char * argv[])
{
if (argc != 3) return EXIT_FAILURE;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[[[TerminationListener alloc] initWithExecutablePath:argv[1] parentProcessId:atoi(argv[2])] autorelease];
[[NSApplication sharedApplication] run];
[pool release];
char const *pathToRelaunch = argv[1];
[[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:pathToRelaunch]];
return EXIT_SUCCESS;
}
@@ -0,0 +1,209 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
3A6C10B4148122790074811C /* relaunch.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A6C10B3148122790074811C /* relaunch.m */; };
3A6C10B7148122940074811C /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A6C10B6148122940074811C /* AppKit.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
CF2F99674C3F98D5739C1B44 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
3A6C10AE148122660074811C /* relaunch */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = relaunch; sourceTree = BUILT_PRODUCTS_DIR; };
3A6C10B3148122790074811C /* relaunch.m */ = {isa = PBXFileReference; fileEncoding = 11; lastKnownFileType = sourcecode.c.objc; path = relaunch.m; sourceTree = "<group>"; };
3A6C10B6148122940074811C /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CF2F99674C3F98D5739C1B43 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3A6C10B7148122940074811C /* AppKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
CF2F99674C3F98D5739C1B39 = {
isa = PBXGroup;
children = (
3A6C10B3148122790074811C /* relaunch.m */,
CF2F99674C3F98D5739C1B3A /* Products */,
CF2F99674C3F98D5739C1B45 /* Frameworks */,
3A6C10B6148122940074811C /* AppKit.framework */,
);
sourceTree = "<group>";
};
CF2F99674C3F98D5739C1B3A /* Products */ = {
isa = PBXGroup;
children = (
3A6C10AE148122660074811C /* relaunch */,
);
name = Products;
sourceTree = "<group>";
};
CF2F99674C3F98D5739C1B45 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
CF2F99674C3F98D5739C1B3E /* relaunch */ = {
isa = PBXNativeTarget;
buildConfigurationList = CF2F99674C3F98D5739C1B3F /* Build configuration list for PBXNativeTarget "relaunch" */;
buildPhases = (
CF2F99674C3F98D5739C1B42 /* Sources */,
CF2F99674C3F98D5739C1B43 /* Frameworks */,
CF2F99674C3F98D5739C1B44 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = relaunch;
productName = relaunch;
productReference = 3A6C10AE148122660074811C /* relaunch */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CF2F99674C3F98D5739C1B37 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = CF2F99674C3F98D5739C1B38 /* Build configuration list for PBXProject "relaunch" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = CF2F99674C3F98D5739C1B39;
productRefGroup = CF2F99674C3F98D5739C1B3A /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CF2F99674C3F98D5739C1B3E /* relaunch */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
CF2F99674C3F98D5739C1B42 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3A6C10B4148122790074811C /* relaunch.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
CF2F99674C3F98D5739C1B3B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_VERSION = 4.0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.4;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = macosx10.4;
};
name = Release;
};
CF2F99674C3F98D5739C1B3C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = 4.0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.4;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = macosx10.4;
};
name = Debug;
};
CF2F99674C3F98D5739C1B40 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PRECOMPILE_PREFIX_HEADER = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
CF2F99674C3F98D5739C1B41 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_PRECOMPILE_PREFIX_HEADER = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CF2F99674C3F98D5739C1B38 /* Build configuration list for PBXProject "relaunch" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF2F99674C3F98D5739C1B3B /* Release */,
CF2F99674C3F98D5739C1B3C /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CF2F99674C3F98D5739C1B3F /* Build configuration list for PBXNativeTarget "relaunch" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CF2F99674C3F98D5739C1B40 /* Release */,
CF2F99674C3F98D5739C1B41 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CF2F99674C3F98D5739C1B37 /* Project object */;
}