From ef0c707b066d5a80084068f66f45eecaf96c2467 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Wed, 1 Aug 2007 21:43:47 -0700 Subject: [PATCH] Changing from using NSStream which didn't actually work correctly to using a custom-rolled socket implementation * Source/SocketWrapper.m/h: Adding to wrap around BSD sockets * Source/DebuggerConnection.h: Removing _input and _output in favor of just socket * Source/DebuggerConnection.m: ([DebuggerConnection initWithHost:port:session:]): Change from using NSStream and its variants to SocketWrapper ([DebuggerConnection stream:handleEvent:]): Removed --- MacGDBp.xcodeproj/project.pbxproj | 6 ++ Source/DebuggerConnection.h | 4 +- Source/DebuggerConnection.m | 68 +---------------------- Source/SocketWrapper.h | 27 +++++++++ Source/SocketWrapper.m | 91 +++++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 67 deletions(-) create mode 100644 Source/SocketWrapper.h create mode 100644 Source/SocketWrapper.m diff --git a/MacGDBp.xcodeproj/project.pbxproj b/MacGDBp.xcodeproj/project.pbxproj index c7cb818..bcb9bc4 100644 --- a/MacGDBp.xcodeproj/project.pbxproj +++ b/MacGDBp.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 1E02C4080C60EF3F006F1752 /* ConnectWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E02C4070C60EF3F006F1752 /* ConnectWindowController.m */; }; 1E02C5710C610158006F1752 /* DebuggerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E02C5700C610158006F1752 /* DebuggerConnection.m */; }; 1E02C5F60C610724006F1752 /* DebuggerWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E02C5F50C610724006F1752 /* DebuggerWindowController.m */; }; + 1EEEE9400C618B70000C0732 /* SocketWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EEEE93F0C618B70000C0732 /* SocketWrapper.m */; }; 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; @@ -33,6 +34,8 @@ 1E02C5700C610158006F1752 /* DebuggerConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DebuggerConnection.m; path = Source/DebuggerConnection.m; sourceTree = ""; }; 1E02C5F40C610724006F1752 /* DebuggerWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DebuggerWindowController.h; path = Source/DebuggerWindowController.h; sourceTree = ""; }; 1E02C5F50C610724006F1752 /* DebuggerWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DebuggerWindowController.m; path = Source/DebuggerWindowController.m; sourceTree = ""; }; + 1EEEE93E0C618B70000C0732 /* SocketWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocketWrapper.h; path = Source/SocketWrapper.h; sourceTree = ""; }; + 1EEEE93F0C618B70000C0732 /* SocketWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SocketWrapper.m; path = Source/SocketWrapper.m; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; @@ -112,6 +115,8 @@ 1E02C5700C610158006F1752 /* DebuggerConnection.m */, 1E02C5F40C610724006F1752 /* DebuggerWindowController.h */, 1E02C5F50C610724006F1752 /* DebuggerWindowController.m */, + 1EEEE93E0C618B70000C0732 /* SocketWrapper.h */, + 1EEEE93F0C618B70000C0732 /* SocketWrapper.m */, ); name = "Other Sources"; sourceTree = ""; @@ -214,6 +219,7 @@ 1E02C4080C60EF3F006F1752 /* ConnectWindowController.m in Sources */, 1E02C5710C610158006F1752 /* DebuggerConnection.m in Sources */, 1E02C5F60C610724006F1752 /* DebuggerWindowController.m in Sources */, + 1EEEE9400C618B70000C0732 /* SocketWrapper.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/DebuggerConnection.h b/Source/DebuggerConnection.h index f114f9c..06435e4 100644 --- a/Source/DebuggerConnection.h +++ b/Source/DebuggerConnection.h @@ -16,6 +16,7 @@ #import #import "DebuggerWindowController.h" +#import "SocketWrapper.h" @interface DebuggerConnection : NSObject { @@ -25,8 +26,7 @@ DebuggerWindowController *_windowController; - NSInputStream *_input; - NSOutputStream *_output; + SocketWrapper *socket; NSMutableData *_data; } diff --git a/Source/DebuggerConnection.m b/Source/DebuggerConnection.m index fbf7b18..69bb8da 100644 --- a/Source/DebuggerConnection.m +++ b/Source/DebuggerConnection.m @@ -35,19 +35,8 @@ _windowController = [[DebuggerWindowController alloc] initWithConnection: self]; [[_windowController window] makeKeyAndOrderFront: self]; - // now that we have our host information, open the streams and put them in the run loop - [NSStream getStreamsToHost: [NSHost hostWithName: _host] port: _port inputStream: &_input outputStream: &_output]; - [_input retain]; - [_output retain]; - - [_input setDelegate: self]; - [_output setDelegate: self]; - - [_input scheduleInRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode]; - [_output scheduleInRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode]; - - [_input open]; - [_output open]; + // now that we have our host information, open the socket + socket = [[SocketWrapper alloc] initWithPort: port]; // clean up after ourselves [[NSNotificationCenter defaultCenter] addObserver: self @@ -73,10 +62,7 @@ { [_host release]; [_session release]; - [_input close]; - [_output close]; - [_input release]; - [_output release]; + [socket release]; [super dealloc]; } @@ -105,52 +91,4 @@ return _session; } -/** - * Handles stream events. This is the delegate method implemented for NSStream and it - * merely calls other methods to do it's bidding - */ -- (void)stream: (NSStream *)stream handleEvent: (NSStreamEvent)event -{ - NSLog(@"hi"); - if (event == NSStreamEventHasBytesAvailable) - { - if (!_data) - { - _data = [[NSMutableData data] retain]; - } - uint8_t buf[1024]; - unsigned int len = 0; - len = [(NSInputStream *)stream read: buf maxLength: 1024]; - if (len) - { - [_data appendBytes: (const void *)buf length: len]; - } - else - { - [self _readFromStream: _data]; - [_data release]; - _data = nil; - } - } - else if (event == NSStreamEventEndEncountered) - { - NSLog(@"we need to close and die right now"); - } - else if (event == NSStreamEventErrorOccurred) - { - NSLog(@"error = %@", [stream streamError]); - } - NSLog(@"status = %d", [stream streamStatus]); -} - -/** - * Called when the stream event handler has finished reading all of the data and - * passes it a data object - */ -- (void)_readFromStream: (NSData *)data -{ - [data retain]; - NSLog(@"data = %@", data); -} - @end diff --git a/Source/SocketWrapper.h b/Source/SocketWrapper.h new file mode 100644 index 0000000..dedbb9d --- /dev/null +++ b/Source/SocketWrapper.h @@ -0,0 +1,27 @@ +/* + * MacGDBp + * Copyright (c) 2002 - 2007, Blue Static + * + * This program is free software; you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if not, + * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#import + + +@interface SocketWrapper : NSObject +{ + int _socket; +} + +- (id)initWithPort: (int)port; + +@end diff --git a/Source/SocketWrapper.m b/Source/SocketWrapper.m new file mode 100644 index 0000000..076b54a --- /dev/null +++ b/Source/SocketWrapper.m @@ -0,0 +1,91 @@ +/* + * MacGDBp + * Copyright (c) 2002 - 2007, Blue Static + * + * This program is free software; you can redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; if not, + * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#import "SocketWrapper.h" +#include +#include +#include +#include + +@implementation SocketWrapper + +/** + * Initializes the socket wrapper with a host and port + */ +- (id)initWithPort: (int)port +{ + if (self = [super init]) + { + // create an INET socket that we'll be listen()ing on + int socketOpen = socket(PF_INET, SOCK_STREAM, 0); + + // create our address given the port + struct sockaddr_in address; + address.sin_family = AF_INET; + address.sin_port = htons(port); + address.sin_addr.s_addr = htonl(INADDR_ANY); + memset(address.sin_zero, '\0', sizeof(address.sin_zero)); + + // bind the socket... and don't give up until we've tried for a while + int tries = 0; + while (bind(socketOpen, (struct sockaddr *)&address, sizeof(address)) < 0) + { + if (tries >= 5) + { + close(socketOpen); + NSLog(@"giving up now"); + return nil; + } + NSLog(@"couldn't bind to the socket... trying again in 5"); + sleep(5); + tries++; + } + + // now we just have to keep our ears open + if (listen(socketOpen, 0) == -1) + { + NSLog(@"listen failed"); + return nil; + } + + // accept a connection + struct sockaddr_in remoteAddress; + socklen_t remoteAddressLen = sizeof(remoteAddress); + _socket = accept(socketOpen, (struct sockaddr *)&remoteAddress, &remoteAddressLen); + if (_socket < 0) + { + close(socketOpen); + NSLog(@"could not accept() the socket"); + return nil; + } + + // we're done listening now that we have a connection + close(socketOpen); + } + return self; +} + +/** + * Close our socket and clean up anything else + */ +- (void)dealloc +{ + close(_socket); + + [super dealloc]; +} + +@end -- 2.22.5