mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Fix for #1905: PythonLauncher not working correctly on OSX 10.5/Leopard
This fixes both Python Launchar and the terminalcommand module.
This commit is contained in:
		
							parent
							
								
									6780a9dd9f
								
							
						
					
					
						commit
						f2ef92cee7
					
				
					 4 changed files with 45 additions and 103 deletions
				
			
		| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
# Generated from 'AEDataModel.h'
 | 
					# Generated from 'AEDataModel.h'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def FOUR_CHAR_CODE(x): return x
 | 
					def FOUR_CHAR_CODE(x): return x
 | 
				
			||||||
 | 
					typeApplicationBundleID = FOUR_CHAR_CODE('bund')
 | 
				
			||||||
typeBoolean = FOUR_CHAR_CODE('bool')
 | 
					typeBoolean = FOUR_CHAR_CODE('bool')
 | 
				
			||||||
typeChar = FOUR_CHAR_CODE('TEXT')
 | 
					typeChar = FOUR_CHAR_CODE('TEXT')
 | 
				
			||||||
typeSInt16 = FOUR_CHAR_CODE('shor')
 | 
					typeSInt16 = FOUR_CHAR_CODE('shor')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def run(command):
 | 
					def run(command):
 | 
				
			||||||
    """Run a shell command in a new Terminal.app window."""
 | 
					    """Run a shell command in a new Terminal.app window."""
 | 
				
			||||||
    termAddress = AE.AECreateDesc(typeApplSignature, TERMINAL_SIG)
 | 
					    termAddress = AE.AECreateDesc(typeApplicationBundleID, "com.apple.Terminal")
 | 
				
			||||||
    theEvent = AE.AECreateAppleEvent(kAECoreSuite, kAEDoScript, termAddress,
 | 
					    theEvent = AE.AECreateAppleEvent(kAECoreSuite, kAEDoScript, termAddress,
 | 
				
			||||||
                                     kAutoGenerateReturnID, kAnyTransactionID)
 | 
					                                     kAutoGenerateReturnID, kAnyTransactionID)
 | 
				
			||||||
    commandDesc = AE.AECreateDesc(typeChar, command)
 | 
					    commandDesc = AE.AECreateDesc(typeChar, command)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,8 +121,8 @@
 | 
				
			||||||
        return YES;
 | 
					        return YES;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        [self run];
 | 
					        [self run];
 | 
				
			||||||
        [self close];
 | 
						[self performSelector:@selector(close) withObject:nil afterDelay:0.0];
 | 
				
			||||||
        return NO;
 | 
					        return YES;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,108 +11,49 @@
 | 
				
			||||||
#import <ApplicationServices/ApplicationServices.h>
 | 
					#import <ApplicationServices/ApplicationServices.h>
 | 
				
			||||||
#import "doscript.h"
 | 
					#import "doscript.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* I assume I could pick these up from somewhere, but where... */
 | 
					 | 
				
			||||||
#define CREATOR 'trmx'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ACTIVATE_CMD 'misc'
 | 
					 | 
				
			||||||
#define ACTIVATE_SUITE 'actv'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DOSCRIPT_CMD 'dosc'
 | 
					 | 
				
			||||||
#define DOSCRIPT_SUITE 'core'
 | 
					 | 
				
			||||||
#define WITHCOMMAND 'cmnd'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ... and there's probably also a better way to do this... */
 | 
					 | 
				
			||||||
#define START_TERMINAL "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal &"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern int 
 | 
					extern int 
 | 
				
			||||||
