* Changed MiniTerminal command line arguments. Location and size are now
specified via options -l and -s. An arbitrary program can be run in the terminal instead of a shell. * Console::fState was never initialized which could cause the terminal to not print anything. * stdin, -out, and -err were set in MiniView::Start() and in MiniView::ExecuteShell(). Thus resetting them in the latter method after executing the shell had no effect. Removed it in the former method and now reset them after loading, but before resuming the shell. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13676 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Arguments.h"
|
||||
|
||||
extern const char *__progname;
|
||||
|
||||
// usage
|
||||
static const char *kUsage =
|
||||
"%s <options> [ <program> ... ]\n"
|
||||
"Starts a terminal with a shell running in it. If <program> is given\n"
|
||||
"and is an absolute or relative path to an executable, it is run instead\n"
|
||||
"of the shell. The command line arguments for the program just follow the\n"
|
||||
"path of the program.\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -h, --help - print this info text\n"
|
||||
" -l <x> <y> - open the terminal window at location (<x>, <y>)\n"
|
||||
" -s <width> <height> - open the terminal window with width <width> and\n"
|
||||
" height <height>)\n";
|
||||
|
||||
// application name
|
||||
const char *kAppName = __progname;
|
||||
|
||||
static void
|
||||
print_usage(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, kUsage, kAppName);
|
||||
}
|
||||
|
||||
static void
|
||||
print_usage_and_exit(bool error)
|
||||
{
|
||||
print_usage(error);
|
||||
exit(error ? 0 : 1);
|
||||
}
|
||||
|
||||
Arguments::Arguments()
|
||||
: fBounds(50, 50, 630, 435),
|
||||
fStandardShell(true),
|
||||
fShellArgumentCount(0),
|
||||
fShellArguments(NULL)
|
||||
{
|
||||
const char *argv[] = { "/bin/sh", "--login" };
|
||||
|
||||
_SetShellArguments(2, argv);
|
||||
}
|
||||
|
||||
|
||||
Arguments::~Arguments()
|
||||
{
|
||||
_SetShellArguments(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Arguments::Parse(int argc, const char *const *argv)
|
||||
{
|
||||
int argi = 1;
|
||||
while (argi < argc) {
|
||||
const char *arg = argv[argi++];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
|
||||
print_usage_and_exit(false);
|
||||
|
||||
} else if (strcmp(arg, "-l") == 0) {
|
||||
// location
|
||||
float x, y;
|
||||
if (argi + 1 >= argc
|
||||
|| sscanf(argv[argi++], "%f", &x) != 1
|
||||
|| sscanf(argv[argi++], "%f", &y) != 1) {
|
||||
print_usage_and_exit(true);
|
||||
}
|
||||
|
||||
fBounds.OffsetTo(x, y);
|
||||
|
||||
} else if (strcmp(arg, "-s") == 0) {
|
||||
// size
|
||||
float width, height;
|
||||
if (argi + 1 >= argc
|
||||
|| sscanf(argv[argi++], "%f", &width) != 1
|
||||
|| sscanf(argv[argi++], "%f", &height) != 1) {
|
||||
print_usage_and_exit(true);
|
||||
}
|
||||
|
||||
fBounds.right = fBounds.left + width;
|
||||
fBounds.bottom = fBounds.top + height;
|
||||
|
||||
} else {
|
||||
// illegal option
|
||||
fprintf(stderr, "Unrecognized option \"%s\"\n", arg);
|
||||
print_usage_and_exit(true);
|
||||
}
|
||||
|
||||
} else {
|
||||
// no option, so the remainder is the shell program with arguments
|
||||
_SetShellArguments(argc - argi + 1, argv + argi - 1);
|
||||
argi = argc;
|
||||
fStandardShell = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Arguments::GetShellArguments(int &argc, const char *const *&argv) const
|
||||
{
|
||||
argc = fShellArgumentCount;
|
||||
argv = fShellArguments;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Arguments::_SetShellArguments(int argc, const char *const *argv)
|
||||
{
|
||||
// delete old arguments
|
||||
delete[] fShellArguments;
|
||||
fShellArguments = NULL;
|
||||
fShellArgumentCount = 0;
|
||||
|
||||
// copy new ones
|
||||
if (argc > 0 && argv) {
|
||||
fShellArguments = new const char*[argc + 1];
|
||||
for (int i = 0; i < argc; i++)
|
||||
fShellArguments[i] = argv[i];
|
||||
|
||||
fShellArguments[argc] = NULL;
|
||||
fShellArgumentCount = argc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ARGUMENTS_H
|
||||
#define ARGUMENTS_H
|
||||
|
||||
#include <Rect.h>
|
||||
|
||||
class Arguments {
|
||||
public:
|
||||
Arguments();
|
||||
~Arguments();
|
||||
|
||||
void Parse(int argc, const char *const *argv);
|
||||
|
||||
BRect Bounds() const { return fBounds; }
|
||||
bool StandardShell() const { return fStandardShell; }
|
||||
void GetShellArguments(int &argc, const char *const *&argv) const;
|
||||
|
||||
private:
|
||||
void _SetShellArguments(int argc, const char *const *argv);
|
||||
|
||||
BRect fBounds;
|
||||
bool fStandardShell;
|
||||
int fShellArgumentCount;
|
||||
const char **fShellArguments;
|
||||
};
|
||||
|
||||
|
||||
#endif // ARGUMENTS_H
|
||||
@@ -17,7 +17,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
Console::Console(ViewBuffer *output)
|
||||
: fOutput(output)
|
||||
: fState(CONSOLE_STATE_NORMAL),
|
||||
fOutput(output)
|
||||
{
|
||||
fOutput->GetSize(&fColumns, &fLines);
|
||||
fOutput->SetResizeCallback(&ResizeCallback, this);
|
||||
|
||||
@@ -4,10 +4,15 @@ UseHeaders [ FDirName $(OBOS_TOP) src tests apps miniterminal ] ;
|
||||
UseHeaders [ FDirName $(OBOS_TOP) src apps terminal MYOB ] ;
|
||||
|
||||
App MiniTerminal :
|
||||
MiniApp.cpp
|
||||
MiniWin.cpp
|
||||
MiniView.cpp
|
||||
Arguments.cpp
|
||||
Console.cpp
|
||||
MiniApp.cpp
|
||||
MiniView.cpp
|
||||
MiniWin.cpp
|
||||
ViewBuffer.cpp ;
|
||||
|
||||
LinkSharedOSLibs MiniTerminal : libroot.so libbe.so ;
|
||||
if $(TARGET_PLATFORM) = haiku {
|
||||
LinkSharedOSLibs MiniTerminal : libroot.so libbe.so ;
|
||||
} else {
|
||||
LinkSharedOSLibs MiniTerminal : libroot.so libopenbeos.so ;
|
||||
}
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "MiniApp.h"
|
||||
#include "MiniWin.h"
|
||||
#include "MiniView.h"
|
||||
|
||||
MiniApp::MiniApp(BRect bounds)
|
||||
#include "Arguments.h"
|
||||
#include "MiniApp.h"
|
||||
#include "MiniView.h"
|
||||
#include "MiniWin.h"
|
||||
|
||||
MiniApp::MiniApp(const Arguments &args)
|
||||
: BApplication("application/x-vnd.Haiku.MiniTerminal")
|
||||
{
|
||||
fWindow = new MiniWin(bounds);
|
||||
fWindow = new MiniWin(args);
|
||||
fWindow->Show();
|
||||
}
|
||||
|
||||
@@ -31,26 +33,12 @@ MiniApp::~MiniApp()
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
main(int argc, const char *const argv[])
|
||||
{
|
||||
BRect bounds(50, 50, 630, 435);
|
||||
Arguments args;
|
||||
args.Parse(argc, argv);
|
||||
|
||||
if (argc >= 3) {
|
||||
BPoint offset;
|
||||
sscanf(argv[1], "%f", &offset.x);
|
||||
sscanf(argv[2], "%f", &offset.y);
|
||||
bounds.OffsetTo(offset);
|
||||
}
|
||||
|
||||
if (argc >= 5) {
|
||||
BPoint size;
|
||||
sscanf(argv[3], "%f", &size.x);
|
||||
sscanf(argv[4], "%f", &size.y);
|
||||
bounds.right = bounds.left + size.x;
|
||||
bounds.bottom = bounds.top + size.y;
|
||||
}
|
||||
|
||||
MiniApp *app = new MiniApp(bounds);
|
||||
MiniApp *app = new MiniApp(args);
|
||||
app->Run();
|
||||
delete app;
|
||||
return 0;
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
class Arguments;
|
||||
class MiniWin;
|
||||
|
||||
class MiniApp : public BApplication {
|
||||
public:
|
||||
MiniApp(BRect bounds);
|
||||
MiniApp(const Arguments &args);
|
||||
virtual ~MiniApp();
|
||||
|
||||
virtual void ReadyToRun();
|
||||
@@ -16,4 +17,4 @@ private:
|
||||
MiniWin *fWindow;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <OS.h>
|
||||
#include <image.h>
|
||||
#include <Message.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
@@ -26,8 +27,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "MiniView.h"
|
||||
#include "Arguments.h"
|
||||
#include "Console.h"
|
||||
#include "MiniView.h"
|
||||
|
||||
#include "VTkeymap.h"
|
||||
|
||||
@@ -65,8 +67,9 @@ Setenv(const char *var, const char *value)
|
||||
environ [++envindex] = NULL;
|
||||
}
|
||||
|
||||
MiniView::MiniView(BRect frame)
|
||||
: ViewBuffer(frame)
|
||||
MiniView::MiniView(const Arguments &args)
|
||||
: ViewBuffer(args.Bounds().OffsetToCopy(0, 0)),
|
||||
fArguments(args)
|
||||
{
|
||||
// we need a message filter so that we get B_TAB keydowns
|
||||
AddFilter(new BMessageFilter(B_KEY_DOWN, &MiniView::MessageFilter));
|
||||
@@ -92,11 +95,6 @@ MiniView::Start()
|
||||
// we're a session leader
|
||||
setsid();
|
||||
|
||||
// move our stdin and stdout to the console
|
||||
dup2(fSlaveFD, 0);
|
||||
dup2(fSlaveFD, 1);
|
||||
dup2(fSlaveFD, 2);
|
||||
|
||||
if (SpawnThreads() != B_OK)
|
||||
TRACE(("error in SpawnThreads\n"));
|
||||
}
|
||||
@@ -269,12 +267,12 @@ MiniView::SpawnThreads()
|
||||
fConsoleWriter = spawn_thread(&MiniView::ConsoleWriter, "console writer", B_URGENT_DISPLAY_PRIORITY, this);
|
||||
if (fConsoleWriter < 0)
|
||||
return B_ERROR;
|
||||
TRACE(("console writer thread is: %d\n", fConsoleWriter));
|
||||
TRACE(("console writer thread is: %ld\n", fConsoleWriter));
|
||||
|
||||
fShellExecutor = spawn_thread(&MiniView::ExecuteShell, "shell process", B_URGENT_DISPLAY_PRIORITY, this);
|
||||
if (fShellExecutor < 0)
|
||||
return B_ERROR;
|
||||
TRACE(("shell process thread is: %d\n", fShellProcess));
|
||||
TRACE(("shell executor thread is: %ld\n", fShellExecutor));
|
||||
|
||||
resume_thread(fConsoleWriter);
|
||||
resume_thread(fShellExecutor);
|
||||
@@ -305,11 +303,10 @@ MiniView::ExecuteShell(void *arg)
|
||||
MiniView *view = (MiniView *)arg;
|
||||
|
||||
for (;;) {
|
||||
const char *argv[3];
|
||||
argv[0] = "/bin/sh";
|
||||
argv[1] = "--login";
|
||||
argv[2] = NULL;
|
||||
|
||||
int argc;
|
||||
const char *const *argv;
|
||||
view->fArguments.GetShellArguments(argc, argv);
|
||||
|
||||
int saved_stdin = dup(0);
|
||||
int saved_stdout = dup(1);
|
||||
int saved_stderr = dup(2);
|
||||
@@ -318,19 +315,25 @@ MiniView::ExecuteShell(void *arg)
|
||||
dup2(view->fSlaveFD, 1);
|
||||
dup2(view->fSlaveFD, 2);
|
||||
|
||||
view->fShellProcess = load_image(2, argv, (const char **)environ);
|
||||
view->fShellProcess = load_image(argc, (const char **)argv,
|
||||
(const char **)environ);
|
||||
setpgid(view->fShellProcess, 0);
|
||||
tcsetpgrp(view->fSlaveFD, view->fShellProcess);
|
||||
|
||||
status_t return_code;
|
||||
wait_for_thread(view->fShellProcess, &return_code);
|
||||
|
||||
dup2(saved_stdin, 0);
|
||||
dup2(saved_stdout, 1);
|
||||
dup2(saved_stderr, 2);
|
||||
close(saved_stdin);
|
||||
close(saved_stdout);
|
||||
close(saved_stderr);
|
||||
|
||||
status_t return_code;
|
||||
wait_for_thread(view->fShellProcess, &return_code);
|
||||
|
||||
if (!view->fArguments.StandardShell()) {
|
||||
view->Window()->PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
#include "ViewBuffer.h"
|
||||
#include "Console.h"
|
||||
|
||||
class Arguments;
|
||||
|
||||
class MiniView : public ViewBuffer {
|
||||
public:
|
||||
MiniView(BRect frame);
|
||||
MiniView(const Arguments &args);
|
||||
virtual ~MiniView();
|
||||
|
||||
void Start();
|
||||
@@ -23,6 +25,7 @@ static int32 ConsoleWriter(void *arg);
|
||||
static int32 ExecuteShell(void *arg);
|
||||
static filter_result MessageFilter(BMessage *message, BHandler **target, BMessageFilter *filter);
|
||||
|
||||
const Arguments &fArguments;
|
||||
Console *fConsole;
|
||||
int fMasterFD;
|
||||
int fSlaveFD;
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
* Distributed under the Haiku License.
|
||||
*/
|
||||
|
||||
#include "MiniWin.h"
|
||||
#include "Arguments.h"
|
||||
#include "MiniView.h"
|
||||
#include "MiniWin.h"
|
||||
|
||||
MiniWin::MiniWin(BRect bounds)
|
||||
: BWindow(bounds, "MiniTerminal", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE)
|
||||
MiniWin::MiniWin(const Arguments &args)
|
||||
: BWindow(args.Bounds(), "MiniTerminal", B_TITLED_WINDOW,
|
||||
B_QUIT_ON_WINDOW_CLOSE)
|
||||
{
|
||||
fView = new MiniView(bounds.OffsetToSelf(0, 0));
|
||||
fView = new MiniView(args);
|
||||
AddChild(fView);
|
||||
fView->MakeFocus();
|
||||
}
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class Arguments;
|
||||
class MiniView;
|
||||
|
||||
class MiniWin : public BWindow {
|
||||
public:
|
||||
MiniWin(BRect bounds);
|
||||
MiniWin(const Arguments &args);
|
||||
virtual ~MiniWin();
|
||||
|
||||
MiniView *View();
|
||||
|
||||
Reference in New Issue
Block a user