* 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:
Ingo Weinhold
2005-07-14 23:55:49 +00:00
parent b8b9dc1c24
commit 42244cf30e
10 changed files with 227 additions and 55 deletions
+136
View File
@@ -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;
}
}
+32
View File
@@ -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
+2 -1
View File
@@ -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);
+9 -4
View File
@@ -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 ;
}
+11 -23
View File
@@ -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 -2
View File
@@ -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
+22 -19
View File
@@ -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;
+4 -1
View File
@@ -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;
+6 -4
View File
@@ -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();
}
+2 -1
View File
@@ -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();