52 #include <nsAutoLock.h>
53 #include <nsAutoPtr.h>
54 #include <nsThreadUtils.h>
90 NS_ENSURE_ARG_POINTER(aProcess);
93 nsRefPtr<sbProcess> process =
new sbProcess();
94 NS_ENSURE_TRUE(process, NS_ERROR_OUT_OF_MEMORY);
97 process->mProcessLock = nsAutoLock::NewLock(
"sbProcess::mProcessLock");
98 NS_ENSURE_TRUE(process->mProcessLock, NS_ERROR_OUT_OF_MEMORY);
101 process.forget(aProcess);
118 sbAutoKillProcess autoSelf(
this);
122 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
123 nsAutoLock autoProcessLock(mProcessLock);
126 PRUint32 argCount = mArgList.Length();
127 NS_ENSURE_TRUE(argCount > 0, NS_ERROR_ILLEGAL_VALUE);
130 nsTArray<nsCString> argListUTF8;
131 for (PRUint32
i = 0;
i < argCount;
i++) {
132 NS_ENSURE_TRUE(argListUTF8.AppendElement
133 (NS_ConvertUTF16toUTF8(mArgList[
i])),
134 NS_ERROR_OUT_OF_MEMORY);
139 char** argList =
reinterpret_cast<char**
>
140 (NS_Alloc((argCount + 1) *
sizeof(
char*)));
141 NS_ENSURE_TRUE(argList, NS_ERROR_OUT_OF_MEMORY);
145 for (PRUint32
i = 0;
i < argCount;
i++) {
146 argList[
i] =
const_cast<char*
>(argListUTF8[
i].get());
148 argList[argCount] = NULL;
151 PRProcessAttr* processAttr = PR_NewProcessAttr();
152 NS_ENSURE_TRUE(processAttr, NS_ERROR_FAILURE);
153 sbAutoPRProcessAttr autoProcessAttr(processAttr);
156 if (mPipeStdinString) {
158 PRFileDesc* stdinReadFD;
159 PRFileDesc* stdinWriteFD;
160 status = PR_CreatePipe(&stdinReadFD, &stdinWriteFD);
161 NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
162 sbAutoPRFileDesc autoStdinReadFD(stdinReadFD);
163 sbAutoPRFileDesc autoStdinWriteFD(stdinWriteFD);
166 status = PR_SetFDInheritable(stdinReadFD, PR_TRUE);
167 NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
168 status = PR_SetFDInheritable(stdinWriteFD, PR_FALSE);
169 NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
172 nsCAutoString writeData = NS_ConvertUTF16toUTF8(mStdinString);
173 PRInt32 bytesWritten;
174 bytesWritten = PR_Write(stdinWriteFD,
177 NS_ENSURE_TRUE(bytesWritten == writeData.Length(), NS_ERROR_FAILURE);
180 PR_ProcessAttrSetStdioRedirect(processAttr,
187 mStdinReadFD = autoStdinReadFD.forget();
188 PR_Close(autoStdinWriteFD.forget());
192 if (mPipeStdoutString) {
194 PRFileDesc* stdoutReadFD;
195 PRFileDesc* stdoutWriteFD;
196 status = PR_CreatePipe(&stdoutReadFD, &stdoutWriteFD);
197 NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
198 sbAutoPRFileDesc autoStdoutReadFD(stdoutReadFD);
199 sbAutoPRFileDesc autoStdoutWriteFD(stdoutWriteFD);
202 status = PR_SetFDInheritable(stdoutReadFD, PR_FALSE);
203 NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
204 status = PR_SetFDInheritable(stdoutWriteFD, PR_TRUE);
205 NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
208 PR_ProcessAttrSetStdioRedirect(processAttr,
213 mStdoutReadFD = autoStdoutReadFD.forget();
214 mStdoutWriteFD = autoStdoutWriteFD.forget();
218 mBaseProcess = PR_CreateProcess(argList[0], argList, NULL, processAttr);
219 NS_ENSURE_TRUE(mBaseProcess, NS_ERROR_FAILURE);
222 nsCOMPtr<nsIRunnable> runnable = NS_NEW_RUNNABLE_METHOD(
sbProcess,
225 NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
226 rv = NS_NewThread(getter_AddRefs(mWaitForDoneThread), runnable);
227 NS_ENSURE_SUCCESS(rv, rv);
246 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
247 nsAutoLock autoProcessLock(mProcessLock);
250 mHasBeenKilled = PR_TRUE;
255 PR_KillProcess(mBaseProcess);
258 if (mWaitForDoneThread)
259 mWaitForDoneThread->Shutdown();
278 PR_DetachProcess(mBaseProcess);
280 mBaseProcess = nsnull;
284 PR_Close(mStdinReadFD);
286 PR_Close(mStdoutReadFD);
288 PR_Close(mStdoutWriteFD);
292 nsAutoLock::DestroyLock(mProcessLock);
293 mProcessLock = nsnull;
310 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
311 nsAutoLock autoProcessLock(mProcessLock);
314 PRUint32 argCount = mArgList.Length();
316 for (PRUint32
i = 0;
i < argCount;
i++) {
317 NS_ENSURE_TRUE(aArgList.AppendElement(mArgList[
i]), NS_ERROR_OUT_OF_MEMORY);
327 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
328 nsAutoLock autoProcessLock(mProcessLock);
331 PRUint32 argCount = aArgList.Length();
333 for (PRUint32
i = 0;
i < argCount;
i++) {
334 NS_ENSURE_TRUE(mArgList.AppendElement(aArgList[
i]), NS_ERROR_OUT_OF_MEMORY);
349 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
350 nsAutoLock autoProcessLock(mProcessLock);
353 if (mPipeStdinString)
354 aStdinString.Assign(mStdinString);
356 aStdinString.SetIsVoid(PR_TRUE);
365 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
366 nsAutoLock autoProcessLock(mProcessLock);
369 mStdinString.Assign(aStdinString);
370 mPipeStdinString = !aStdinString.IsVoid();
384 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
385 nsAutoLock autoProcessLock(mProcessLock);
388 if (mPipeStdoutString)
389 aStdoutString.Assign(mStdoutString);
391 aStdoutString.SetIsVoid(PR_TRUE);
404 NS_ENSURE_ARG_POINTER(aPipeStdoutString);
407 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
408 nsAutoLock autoProcessLock(mProcessLock);
411 *aPipeStdoutString = mPipeStdoutString;
420 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
421 nsAutoLock autoProcessLock(mProcessLock);
424 mPipeStdoutString = aPipeStdoutString;
437 NS_ENSURE_ARG_POINTER(aDoneMonitor);
440 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
441 nsAutoLock autoProcessLock(mProcessLock);
444 *aDoneMonitor = mDoneMonitor;
453 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
454 nsAutoLock autoProcessLock(mProcessLock);
457 mDoneMonitor = aDoneMonitor;
475 NS_ENSURE_ARG_POINTER(aIsDone);
478 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
479 nsAutoLock autoProcessLock(mProcessLock);
495 NS_ENSURE_ARG_POINTER(aDoneResult);
498 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
499 nsAutoLock autoProcessLock(mProcessLock);
502 *aDoneResult = mDoneResult;
515 NS_ENSURE_ARG_POINTER(aExitCode);
518 NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
519 nsAutoLock autoProcessLock(mProcessLock);
522 *aExitCode = mExitCode;
538 sbProcess::sbProcess() :
539 mProcessLock(nsnull),
540 mPipeStdinString(PR_FALSE),
541 mPipeStdoutString(PR_FALSE),
542 mStdinReadFD(nsnull),
543 mStdoutReadFD(nsnull),
544 mStdoutWriteFD(nsnull),
545 mBaseProcess(nsnull),
548 mHasBeenKilled(PR_FALSE),
549 mDoneMonitor(nsnull),
562 sbProcess::WaitForDone()
564 PRStatus status = PR_SUCCESS;
569 status = PR_WaitProcess(mBaseProcess, &exitCode);
570 if (status != PR_SUCCESS)
571 rv = NS_ERROR_FAILURE;
575 nsAutoLock autoProcessLock(mProcessLock);
578 if (NS_SUCCEEDED(rv))
582 if (NS_SUCCEEDED(rv))
583 mExitCode = exitCode;
590 nsAutoMonitor monitor(mDoneMonitor);
592 nsAutoLock autoProcessLock(mProcessLock);
597 nsAutoLock autoProcessLock(mProcessLock);
608 sbProcess::HandleDone()
611 if (mPipeStdoutString) {
613 PRFileDesc* stdoutReadFD = mStdoutReadFD;
614 PRFileDesc* stdoutWriteFD = mStdoutWriteFD;
620 nsAutoUnlock autoProcessUnlock(mProcessLock);
621 PR_Close(stdoutWriteFD);
623 mStdoutWriteFD = nsnull;
628 mStdoutString.Truncate();
633 nsAutoUnlock autoProcessUnlock(mProcessLock);
634 bytesRead = PR_Read(stdoutReadFD, readData,
sizeof(readData));
636 NS_ENSURE_TRUE(bytesRead >= 0, NS_ERROR_FAILURE);
640 nsCAutoString dataString;
641 dataString.Assign(readData, bytesRead);
642 mStdoutString.Append(NS_ConvertUTF8toUTF16(dataString));
644 }
while (bytesRead > 0);
678 nsTArray<nsString>& aArgList,
679 const nsAString* aStdin,
680 PRBool aPipeStdoutString,
681 PRMonitor* aDoneMonitor)
686 nsRefPtr<sbProcess> process;
688 NS_ENSURE_SUCCESS(rv, rv);
691 rv = process->SetArgList(aArgList);
692 NS_ENSURE_SUCCESS(rv, rv);
694 rv = process->SetStdinString(*aStdin);
695 NS_ENSURE_SUCCESS(rv, rv);
697 rv = process->SetPipeStdoutString(aPipeStdoutString);
698 NS_ENSURE_SUCCESS(rv, rv);
699 rv = process->SetDoneMonitor(aDoneMonitor);
700 NS_ENSURE_SUCCESS(rv, rv);
704 NS_ENSURE_SUCCESS(rv, rv);
707 process.forget(aProcess);
nsresult GetStdoutString(nsAString &aStdoutString)
nsresult GetDoneMonitor(PRMonitor **aDoneMonitor)
Songbird Process Services Definitions.
nsresult GetExitCode(PRInt32 *aExitCode)
nsresult GetDoneResult(nsresult *aDoneResult)
nsresult SB_RunProcess(sbProcess **aProcess, nsTArray< nsString > &aArgList, const nsAString *aStdin, PRBool aPipeStdoutString, PRMonitor *aDoneMonitor)
nsresult GetIsDone(PRBool *aIsDone)
nsresult SetDoneMonitor(PRMonitor *aDoneMonitor)
nsresult SetPipeStdoutString(PRBool aPipeStdoutString)
nsresult GetArgList(nsTArray< nsString > &aArgList)
nsresult GetPipeStdoutString(PRBool *aPipeStdoutString)
nsresult SetArgList(const nsTArray< nsString > &aArgList)
static NS_DECL_ISUPPORTS nsresult New(sbProcess **aProcess)
_getSelectedPageStyle s i
nsresult GetStdinString(nsAString &aStdinString)
nsresult SetStdinString(const nsAString &aStdinString)