mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-16 00:21:01 +00:00
209 lines
5.7 KiB
Objective-C
209 lines
5.7 KiB
Objective-C
|
|
/** Enterprise Control Configuration and Logging
|
|
|
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
|
|
|
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
|
Date: Febrary 2010
|
|
Originally developed from 1996 to 2012 by Brainstorm, and donated to
|
|
the FSF.
|
|
|
|
This file is part of the GNUstep project.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 3 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02111 USA.
|
|
|
|
*/
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import "EcProcess.h"
|
|
|
|
#if !defined(EC_BASE_CLASS)
|
|
#define EC_BASE_CLASS EcCommand
|
|
#endif
|
|
|
|
/* Create a fake interface to satisfy compiler ...
|
|
*/
|
|
@interface EC_BASE_CLASS : EcProcess
|
|
@end
|
|
|
|
void
|
|
inner_main()
|
|
{
|
|
NSAutoreleasePool *arp;
|
|
NSDictionary *defs;
|
|
int status;
|
|
|
|
arp = [NSAutoreleasePool new];
|
|
|
|
cmdVersion(@"$Date: 2012-02-13 08:11:49 +0000 (Mon, 13 Feb 2012) $ $Revision: 65934 $");
|
|
|
|
defs = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"Command", @"HomeDirectory",
|
|
@"YES", @"Daemon",
|
|
#if defined(EC_REGISTRATION_DOMAIN)
|
|
EC_REGISTRATION_DOMAIN
|
|
#endif
|
|
nil];
|
|
|
|
if (nil == [[EC_BASE_CLASS alloc] initWithDefaults: defs])
|
|
{
|
|
NSLog(@"Unable to create command object.");
|
|
exit(1);
|
|
}
|
|
|
|
[EcProc ecRun];
|
|
|
|
status = [EcProc ecQuitStatus];
|
|
|
|
[arp release];
|
|
|
|
exit(status);
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
NSProcessInfo *pInfo;
|
|
NSArray *pArgs;
|
|
NSString *pName;
|
|
CREATE_AUTORELEASE_POOL(pool);
|
|
|
|
pInfo = [NSProcessInfo processInfo];
|
|
pArgs = [pInfo arguments];
|
|
pName = [pInfo processName];
|
|
|
|
if ([pArgs containsObject: @"--Watched"] == NO)
|
|
{
|
|
NSMutableArray *args = AUTORELEASE([pArgs mutableCopy]);
|
|
NSString *path = [[NSBundle mainBundle] executablePath];
|
|
NSEnumerator *dbg;
|
|
NSString *key;
|
|
NSAutoreleasePool *inner = nil;
|
|
BOOL done = NO;
|
|
int status = 0;
|
|
NSFileHandle *null;
|
|
NSTask *t;
|
|
|
|
[args removeObjectAtIndex: 0];
|
|
|
|
/* Pass debug settings to child
|
|
* qdddd
|
|
* q
|
|
*/
|
|
dbg = [[[NSProcessInfo processInfo] debugSet] objectEnumerator];
|
|
while (nil != (key = [dbg nextObject]))
|
|
{
|
|
NSString *arg = [@"--GNU-Debug=" stringByAppendingString: key];
|
|
|
|
[args addObject: arg];
|
|
}
|
|
|
|
if ([pArgs containsObject: @"--Watcher"] == NO)
|
|
{
|
|
/* In the top level task ... set flags to create a subtask
|
|
* to act as a watcher for other tasks, and once that has
|
|
* been created, exit to leave it running as a daemon.
|
|
*/
|
|
[args addObject: @"--Watcher"];
|
|
t = [NSTask new];
|
|
NS_DURING
|
|
{
|
|
[t setLaunchPath: path];
|
|
[t setArguments: args];
|
|
[t setEnvironment: [pInfo environment]];
|
|
null = [NSFileHandle fileHandleWithNullDevice];
|
|
[t setStandardInput: null];
|
|
[t setStandardOutput: null];
|
|
[t setStandardError: null];
|
|
[t launch];
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
NSLog(@"Problem creating %@ subprocess: %@",
|
|
pName, localException);
|
|
exit(1);
|
|
}
|
|
NS_ENDHANDLER
|
|
[t release];
|
|
exit(0);
|
|
}
|
|
|
|
/* This is the watcher ... its subtasks are those which are watched.
|
|
*/
|
|
|
|
/* Set args to tell subtask task not to make itself a daemon
|
|
*/
|
|
[args addObject: @"-Daemon"];
|
|
[args addObject: @"NO"];
|
|
|
|
/* Set args to tell task it is being watched.
|
|
*/
|
|
[args removeObject: @"--Watcher"];
|
|
[args addObject: @"--Watched"];
|
|
|
|
while (NO == done)
|
|
{
|
|
DESTROY(inner);
|
|
inner = [NSAutoreleasePool new];
|
|
t = [[NSTask new] autorelease];
|
|
NS_DURING
|
|
{
|
|
[t setLaunchPath: path];
|
|
[t setArguments: args];
|
|
[t setEnvironment: [pInfo environment]];
|
|
null = [NSFileHandle fileHandleWithNullDevice];
|
|
[t setStandardInput: null];
|
|
[t setStandardOutput: null];
|
|
[t setStandardError: null];
|
|
[t launch];
|
|
[t waitUntilExit];
|
|
if (0 == [t terminationStatus])
|
|
{
|
|
done = YES;
|
|
}
|
|
else if (255 == ([t terminationStatus] & 255))
|
|
{
|
|
/* A 'restart' uses this termination status ... try
|
|
* to do it promptly.
|
|
*/
|
|
[NSThread sleepForTimeInterval: 0.5];
|
|
}
|
|
else
|
|
{
|
|
/* Subprocess died ... try to restart after 30 seconds
|
|
*/
|
|
[NSThread sleepForTimeInterval: 30.0];
|
|
}
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
done = YES;
|
|
status = 1;
|
|
NSLog(@"Problem creating %@ subprocess: %@",
|
|
pName, localException);
|
|
}
|
|
NS_ENDHANDLER
|
|
}
|
|
DESTROY(inner);
|
|
DESTROY(pool);
|
|
exit(status);
|
|
}
|
|
DESTROY(pool);
|
|
|
|
inner_main();
|
|
return 0;
|
|
}
|