[39599] branches/gsoc08-framework/MacPorts_Framework_Release
armahg at macports.org
armahg at macports.org
Mon Aug 25 23:34:47 PDT 2008
Revision: 39599
http://trac.macosforge.org/projects/macports/changeset/39599
Author: armahg at macports.org
Date: 2008-08-25 23:34:46 -0700 (Mon, 25 Aug 2008)
Log Message:
-----------
Abstracted client connection in NotificationsClient object within MPHelperTool.m. This corrects initial premature client connection closing errors. Need to fix IPC issues when calls to HelperTool are made in rapid succession.
Modified Paths:
--------------
branches/gsoc08-framework/MacPorts_Framework_Release/MPHelperTool.m
branches/gsoc08-framework/MacPorts_Framework_Release/MPInterpreter.m
branches/gsoc08-framework/MacPorts_Framework_Release/MPNotifications+IPCAdditions.m
Modified: branches/gsoc08-framework/MacPorts_Framework_Release/MPHelperTool.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework_Release/MPHelperTool.m 2008-08-26 05:24:47 UTC (rev 39598)
+++ branches/gsoc08-framework/MacPorts_Framework_Release/MPHelperTool.m 2008-08-26 06:34:46 UTC (rev 39599)
@@ -61,8 +61,39 @@
int notificationsFileDescriptor;
BOOL hasSetFileDescriptor = NO;
+#pragma mark -
+#pragma mark ASL Logging
+ at interface ASLLogger : NSObject {
+
+}
++ (BOOL) logString:(NSString *)log;
+ at end
+ at implementation ASLLogger
++(BOOL) logString:(NSString *)log {
+ //Initialize asl loggin asl logging stuff
+ aslmsg logMsg = asl_new(ASL_TYPE_MSG) ;
+ assert(logMsg != NULL);
+ asl_set(logMsg, ASL_KEY_FACILITY, "com.apple.console");
+ asl_set(logMsg, ASL_KEY_SENDER, "MPHelperTool");
+ aslclient logClient = asl_open(NULL , NULL, ASL_OPT_STDERR);
+ assert(logClient != NULL);
+
+ int res = asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: %@" , log);
+ asl_close(logClient);
+
+ if (res == 0)
+ return YES;
+ return NO;
+}
+
+ at end
+
+
+
+
+
#pragma mark -
/////////////////////////////////////////////////////////////////
#pragma mark ***** Notifications Connection Abstraction
@@ -217,7 +248,122 @@
return err;
}
+static int ConnectionRPC(
+ ConnectionRef conn,
+ const PacketHeader * request,
+ PacketHeader * reply,
+ size_t replySize
+)
+// Perform an RPC (Remote Procedure Call) with the server. That is, send
+// the server a packet and wait for a reply. You can only use this on
+// connections that are not in listening mode.
+//
+// conn must be a valid connection
+//
+// packet must be a valid, ready-to-send, packet
+//
+// reply and replySize specify a buffer where the reply packet is placed;
+// reply size must not be NULL; replySize must not be less that the
+// packet header size (sizeof(PacketHeader)); if the reply packet is bigger
+// than replySize, the data that won't fit is discarded; you can detect this
+// by looking at reply->fSize
+//
+// Returns an errno-style error code
+// On success, the buffer specified by reply and replySize will contain the
+// reply packet; on error, the contents of that buffer is invalid; also,
+// if this routine errors the connection is no longer useful (conn is still
+// valid, but you can't use it to transmit any more data)
+{
+ int err;
+
+ assert(conn != NULL);
+ assert(conn->fSockFD != -1); // connection must not be shut down
+ assert(conn->fSockCF == NULL); // RPC and listening are mutually exclusive
+ // because unsolicited packet might get mixed up
+ // with the reply
+
+ assert(request != NULL);
+ assert(request->fMagic == kPacketMagic);
+ assert(request->fSize >= sizeof(PacketHeader));
+
+ assert(reply != NULL);
+ assert(replySize >= sizeof(PacketHeader));
+
+ // Send the request.
+
+ err = ConnectionSend(conn, request);
+
+ // Read and validate the reply header.
+
+ if (err == 0) {
+ err = MoreUNIXRead(conn->fSockFD, reply, sizeof(PacketHeader), NULL);
+ }
+ if ( (err == 0) && (reply->fMagic != kPacketMagic) ) {
+ fprintf(stderr, "ConnectionRPC: Bad magic (%.4s).\n", (char *) &reply->fMagic);
+ err = EINVAL;
+ }
+ if ( (err == 0) && (reply->fType != kPacketTypeReply) ) {
+ fprintf(stderr, "ConnectionRPC: Type wrong (%.4s).\n", (char *) &reply->fType);
+ err = EINVAL;
+ }
+ if ( (err == 0) && (reply->fID != request->fID) ) {
+ fprintf(stderr, "ConnectionRPC: ID mismatch (%" PRId32 ").\n", reply->fID);
+ err = EINVAL;
+ }
+ if ( (err == 0) && ( (reply->fSize < sizeof(PacketHeader)) || (reply->fSize > kPacketMaximumSize) ) ) {
+ fprintf(stderr, "ConnectionRPC: Bogus packet size (%" PRIu32 ").\n", reply->fSize);
+ err = EINVAL;
+ }
+
+ // Read the packet payload that will fit in the reply buffer.
+
+ if ( (err == 0) && (reply->fSize > sizeof(PacketHeader)) ) {
+ uint32_t payloadToRead;
+
+ if (reply->fSize > replySize) {
+ payloadToRead = replySize;
+ } else {
+ payloadToRead = reply->fSize;
+ }
+ payloadToRead -= sizeof(PacketHeader);
+
+ err = MoreUNIXRead(conn->fSockFD, ((char *) reply) + sizeof(PacketHeader), payloadToRead, NULL);
+ }
+
+ // Discard any remaining packet payload that will fit in the reply buffer.
+ // The addition check in the next line is necessary to avoid the undefined behaviour
+ // of malloc(0) in the dependent block.
+
+ if ( (err == 0) && (reply->fSize > replySize) ) {
+ uint32_t payloadToJunk;
+ void * junkBuf;
+
+ payloadToJunk = reply->fSize - replySize;
+
+ junkBuf = malloc(payloadToJunk);
+ if (junkBuf == NULL) {
+ err = ENOMEM;
+ }
+
+ if (err == 0) {
+ err = MoreUNIXRead(conn->fSockFD, junkBuf, payloadToJunk, NULL);
+ }
+
+ free(junkBuf);
+ }
+
+ // Any errors cause us to immediately shut down our connection because we
+ // we're no longer sure of the state of the channel (that is, did we leave
+ // half a packet stuck in the pipe).
+
+ if (err != 0) {
+ ConnectionShutdown(conn);
+ }
+
+ return err;
+}
+
static void ConnectionShutdown(ConnectionRef conn)
// This routine shuts down down the connection to the server
// without saying goodbye; it leaves conn valid. This routine
@@ -374,45 +520,207 @@
-static void DoShout(ConnectionRef conn, const char *message)
+static void DoShout(ConnectionRef conn, const char *message, int * ret)
// Implements the "shout" command by sending a shout packet to the server.
// Note that this is /not/ an RPC.
//
// The server responds to this packet by echoing it to each registered
// listener.
{
-
- //asl logging stuff
- aslmsg logMsg = asl_new(ASL_TYPE_MSG) ;
- assert(logMsg != NULL);
- asl_set(logMsg, ASL_KEY_FACILITY, "com.apple.console");
- asl_set(logMsg, ASL_KEY_SENDER, "MPHelperTool");
-
- aslclient logClient = asl_open(NULL , NULL, ASL_OPT_STDERR);
- assert(logClient != NULL);
-
-
int err;
NSString * shoutString = [NSString stringWithFormat:@"Do Shout is passing %@",
[NSString stringWithCString:message encoding:NSUTF8StringEncoding]];
- err = asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @" %@", shoutString );
+ [ASLLogger logString:shoutString];
-
PacketShout request;
InitPacketHeader(&request.fHeader, kPacketTypeShout, sizeof(request), false);
snprintf(request.fMessage, sizeof(request.fMessage), "%s", message);
err = ConnectionSend(conn, &request.fHeader);
PrintResult("shout", err, message);
+ *ret = err;
+}
+
+static void DoQuit(ConnectionRef conn, int * ret)
+// Implements the "quit" command by doing a quit RPC with the server.
+// The server responds to this RPC by quitting. Cleverly, it sends us
+// the RPC reply right before quitting.
+{
+ int err;
+ PacketQuit request;
+ PacketReply reply;
+
+ InitPacketHeader(&request.fHeader, kPacketTypeQuit, sizeof(request), true);
+
+ err = ConnectionRPC(conn, &request.fHeader, &reply.fHeader, sizeof(reply));
+ if (err == 0) {
+ err = reply.fErr;
+ *ret = err;
+ }
+ if (err == 0) {
+ // If the quit is successful, we shut down our end of the connection
+ // because we know that the server has shut down its end.
+ ConnectionShutdown(conn);
+ }
+ [ASLLogger logString:@"DoQuit being called"];
+ PrintResult("quit", err, NULL);
+}
+
+void initIPC (ConnectionRef iConn) {
- asl_close(logClient);
+ int err = 0;
+ //ConnectionRef conn;
+ iConn = NULL;
+
+ // SIGPIPE is evil, so tell the system not to send it to us.
+ if (err == 0) {
+ err = MoreUNIXIgnoreSIGPIPE();
+ //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: err started out as ZERO %i", err);
+ [ASLLogger logString:[NSString stringWithFormat:@"MPHelperTool: err started out as ZERO %i", err]];
+
+ }
+
+ // Organise to have SIGINT delivered to a runloop callback.
+ if (err == 0) {
+ sigset_t justSIGINT;
+
+ (void) sigemptyset(&justSIGINT);
+ (void) sigaddset(&justSIGINT, SIGINT);
+
+ err = InstallSignalToSocket(
+ &justSIGINT,
+ CFRunLoopGetCurrent(),
+ kCFRunLoopDefaultMode,
+ SIGINTRunLoopCallback,
+ NULL
+ );
+ //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: IgnoreSigPipe Successful");
+ [ASLLogger logString:@"MPHelperTool: IgnoreSigPipe Successful"];
+ }
+
+ // Connect to the server.
+ if (err == 0) {
+ err = ConnectionOpen(&iConn);
+ //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: Installed Signal to Socket!");
+ [ASLLogger logString:@"MPHelperTool: Installed Signal to Socket!"];
+ }
+
+
+
+ if (err == 0) {
+ //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: calling DoShout");
+ [ASLLogger logString:@"MPHelperTool: calling DoShout"];
+ int i;
+ DoShout(iConn, "Testing initIPC", &i);
+ }
+ else
+ [ASLLogger logString:@"MPHelperTool: NOT calling DoShout"];
+ //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: NOT calling DoShout");
+
}
+#pragma mark -
+#pragma mark Notifications Connection Abstraction
+
+ at interface NotificationsClient : NSObject
+{
+ ConnectionRef nConn;
+ BOOL connected;
+}
+
+-(BOOL) initializeConnection;
+-(BOOL) doShout:(NSString *)shout;
+-(BOOL) closeConnection;
+-(BOOL) connected;
+ at end
+
+ at implementation NotificationsClient
+
+-(BOOL) initializeConnection {
+ int err = 0;
+ nConn = NULL;
+
+ // SIGPIPE is evil, so tell the system not to send it to us.
+ if (err == 0) {
+ err = MoreUNIXIgnoreSIGPIPE();
+ [ASLLogger logString:[NSString stringWithFormat:@"MPHelperTool: err started out as ZERO %i", err]];
+
+ }
+
+ // Organise to have SIGINT delivered to a runloop callback.
+ if (err == 0) {
+ sigset_t justSIGINT;
+
+ (void) sigemptyset(&justSIGINT);
+ (void) sigaddset(&justSIGINT, SIGINT);
+
+ err = InstallSignalToSocket(
+ &justSIGINT,
+ CFRunLoopGetCurrent(),
+ kCFRunLoopDefaultMode,
+ SIGINTRunLoopCallback,
+ NULL
+ );
+ [ASLLogger logString:@"MPHelperTool: IgnoreSigPipe Successful"];
+ }
+
+ // Connect to the server.
+ if (err == 0) {
+ err = ConnectionOpen(&nConn);
+ [ASLLogger logString:@"MPHelperTool: Installed Signal to Socket!"];
+ }
+
+ if (err == 0)
+ connected = YES;
+ else
+ connected = NO;
+
+ return connected;
+}
+
+-(BOOL) connected {
+ return connected;
+}
+-(BOOL) doShout:(NSString *)shout {
+ BOOL ret = YES;
+ int v;
+
+ if(nConn != NULL) {
+ DoShout(nConn, [shout cStringUsingEncoding:NSUTF8StringEncoding], &v);
+ if (v != 0) {
+ ret = NO;
+ }
+ }
+ else
+ ret = NO;
+
+ return ret;
+}
+
+-(BOOL) closeConnection {
+ int v;
+ BOOL ret = YES;
+ if(nConn != NULL) {
+ DoQuit(nConn, &v);
+ if ( v != 0) {
+ ret = NO;
+ }
+ }
+ else
+ ret = NO;
+
+ return ret;
+}
+
+
+ at end
+
+
+
# pragma mark -
-
#pragma mark Tcl Commands
-
+NotificationsClient * notifier = nil;
//For now we just log to Console ... soon we will be doing fully fledged IPC
int SimpleLog_Command
(
@@ -424,33 +732,48 @@
{
int returnCode = TCL_ERROR;
- int err;
+ //int err;
+ //assert(logClient != NULL);
- //asl logging stuff
- aslmsg logMsg = asl_new(ASL_TYPE_MSG) ;
- assert(logMsg != NULL);
- asl_set(logMsg, ASL_KEY_FACILITY, "com.apple.console");
- asl_set(logMsg, ASL_KEY_SENDER, "MPHelperTool");
+// ConnectionRef iConn;
+// initIPC(iConn);
- aslclient logClient = asl_open(NULL , NULL, ASL_OPT_STDERR);
- assert(logClient != NULL);
+ //if(!globalConnInitialized){
+// initIPC(globalConn);
+// globalConnInitialized = YES;
+// }
+
-
- //err = asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"Starting simplelog Logging");
- //assert( err == 0);
-
++objv, --objc;
if (objc) {
- NSString * data = [NSString stringWithUTF8String:Tcl_GetString(*objv)];
- err = asl_NSLog(logClient , logMsg, ASL_LEVEL_INFO, @"MPHelperTool: %@ " , data);
- //DoShout(<#ConnectionRef conn#>, <#const char * message#>)
- assert(err == 0);
+ const char * log = Tcl_GetString(*objv);
+ NSString * data = [NSString stringWithUTF8String:log];
+ [ASLLogger logString:data];
+ if (notifier != nil && [notifier connected]) {
+ [notifier doShout:data];
+ }
+ else
+ [ASLLogger logString:[NSString stringWithFormat:@"notifier has value %@", notifier]];
+
+ //DoShout(iConn, log);
+
+ //err = asl_NSLog(logClient , logMsg, ASL_LEVEL_INFO, @"MPHelperTool: %@ " , data);
+// if (globalConn != NULL) {
+// //DoShout(globalConn, log);
+// }
+// else {
+// [ASLLogger logString:[NSString stringWithFormat:@"globalConn is NULL on message %@",log]];
+// }
+ //assert(err == 0);
returnCode = TCL_OK;
}
- asl_close(logClient);
+ //ConnectionClose(iConn);
+ //DoQuit(iConn);
+
+ //asl_close(logClient);
return returnCode;
}
@@ -627,72 +950,79 @@
int main(int argc, char const * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ //assert(logClient != NULL);
+//
+// int err = 0;
+// ConnectionRef conn;
+// conn = NULL;
+//
+// // SIGPIPE is evil, so tell the system not to send it to us.
+// if (err == 0) {
+// err = MoreUNIXIgnoreSIGPIPE();
+// //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: err started out as ZERO %i", err);
+// [ASLLogger logString:[NSString stringWithFormat:@"MPHelperTool: err started out as ZERO %i", err]];
+//
+// }
+//
+// // Organise to have SIGINT delivered to a runloop callback.
+// if (err == 0) {
+// sigset_t justSIGINT;
+//
+// (void) sigemptyset(&justSIGINT);
+// (void) sigaddset(&justSIGINT, SIGINT);
+//
+// err = InstallSignalToSocket(
+// &justSIGINT,
+// CFRunLoopGetCurrent(),
+// kCFRunLoopDefaultMode,
+// SIGINTRunLoopCallback,
+// NULL
+// );
+// //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: IgnoreSigPipe Successful");
+// [ASLLogger logString:@"MPHelperTool: IgnoreSigPipe Successful"];
+// }
+//
+// // Connect to the server.
+// if (err == 0) {
+// err = ConnectionOpen(&conn);
+// //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: Installed Signal to Socket!");
+// [ASLLogger logString:@"MPHelperTool: Installed Signal to Socket!"];
+// }
+//
+//
+//
+// if (err == 0) {
+// //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: calling DoShout");
+// [ASLLogger logString:@"MPHelperTool: calling DoShout"];
+//
+// DoShout(conn, "Testing MPHelperTool IPC");
+// }
+// else
+// [ASLLogger logString:@"MPHelperTool: NOT calling DoShout"];
+// //asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: NOT calling DoShout");
- //For Debugging
- //asl logging stuff
- aslmsg logMsg = asl_new(ASL_TYPE_MSG) ;
- assert(logMsg != NULL);
- asl_set(logMsg, ASL_KEY_FACILITY, "com.apple.console");
- asl_set(logMsg, ASL_KEY_SENDER, "MPHelperTool");
- aslclient logClient = asl_open(NULL , NULL, ASL_OPT_STDERR);
- assert(logClient != NULL);
+ //initIPC(globalConn);
- int err = 0;
- ConnectionRef conn;
- conn = NULL;
-
- // SIGPIPE is evil, so tell the system not to send it to us.
- if (err == 0) {
- err = MoreUNIXIgnoreSIGPIPE();
- asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: err started out as ZERO %i", err);
-
- }
+ //if(!globalConnInitialized){
+// initIPC(globalConn);
+// globalConnInitialized = YES;
+// }
+//
- // Organise to have SIGINT delivered to a runloop callback.
- if (err == 0) {
- sigset_t justSIGINT;
-
- (void) sigemptyset(&justSIGINT);
- (void) sigaddset(&justSIGINT, SIGINT);
-
- err = InstallSignalToSocket(
- &justSIGINT,
- CFRunLoopGetCurrent(),
- kCFRunLoopDefaultMode,
- SIGINTRunLoopCallback,
- NULL
- );
- asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: IgnoreSigPipe Successful");
- }
-
- // Connect to the server.
- if (err == 0) {
- err = ConnectionOpen(&conn);
- asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: Installed Signal to Socket!");
- }
-
- // Process the command line arguments. Basically the arguments are a
- // sequence of commands, which we process in order. The logic is
- // a little convoluted because some commands have arguments and because
- // the "listen" command must come last.
-
- if (err == 0) {
- asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: calling DoShout");
- DoShout(conn, "Testing MPHelperTool IPC");
- }
- else
- asl_NSLog(logClient , logMsg, ASL_LEVEL_DEBUG, @"MPHelperTool: NOT calling DoShout");
- asl_close(logClient);
+ notifier = [[NotificationsClient alloc] init];
+ [notifier initializeConnection];
- // Clean up.
- ConnectionClose(conn);
-
-
int result = BASHelperToolMain(kMPHelperCommandSet, kMPHelperCommandProcs);
+ // Clean up.
+ //DoQuit(globalConn);
+ // ConnectionClose(globalConn);
+ //asl_close(logClient);
+ [notifier closeConnection];
+ [notifier release];
[pool release];
Modified: branches/gsoc08-framework/MacPorts_Framework_Release/MPInterpreter.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework_Release/MPInterpreter.m 2008-08-26 05:24:47 UTC (rev 39598)
+++ branches/gsoc08-framework/MacPorts_Framework_Release/MPInterpreter.m 2008-08-26 06:34:46 UTC (rev 39599)
@@ -456,7 +456,7 @@
(CFStringRef) bundleID,
NULL);
- NSLog(@"BEFORE Tool Execution request is %@ , response is %@ \n\n", request, response);
+ //NSLog(@"BEFORE Tool Execution request is %@ , response is %@ \n\n", request, response);
err = BASExecuteRequestInHelperTool(internalMacPortsAuthRef,
kMPHelperCommandSet,
(CFStringRef) bundleID,
@@ -549,7 +549,7 @@
}
}
- NSLog(@"AFTER Tool Execution request is %@ , response is %@ \n\n", request, response);
+ //NSLog(@"AFTER Tool Execution request is %@ , response is %@ \n\n", request, response);
return result;
}
Modified: branches/gsoc08-framework/MacPorts_Framework_Release/MPNotifications+IPCAdditions.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework_Release/MPNotifications+IPCAdditions.m 2008-08-26 05:24:47 UTC (rev 39598)
+++ branches/gsoc08-framework/MacPorts_Framework_Release/MPNotifications+IPCAdditions.m 2008-08-26 06:34:46 UTC (rev 39599)
@@ -795,11 +795,17 @@
result = ClientCheckPacketSize(client, &packet->fHeader, sizeof(PacketShout));
if (result) {
result = ClientCheckPacketID(client, &packet->fHeader, kPacketIDNone);
+ NSLog(@"Packetsize is OK");
}
+ else
+ NSLog(@"Packetsize is NOT OK");
// The Shout packet is good. Let's echo it to each listener.
if (result) {
+ NSLog(@"PacketID is ok");
+
+
ClientState ** allClients;
CFIndex clientCount;
CFIndex clientIndex;
@@ -899,6 +905,8 @@
// the client's fault (-:
result = ClientSendReply(client, &packet->fHeader, 0);
+
+ NSLog(@"CLIENT QUIT BEING CALLED (YAAAY!!)");
}
return result;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20080825/a29425ad/attachment-0001.html
More information about the macports-changes
mailing list