Terminal: added ability to execute a command using scripting
Add a B_EXECUTE_PROPERTY to execute a given command.
Also set fAttached to false in _DetachShell() for symmetry.
Done by Andrea Anzani plus some style / refactoring by myself
Change-Id: Ifa26b60b1c1d3598a863adc4fb701155f9edf588
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9154
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Diff
src/apps/terminal/Shell.cpp | 4 +++-
src/apps/terminal/TermView.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
src/apps/terminal/TermView.h | 5 ++++-
3 files changed, 65 insertions(+), 20 deletions(-)
@@ -312,8 +312,10 @@
void
Shell::DetachBuffer()
{
if (fAttached)
if (fAttached) {
fTermParse->StopThreads();
fAttached = false;
}
}
@@ -18,15 +18,12 @@
#include "TermView.h"
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <algorithm>
#include <new>
#include <vector>
#include <Alert.h>
#include <Application.h>
#include <Beep.h>
@@ -87,7 +84,11 @@
{B_GET_PROPERTY, 0},
{B_DIRECT_SPECIFIER, 0},
"get tty name."},
{ 0 }
{ "command",
{B_EXECUTE_PROPERTY, 0},
{B_DIRECT_SPECIFIER, 0},
"execute command"},
{ 0 },
};
@@ -245,13 +246,8 @@
fRows = ROWS_DEFAULT;
int32 argc = 0;
if (archive->HasInt32("argc"))
archive->FindInt32("argc", &argc);
const char **argv = new const char*[argc];
for (int32 i = 0; i < argc; i++) {
archive->FindString("argv", i, (const char**)&argv[i]);
}
const char** argv = NULL;
_GetArgumentsFromMessage(archive, argv, argc);
status_t status = _InitObject(ShellParameters(argc, argv));
@@ -364,13 +360,8 @@
ShellParameters modifiedShellParameters(shellParameters);
modifiedShellParameters.SetEncoding(fEncoding);
error = fShell->Open(fRows, fColumns, modifiedShellParameters);
if (error < B_OK)
return error;
error = _AttachShell(fShell);
error = _AttachShell(fShell, modifiedShellParameters);
if (error < B_OK)
return error;
@@ -992,11 +983,29 @@
}
void
TermView::_GetArgumentsFromMessage(const BMessage* message, const char**& argv, int32& argc)
{
type_code type;
if (message->GetInfo("argv", &type, &argc) == B_OK) {
argv = new const char*[argc + 1];
int32 i = 0;
while (message->FindString("argv", i, &argv[i]) == B_OK)
i++;
argv[i] = NULL;
}
}
status_t
TermView::_AttachShell(Shell *shell)
TermView::_AttachShell(Shell *shell, const ShellParameters& shellParameters)
{
if (shell == NULL)
return B_BAD_VALUE;
status_t status = shell->Open(fRows, fColumns, shellParameters);
if (status != B_OK)
return status;
fShell = shell;
@@ -1742,6 +1751,37 @@
BView::MessageReceived(message);
} else
BView::MessageReceived(message);
break;
}
case B_EXECUTE_PROPERTY:
{
int32 i;
BMessage specifier;
if (message->GetCurrentSpecifier(&i, &specifier) == B_OK
&& strcmp("command",
specifier.FindString("property", i)) == 0) {
Shell* shell = _DetachShell();
shell->Close();
int32 argc = 0;
const char** argv = NULL;
_GetArgumentsFromMessage(message, argv, argc);
if (message->GetBool("clear", false))
Clear();
ShellParameters shellParameters(argc, argv);
shellParameters.SetEncoding(fEncoding);
_AttachShell(shell, shellParameters);
delete[] argv;
message->SendReply(B_REPLY);
} else {
BView::MessageReceived(message);
}
break;
}
@@ -197,7 +197,10 @@
status_t _InitObject(
const ShellParameters& shellParameters);
status_t _AttachShell(Shell* shell);
void _GetArgumentsFromMessage(const BMessage* message,
const char**& argv, int32& argc);
status_t _AttachShell(Shell* shell, const ShellParameters& shellParameters);
Shell* _DetachShell();
void _Activate();