/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla IPC. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include #include "ipcClient.h" #include "ipcMessage.h" #include "ipcd.h" #include "prio.h" #include "plstr.h" int ipcClient::gLastID = 0; // // called to initialize this client context // // return: // PR_POLL_READ - to wait for the client socket to become readable // PR_POLL_WRITE - to wait for the client socket to become writable // int ipcClient::Init() { mID = ++gLastID; mName = NULL; mInMsg = new ipcMessage(); mSendOffset = 0; // wait for the client to send us a command return PR_POLL_READ; } // // called when this client context is going away // int ipcClient::Finalize() { if (mName) PL_strfree(mName); if (mInMsg) delete mInMsg; mOutMsgQ.DeleteAll(); return 0; } // // called to process a client socket // // params: // fd - the client socket // poll_flags - the state of the client socket // // return: // 0 - to end session with this client // PR_POLL_READ - to wait for the client socket to become readable // PR_POLL_WRITE - to wait for the client socket to become writable // int ipcClient::Process(PRFileDesc *fd, int poll_flags) { if ((poll_flags & PR_POLL_ERR) || (poll_flags & PR_POLL_HUP) || (poll_flags & PR_POLL_EXCEPT) || (poll_flags & PR_POLL_NVAL)) { // // expect Finalize method to be called next. // printf("### client socket appears to have closed\n"); return 0; } // always wait for more data int ret_flags = PR_POLL_READ; if (poll_flags & PR_POLL_READ) { printf("### client socket is now readable\n"); char buf[1024]; PRInt32 n; // find out how much data is available for reading... // n = PR_Available(fd); n = PR_Read(fd, buf, sizeof(buf)); if (n <= 0) return 0; // cancel connection char *ptr = buf; while (n) { PRUint32 nread; PRBool complete; mInMsg->ReadFrom(ptr, PRUint32(n), &nread, &complete); if (complete) { IPC_DispatchMsg(this, mInMsg); mInMsg->Reset(); } n -= nread; ptr += nread; } } if (poll_flags & PR_POLL_WRITE) { printf("### client socket is now writable\n"); if (mOutMsgQ.First()) WriteMsgs(fd); } if (mOutMsgQ.First()) ret_flags |= PR_POLL_WRITE; return ret_flags; } void ipcClient::SetName(const char *name) { printf("### setting client name to \"%s\"\n", name); if (mName) PL_strfree(mName); mName = PL_strdup(name); } // // called to write out any messages from the outgoing queue. // int ipcClient::WriteMsgs(PRFileDesc *fd) { while (mOutMsgQ.First()) { const char *buf = (const char *) mOutMsgQ.First()->MsgBuf(); PRInt32 bufLen = (PRInt32) mOutMsgQ.First()->MsgLen(); if (mSendOffset) { buf += mSendOffset; bufLen -= mSendOffset; } PRInt32 nw = PR_Write(fd, buf, bufLen); if (nw <= 0) break; printf("### wrote %d bytes\n", nw); if (nw == bufLen) mOutMsgQ.DeleteFirst(); else mSendOffset += nw; } return 0; }