diff --git a/ChangeLog b/ChangeLog index 2f13976c2..f247f94af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ +2005-02-08 10:10 Richard Frith-Macdonald + + * 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 - + * Source/NSFileManager.m: Restructure last patch to conform to gnustep coding standards. (localFromOpenStepPath:) for unix paths, expand '~' abbreviations. diff --git a/Source/NSTask.m b/Source/NSTask.m index b575c9e25..ceedee77e 100644 --- a/Source/NSTask.m +++ b/Source/NSTask.m @@ -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); } diff --git a/Tools/gdnc.m b/Tools/gdnc.m index 5973ac2f8..e4076c7e4 100644 --- a/Tools/gdnc.m +++ b/Tools/gdnc.m @@ -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); }