Return to Snippet

Revision: 4029
at April 3, 2008 15:58 by 0xced


Updated Code
// gcc -Wall -arch i386 -arch ppc -mmacosx-version-min=10.4 -Os -framework AppKit -o relaunch relaunch.m

#import <AppKit/AppKit.h>

@interface TerminationListener : NSObject
{
    const char *executablePath;
    pid_t parentProcessId;
}

- (void) relaunch;

@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];
        }
    }
    return self;
}

- (void) applicationDidTerminate:(NSNotification *)notification
{
    if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) {
        // parent just terminated
        [self relaunch];
    }
}

- (void) relaunch
{
    [[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];
    
    return EXIT_SUCCESS;
}

Revision: 4028
at November 13, 2007 05:58 by 0xced


Updated Code
// gcc -Wall -arch i386 -arch ppc -Os -s -framework AppKit -o relaunch relaunch.m

#import <AppKit/AppKit.h>
#import <unistd.h>

@interface TerminationListener : NSObject
{
	const char *executablePath;
	pid_t parentProcessId;
}

- (void) relaunch;

@end

@implementation TerminationListener

- (id) initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid
{
	self = [super init];
	if (self != nil) {
		executablePath = execPath;
		parentProcessId = ppid;
		
		[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
		if (getppid() == 1) {
			// ppid is launchd (1) => parent terminated already
			[self relaunch];
		}
	}
	return self;
}

- (void) applicationDidTerminate:(NSNotification *)notification
{
	if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) {
		// parent just terminated
		[self relaunch];
	}
}

- (void) relaunch
{
	[[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:executablePath]];	
	[NSApp stop:self];
}

@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];
	
	return EXIT_SUCCESS;
}

Revision: 4027
at November 13, 2007 05:56 by 0xced


Updated Code
// gcc -Wall -arch i386 -arch ppc -Os -s -framework AppKit -o relaunch relaunch.m

#import <AppKit/AppKit.h>
#import <unistd.h>

@interface TerminationListener : NSObject
{
	const char *executablePath;
	pid_t parentProcessId;
}

- (void) relaunch;

@end

@implementation TerminationListener

- (id) initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid
{
	self = [super init];
	if (self != nil) {
		executablePath = execPath;
		parentProcessId = ppid;
		
		[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
		if (getppid() == 1) {
			// ppid is launchd (1) => parent terminated already
			[self relaunch];
		}
	}
	return self;
}

- (void) applicationDidTerminate:(NSNotification *)notification
{
	if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) {
		// parent just terminated
		[self relaunch];
	}
}

- (void) relaunch
{
	[[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:executablePath]];	
	[NSApp stop];
}

@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];
	
	return EXIT_SUCCESS;
}

Revision: 4026
at November 13, 2007 05:47 by 0xced


Updated Code
// gcc -Wall -arch i386 -arch ppc -Os -s -framework AppKit -o relaunch relaunch.m

#import <AppKit/AppKit.h>
#import <unistd.h>

@interface TerminationListener : NSObject
{
	const char *executablePath;
	pid_t parentProcessId;
}

- (void) relaunch;

@end

@implementation TerminationListener

- (id) initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid
{
	self = [super init];
	if (self != nil) {
		executablePath = execPath;
		parentProcessId = ppid;
		
		[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
		if (getppid() == 1) {
			// ppid is launchd (1) => parent terminated already
			[self relaunch];
		}
	}
	return self;
}

- (void) applicationDidTerminate:(NSNotification *)notification
{
	if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) {
		// parent just terminated
		[self relaunch];
	}
}

- (void) relaunch
{
	[[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:executablePath]];	
	[NSApp terminate:self];
}

@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];
	
	// This will not be executed because -[NSApp terminate:] is called
	[pool release];
	
	return EXIT_SUCCESS;
}

Revision: 4025
at October 18, 2007 15:11 by 0xced


Initial Code
// gcc -Wall -arch i386 -arch ppc -Os -s -framework AppKit -o relaunch relaunch.m

#import <AppKit/AppKit.h>
#import <unistd.h>

@interface TerminationListener : NSObject
{
	const char *executablePath;
	pid_t parentProcessId;
}

- (void) relaunch;

@end

@implementation TerminationListener

- (id) initWithExecutablePath:(const char *)execPath parentProcessId:(pid_t)ppid
{
	self = [super init];
	if (self != nil) {
		executablePath = execPath;
		parentProcessId = ppid;
		
		[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(applicationDidTerminate:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
		if (getppid() == 1) {
			// ppid is launchd (1) => parent terminated already
			[self relaunch];
		}
	}
	return self;
}

- (void) applicationDidTerminate:(NSNotification *)notification
{
	if (parentProcessId == [[[notification userInfo] valueForKey:@"NSApplicationProcessIdentifier"] intValue]) {
		// parent just terminated
		[self relaunch];
	}
}

- (void) relaunch
{
	[[NSWorkspace sharedWorkspace] launchApplication:[NSString stringWithUTF8String:executablePath]];	
	[NSApp terminate:self];
}

@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];
	[NSApp run];
	
	// This will not be executed because -[NSApp terminate:] is called
	[pool release];
	
	return EXIT_SUCCESS;
}

Initial URL

                                

Initial Description
The application that needs to be restarted must fork 'relaunch' with two arguments, then terminate. In Cocoa, the fork is easily achieved with a NSTask. The first argument must be the path to the application to relaunch. The second argument must be the process identifier of the terminating application. In Cocoa, you can get it with [[NSProcessInfo processInfo] processIdentifier], which is equivalent to getpid().

Initial Title
Relaunch an application

Initial Tags

                                

Initial Language
Objective C