[launchd-dev] ~/LaunchAgent + KeepAlive=true = Login Jail
James Bucanek
subscriber at gloaming.com
Thu Jan 31 10:17:30 PST 2008
Quinn <mailto:eskimo1 at apple.com> wrote (Tuesday, January 29,
2008 3:45 AM -0000):
>A better solution is to look at the kAEWhyAmIBeingLoggedOutAttr
>('why?') attribute of the kAEQuitApplication ('quit') Apple event. If
>you're being quit by loginwindow, this will contain one of four
>different codes indicating why (kAEQuitAll, kAEShutDown, kAERestart,
>kAEReallyLogOut). If you're being quit by the user (or by an
>AppleScript or any other 'quit' Apple event mechanism), this attribute
>won't be present.
Thanks, Quinn. That's a excellent solution.
I did, indeed, search the documentation, developer.apple.com,
and the various lists for any mention of determining if a Quit
event was being sent because of a shutdown, restart, or logout.
So this isn't just undocumented, it's below the radar.
Inside Apple, you're probably using header files we don't have. ;)
grepping of all of the 10.4 & 10.5 SDK header files, I can't
find any declaration for kAEWhyAmIBeingLoggedOutAttr. However,
there is a declaration for kEventParamReason = 'why?' in
CarbonEvents.h. That's good enough for me.
So I think I have this working nicely now. I added the
SuccessfulExit=false to the KeepAlive property and added the
following code to my Cocoa application
static void dirtyExit( void )
{
// At the very last moment possible, force an abnormal exit
_exit(2);
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
{
#pragma unused(sender)
// Find out if the application is quitting for a Log Out,
Shutdown, or Restart
// This has to be detemined in applicationShouldTerminate:
becuase the AppleEvent goes away soon.
NSAppleEventDescriptor* quitEventDesc =
[[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
// NSLog(@"%p%s %@",self,__func__,quitEventDesc);
NSAppleEventDescriptor* whyDesc = [quitEventDesc attributeDescriptorForKeyword:kEventParamReason];
OSType why = [whyDesc typeCodeValue];
if ( !(why==kAEQuitAll || why==kAEShutDown ||
why==kAERestart || why==kAEReallyLogOut) )
{
//NSLog(@"application will exit abnormally");
// If the monitor is not exiting cleanly, register a
program exit handler that will throw an error following normal termination
atexit(dirtyExit);
}
return (YES);
}
Thanks again. I'll file a bug report on the documentation.
James
--
James Bucanek
More information about the launchd-dev
mailing list