mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
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:
parent
95707c1157
commit
3d5fdd69f4
3 changed files with 55 additions and 95 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
110
Tools/gdnc.m
110
Tools/gdnc.m
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue