Port to MinGW

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@7524 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 2000-09-15 22:06:01 +00:00
parent 9c6703537a
commit 44d1336beb
10 changed files with 377 additions and 150 deletions

View file

@ -1,3 +1,20 @@
2000-09-15 Adam Fedor <fedor@gnu.org>
* configure.in: Turn off enable_fake_main if on MinGW.
* Source/WindowsFileHandle.m: New class.
* Source/NSFileHandle.m: Use it on MinGW
* Source/NSTask.m: Break into concrete subclasses for
Unix and Windows.
* Source/NSProcessInfo.m: on MinGW, don't try to redefine
__argv, __argc, etc.
* Source/libgnustep_base_entry.m: Renamed from win32-entry.m
* Tools/gdnc.m: Don't fork on MinGW
* Tools/gdomap.c: Define MINGW ifdef MINGW32.
2000-09-15 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSXML.m: made method names more consistent.

View file

@ -27,7 +27,11 @@
#include <Foundation/NSData.h>
#include <Foundation/NSString.h>
#include <Foundation/NSFileHandle.h>
#ifdef __MINGW__
#include <Foundation/WindowsFileHandle.h>
#else
#include <Foundation/UnixFileHandle.h>
#endif
static Class NSFileHandle_abstract_class = nil;
static Class NSFileHandle_concrete_class = nil;
@ -39,7 +43,11 @@ static Class NSFileHandle_concrete_class = nil;
if (self == [NSFileHandle class])
{
NSFileHandle_abstract_class = self;
#ifdef __MINGW__
NSFileHandle_concrete_class = [WindowsFileHandle class];
#else
NSFileHandle_concrete_class = [UnixFileHandle class];
#endif
}
}

View file

@ -478,11 +478,7 @@ _gnu_noobjc_free_vars(void)
#else /* !HAVE_PROC_FS || !HAVE_LOAD_METHOD */
#ifdef __MINGW__
/* For WindowsAPI Library, we know the global variables */
extern int __argc;
extern char** __argv;
extern char** _environ;
/* For WindowsAPI Library, we know the global variables (argc, etc) */
+ (void) initialize
{
if (self == [NSProcessInfo class])

View file

@ -42,10 +42,16 @@
#include <string.h>
#include <unistd.h>
#include <sys/signal.h>
#include <sys/types.h>
#ifndef __MINGW__
#include <sys/signal.h>
#include <sys/param.h>
#include <sys/wait.h>
#endif
#if HAVE_WINDOWS_H
# include <windows.h>
#endif
/*
* If we don't have NFILE, default to 256 open descriptors.
@ -59,55 +65,45 @@ NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
static NSRecursiveLock *tasksLock = nil;
static NSMapTable *activeTasks = 0;
@interface NSTask (Private)
- (void) _collectChild;
- (void) _sendNotification;
- (void) _terminatedChild: (int)status;
@end
@implementation NSTask
static BOOL hadChildSignal = NO;
static void handleSignal(int sig)
{
hadChildSignal = YES;
}
BOOL
GSCheckTasks()
#ifdef __MINGW__
@interface NSConcreteWindowsTask : NSTask
{
BOOL found = NO;
PROCESS_INFORMATION proc_info;
}
@end
#define NSConcreteTask NSConcreteWindowsTask
#else
@interface NSConcreteUnixTask : NSTask
{
}
@end
#define NSConcreteTask NSConcreteUnixTask
#endif
if (hadChildSignal)
{
int result;
int status;
@interface NSTask (Private)
- (NSString *) _fullLaunchPath;
- (void) _sendNotification;
- (void) _collectChild;
- (void) _terminatedChild: (int)status;
@end
hadChildSignal = NO;
do
{
result = waitpid(-1, &status, WNOHANG);
if (result > 0)
{
if (WIFEXITED(status))
{
NSTask *t;
@implementation NSTask
[tasksLock lock];
t = (NSTask*)NSMapGet(activeTasks, (void*)result);
[tasksLock unlock];
if (t)
{
[t _terminatedChild: WEXITSTATUS(status)];
found = YES;
}
}
}
}
while (result > 0);
}
return found;
+ (id)allocWithZone:(NSZone*)zone
{
NSTask *task;
if (self == [NSTask class])
task = (NSTask *)NSAllocateObject([NSConcreteTask class], 0, zone);
else
task = (NSTask *)NSAllocateObject(self, 0, zone);
return task;
}
+ (void) initialize
@ -123,7 +119,9 @@ GSCheckTasks()
}
[gnustep_global_lock unlock];
#ifndef __MINGW__
signal(SIGCHLD, handleSignal);
#endif
}
}
@ -354,16 +352,63 @@ GSCheckTasks()
return;
}
#ifndef __MINGW__
#ifdef HAVE_KILLPG
killpg(_taskId, SIGINT);
#else
kill(-_taskId, SIGINT);
#endif
#endif
}
- (void) launch
{
NSMutableArray *toClose;
[self subclassResponsibility: _cmd];
}
- (void) terminate
{
if (_hasLaunched == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
if (_hasTerminated)
{
return;
}
_hasTerminated = YES;
#ifndef __MINGW__
#ifdef HAVE_KILLPG
killpg(_taskId, SIGTERM);
#else
kill(-_taskId, SIGTERM);
#endif
#endif
}
- (void) waitUntilExit
{
while ([self isRunning])
{
NSDate *limit;
/*
* Poll at 0.1 second intervals.
*/
limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
beforeDate: limit];
RELEASE(limit);
}
}
@end
@implementation NSTask (Private)
- (NSString *) _fullLaunchPath
{
NSFileManager *mgr = [NSFileManager defaultManager];
NSString *libs = [NSBundle _library_combo];
NSString *arch = [NSBundle _gnustep_target_dir];
@ -372,26 +417,6 @@ GSCheckTasks()
NSString *base_path;
NSString *arch_path;
NSString *full_path;
int pid;
const char *executable;
const char *path;
int idesc;
int odesc;
int edesc;
NSDictionary *e = [self environment];
NSArray *k = [e allKeys];
NSArray *a = [self arguments];
int ec = [e count];
int ac = [a count];
const char *args[ac+2];
const char *envl[ec+1];
id hdl;
int i;
if (_hasLaunched)
{
return;
}
if (_launchPath == nil)
{
@ -453,6 +478,245 @@ GSCheckTasks()
}
lpath = [lpath stringByStandardizingPath];
return lpath;
}
- (void) _sendNotification
{
if (_hasNotified == NO)
{
NSNotification *n;
_hasNotified = YES;
n = [NSNotification notificationWithName: NSTaskDidTerminateNotification
object: self
userInfo: nil];
[[NSNotificationQueue defaultQueue] enqueueNotification: n
postingStyle: NSPostASAP
coalesceMask: NSNotificationNoCoalescing
forModes: nil];
}
}
- (void) _collectChild
{
[self subclassResponsibility: _cmd];
}
- (void) _terminatedChild: (int)status
{
[tasksLock lock];
NSMapRemove(activeTasks, (void*)_taskId);
[tasksLock unlock];
_terminationStatus = status;
_hasCollected = YES;
_hasTerminated = YES;
if (_hasNotified == NO)
{
[self _sendNotification];
}
}
@end
#ifdef __MINGW__
@implementation NSConcreteWindowsTask
BOOL
GSCheckTasks()
{
/* FIXME: Implement */
return YES;
}
- (void) gcFinalize
{
[super gcFinalize];
if (proc_info.hProcess != NULL)
CloseHandle(proc_info.hProcess);
if (proc_info.hThread != NULL)
CloseHandle(proc_info.hThread);
}
- (void) interrupt
{
}
- (void) terminate
{
if (_hasLaunched == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
if (_hasTerminated)
{
return;
}
_hasTerminated = YES;
TerminateProcess(proc_info.hProcess, 10);
}
- (void) launch
{
STARTUPINFO start_info;
NSString *lpath;
NSString *arg;
NSEnumerator *arg_enum;
NSMutableString *args;
char *c_args;
int result;
if (_hasLaunched)
{
return;
}
lpath = [self _fullLaunchPath];
args = [lpath mutableCopy];
arg_enum = [[self arguments] objectEnumerator];
while ((arg = [arg_enum nextObject]))
{
[args appendString: @" "];
[args appendString: arg];
}
c_args = objc_malloc([args cStringLength]+1);
[args getCString: c_args];
memset (&start_info, 0, sizeof(start_info));
start_info.cb = sizeof(start_info);
start_info.dwFlags |= STARTF_USESTDHANDLES;
start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
start_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
result = CreateProcess([lpath cString],
c_args,
NULL, /* proc attrs */
NULL, /* thread attrs */
1, /* inherit handles */
0, /* creation flags */
NULL, /* env block */
[[self currentDirectoryPath] cString],
&start_info,
&proc_info);
objc_free(c_args);
if (result == 0)
{
NSLog(@"Error launching task: %@", lpath);
return;
}
_taskId = proc_info.dwProcessId;
_hasLaunched = YES;
ASSIGN(_launchPath, lpath); // Actual path used.
[tasksLock lock];
NSMapInsert(activeTasks, (void*)_taskId, (void*)self);
[tasksLock unlock];
}
- (void) _collectChild
{
if (_hasCollected == NO)
{
/* FIXME: Implement */
}
}
- (int) terminationStatus
{
DWORD exit_code;
int result;
[super terminationStatus];
result = GetExitCodeProcess(proc_info.hProcess, &exit_code);
_terminationStatus = exit_code;
if (result == 0)
{
NSLog(@"Error getting exit code");
return -1;
}
return exit_code;
}
- (void) waitUntilExit
{
DWORD result;
result = WaitForSingleObject(proc_info.hProcess, INFINITE);
}
@end
#else /* !MINGW */
@implementation NSConcreteUnixTask
BOOL
GSCheckTasks()
{
BOOL found = NO;
if (hadChildSignal)
{
int result;
int status;
hadChildSignal = NO;
do
{
result = waitpid(-1, &status, WNOHANG);
if (result > 0)
{
if (WIFEXITED(status))
{
NSTask *t;
[tasksLock lock];
t = (NSTask*)NSMapGet(activeTasks, (void*)result);
[tasksLock unlock];
if (t)
{
[t _terminatedChild: WEXITSTATUS(status)];
found = YES;
}
}
}
}
while (result > 0);
}
return found;
}
- (void) launch
{
NSMutableArray *toClose;
NSString *lpath;
int pid;
const char *executable;
const char *path;
int idesc;
int odesc;
int edesc;
NSDictionary *e = [self environment];
NSArray *k = [e allKeys];
NSArray *a = [self arguments];
int ec = [e count];
int ac = [a count];
const char *args[ac+2];
const char *envl[ec+1];
id hdl;
int i;
if (_hasLaunched)
{
return;
}
lpath = [self _fullLaunchPath];
executable = [lpath cString];
args[0] = executable;
@ -600,45 +864,6 @@ GSCheckTasks()
}
}
- (void) terminate
{
if (_hasLaunched == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"NSTask - task has not yet launched"];
}
if (_hasTerminated)
{
return;
}
_hasTerminated = YES;
#ifdef HAVE_KILLPG
killpg(_taskId, SIGTERM);
#else
kill(-_taskId, SIGTERM);
#endif
}
- (void) waitUntilExit
{
while ([self isRunning])
{
NSDate *limit;
/*
* Poll at 0.1 second intervals.
*/
limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 0.1];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
beforeDate: limit];
RELEASE(limit);
}
}
@end
@implementation NSTask (Private)
- (void) _collectChild
{
if (_hasCollected == NO)
@ -677,37 +902,5 @@ GSCheckTasks()
}
}
- (void) _sendNotification
{
if (_hasNotified == NO)
{
NSNotification *n;
_hasNotified = YES;
n = [NSNotification notificationWithName: NSTaskDidTerminateNotification
object: self
userInfo: nil];
[[NSNotificationQueue defaultQueue] enqueueNotification: n
postingStyle: NSPostASAP
coalesceMask: NSNotificationNoCoalescing
forModes: nil];
}
}
- (void) _terminatedChild: (int)status
{
[tasksLock lock];
NSMapRemove(activeTasks, (void*)_taskId);
[tasksLock unlock];
_terminationStatus = status;
_hasCollected = YES;
_hasTerminated = YES;
if (_hasNotified == NO)
{
[self _sendNotification];
}
}
@end
#endif /* !MINGW */

View file

@ -27,6 +27,7 @@
;
LIBRARY libgnustep-base
EXPORTS
__objc_class_name_GSBaseDefaultObserver
__objc_class_name_GSTcpHandle
__objc_class_name_GSTcpPort
__objc_class_name_NSArchiver
@ -56,7 +57,6 @@ __objc_class_name_NSConnection
__objc_class_name_NSCountedSet
__objc_class_name_NSData
__objc_class_name_NSDataMalloc
__objc_class_name_NSDataMappedFile
__objc_class_name_NSDataStatic
__objc_class_name_NSMutableData
__objc_class_name_NSMutableDataMalloc
@ -67,6 +67,8 @@ __objc_class_name_NSDate
__objc_class_name_NSGDate
__objc_class_name_NSDateFormatter
__objc_class_name_GSDebugAlloc
__objc_class_name_NSDecimalNumber
__objc_class_name_NSDecimalNumberHandler
__objc_class_name_NSDictionary
__objc_class_name_NSDictionaryNonCore
__objc_class_name_NSMutableDictionary
@ -126,6 +128,7 @@ __objc_class_name_NSUIntNumber
__objc_class_name_NSLongNumber
__objc_class_name_NSULongNumber
__objc_class_name_NSLongLongNumber
__objc_class_name_NSNumberFormatter
__objc_class_name_NSObject
__objc_class_name__FastMallocBuffer
__objc_class_name_NSPipe
@ -153,6 +156,7 @@ __objc_class_name_NSSet
__objc_class_name_NSSetNonCore
__objc_class_name_NSMutableString
__objc_class_name_NSString
__objc_class_name_NSConcreteWindowsTask
__objc_class_name_NSTask
__objc_class_name_NSThread
__objc_class_name_NSConcreteAbsoluteTimeZone
@ -178,4 +182,4 @@ __objc_class_name_NSPointValue
__objc_class_name_NSPointerValue
__objc_class_name_NSRectValue
__objc_class_name_NSSizeValue
__objc_class_name_UnixFileHandle
__objc_class_name_WindowsFileHandle

View file

@ -23,6 +23,8 @@
#include <config.h>
#include <base/preface.h>
#include <Foundation/NSObjCRuntime.h>
#include <Foundation/NSString.h>
/* Only if using Microsoft's tools and libraries */
#ifdef __MS_WIN32__
@ -40,11 +42,6 @@ int _MB_init_runtime()
}
#endif /* __MS_WIN32__ */
int gnustep_base_user_main(int argc, char *argv[], char *env[])
{
return 0;
}
LONG APIENTRY
gnustep_base_socket_handler(HWND hWnd, UINT message,
UINT wParam, LONG lParam);

View file

@ -764,7 +764,7 @@ main(int argc, char** argv, char** env)
shouldFork = NO;
}
RELEASE(pool);
#ifndef __MINGW__ /* Don't fork on Win32 */
if (shouldFork)
{
switch (fork())
@ -788,6 +788,7 @@ main(int argc, char** argv, char** env)
exit(0);
}
}
#endif /* !MINGW */
{
CREATE_AUTORELEASE_POOL(pool);

View file

@ -22,6 +22,11 @@
*/
/* Ported to mingw 07/12/00 by Björn Giesler <Bjoern.Giesler@gmx.de> */
#ifdef __MINGW32__
#ifndef __MINGW__
#define __MINGW__
#endif
#endif
#include <stdio.h>
#include <stdlib.h>

13
configure vendored
View file

@ -4314,6 +4314,9 @@ EOF
fi
fi
case "$target_os" in
mingw*) enable_fake_main=no; GS_FAKE_MAIN=0;;
esac
echo "$ac_t""$enable_fake_main" 1>&6
@ -4325,17 +4328,17 @@ for ac_hdr in libxml/xmlversion.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:4329: checking for $ac_hdr" >&5
echo "configure:4332: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 4334 "configure"
#line 4337 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4339: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4342: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@ -4368,7 +4371,7 @@ if test $ac_cv_header_libxml_xmlversion_h = no; then
HAVE_LIBXML=0
else
cat > conftest.$ac_ext <<EOF
#line 4372 "configure"
#line 4375 "configure"
#include "confdefs.h"
#include "libxml/xmlversion.h"
#if LIBXML_VERSION < 20000
@ -4376,7 +4379,7 @@ else
#endif
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4380: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*

View file

@ -767,6 +767,9 @@ elif test "$enable_pass_arguments" = "no"; then
AC_DEFINE(HAVE_PROC_FS_EXE_LINK)
fi
fi
case "$target_os" in
mingw*) enable_fake_main=no; GS_FAKE_MAIN=0;;
esac
AC_SUBST(GS_FAKE_MAIN)
AC_MSG_RESULT($enable_fake_main)