1

I am having endless problems checking to see if the screen saver is running. If I use an NSTask with ps, it crashes or hangs on a lot of users. If I use notifications it seems to be spotty for others.

Any ideas as to why this NSTask is flakey? (Yes, I know it's messy for now as I debug)

  -(BOOL)checkScreenSaverRunning
{
    MYLog(@"Building task to check screen saver running");
    BOOL foundSaver=FALSE;

    NSTask *task;
    int i;
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/ps"];

    NSArray *arguments;
    arguments = [NSArray arrayWithObjects:  @"-ax", nil];
    [task setArguments: arguments];

    NSPipe *stdpipe;
    stdpipe = [NSPipe pipe];
    [task setStandardOutput: stdpipe];
    NSFileHandle *stdfile;
    stdfile = [stdpipe fileHandleForReading];
    MYLog(@"Launching task to check screen saver running");
    [task launch];

    while ([task isRunning]){
        NSData *stddata;
        stddata = [stdfile readDataToEndOfFile];
        if([stddata length]>0){
            NSString *stdstring = [[NSString alloc] initWithData:stddata
                                            encoding:NSUTF8StringEncoding];
            NSArray *stdReturnValues=[stdstring componentsSeparatedByString:@"\n"];

            for(i=0;i<[stdReturnValues count];i++){

                if([[stdReturnValues objectAtIndex:i]
                     rangeOfString:@"ScreenSaverEngine"].location != NSNotFound){
                    foundSaver=TRUE;
                    MYLog(@"Found screensaver in running processes");
                }
            }
            [stdstring release];
            stdstring=nil;
        }
    }
    MYLog(@"Task ended");
    [task release];
    if(foundSaver)screenSaverIsActive=TRUE;
    else screenSaverIsActive=FALSE;
    return(foundSaver);
}
NSGod
  • 22,699
  • 3
  • 58
  • 66
JeremyLaurenson
  • 979
  • 2
  • 11
  • 23
  • Why are you trying to check for a screensaver process? Wouldn't you be better checking if the screen is locked? http://stackoverflow.com/questions/11505255/osx-check-if-the-screen-is-locked – Anya Shenanigans Jan 28 '13 at 23:38
  • What do you mean by "using notifications"? – NSGod Jan 29 '13 at 01:09
  • Using system wide notifications such as com.apple.screensaverstarted. Petesh, I will certainly take a look at the other api – JeremyLaurenson Jan 29 '13 at 01:18

1 Answers1

1

What is your higher-level purpose for wanting to know if the screen saver is running? There may be a better way to accomplish that.

If you're trying to diagnose a crash or a hang, show the crash or hang report.

Anyway, if you're going to spawn a subprocess for this, you should probably use killall -0 ScreenSaverEngine instead of ps. killall will find a process by name for you. Using the signal 0 (-0) means "just test for process existence, don't actually signal it". Do [task setStandardError:[NSFileHandle fileHandleWithNullDevice]] to make sure its output goes nowhere. You determine if the process existed by examining the success or failure status of the task after it terminates.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154