X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2Flibaxwin3.so_src%2Fmsg.c;h=a9e416470f7b18c0ffc6b43e378bd01b22c55770;hb=45ff232a1db704623e0c4baed011d12cbd44b06e;hp=17d089f9238babbda6375f9d35a3f776a1393a92;hpb=8c12dd82f2a4e01d8de5d29db6d4fdd0802c7e83;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/libaxwin3.so_src/msg.c b/Usermode/Applications/axwin3_src/libaxwin3.so_src/msg.c index 17d089f9..a9e41647 100644 --- a/Usermode/Applications/axwin3_src/libaxwin3.so_src/msg.c +++ b/Usermode/Applications/axwin3_src/libaxwin3.so_src/msg.c @@ -13,10 +13,16 @@ #include "include/internal.h" #include "include/ipc.h" +#define assert(cnd) do{if(!(cnd)){_SysDebug("Assertion failed: %s", #cnd);}}while(0) + +#define STATICBUF_SIZE 0x1000 + // === CONSTANTS === enum eConnectionType { + CONNTYPE_NONE, CONNTYPE_SENDMESSAGE, + CONNTYPE_IPCPIPE, CONNTYPE_UDP, CONNTYPE_TCP }; @@ -32,9 +38,7 @@ tAxWin3_MessageCallback gAxWin3_MessageCallback; // === CODE === void AxWin3_Connect(const char *ServerDesc) { - _SysDebug("ServerDesc = %s", ServerDesc); - if( !ServerDesc ) - { + if( !ServerDesc ) { ServerDesc = gsAxWin3_int_ServerDesc; } _SysDebug("ServerDesc = %s", ServerDesc); @@ -49,17 +53,37 @@ void AxWin3_Connect(const char *ServerDesc) case '6': case '7': case '8': case '9': case '0': giConnectionType = CONNTYPE_SENDMESSAGE; giConnectionNum = atoi(ServerDesc); + if( giConnectionNum == 0 ) { + _SysDebug("Invalid server PID"); + exit(-1); + } break; case 'u': - while(*ServerDesc && *ServerDesc != ':') ServerDesc ++; - ServerDesc ++; + assert( strncmp(ServerDesc, "udp:", 4) == 0 ); + ServerDesc += 4; + _SysDebug("TODO: UDP connection to '%s'", ServerDesc); // TODO: Open socket and create UDP header break; case 't': - while(*ServerDesc && *ServerDesc != ':') ServerDesc ++; - ServerDesc ++; + assert( strncmp(ServerDesc, "tcp:", 4) == 0 ); + ServerDesc += 4; + _SysDebug("TODO: TCP connection to '%s'", ServerDesc); // TODO: Open socket break; + case 'p': + assert( strncmp(ServerDesc, "pipe:", 5) == 0 ); + ServerDesc += 5; + giConnectionType = CONNTYPE_IPCPIPE; + giConnectionNum = _SysOpen(ServerDesc, OPENFLAG_READ|OPENFLAG_WRITE); + if( giConnectionNum == -1 ) { + _SysDebug("Cannot open IPC Pipe '%s'", ServerDesc); + exit(-1); + } + break; + default: + _SysDebug("Unknown server desc format '%s'", ServerDesc); + exit(-1); + break; } } @@ -96,71 +120,89 @@ void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg) switch(giConnectionType) { case CONNTYPE_SENDMESSAGE: - SysSendMessage(giConnectionNum, size, Msg); + _SysSendMessage(giConnectionNum, size, Msg); break; case CONNTYPE_UDP: { // Create UDP header char tmpbuf[giAxWin3_int_UDPHeaderLen + size]; memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen); memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size); - write(giConnectionNum, tmpbuf, sizeof(tmpbuf)); + _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf)); } break; + case CONNTYPE_IPCPIPE: case CONNTYPE_TCP: - write(giConnectionNum, Msg, size); + _SysWrite(giConnectionNum, Msg, size); break; default: break; } } -tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(void) +tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds) { int len; tAxWin_IPCMessage *ret = NULL; - switch(giConnectionType) + int tid; + fd_set local_set; + + if(!fds) + fds = &local_set; + + if( giConnectionType != CONNTYPE_SENDMESSAGE ) { - case CONNTYPE_SENDMESSAGE: - _SysWaitEvent(THREAD_EVENT_IPCMSG); - while(SysGetMessage(NULL, NULL)) + if(nFD <= giConnectionNum) + nFD = giConnectionNum+1; + FD_SET(giConnectionNum, fds); + } + + _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG); + + // Clear out IPC messages + while( (len = _SysGetMessage(&tid, 0, NULL)) ) + { + if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum ) { - pid_t tid; - len = SysGetMessage(&tid, NULL); - // Check if the message came from the server - if(tid != giConnectionNum) + _SysDebug("%i byte message from %i", len, tid); + // If not, pass the buck (or ignore) + if( gAxWin3_MessageCallback ) + gAxWin3_MessageCallback(tid, len); + else + _SysGetMessage(NULL, 0, GETMSG_IGNORE); + continue ; + } + + // Using CONNTYPE_SENDMESSAGE and server message has arrived + ret = malloc(len); + if(ret == NULL) { + _SysDebug("malloc() failed, ignoring message"); + _SysGetMessage(NULL, 0, GETMSG_IGNORE); + return NULL; + } + _SysGetMessage(NULL, len, ret); + break; + } + + if( giConnectionType != CONNTYPE_SENDMESSAGE ) + { + if( FD_ISSET(giConnectionNum, fds) ) + { + char tmpbuf[STATICBUF_SIZE]; + char *data = tmpbuf; + size_t len = _SysRead(giConnectionNum, tmpbuf, sizeof(tmpbuf)); + + if( giConnectionType == CONNTYPE_UDP ) { - _SysDebug("%i byte message from %i", len, tid); - // If not, pass the buck (or ignore) - if( gAxWin3_MessageCallback ) - gAxWin3_MessageCallback(tid, len); - else - SysGetMessage(NULL, GETMSG_IGNORE); - continue ; + assert(len > giAxWin3_int_UDPHeaderLen); + len -= giAxWin3_int_UDPHeaderLen; + data += giAxWin3_int_UDPHeaderLen; } - - // If it's from the server, allocate a buffer and return it + assert(len >= sizeof(tAxWin_IPCMessage)); ret = malloc(len); - if(ret == NULL) { - _SysDebug("malloc() failed, ignoring message"); - SysGetMessage(NULL, GETMSG_IGNORE); - return NULL; - } - SysGetMessage(NULL, ret); - break; + memcpy(ret, data, len); } - break; - default: - // TODO: Implement - _SysDebug("TODO: Implement AxWin3_int_GetIPCMessage for TCP/UDP"); - break; } - // No message? - if( ret == NULL ) - return NULL; - - // TODO: Sanity checks, so a stupid server can't crash us - return ret; } @@ -169,10 +211,9 @@ tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID) tAxWin_IPCMessage *msg; for(;;) { - msg = AxWin3_int_GetIPCMessage(); + msg = AxWin3_int_GetIPCMessage(0, NULL); if(msg->ID == WantedID) return msg; AxWin3_int_HandleMessage( msg ); - free(msg); } }