Try to fix windows bug by using NSTask to create daemon.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@20670 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2005-02-08 10:11:18 +00:00
parent 95707c1157
commit 3d5fdd69f4
3 changed files with 55 additions and 95 deletions

View file

@ -1,3 +1,9 @@
2005-02-08 10:10 Richard Frith-Macdonald <rfm@gnu.org>
* Tools/gdnc.m: Rewrite startup code to create a daemon using NSTask
rather than calling fork()/spawn() etc.
* Source/NSTask.m: Minor code layout/indentation tweaks.
2005-02-02 09:40 Richard Frith-Macdonald <rfm@gnu.org> 2005-02-02 09:40 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSFileManager.m: Restructure last patch to conform to * Source/NSFileManager.m: Restructure last patch to conform to

View file

@ -1069,7 +1069,7 @@ quotedFromString(NSString *aString)
NSString *arg; NSString *arg;
NSEnumerator *arg_enum; NSEnumerator *arg_enum;
NSMutableString *args; NSMutableString *args;
wchar_t *w_args; wchar_t *w_args;
int result; int result;
const wchar_t *wexecutable; const wchar_t *wexecutable;
@ -1082,7 +1082,8 @@ quotedFromString(NSString *aString)
wexecutable = [[lpath localFromOpenStepPath] unicharString]; wexecutable = [[lpath localFromOpenStepPath] unicharString];
args = [[NSMutableString alloc] initWithString: args = [[NSMutableString alloc] initWithString:
quotedFromString([NSString stringWithCharacters:wexecutable length:wcslen(wexecutable)])]; quotedFromString([NSString stringWithCharacters: wexecutable
length: wcslen(wexecutable)])];
arg_enum = [[self arguments] objectEnumerator]; arg_enum = [[self arguments] objectEnumerator];
while ((arg = [arg_enum nextObject])) while ((arg = [arg_enum nextObject]))
{ {
@ -1090,7 +1091,8 @@ quotedFromString(NSString *aString)
[args appendString: quotedFromString(arg)]; [args appendString: quotedFromString(arg)];
} }
w_args = NSZoneMalloc(NSDefaultMallocZone(),sizeof(wchar_t) *([args length]+1)); w_args = NSZoneMalloc(NSDefaultMallocZone(),
sizeof(wchar_t) * ([args length] + 1));
[args getCharacters: (unichar*)w_args]; [args getCharacters: (unichar*)w_args];
memset (&start_info, 0, sizeof(start_info)); memset (&start_info, 0, sizeof(start_info));
@ -1101,15 +1103,15 @@ quotedFromString(NSString *aString)
start_info.hStdError = [[self standardError] nativeHandle]; start_info.hStdError = [[self standardError] nativeHandle];
result = CreateProcessW(wexecutable, result = CreateProcessW(wexecutable,
w_args, w_args,
NULL, /* proc attrs */ NULL, /* proc attrs */
NULL, /* thread attrs */ NULL, /* thread attrs */
1, /* inherit handles */ 1, /* inherit handles */
0, /* creation flags */ 0, /* creation flags */
NULL, /* env block */ NULL, /* env block */
[[[self currentDirectoryPath] localFromOpenStepPath] unicharString], [[[self currentDirectoryPath] localFromOpenStepPath] unicharString],
&start_info, &start_info,
&procInfo); &procInfo);
NSZoneFree(NSDefaultMallocZone(), w_args); NSZoneFree(NSDefaultMallocZone(), w_args);
if (result == 0) if (result == 0)
{ {
@ -1124,9 +1126,9 @@ quotedFromString(NSString *aString)
[tasksLock lock]; [tasksLock lock];
NSMapInsert(activeTasks, (void*)_taskId, (void*)self); NSMapInsert(activeTasks, (void*)_taskId, (void*)self);
[tasksLock unlock]; [tasksLock unlock];
/* /*
* Create thread to watch for termination of process. * Create thread to watch for termination of process.
*/ */
wThread = CreateThread(NULL, 0, _threadFunction, (LPVOID)self, 0, &tid); wThread = CreateThread(NULL, 0, _threadFunction, (LPVOID)self, 0, &tid);
} }

View file

@ -996,107 +996,57 @@ ihandler(int sig)
int int
main(int argc, char** argv, char** env) main(int argc, char** argv, char** env)
{ {
int c;
GDNCServer *server; GDNCServer *server;
NSString *str; BOOL subtask = YES;
BOOL shouldFork = YES;
BOOL debugging = NO; BOOL debugging = NO;
NSProcessInfo *pInfo;
CREATE_AUTORELEASE_POOL(pool); CREATE_AUTORELEASE_POOL(pool);
#ifdef GS_PASS_ARGUMENTS #ifdef GS_PASS_ARGUMENTS
[NSProcessInfo initializeWithArguments:argv count:argc environment:env]; [NSProcessInfo initializeWithArguments: argv count: argc environment: env];
#endif #endif
[NSObject enableDoubleReleaseCheck: YES]; [NSObject enableDoubleReleaseCheck: YES];
if (argc > 1 && strcmp(argv[argc-1], "-f") == 0) pInfo = [NSProcessInfo processInfo];
if ([[pInfo arguments] containsObject: @"-f"] == YES)
{ {
shouldFork = NO; subtask = NO;
} }
str = [[NSUserDefaults standardUserDefaults] stringForKey: @"debug"]; if ([[NSUserDefaults standardUserDefaults] boolForKey: @"debug"] == YES)
if (str != nil && [str caseInsensitiveCompare: @"yes"] == NSOrderedSame)
{ {
shouldFork = NO; subtask = NO;
debugging = YES; debugging = YES;
} }
RELEASE(pool);
if (shouldFork) if (subtask)
{ {
char **a = malloc((argc+2) * sizeof(char*)); NSFileHandle *null;
NSMutableArray *args;
NSTask *t;
memcpy(a, argv, argc*sizeof(char*)); t = [NSTask new];
a[argc] = "-f"; NS_DURING
a[argc+1] = 0;
#ifdef __MINGW__
if (_spawnv(_P_NOWAIT, argv[0], a) == -1)
{ {
fprintf(stderr, "gdnc - spawn failed - bye.\n"); args = [[pInfo arguments] mutableCopy];
exit(EXIT_FAILURE); [args addObject: @"-f"];
[t setLaunchPath: [[NSBundle mainBundle] executablePath]];
[t setArguments: args];
[t setEnvironment: [pInfo environment]];
null = [NSFileHandle fileHandleWithNullDevice];
[t setStandardInput: null];
[t setStandardOutput: null];
[t setStandardError: null];
[t launch];
DESTROY(t);
} }
exit(EXIT_SUCCESS); NS_HANDLER
#else
is_daemon = 1;
switch (fork())
{ {
case -1:
fprintf(stderr, "gdnc - fork failed - bye.\n");
exit(EXIT_FAILURE);
case 0:
/*
* Try to run in background.
*/
#ifdef NeXT
setpgrp(0, getpid());
#else
setsid();
#endif
break;
default:
exit(EXIT_SUCCESS);
}
/*
* Ensure we don't have any open file descriptors which may refer
* to sockets bound to ports we may try to use.
*
* Use '/dev/null' for stdin and stdout.
*/
for (c = 0; c < FD_SETSIZE; c++)
{
if (is_daemon || (c != 2))
{
(void)close(c);
}
}
if (open("/dev/null", O_RDONLY) != 0)
{
sprintf(ebuf, "failed to open stdin from /dev/null (%s)\n",
strerror(errno));
gdnc_log(LOG_CRIT); gdnc_log(LOG_CRIT);
exit(EXIT_FAILURE); DESTROY(t);
} }
if (open("/dev/null", O_WRONLY) != 1) NS_ENDHANDLER
{
sprintf(ebuf, "failed to open stdout from /dev/null (%s)\n",
strerror(errno));
gdnc_log(LOG_CRIT);
exit(EXIT_FAILURE);
}
if (is_daemon && open("/dev/null", O_WRONLY) != 2)
{
sprintf(ebuf, "failed to open stderr from /dev/null (%s)\n",
strerror(errno));
gdnc_log(LOG_CRIT);
exit(EXIT_FAILURE);
}
execve([[[NSBundle mainBundle] executablePath] cString], a, env);
sprintf(ebuf, "failed to exec to '%s' (%s)\n",
argv[0], strerror(errno));
gdnc_log(LOG_CRIT);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
#endif /* !MINGW */
} }
RELEASE(pool);
{ {
#if GS_WITH_GC == 0 #if GS_WITH_GC == 0
@ -1138,6 +1088,8 @@ main(int argc, char** argv, char** env)
} }
#endif #endif
is_daemon = YES;
RELEASE(pool); RELEASE(pool);
} }