doscript(const char *command)
 | 
					doscript(const char *command)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    OSErr err;
 | 
						char *bundleID = "com.apple.Terminal";
 | 
				
			||||||
    AppleEvent theAEvent, theReply;
 | 
						AppleEvent evt, res;
 | 
				
			||||||
    AEAddressDesc terminalAddress;
 | 
						AEDesc desc;
 | 
				
			||||||
    AEDesc commandDesc;
 | 
						OSStatus err;
 | 
				
			||||||
    OSType terminalCreator = CREATOR;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* set up locals  */
 | 
					 | 
				
			||||||
    AECreateDesc(typeNull, NULL, 0, &theAEvent);
 | 
					 | 
				
			||||||
    AECreateDesc(typeNull, NULL, 0, &terminalAddress);
 | 
					 | 
				
			||||||
    AECreateDesc(typeNull, NULL, 0, &theReply);
 | 
					 | 
				
			||||||
    AECreateDesc(typeNull, NULL, 0, &commandDesc);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* create the "activate" event for Terminal */
 | 
					 | 
				
			||||||
    err = AECreateDesc(typeApplSignature, (Ptr) &terminalCreator,
 | 
					 | 
				
			||||||
            sizeof(terminalCreator), &terminalAddress);
 | 
					 | 
				
			||||||
    if (err != noErr) {
 | 
					 | 
				
			||||||
        NSLog(@"doscript: AECreateDesc: error %d\n", err);
 | 
					 | 
				
			||||||
        goto bail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    err = AECreateAppleEvent(ACTIVATE_SUITE, ACTIVATE_CMD,
 | 
					 | 
				
			||||||
            &terminalAddress, kAutoGenerateReturnID,
 | 
					 | 
				
			||||||
            kAnyTransactionID, &theAEvent);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (err != noErr) {
 | 
					 | 
				
			||||||
        NSLog(@"doscript: AECreateAppleEvent(activate): error %d\n", err);
 | 
					 | 
				
			||||||
        goto bail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    /* send the event  */
 | 
					 | 
				
			||||||
    err = AESend(&theAEvent, &theReply, kAEWaitReply,
 | 
					 | 
				
			||||||
            kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
 | 
					 | 
				
			||||||
    if ( err == -600 ) {
 | 
					 | 
				
			||||||
        int count=10;
 | 
					 | 
				
			||||||
        /* If it failed with "no such process" try to start Terminal */
 | 
					 | 
				
			||||||
        err = system(START_TERMINAL);
 | 
					 | 
				
			||||||
        if ( err ) {
 | 
					 | 
				
			||||||
            NSLog(@"doscript: system(): %s\n", strerror(errno));
 | 
					 | 
				
			||||||
            goto bail;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        do {
 | 
					 | 
				
			||||||
            sleep(1);
 | 
					 | 
				
			||||||
            /* send the event again */
 | 
					 | 
				
			||||||
            err = AESend(&theAEvent, &theReply, kAEWaitReply,
 | 
					 | 
				
			||||||
                    kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
 | 
					 | 
				
			||||||
        } while (err == -600 && --count > 0);
 | 
					 | 
				
			||||||
        if ( err == -600 )
 | 
					 | 
				
			||||||
            NSLog(@"doscript: Could not activate Terminal\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (err != noErr) {
 | 
					 | 
				
			||||||
        NSLog(@"doscript: AESend(activate): error %d\n", err);
 | 
					 | 
				
			||||||
        goto bail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
    /* create the "doscript with command" event for Terminal */
 | 
					 | 
				
			||||||
    err = AECreateAppleEvent(DOSCRIPT_SUITE, DOSCRIPT_CMD,
 | 
					 | 
				
			||||||
            &terminalAddress, kAutoGenerateReturnID,
 | 
					 | 
				
			||||||
            kAnyTransactionID, &theAEvent);
 | 
					 | 
				
			||||||
    if (err != noErr) {
 | 
					 | 
				
			||||||
        NSLog(@"doscript: AECreateAppleEvent(doscript): error %d\n", err);
 | 
					 | 
				
			||||||
        goto bail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /* add the command to the apple event */
 | 
					 | 
				
			||||||
    err = AECreateDesc(typeChar, command, strlen(command), &commandDesc);
 | 
					 | 
				
			||||||
    if (err != noErr) {
 | 
					 | 
				
			||||||
        NSLog(@"doscript: AECreateDesc(command): error %d\n", err);
 | 
					 | 
				
			||||||
        goto bail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    err = AEPutParamDesc(&theAEvent, WITHCOMMAND, &commandDesc);
 | 
					 | 
				
			||||||
    if (err != noErr) {
 | 
					 | 
				
			||||||
        NSLog(@"doscript: AEPutParamDesc: error %d\n", err);
 | 
					 | 
				
			||||||
        goto bail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* send the command event to Terminal.app */
 | 
						[[NSWorkspace sharedWorkspace] launchApplication:@"/Applications/Utilities/Terminal.app/"];
 | 
				
			||||||
    err = AESend(&theAEvent, &theReply, kAEWaitReply,
 | 
					
 | 
				
			||||||
            kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
 | 
						// Build event
 | 
				
			||||||
    
 | 
						err = AEBuildAppleEvent(kAECoreSuite, kAEDoScript,
 | 
				
			||||||
    if (err != noErr) {
 | 
						                         typeApplicationBundleID,
 | 
				
			||||||
        NSLog(@"doscript: AESend(docommand): error %d\n", err);
 | 
						                         bundleID, strlen(bundleID),
 | 
				
			||||||
        goto bail;
 | 
						                         kAutoGenerateReturnID,
 | 
				
			||||||
    }
 | 
						                         kAnyTransactionID,
 | 
				
			||||||
    /* clean up and leave */
 | 
						                         &evt, NULL,
 | 
				
			||||||
bail:
 | 
						                         "'----':utf8(@)", strlen(command),
 | 
				
			||||||
    AEDisposeDesc(&commandDesc);
 | 
						                         command);
 | 
				
			||||||
    AEDisposeDesc(&theAEvent);
 | 
						if (err) {
 | 
				
			||||||
    AEDisposeDesc(&terminalAddress);
 | 
							NSLog(@"AEBuildAppleEvent failed: %d\n", err);
 | 
				
			||||||
    AEDisposeDesc(&theReply);
 | 
							return err;
 | 
				
			||||||
    return err;
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Send event and check for any Apple Event Manager errors
 | 
				
			||||||
 | 
						err = AESendMessage(&evt, &res, kAEWaitReply, kAEDefaultTimeout);
 | 
				
			||||||
 | 
						AEDisposeDesc(&evt);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							NSLog(@"AESendMessage failed: %d\n", err);
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Check for any application errors
 | 
				
			||||||
 | 
						err = AEGetParamDesc(&res, keyErrorNumber, typeSInt32, &desc);
 | 
				
			||||||
 | 
						AEDisposeDesc(&res);
 | 
				
			||||||
 | 
						if (!err) {
 | 
				
			||||||
 | 
							AEGetDescData(&desc, &err, sizeof(err));
 | 
				
			||||||
 | 
							NSLog(@"Terminal returned an error: %d", err);
 | 
				
			||||||
 | 
							AEDisposeDesc(&desc);
 | 
				
			||||||
 | 
						} else if (err == errAEDescNotFound) {
 | 
				
			||||||
 | 
							err = noErr;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							NSLog(@"AEGetPArmDesc returned an error: %d", err);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue