Encapsulated low level terminal stuff into a Shell class, which also
supersedes spawn_shell(). Removed window parameter from TermParse. Since we already have a pointer to the view, we just call Window() on it (only used in one place, no need to save a pointer). Other cleanups. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21628 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ca210f74f1
commit
f3d05c8b3a
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "CodeConv.h"
|
#include "CodeConv.h"
|
||||||
#include "PrefHandler.h"
|
#include "PrefHandler.h"
|
||||||
#include "spawn.h"
|
//#include "spawn.h"
|
||||||
#include "TermBuffer.h"
|
#include "TermBuffer.h"
|
||||||
#include "TermWindow.h"
|
#include "TermWindow.h"
|
||||||
#include "TermConst.h"
|
#include "TermConst.h"
|
||||||
@ -25,11 +25,10 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
#include <signal.h>
|
//#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
@ -119,14 +118,8 @@ TermApp::ReadyToRun()
|
|||||||
void
|
void
|
||||||
TermApp::Quit()
|
TermApp::Quit()
|
||||||
{
|
{
|
||||||
if (!sUsageRequested){
|
if (!sUsageRequested)
|
||||||
int status;
|
|
||||||
|
|
||||||
kill(-gShPid, SIGHUP);
|
|
||||||
wait(&status);
|
|
||||||
|
|
||||||
_UnregisterTerminal();
|
_UnregisterTerminal();
|
||||||
}
|
|
||||||
|
|
||||||
BApplication::Quit();
|
BApplication::Quit();
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,10 @@ extern int mbcstable[]; /* ESC $ */
|
|||||||
#define NPARAM 10 // Max parameters
|
#define NPARAM 10 // Max parameters
|
||||||
|
|
||||||
|
|
||||||
TermParse::TermParse(int fd, TermWindow *inWinObj, TermView *inViewObj,
|
TermParse::TermParse(int fd, TermView *inViewObj, CodeConv *inConvObj)
|
||||||
CodeConv *inConvObj)
|
|
||||||
:
|
:
|
||||||
fFd(fd),
|
fFd(fd),
|
||||||
fViewObj(inViewObj),
|
fViewObj(inViewObj),
|
||||||
fWinObj(inWinObj),
|
|
||||||
fConvObj(inConvObj),
|
fConvObj(inConvObj),
|
||||||
fParseThread(-1),
|
fParseThread(-1),
|
||||||
fParseSem(-1),
|
fParseSem(-1),
|
||||||
@ -807,7 +805,7 @@ TermParse::EscParse()
|
|||||||
switch (mode_char) {
|
switch (mode_char) {
|
||||||
case '0':
|
case '0':
|
||||||
case '2':
|
case '2':
|
||||||
fWinObj->SetTitle(string);
|
fViewObj->Window()->SetTitle(string);
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
break;
|
break;
|
||||||
|
@ -39,14 +39,13 @@
|
|||||||
|
|
||||||
class TermView;
|
class TermView;
|
||||||
class CodeConv;
|
class CodeConv;
|
||||||
class TermWindow;
|
|
||||||
|
|
||||||
//PtyReader buffer size.
|
//PtyReader buffer size.
|
||||||
#define READ_BUF_SIZE 2048
|
#define READ_BUF_SIZE 2048
|
||||||
|
|
||||||
class TermParse : public BHandler {
|
class TermParse : public BHandler {
|
||||||
public:
|
public:
|
||||||
TermParse(int fd, TermWindow *inWinObj, TermView *inViewObj, CodeConv *inConvObj);
|
TermParse(int fd, TermView *inViewObj, CodeConv *inConvObj);
|
||||||
~TermParse();
|
~TermParse();
|
||||||
|
|
||||||
status_t StartThreads();
|
status_t StartThreads();
|
||||||
@ -72,7 +71,6 @@ private:
|
|||||||
int fFd;
|
int fFd;
|
||||||
|
|
||||||
TermView *fViewObj;
|
TermView *fViewObj;
|
||||||
TermWindow *fWinObj;
|
|
||||||
CodeConv *fConvObj;
|
CodeConv *fConvObj;
|
||||||
|
|
||||||
thread_id fParseThread;
|
thread_id fParseThread;
|
||||||
|
@ -63,9 +63,9 @@ const static rgb_color kTermColorTable[16] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TermView::TermView(BRect frame, CodeConv *inCodeConv, int fd)
|
TermView::TermView(BRect frame, CodeConv *inCodeConv)
|
||||||
: BView(frame, "termview", B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS),
|
: BView(frame, "termview", B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS),
|
||||||
fTerminalFd(fd),
|
fShell(NULL),
|
||||||
fFontWidth(0),
|
fFontWidth(0),
|
||||||
fFontHeight(0),
|
fFontHeight(0),
|
||||||
fFontAscent(0),
|
fFontAscent(0),
|
||||||
@ -122,6 +122,25 @@ TermView::~TermView()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TermView::AttachShell(Shell *shell)
|
||||||
|
{
|
||||||
|
if (shell == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
fShell = shell;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TermView::DetachShell()
|
||||||
|
{
|
||||||
|
fShell = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Get width and height for terminal font
|
//! Get width and height for terminal font
|
||||||
void
|
void
|
||||||
TermView::GetFontSize(int* _width, int* _height)
|
TermView::GetFontSize(int* _width, int* _height)
|
||||||
@ -1010,11 +1029,7 @@ TermView::UpdateSIGWINCH()
|
|||||||
ScrollTo(0, fTop);
|
ScrollTo(0, fTop);
|
||||||
ResizeScrBarRange();
|
ResizeScrBarRange();
|
||||||
|
|
||||||
struct winsize ws;
|
fShell->UpdateWindowSize(fTermRows, fTermColumns);
|
||||||
ws.ws_row = fTermRows;
|
|
||||||
ws.ws_col = fTermColumns;
|
|
||||||
ioctl(fTerminalFd, TIOCSWINSZ, &ws);
|
|
||||||
kill(-gShPid, SIGWINCH);
|
|
||||||
|
|
||||||
fFrameResized = 0;
|
fFrameResized = 0;
|
||||||
if (fScrRegionSet == 0)
|
if (fScrRegionSet == 0)
|
||||||
@ -1033,11 +1048,11 @@ TermView::DeviceStatusReport(int n)
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case 5:
|
case 5:
|
||||||
len = sprintf(sbuf,"\033[0n") ;
|
len = sprintf(sbuf,"\033[0n") ;
|
||||||
write(fTerminalFd, sbuf, len);
|
fShell->Write(sbuf, len);
|
||||||
break ;
|
break ;
|
||||||
case 6:
|
case 6:
|
||||||
len = sprintf(sbuf,"\033[%d;%dR", fTermRows, fTermColumns) ;
|
len = sprintf(sbuf,"\033[%d;%dR", fTermRows, fTermColumns) ;
|
||||||
write(fTerminalFd, sbuf, len);
|
fShell->Write(sbuf, len);
|
||||||
break ;
|
break ;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -1210,10 +1225,10 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
|
|
||||||
// If bytes[0] equal intr charactor,
|
// If bytes[0] equal intr charactor,
|
||||||
// send signal to shell process group.
|
// send signal to shell process group.
|
||||||
tcgetattr(fTerminalFd, &tio);
|
fShell->GetAttr(tio);
|
||||||
if (*bytes == tio.c_cc[VINTR]) {
|
if (*bytes == tio.c_cc[VINTR]) {
|
||||||
if (tio.c_lflag & ISIG)
|
if (tio.c_lflag & ISIG)
|
||||||
kill(-gShPid, SIGINT);
|
fShell->Signal(SIGINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminal changes RET, ENTER, F1...F12, and ARROW key code.
|
// Terminal changes RET, ENTER, F1...F12, and ARROW key code.
|
||||||
@ -1224,24 +1239,24 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
case B_RETURN:
|
case B_RETURN:
|
||||||
c = 0x0d;
|
c = 0x0d;
|
||||||
if (key == RETURN_KEY || key == ENTER_KEY) {
|
if (key == RETURN_KEY || key == ENTER_KEY) {
|
||||||
write(fTerminalFd, &c, 1);
|
fShell->Write(&c, 1);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
write(fTerminalFd, bytes, numBytes);
|
fShell->Write(bytes, numBytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_LEFT_ARROW:
|
case B_LEFT_ARROW:
|
||||||
if (key == LEFT_ARROW_KEY) {
|
if (key == LEFT_ARROW_KEY) {
|
||||||
write(fTerminalFd, LEFT_ARROW_KEY_CODE, sizeof(LEFT_ARROW_KEY_CODE)-1);
|
fShell->Write(LEFT_ARROW_KEY_CODE, sizeof(LEFT_ARROW_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_RIGHT_ARROW:
|
case B_RIGHT_ARROW:
|
||||||
if (key == RIGHT_ARROW_KEY) {
|
if (key == RIGHT_ARROW_KEY) {
|
||||||
write(fTerminalFd, RIGHT_ARROW_KEY_CODE, sizeof(RIGHT_ARROW_KEY_CODE)-1);
|
fShell->Write(RIGHT_ARROW_KEY_CODE, sizeof(RIGHT_ARROW_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1256,7 +1271,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key == UP_ARROW_KEY) {
|
if (key == UP_ARROW_KEY) {
|
||||||
write(fTerminalFd, UP_ARROW_KEY_CODE, sizeof(UP_ARROW_KEY_CODE)-1);
|
fShell->Write(UP_ARROW_KEY_CODE, sizeof(UP_ARROW_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1269,21 +1284,21 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key == DOWN_ARROW_KEY) {
|
if (key == DOWN_ARROW_KEY) {
|
||||||
write(fTerminalFd, DOWN_ARROW_KEY_CODE, sizeof(DOWN_ARROW_KEY_CODE)-1);
|
fShell->Write(DOWN_ARROW_KEY_CODE, sizeof(DOWN_ARROW_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_INSERT:
|
case B_INSERT:
|
||||||
if (key == INSERT_KEY) {
|
if (key == INSERT_KEY) {
|
||||||
write(fTerminalFd, INSERT_KEY_CODE, sizeof(INSERT_KEY_CODE)-1);
|
fShell->Write(INSERT_KEY_CODE, sizeof(INSERT_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_HOME:
|
case B_HOME:
|
||||||
if (key == HOME_KEY) {
|
if (key == HOME_KEY) {
|
||||||
write(fTerminalFd, HOME_KEY_CODE, sizeof(HOME_KEY_CODE)-1);
|
fShell->Write(HOME_KEY_CODE, sizeof(HOME_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1298,7 +1313,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key == PAGE_UP_KEY) {
|
if (key == PAGE_UP_KEY) {
|
||||||
write(fTerminalFd, PAGE_UP_KEY_CODE, sizeof(PAGE_UP_KEY_CODE)-1);
|
fShell->Write(PAGE_UP_KEY_CODE, sizeof(PAGE_UP_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1311,14 +1326,14 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (key == PAGE_DOWN_KEY) {
|
if (key == PAGE_DOWN_KEY) {
|
||||||
write(fTerminalFd, PAGE_DOWN_KEY_CODE, sizeof(PAGE_DOWN_KEY_CODE)-1);
|
fShell->Write(PAGE_DOWN_KEY_CODE, sizeof(PAGE_DOWN_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_END:
|
case B_END:
|
||||||
if (key == END_KEY) {
|
if (key == END_KEY) {
|
||||||
write(fTerminalFd, END_KEY_CODE, sizeof(END_KEY_CODE)-1);
|
fShell->Write(END_KEY_CODE, sizeof(END_KEY_CODE)-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1326,7 +1341,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
case B_FUNCTION_KEY:
|
case B_FUNCTION_KEY:
|
||||||
for (c = 0; c < 12; c++) {
|
for (c = 0; c < 12; c++) {
|
||||||
if (key == function_keycode_table[c]) {
|
if (key == function_keycode_table[c]) {
|
||||||
write(fTerminalFd, function_key_char_table[c], 5);
|
fShell->Write(function_key_char_table[c], 5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1341,12 +1356,12 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
if (GetEncoding() != M_UTF8) {
|
if (GetEncoding() != M_UTF8) {
|
||||||
int cnum = fCodeConv->ConvertFromInternal(bytes, numBytes,
|
int cnum = fCodeConv->ConvertFromInternal(bytes, numBytes,
|
||||||
(char *)dstbuf, GetEncoding());
|
(char *)dstbuf, GetEncoding());
|
||||||
write(fTerminalFd, dstbuf, cnum);
|
fShell->Write(dstbuf, cnum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write(fTerminalFd, bytes, numBytes);
|
fShell->Write(bytes, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1428,7 +1443,7 @@ TermView::MessageReceived(BMessage *msg)
|
|||||||
|
|
||||||
case MENU_CLEAR_ALL:
|
case MENU_CLEAR_ALL:
|
||||||
DoClearAll();
|
DoClearAll();
|
||||||
write(fTerminalFd, ctrl_l, 1);
|
fShell->Write(ctrl_l, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSGRUN_CURSOR:
|
case MSGRUN_CURSOR:
|
||||||
@ -1589,10 +1604,10 @@ TermView::WritePTY(const uchar *text, int numBytes)
|
|||||||
uchar *destBuffer = (uchar *)malloc(numBytes * 3);
|
uchar *destBuffer = (uchar *)malloc(numBytes * 3);
|
||||||
numBytes = fCodeConv->ConvertFromInternal((char*)text, numBytes,
|
numBytes = fCodeConv->ConvertFromInternal((char*)text, numBytes,
|
||||||
(char*)destBuffer, GetEncoding());
|
(char*)destBuffer, GetEncoding());
|
||||||
write(fTerminalFd, destBuffer, numBytes);
|
fShell->Write(destBuffer, numBytes);
|
||||||
free(destBuffer);
|
free(destBuffer);
|
||||||
} else {
|
} else {
|
||||||
write(fTerminalFd, text, numBytes);
|
fShell->Write(text, numBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@
|
|||||||
#define CUROFF 0
|
#define CUROFF 0
|
||||||
#define CURON 1
|
#define CURON 1
|
||||||
|
|
||||||
#define VIEW_THR_CODE 'vtcd'
|
|
||||||
#define MOUSE_THR_CODE 'mtcd'
|
#define MOUSE_THR_CODE 'mtcd'
|
||||||
#define RECT_BUF_SIZE 32
|
#define RECT_BUF_SIZE 32
|
||||||
|
|
||||||
@ -95,12 +94,16 @@ class CodeConv;
|
|||||||
class BPopUpMenu;
|
class BPopUpMenu;
|
||||||
class BScrollBar;
|
class BScrollBar;
|
||||||
class BString;
|
class BString;
|
||||||
|
class Shell;
|
||||||
|
|
||||||
class TermView : public BView {
|
class TermView : public BView {
|
||||||
public:
|
public:
|
||||||
TermView(BRect frame, CodeConv *inCodeConv, int fd);
|
TermView(BRect frame, CodeConv *inCodeConv);
|
||||||
~TermView();
|
~TermView();
|
||||||
|
|
||||||
|
status_t AttachShell(Shell *shell);
|
||||||
|
void DetachShell();
|
||||||
|
|
||||||
void SetTermFont(const BFont *halfFont, const BFont *fullFont);
|
void SetTermFont(const BFont *halfFont, const BFont *fullFont);
|
||||||
void GetFontSize(int *width, int *height);
|
void GetFontSize(int *width, int *height);
|
||||||
BRect SetTermSize(int rows, int cols, bool flag);
|
BRect SetTermSize(int rows, int cols, bool flag);
|
||||||
@ -225,7 +228,7 @@ class TermView : public BView {
|
|||||||
bool CheckSelectedRegion(const CurPos &pos);
|
bool CheckSelectedRegion(const CurPos &pos);
|
||||||
inline void Redraw(int, int, int, int);
|
inline void Redraw(int, int, int, int);
|
||||||
|
|
||||||
int fTerminalFd;
|
Shell *fShell;
|
||||||
|
|
||||||
// Font and Width
|
// Font and Width
|
||||||
BFont fHalfFont;
|
BFont fHalfFont;
|
||||||
|
@ -56,7 +56,7 @@ extern PrefHandler *gTermPref;
|
|||||||
|
|
||||||
TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
||||||
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
|
||||||
fPfd(-1),
|
fShell(NULL),
|
||||||
fTermParse(NULL),
|
fTermParse(NULL),
|
||||||
fMenubar(NULL),
|
fMenubar(NULL),
|
||||||
fFilemenu(NULL),
|
fFilemenu(NULL),
|
||||||
@ -96,9 +96,10 @@ TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
|||||||
|
|
||||||
// Get encoding name (setenv TTYPE in spawn_shell functions)
|
// Get encoding name (setenv TTYPE in spawn_shell functions)
|
||||||
const char *encoding = longname2shortname(gTermPref->getString(PREF_TEXT_ENCODING));
|
const char *encoding = longname2shortname(gTermPref->getString(PREF_TEXT_ENCODING));
|
||||||
fPfd = spawn_shell(rows, cols, command, encoding);
|
fShell = new Shell();
|
||||||
if (fPfd < 0)
|
status_t status = fShell->Open(rows, cols, command, encoding);
|
||||||
throw fPfd;
|
if (status < 0)
|
||||||
|
throw status;
|
||||||
|
|
||||||
InitWindow();
|
InitWindow();
|
||||||
}
|
}
|
||||||
@ -106,7 +107,9 @@ TermWindow::TermWindow(BRect frame, const char* title, const char *command)
|
|||||||
|
|
||||||
TermWindow::~TermWindow()
|
TermWindow::~TermWindow()
|
||||||
{
|
{
|
||||||
close(fPfd);
|
fTermView->DetachShell();
|
||||||
|
|
||||||
|
delete fShell;
|
||||||
delete fTermParse;
|
delete fTermParse;
|
||||||
delete fCodeConv;
|
delete fCodeConv;
|
||||||
if (fPrefWindow)
|
if (fPrefWindow)
|
||||||
@ -159,7 +162,9 @@ TermWindow::InitWindow()
|
|||||||
textframe.top = fMenubar->Bounds().bottom + 1.0;
|
textframe.top = fMenubar->Bounds().bottom + 1.0;
|
||||||
|
|
||||||
fCodeConv = new CodeConv();
|
fCodeConv = new CodeConv();
|
||||||
fTermView = new TermView(Bounds(), fCodeConv, fPfd);
|
fTermView = new TermView(Bounds(), fCodeConv);
|
||||||
|
|
||||||
|
fTermView->AttachShell(fShell);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MuTerm has two views. BaseView is window base view.
|
* MuTerm has two views. BaseView is window base view.
|
||||||
@ -214,7 +219,7 @@ TermWindow::InitWindow()
|
|||||||
|
|
||||||
// Initialize TermParse
|
// Initialize TermParse
|
||||||
SetEncoding(longname2id(gTermPref->getString(PREF_TEXT_ENCODING)));
|
SetEncoding(longname2id(gTermPref->getString(PREF_TEXT_ENCODING)));
|
||||||
fTermParse = new TermParse(fPfd, this, fTermView, fCodeConv);
|
fTermParse = new TermParse(fShell->FD(), fTermView, fCodeConv);
|
||||||
if (fTermParse->StartThreads() < B_OK)
|
if (fTermParse->StartThreads() < B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -463,7 +468,7 @@ TermWindow::MessageReceived(BMessage *message)
|
|||||||
}
|
}
|
||||||
else if (!strcmp("tty", spe.FindString("property", i))) {
|
else if (!strcmp("tty", spe.FindString("property", i))) {
|
||||||
BMessage reply(B_REPLY);
|
BMessage reply(B_REPLY);
|
||||||
reply.AddString("result", ttyname(fPfd));
|
reply.AddString("result", fShell->TTYName());
|
||||||
message->SendReply(&reply);
|
message->SendReply(&reply);
|
||||||
} else {
|
} else {
|
||||||
BWindow::MessageReceived(message);
|
BWindow::MessageReceived(message);
|
||||||
|
@ -45,7 +45,7 @@ class TermParse;
|
|||||||
class CodeConv;
|
class CodeConv;
|
||||||
class PrefWindow;
|
class PrefWindow;
|
||||||
class FindWindow;
|
class FindWindow;
|
||||||
|
class Shell;
|
||||||
|
|
||||||
class TermWindow : public BWindow {
|
class TermWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
@ -74,7 +74,7 @@ class TermWindow : public BWindow {
|
|||||||
/*
|
/*
|
||||||
* data member
|
* data member
|
||||||
*/
|
*/
|
||||||
int fPfd;
|
Shell *fShell;
|
||||||
TermParse *fTermParse;
|
TermParse *fTermParse;
|
||||||
BMenuBar *fMenubar;
|
BMenuBar *fMenubar;
|
||||||
BMenu *fFilemenu, *fEditmenu, *fEncodingmenu, *fHelpmenu, *fFontMenu, *fWindowSizeMenu, *fNewFontMenu;
|
BMenu *fFilemenu, *fEditmenu, *fEncodingmenu, *fHelpmenu, *fFontMenu, *fWindowSizeMenu, *fNewFontMenu;
|
||||||
|
@ -30,20 +30,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/param.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <sys/param.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <termios.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <kernel/OS.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
#include "TermConst.h"
|
#include "TermConst.h"
|
||||||
#include "spawn.h"
|
#include "spawn.h"
|
||||||
@ -53,18 +54,20 @@ extern PrefHandler *gTermPref;
|
|||||||
|
|
||||||
/* default shell command and options. */
|
/* default shell command and options. */
|
||||||
#define SHELL_COMMAND "/bin/sh -login"
|
#define SHELL_COMMAND "/bin/sh -login"
|
||||||
extern char **environ;
|
|
||||||
|
|
||||||
const char *kSpawnAlertMessage = "alert --stop " "'Cannot execute \"%s\":\n"
|
|
||||||
|
const static char *kSpawnAlertMessage = "alert --stop " "'Cannot execute \"%s\":\n"
|
||||||
"\t%s\n'"
|
"\t%s\n'"
|
||||||
"'Use Default Shell' 'Abort'";
|
"'Use Default Shell' 'Abort'";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set environment varriable.
|
* Set environment variable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(__HAIKU__) || defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST)
|
#if !defined(__HAIKU__) || defined(HAIKU_TARGET_PLATFORM_LIBBE_TEST)
|
||||||
int
|
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
|
static int
|
||||||
setenv(const char *var, const char *value, bool overwrite)
|
setenv(const char *var, const char *value, bool overwrite)
|
||||||
{
|
{
|
||||||
int envindex = 0;
|
int envindex = 0;
|
||||||
@ -110,9 +113,9 @@ typedef struct
|
|||||||
#define PTY_NG 1 /* pty open or set termios NG */
|
#define PTY_NG 1 /* pty open or set termios NG */
|
||||||
#define PTY_WS 2 /* pty need WINSIZE (row and col ) */
|
#define PTY_WS 2 /* pty need WINSIZE (row and col ) */
|
||||||
|
|
||||||
/* global variables */
|
|
||||||
|
|
||||||
pid_t gShPid;
|
|
||||||
|
static pid_t sShPid;
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
@ -130,7 +133,7 @@ receive_handshake_message(handshake_t& handshake)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
static int
|
||||||
spawn_shell(int row, int col, const char *command, const char *coding)
|
spawn_shell(int row, int col, const char *command, const char *coding)
|
||||||
{
|
{
|
||||||
signal(SIGTTOU, SIG_IGN);
|
signal(SIGTTOU, SIG_IGN);
|
||||||
@ -180,7 +183,7 @@ spawn_shell(int row, int col, const char *command, const char *coding)
|
|||||||
thread_id terminalThread = find_thread(NULL);
|
thread_id terminalThread = find_thread(NULL);
|
||||||
|
|
||||||
/* Fork a child process. */
|
/* Fork a child process. */
|
||||||
if ((gShPid = fork()) < 0) {
|
if ((sShPid = fork()) < 0) {
|
||||||
close(master);
|
close(master);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -188,7 +191,7 @@ spawn_shell(int row, int col, const char *command, const char *coding)
|
|||||||
|
|
||||||
handshake_t handshake;
|
handshake_t handshake;
|
||||||
|
|
||||||
if (gShPid == 0) {
|
if (sShPid == 0) {
|
||||||
// Now in child process.
|
// Now in child process.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -443,7 +446,7 @@ spawn_shell(int row, int col, const char *command, const char *coding)
|
|||||||
handshake.row = row;
|
handshake.row = row;
|
||||||
handshake.col = col;
|
handshake.col = col;
|
||||||
handshake.status = PTY_WS;
|
handshake.status = PTY_WS;
|
||||||
send_handshake_message(gShPid, handshake);
|
send_handshake_message(sShPid, handshake);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,3 +454,116 @@ spawn_shell(int row, int col, const char *command, const char *coding)
|
|||||||
return (done > 0) ? master : -1;
|
return (done > 0) ? master : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_shell(int fd)
|
||||||
|
{
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
int status;
|
||||||
|
kill(-sShPid, SIGHUP);
|
||||||
|
wait(&status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Shell::Shell()
|
||||||
|
:fFd(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Shell::~Shell()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Shell::Open(int row, int col, const char *command, const char *coding)
|
||||||
|
{
|
||||||
|
fFd = spawn_shell(row, col, command, coding);
|
||||||
|
if (fFd < 0)
|
||||||
|
return fFd;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Shell::Close()
|
||||||
|
{
|
||||||
|
if (fFd >= 0) {
|
||||||
|
close_shell(fFd);
|
||||||
|
fFd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
Shell::TTYName() const
|
||||||
|
{
|
||||||
|
return ttyname(fFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
Shell::Read(void *buffer, size_t numBytes)
|
||||||
|
{
|
||||||
|
if (fFd < 0)
|
||||||
|
return B_NO_INIT;
|
||||||
|
|
||||||
|
return read(fFd, buffer, numBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
Shell::Write(const void *buffer, size_t numBytes)
|
||||||
|
{
|
||||||
|
if (fFd < 0)
|
||||||
|
return B_NO_INIT;
|
||||||
|
|
||||||
|
return write(fFd, buffer, numBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Shell::UpdateWindowSize(int rows, int columns)
|
||||||
|
{
|
||||||
|
struct winsize winSize;
|
||||||
|
winSize.ws_row = rows;
|
||||||
|
winSize.ws_col = columns;
|
||||||
|
ioctl(fFd, TIOCSWINSZ, &winSize);
|
||||||
|
Signal(SIGWINCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Shell::Signal(int signal)
|
||||||
|
{
|
||||||
|
kill(-sShPid, signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Shell::GetAttr(struct termios &attr)
|
||||||
|
{
|
||||||
|
return tcgetattr(fFd, &attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Shell::SetAttr(struct termios &attr)
|
||||||
|
{
|
||||||
|
return tcsetattr(fFd, TCSANOW, &attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Shell::FD() const
|
||||||
|
{
|
||||||
|
return fFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -80,14 +80,30 @@
|
|||||||
#define APC 0x9F
|
#define APC 0x9F
|
||||||
#define RDEL 0xFF
|
#define RDEL 0xFF
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototype:
|
|
||||||
*/
|
|
||||||
|
|
||||||
int spawn_shell (int, int, const char *, const char *);
|
class Shell {
|
||||||
void Setenv (const char *, const char *);
|
public:
|
||||||
|
Shell();
|
||||||
|
~Shell();
|
||||||
|
|
||||||
extern pid_t gShPid; /* shell process ID */
|
status_t Open(int row, int col, const char *command, const char *coding);
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
const char * TTYName() const;
|
||||||
|
|
||||||
|
ssize_t Read(void *buffer, size_t numBytes);
|
||||||
|
ssize_t Write(const void *buffer, size_t numBytes);
|
||||||
|
|
||||||
|
void UpdateWindowSize(int row, int columns);
|
||||||
|
void Signal(int signal);
|
||||||
|
|
||||||
|
status_t GetAttr(struct termios &attr);
|
||||||
|
status_t SetAttr(struct termios &attr);
|
||||||
|
|
||||||
|
int FD() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fFd;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SPAWN_H */
|
#endif /* SPAWN_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user