* switch output and error stream to non blocking and snooze between each run.
* read error messages and present an alert with the option to stop processing * should fix #1870 and help with #5009 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38871 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
97176323ed
commit
750111c966
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2006, Jérôme Duval. All rights reserved.
|
||||
* Copyright 2004-2010, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
* Original code from ZipOMatic by jonas.sundstrom@kirilla.com
|
||||
*/
|
||||
@ -21,8 +21,7 @@ ExpanderThread::ExpanderThread(BMessage * refs_message, BMessenger * messenger)
|
||||
fStdOut(-1),
|
||||
fStdErr(-1),
|
||||
fExpanderOutput(NULL),
|
||||
fExpanderOutputString(),
|
||||
fExpanderOutputBuffer(new char [4096])
|
||||
fExpanderError(NULL)
|
||||
{
|
||||
SetDataStore(new BMessage(* refs_message)); // leak?
|
||||
// prevents bug with B_SIMPLE_DATA
|
||||
@ -33,16 +32,15 @@ ExpanderThread::ExpanderThread(BMessage * refs_message, BMessenger * messenger)
|
||||
ExpanderThread::~ExpanderThread()
|
||||
{
|
||||
delete fWindowMessenger;
|
||||
delete [] fExpanderOutputBuffer;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ExpanderThread::ThreadStartup()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
entry_ref srcRef, destRef;
|
||||
BString cmd;
|
||||
status_t status = B_OK;
|
||||
entry_ref srcRef, destRef;
|
||||
BString cmd;
|
||||
|
||||
if ((status = GetDataStore()->FindRef("srcRef", &srcRef)) != B_OK)
|
||||
return status;
|
||||
@ -63,9 +61,9 @@ ExpanderThread::ThreadStartup()
|
||||
int32 argc = 3;
|
||||
const char ** argv = new const char * [argc + 1];
|
||||
|
||||
argv[0] = strdup("/bin/sh");
|
||||
argv[1] = strdup("-c");
|
||||
argv[2] = strdup(cmd.String());
|
||||
argv[0] = strdup("/bin/sh");
|
||||
argv[1] = strdup("-c");
|
||||
argv[2] = strdup(cmd.String());
|
||||
argv[argc] = NULL;
|
||||
|
||||
fThreadId = PipeCommand(argc, argv, fStdIn, fStdOut, fStdErr);
|
||||
@ -79,9 +77,17 @@ ExpanderThread::ThreadStartup()
|
||||
set_thread_priority(fThreadId, B_LOW_PRIORITY);
|
||||
|
||||
resume_thread(fThreadId);
|
||||
|
||||
int flags = fcntl(fStdOut, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(fStdOut, F_SETFL, flags);
|
||||
flags = fcntl(fStdErr, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(fStdErr, F_SETFL, flags);
|
||||
|
||||
fExpanderOutput = fdopen(fStdOut, "r");
|
||||
|
||||
fExpanderError = fdopen(fStdErr, "r");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -89,23 +95,33 @@ ExpanderThread::ThreadStartup()
|
||||
status_t
|
||||
ExpanderThread::ExecuteUnit(void)
|
||||
{
|
||||
// read output from command
|
||||
// read output and error from command
|
||||
// send it to window
|
||||
|
||||
char *output_string = fgets(fExpanderOutputBuffer , 4096 - 1, fExpanderOutput);
|
||||
|
||||
if (output_string == NULL)
|
||||
return EOF;
|
||||
|
||||
|
||||
BMessage message('outp');
|
||||
message.AddString("output", output_string);
|
||||
for (int32 i = 0; i < 5; i++) {
|
||||
output_string = fgets(fExpanderOutputBuffer , 4096 - 1, fExpanderOutput);
|
||||
bool outputAdded = false;
|
||||
for (int32 i = 0; i < 50; i++) {
|
||||
char *output_string = fgets(fExpanderOutputBuffer , LINE_MAX, fExpanderOutput);
|
||||
if (!output_string)
|
||||
break;
|
||||
message.AddString("output", output_string);
|
||||
outputAdded = true;
|
||||
}
|
||||
fWindowMessenger->SendMessage(&message);
|
||||
if (outputAdded)
|
||||
fWindowMessenger->SendMessage(&message);
|
||||
if (feof(fExpanderOutput))
|
||||
return EOF;
|
||||
|
||||
char *error_string = fgets(fExpanderOutputBuffer , LINE_MAX, fExpanderError);
|
||||
if (error_string != NULL
|
||||
&& strcmp(error_string, "\n")) {
|
||||
BMessage message('errp');
|
||||
message.AddString("error", error_string);
|
||||
fWindowMessenger->SendMessage(&message);
|
||||
}
|
||||
|
||||
// streams are non blocking, sleep every 100ms
|
||||
snooze(100000);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -173,7 +189,7 @@ ExpanderThread::PipeCommand(int argc, const char **argv, int &in, int &out, int
|
||||
int old_err = dup(2);
|
||||
|
||||
int filedes[2];
|
||||
|
||||
|
||||
/* Create new pipe FDs as stdin, stdout, stderr */
|
||||
pipe(filedes); dup2(filedes[0], 0); close(filedes[0]);
|
||||
in = filedes[1]; // Write to in, appears on cmd's stdin
|
||||
|
@ -1,30 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
// Expander
|
||||
// Written by Jérôme Duval
|
||||
//
|
||||
// ExpanderThread.h
|
||||
//
|
||||
// Copyright (c) 2004 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 2004-2010, Jérôme Duval. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
* Original code from ZipOMatic by jonas.sundstrom@kirilla.com
|
||||
*/
|
||||
#ifndef __EXPANDERTHREAD_H__
|
||||
#define __EXPANDERTHREAD_H__
|
||||
|
||||
@ -74,8 +52,8 @@ class ExpanderThread : public GenericThread
|
||||
int fStdOut;
|
||||
int fStdErr;
|
||||
FILE * fExpanderOutput;
|
||||
BString fExpanderOutputString;
|
||||
char * fExpanderOutputBuffer;
|
||||
FILE * fExpanderError;
|
||||
char fExpanderOutputBuffer[LINE_MAX];
|
||||
};
|
||||
|
||||
#endif // __EXPANDERTHREAD_H__
|
||||
|
@ -337,7 +337,24 @@ ExpanderWindow::MessageReceived(BMessage* msg)
|
||||
fListingText->ScrollToSelection();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'errp':
|
||||
{
|
||||
BString string;
|
||||
if (msg->FindString("error", &string) == B_OK
|
||||
&& fExpandingStarted) {
|
||||
fExpandingThread->SuspendExternalExpander();
|
||||
BAlert* alert = new BAlert("stopAlert", string,
|
||||
B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL,
|
||||
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
|
||||
if (alert->Go() == 0) {
|
||||
fExpandingThread->ResumeExternalExpander();
|
||||
StopExpanding();
|
||||
} else
|
||||
fExpandingThread->ResumeExternalExpander();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'exit':
|
||||
// thread has finished (finished, quit, killed, we don't know)
|
||||
// reset window state
|
||||
|
Loading…
Reference in New Issue
Block a user