On Dec 16, 12:55 am, Peter Hosey <[email protected]> wrote:
> On Dec 15, 2009, at 12:41:32, MyztikJenz wrote:
>
> > The call to ProcessInformationCopyDictionary() in isGrowlRunning is
> > not checked for a null return, which causes a crash in the
> > subsequent CFDictionaryGetValue() if the PSN is no longer valid.
>
> Your fix suffers from the same problem: When it continues, the loop
> condition will pass this no-longer-valid PSN to GetNextProcess. The
> documentation doesn't define what will happen; one of the better cases
> is that GetNextProcess will return procNotFound, which is the loop's
> termination condition. Thus, the loop will exit before it finds the
> GHA process (if there is one). A worse possibility is that it could
> crash.
>
> The only true fix I can see is to try the loop repeatedly until we
> either find a GHA process or reach the end of the process list.
Hmm, interesting point. The documentation really doesn't say what will
happen with a now-invalid psn but does make reference that the order
of the list is "internal to the Process Manager". I'm thinking the
Process Manager is smart enough to know that the PSN was valid at one
point and its internal list knows how to continue. Running a few
simple tests of killing an application in the middle of the loop seems
to work just fine.
My test was to launch Console.app, set the variable ConsolePID to its
pid and run the following program, quitting Console.app once it was
found in the list.
/* gcc -o GNPTest -ObjC -framework Foundation -framework Carbon
GNPTest.m */
#import <Foundation/Foundation.h>
#import <Carbon/Carbon.h>
int main( int argc, char *argv[] )
{
ProcessSerialNumber PSN = { kNoProcess, kNoProcess };
pid_t pid;
pid_t ConsolePID = 69416;
while (GetNextProcess(&PSN) == noErr)
{
GetProcessPID( &PSN, &pid );
if( pid == ConsolePID )
{
NSLog( @"Console PID found: %d", pid );
sleep( 10 );
}
CFDictionaryRef infoDict =
ProcessInformationCopyDictionary(&PSN,
kProcessDictionaryIncludeAllInformationMask);
if( !infoDict )
continue;
CFStringRef bundleId = CFDictionaryGetValue(infoDict,
kCFBundleIdentifierKey);
NSLog( @"bundleId: %@", (NSString *)bundleId );
CFRelease( infoDict );
}
return( 0 );
}
--
You received this message because you are subscribed to the Google Groups
"Growl Discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/growldiscuss?hl=en.