aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/SPAppController.h5
-rw-r--r--Source/SPAppController.m59
-rw-r--r--Source/SPCopyTable.m2
-rw-r--r--Source/SPDatabaseDocument.h7
-rw-r--r--Source/SPDatabaseDocument.m26
-rw-r--r--Source/SPStringAdditions.h1
-rw-r--r--Source/SPStringAdditions.m35
-rw-r--r--Source/SPTextViewAdditions.m2
8 files changed, 131 insertions, 6 deletions
diff --git a/Source/SPAppController.h b/Source/SPAppController.h
index d9763766..d96af12f 100644
--- a/Source/SPAppController.h
+++ b/Source/SPAppController.h
@@ -50,6 +50,8 @@
NSMutableDictionary *bundleKeyEquivalents;
NSMutableDictionary *installedBundleUUIDs;
+ NSMutableArray *runningBASHprocesses;
+
}
// Window management
@@ -95,6 +97,9 @@
- (NSArray *)bundleCategoriesForScope:(NSString*)scope;
- (NSArray *)bundleItemsForScope:(NSString*)scope;
- (NSDictionary *)bundleKeyEquivalentsForScope:(NSString*)scope;
+- (void)registerBASHCommand:(NSDictionary*)commandDict;
+- (void)unRegisterBASHCommand:(NSInteger)pid;
+- (NSArray*)runningBASHProcesses;
- (void)handleEventWithURL:(NSURL*)url;
diff --git a/Source/SPAppController.m b/Source/SPAppController.m
index 55eb4e17..12b9e9a4 100644
--- a/Source/SPAppController.m
+++ b/Source/SPAppController.m
@@ -57,6 +57,7 @@
bundleUsedScopes = [[NSMutableArray alloc] initWithCapacity:1];
bundleKeyEquivalents = [[NSMutableDictionary alloc] initWithCapacity:1];
installedBundleUUIDs = [[NSMutableDictionary alloc] initWithCapacity:1];
+ runningBASHprocesses = [[NSMutableArray alloc] init];
[NSApp setDelegate:self];
}
@@ -780,7 +781,7 @@
return;
}
- NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil error:&err];
+ NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerDocument:self withName:([cmdData objectForKey:SPBundleFileNameKey])?[cmdData objectForKey:SPBundleFileNameKey]:@"" error:&err];
[[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil];
@@ -831,6 +832,26 @@
}
+- (void)registerBASHCommand:(NSDictionary*)commandDict
+{
+ [runningBASHprocesses addObject:commandDict];
+}
+
+- (void)unRegisterBASHCommand:(NSInteger)pid
+{
+ for(id cmd in runningBASHprocesses) {
+ if([[cmd objectForKey:@"pid"] integerValue] == pid) {
+ [runningBASHprocesses removeObject:cmd];
+ break;
+ }
+ }
+}
+
+- (NSArray*)runningBASHProcesses
+{
+ return (NSArray*)runningBASHprocesses;
+}
+
#pragma mark -
#pragma mark Window management
@@ -1507,6 +1528,41 @@
}
}
+/**
+ * If Sequel Pro is terminating kill all running BASH scripts
+ */
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+
+ // Kill all registered BASH commands
+ for (NSWindow *aWindow in [NSApp orderedWindows]) {
+ if([[aWindow windowController] isMemberOfClass:[SPWindowController class]]) {
+ for(SPDatabaseDocument *doc in [[aWindow windowController] documents]) {
+ for(NSDictionary* cmd in [doc runningBASHProcesses]) {
+ NSInteger pid = [[cmd objectForKey:@"pid"] intValue];
+ NSTask *killTask = [[NSTask alloc] init];
+ [killTask setLaunchPath:@"/bin/sh"];
+ [killTask setArguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"kill -9 -%ld", pid], nil]];
+ [killTask launch];
+ [killTask waitUntilExit];
+ [killTask release];
+ }
+ }
+ }
+ }
+ for(NSDictionary* cmd in [self runningBASHProcesses]) {
+ NSInteger pid = [[cmd objectForKey:@"pid"] intValue];
+ NSTask *killTask = [[NSTask alloc] init];
+ [killTask setLaunchPath:@"/bin/sh"];
+ [killTask setArguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"kill -9 -%ld", pid], nil]];
+ [killTask launch];
+ [killTask waitUntilExit];
+ [killTask release];
+ }
+ return YES;
+
+}
+
#pragma mark -
/**
@@ -1521,6 +1577,7 @@
if(bundleCategories) [bundleCategories release];
if(bundleKeyEquivalents) [bundleKeyEquivalents release];
if(installedBundleUUIDs) [installedBundleUUIDs release];
+ if (runningBASHprocesses) [runningBASHprocesses release];
[prefsController release], prefsController = nil;
diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m
index 6b746099..f06c4700 100644
--- a/Source/SPCopyTable.m
+++ b/Source/SPCopyTable.m
@@ -923,7 +923,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003;
return;
}
- NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil error:&err];
+ NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerDocument:[[NSApp delegate] frontDocument] withName:([cmdData objectForKey:SPBundleFileNameKey])?[cmdData objectForKey:SPBundleFileNameKey]:@"" error:&err];
[[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil];
diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h
index e4d12346..16330b39 100644
--- a/Source/SPDatabaseDocument.h
+++ b/Source/SPDatabaseDocument.h
@@ -188,7 +188,9 @@
NSDictionary *spfSession;
NSMutableDictionary *spfPreferences;
NSMutableDictionary *spfDocData;
-
+
+ NSMutableArray *runningBASHprocesses;
+
NSString *keyChainID;
NSThread *printThread;
@@ -355,6 +357,9 @@
// Scripting
- (void)handleSchemeCommand:(NSDictionary*)commandDict;
+- (void)registerBASHCommand:(NSDictionary*)commandDict;
+- (void)unRegisterBASHCommand:(NSInteger)pid;
+- (NSArray*)runningBASHProcesses;
- (NSDictionary*)shellVariables;
// State saving and setting
diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m
index 4b52b39d..23805b12 100644
--- a/Source/SPDatabaseDocument.m
+++ b/Source/SPDatabaseDocument.m
@@ -116,6 +116,7 @@
spfSession = nil;
spfPreferences = [[NSMutableDictionary alloc] init];
spfDocData = [[NSMutableDictionary alloc] init];
+ runningBASHprocesses = [[NSMutableArray alloc] init];
titleAccessoryView = nil;
taskProgressWindow = nil;
@@ -2400,6 +2401,7 @@
*/
- (void)applicationWillTerminate:(NSNotification *)notification
{
+
// Auto-save preferences to spf file based connection
if([self fileURL] && [[[self fileURL] path] length] && ![self isUntitled])
if(_isConnected && ![self saveDocumentWithFilePath:nil inBackground:YES onlyPreferences:YES contextInfo:nil]) {
@@ -2408,7 +2410,7 @@
}
[tablesListInstance selectionShouldChangeInTableView:nil];
-
+
// Note that this call does not need to be removed in release builds as leaks analysis output is only
// dumped if [[SPLogger logger] setDumpLeaksOnTermination]; has been called first.
[[SPLogger logger] dumpLeaks];
@@ -4738,6 +4740,26 @@
NSLog(@"received: %@", commandDict);
}
+- (void)registerBASHCommand:(NSDictionary*)commandDict
+{
+ [runningBASHprocesses addObject:commandDict];
+}
+
+- (void)unRegisterBASHCommand:(NSInteger)pid
+{
+ for(id cmd in runningBASHprocesses) {
+ if([[cmd objectForKey:@"pid"] integerValue] == pid) {
+ [runningBASHprocesses removeObject:cmd];
+ break;
+ }
+ }
+}
+
+- (NSArray*)runningBASHProcesses
+{
+ return (NSArray*)runningBASHprocesses;
+}
+
- (NSDictionary*)shellVariables
{
NSMutableDictionary *env = [NSMutableDictionary dictionary];
@@ -4989,6 +5011,7 @@
*/
- (void)dealloc
{
+
// Unregister observers
[prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines];
[prefs removeObserver:tableSourceInstance forKeyPath:SPDisplayTableViewVerticalGridlines];
@@ -5037,6 +5060,7 @@
if (taskProgressWindow) [taskProgressWindow release];
if (serverSupport) [serverSupport release];
if (processID) [processID release];
+ if (runningBASHprocesses) [runningBASHprocesses release];
[super dealloc];
}
diff --git a/Source/SPStringAdditions.h b/Source/SPStringAdditions.h
index e9e3784c..b0e085aa 100644
--- a/Source/SPStringAdditions.h
+++ b/Source/SPStringAdditions.h
@@ -77,6 +77,7 @@ static inline id NSMutableAttributedStringAttributeAtIndex (NSMutableAttributedS
- (CGFloat)levenshteinDistanceWithWord:(NSString *)stringB;
+- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerDocument:(id)caller withName:(NSString*)name error:(NSError**)theError;
- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path error:(NSError**)theError;
@end
diff --git a/Source/SPStringAdditions.m b/Source/SPStringAdditions.m
index 907ebc05..658baadb 100644
--- a/Source/SPStringAdditions.m
+++ b/Source/SPStringAdditions.m
@@ -444,10 +444,14 @@
*
* @param path The current directory for the bash command. If path is nil, the current directory is inherited from the process that created the receiver (normally /).
*
+ * @param caller The SPDatabaseDocument which invoked that command to register the command for cancelling; if nil the command won't be registered.
+ *
+ * @param name The menu title of the command.
+ *
* @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
*
*/
-- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path error:(NSError**)theError
+- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path callerDocument:(id)caller withName:(NSString*)name error:(NSError**)theError
{
BOOL userTerminated = NO;
@@ -544,6 +548,16 @@
[bashTask setStandardError:stderr_pipe];
NSFileHandle *stderr_file = [stderr_pipe fileHandleForReading];
[bashTask launch];
+ NSInteger pid = -1;
+ if(caller != nil && [caller respondsToSelector:@selector(registerBASHCommand:)]) {
+ // register command
+ pid = [bashTask processIdentifier];
+ NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:pid], @"pid",
+ name, @"name",
+ [[NSDate date] descriptionWithCalendarFormat:@"%H:%M:%S" timeZone:nil locale:[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]], @"starttime",
+ nil];
+ [caller registerBASHCommand:dict];
+ }
// Listen to ⌘. to terminate
while(1) {
@@ -569,6 +583,9 @@
[bashTask waitUntilExit];
+ // unregister BASH command if it was registered
+ if(pid >= 0) [caller unRegisterBASHCommand:pid];
+
if(userTerminated) {
if(bashTask) [bashTask release];
NSBeep();
@@ -639,6 +656,22 @@
}
/**
+ * Run self as BASH command(s) and return the result.
+ * This task can be interrupted by pressing ⌘.
+ *
+ * @param shellEnvironment A dictionary of environment variable values whose keys are the variable names.
+ *
+ * @param path The current directory for the bash command. If path is nil, the current directory is inherited from the process that created the receiver (normally /).
+ *
+ * @param theError If not nil and the bash command failed it contains the returned error message as NSLocalizedDescriptionKey
+ *
+ */
+- (NSString *)runBashCommandWithEnvironment:(NSDictionary*)shellEnvironment atCurrentDirectoryPath:(NSString*)path error:(NSError**)theError
+{
+ return [self runBashCommandWithEnvironment:shellEnvironment atCurrentDirectoryPath:path callerDocument:nil withName:@"" error:theError];
+}
+
+/**
* Returns the minimum of a, b and c.
*/
- (NSInteger)smallestOf:(NSInteger)a andOf:(NSInteger)b andOf:(NSInteger)c
diff --git a/Source/SPTextViewAdditions.m b/Source/SPTextViewAdditions.m
index 0c9fe630..f75505df 100644
--- a/Source/SPTextViewAdditions.m
+++ b/Source/SPTextViewAdditions.m
@@ -603,7 +603,7 @@
return;
}
- NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil error:&err];
+ NSString *output = [cmd runBashCommandWithEnvironment:env atCurrentDirectoryPath:nil callerDocument:[[NSApp delegate] frontDocument] withName:([cmdData objectForKey:SPBundleFileNameKey])?[cmdData objectForKey:SPBundleFileNameKey]:@"" error:&err];
[[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil];