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,5 +1,11 @@
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>
* Source/NSFileManager.m: Restructure last patch to conform to
gnustep coding standards.
(localFromOpenStepPath:) for unix paths, expand '~' abbreviations.

View file

@ -1069,7 +1069,7 @@ quotedFromString(NSString *aString)
NSString *arg;
NSEnumerator *arg_enum;
NSMutableString *args;
wchar_t *w_args;
wchar_t *w_args;
int result;
const wchar_t *wexecutable;
@ -1082,7 +1082,8 @@ quotedFromString(NSString *aString)
wexecutable = [[lpath localFromOpenStepPath] unicharString];
args = [[NSMutableString alloc] initWithString:
quotedFromString([NSString stringWithCharacters:wexecutable length:wcslen(wexecutable)])];
quotedFromString([NSString stringWithCharacters: wexecutable
length: wcslen(wexecutable)])];
arg_enum = [[self arguments] objectEnumerator];
while ((arg = [arg_enum nextObject]))
{
@ -1090,7 +1091,8 @@ quotedFromString(NSString *aString)
[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];
memset (&start_info, 0, sizeof(start_info));
@ -1101,15 +1103,15 @@ quotedFromString(NSString *aString)
start_info.hStdError = [[self standardError] nativeHandle];
result = CreateProcessW(wexecutable,
w_args,
NULL, /* proc attrs */
NULL, /* thread attrs */
1, /* inherit handles */
0, /* creation flags */
NULL, /* env block */
[[[self currentDirectoryPath] localFromOpenStepPath] unicharString],
&start_info,
&procInfo);
w_args,
NULL, /* proc attrs */
NULL, /* thread attrs */
1, /* inherit handles */
0, /* creation flags */
NULL, /* env block */
[[[self currentDirectoryPath] localFromOpenStepPath] unicharString],
&start_info,
&procInfo);
NSZoneFree(NSDefaultMallocZone(), w_args);
if (result == 0)
{
@ -1124,9 +1126,9 @@ quotedFromString(NSString *aString)
[tasksLock lock];
NSMapInsert(activeTasks, (void*)_taskId, (void*)self);
[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);
}

View file

@ -996,107 +996,57 @@ ihandler(int sig)
int
main(int argc, char** argv, char** env)
{
int c;
GDNCServer *server;
NSString *str;
BOOL shouldFork = YES;
BOOL subtask = YES;
BOOL debugging = NO;
NSProcessInfo *pInfo;
CREATE_AUTORELEASE_POOL(pool);
#ifdef GS_PASS_ARGUMENTS
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
[NSProcessInfo initializeWithArguments: argv count: argc environment: env];
#endif
[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 (str != nil && [str caseInsensitiveCompare: @"yes"] == NSOrderedSame)
if ([[NSUserDefaults standardUserDefaults] boolForKey: @"debug"] == YES)
{
shouldFork = NO;
subtask = NO;
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*));
a[argc] = "-f";
a[argc+1] = 0;
#ifdef __MINGW__
if (_spawnv(_P_NOWAIT, argv[0], a) == -1)
t = [NSTask new];
NS_DURING
{
fprintf(stderr, "gdnc - spawn failed - bye.\n");
exit(EXIT_FAILURE);
args = [[pInfo arguments] mutableCopy];
[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);
#else
is_daemon = 1;
switch (fork())
NS_HANDLER
{
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);
exit(EXIT_FAILURE);
DESTROY(t);
}
if (open("/dev/null", O_WRONLY) != 1)
{
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);
NS_ENDHANDLER
exit(EXIT_FAILURE);
#endif /* !MINGW */
}
RELEASE(pool);
{
#if GS_WITH_GC == 0
@ -1138,6 +1088,8 @@ main(int argc, char** argv, char** env)
}
#endif
is_daemon = YES;
RELEASE(pool);
}