2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "MPL"); you may not use this file
4
* except in compliance with the MPL. You may obtain a copy of
5
* the MPL at http://www.mozilla.org/MPL/
7
* Software distributed under the MPL is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the MPL for the specific language governing
10
* rights and limitations under the MPL.
12
* The Original Code is protoZilla.
14
* The Initial Developer of the Original Code is Ramalingam Saravanan.
15
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
16
* Copyright (C) 2000 Ramalingam Saravanan. All Rights Reserved.
20
* Alternatively, the contents of this file may be used under the
21
* terms of the GNU General Public License (the "GPL"), in which case
22
* the provisions of the GPL are applicable instead of
23
* those above. If you wish to allow use of your version of this
24
* file only under the terms of the GPL and not to allow
25
* others to use your version of this file under the MPL, indicate
26
* your decision by deleting the provisions above and replace them
27
* with the notice and other provisions required by the GPL.
28
* If you do not delete the provisions above, a recipient
29
* may use your version of this file under either the MPL or the
34
//#define DEBUG_pipet 1
37
* A Test application that exercises the PipeTransport module.
41
#include "nsIRequestObserver.h"
42
#include "nsIStreamListener.h"
43
#include "nsIPipeTransport.h"
44
#include "nsIServiceManager.h"
45
#include "nsXPIDLString.h"
46
#include "nsIEventQueueService.h"
47
#include "nsIThread.h"
48
#include "nsIRunnable.h"
49
#include "nsIInputStream.h"
50
#include "nsIOutputStream.h"
55
// Helper class to handle polling of STDOUT pipe
56
class nsListenerImpl : public nsIStreamListener
60
NS_DECL_NSIREQUESTOBSERVER
61
NS_DECL_NSISTREAMLISTENER
64
virtual ~nsListenerImpl() {};
70
// nsListenerImpl implementation
71
nsListenerImpl::nsListenerImpl(void)
77
// nsISupports implementation
78
NS_IMPL_THREADSAFE_ISUPPORTS1 (nsListenerImpl, nsIStreamListener);
80
// nsIStreamListener implementation
82
nsListenerImpl::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) {
83
printf("nsListenerImpl::OnStartRequest\n");
89
nsListenerImpl::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
92
printf("nsListenerImpl::OnStopRequest\n");
97
// nsIStreamListener method
99
nsListenerImpl::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
100
nsIInputStream *aInputStream, PRUint32 aSourceOffset,
105
printf("nsListenerImpl::OnDataAvailable, offset=%d, length=%d\n",
106
aSourceOffset, aLength);
110
PRUint32 readCount = 0;
112
while (aLength > 0) {
114
rv = aInputStream->Read((char*) buf, 80, &readCount);
116
if (NS_FAILED(rv) || (readCount <= 0))
117
return NS_ERROR_FAILURE;
119
buf[readCount] = '\0';
121
printf("READ(%d): ", readCount);
125
aLength -= readCount;
132
// Helper class to handle polling of STDOUT pipe
133
class nsConsolePoll : public nsIRunnable
139
nsConsolePoll(nsIPipeTransport* aPipeT);
140
virtual ~nsConsolePoll();
143
nsCOMPtr<nsIPipeTransport> mPipeT;
146
// nsConsolePoll implementation
148
// nsISupports implementation
149
NS_IMPL_THREADSAFE_ISUPPORTS1 (nsConsolePoll, nsIRunnable);
151
// nsConsolePoll implementation
152
nsConsolePoll::nsConsolePoll(nsIPipeTransport* aPipeT)
158
nsConsolePoll::~nsConsolePoll()
163
// nsIRunnable implementation
170
nsCOMPtr<nsIThread> myThread;
171
rv = nsIThread::GetCurrent(getter_AddRefs(myThread));
172
printf("nsConsolePoll::Run: myThread=%x\n", (int) myThread.get());
175
nsCOMPtr<nsIOutputStream> stdinWrite;
176
rv = mPipeT->OpenOutputStream(0, PRUint32(-1), 0,
177
getter_AddRefs(stdinWrite));
178
if (NS_FAILED(rv)) return rv;
180
printf("***Accepting console line input\n");
186
fgets(line, 81, stdin);
187
if (strstr(line, "quit") == line)
190
printf("CONSOLE: %s", line);
192
rv = stdinWrite->Write(line, strlen(line), &writeCount);
193
if (NS_FAILED(rv)) return rv;
206
rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
209
printf("ERROR: XPCOM intialization error [%x].\n", rv);
213
printf("pipetest: Creating event Q\n");
215
nsCOMPtr<nsIEventQueueService> service = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
216
if (NS_FAILED(rv)) return rv;
218
rv = service->CreateThreadEventQueue();
219
if (NS_FAILED(rv)) return rv;
221
nsCOMPtr<nsIEventQueue> currentThreadQ;
222
rv = service->GetThreadEventQueue(NS_CURRENT_THREAD,
223
getter_AddRefs(currentThreadQ));
224
if (NS_FAILED(rv)) return rv;
226
(void) nsComponentManager::AutoRegister(nsIComponentManagerObsolete::NS_Startup, nsnull);
228
// Create an instance of our component
229
nsCOMPtr<nsIPipeTransport> mypipet = do_CreateInstance(NS_PIPETRANSPORT_CONTRACTID, &rv);
231
printf("pipetest: ERROR: creating PipeTransport [%x]\n", rv);
235
// Call methods on our component to test it out.
236
printf("pipetest: Testing PipeTransport interface\n");
240
const char *executable = "bash";
244
const char *executable = "/bin/sh";
248
rv = mypipet->Init(executable,
249
(const char **)args, nArgs,
252
false, false, nsnull);
254
printf("pipetest: ERROR: Calling Init [%x]\n", rv);
259
nsCOMPtr<nsIRequest> pipeRequest;
260
nsIStreamListener* listener = new nsListenerImpl();
261
rv = mypipet->AsyncRead( listener, (nsISupports*) nsnull,
263
getter_AddRefs(pipeRequest) );
265
printf("pipetest: ERROR: Calling ReadStdout [%x]\n", rv);
269
// Console input helper class
270
nsConsolePoll* consolePoll = new nsConsolePoll(mypipet);
271
nsCOMPtr<nsIThread> consoleThread;
273
// Spin up a new thread to handle STDOUT polling
274
rv = NS_NewThread(getter_AddRefs(consoleThread),
275
NS_STATIC_CAST(nsIRunnable*, consolePoll));
277
// Process events until we're finished.
279
PRBool eventAvailable;
280
PRIntervalTime sleepInterval = PR_MillisecondsToInterval(20);
285
rv = pipeRequest->Cancel(NS_BINDING_ABORTED);
286
if (gExited == 1) break;
290
rv = currentThreadQ->EventAvailable(eventAvailable);
291
if (NS_FAILED(rv)) return rv;
293
if (eventAvailable) {
294
rv = currentThreadQ->WaitForEvent(&event);
295
if (NS_FAILED(rv)) return rv;
297
rv = currentThreadQ->HandleEvent(event);
298
if (NS_FAILED(rv)) return rv;
301
PR_Sleep(sleepInterval);
306
printf("pipetest: ERROR: Calling Kill [%x]\n", rv);
307
return NS_ERROR_FAILURE;
310
printf("pipetest: Finished testing ....\n");
313
printf("pipetest: Destroying event Q\n");
314
rv = service->DestroyThreadEventQueue();
315
if (NS_FAILED(rv)) return rv;
318
NS_ShutdownXPCOM(nsnull);