aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop-utilities/lumina-terminal/TerminalWidget.cpp41
-rw-r--r--desktop-utilities/lumina-terminal/TerminalWidget.h1
-rw-r--r--desktop-utilities/lumina-terminal/TtyProcess.cpp72
-rw-r--r--desktop-utilities/lumina-terminal/TtyProcess.h21
4 files changed, 88 insertions, 47 deletions
diff --git a/desktop-utilities/lumina-terminal/TerminalWidget.cpp b/desktop-utilities/lumina-terminal/TerminalWidget.cpp
index 939b9711..6818201a 100644
--- a/desktop-utilities/lumina-terminal/TerminalWidget.cpp
+++ b/desktop-utilities/lumina-terminal/TerminalWidget.cpp
@@ -19,24 +19,15 @@ TerminalWidget::TerminalWidget(QWidget *parent, QString dir) : QTextEdit(parent)
//Create/open the TTY port
PROC = new TTYProcess(this);
qDebug() << "Open new TTY";
- int fd;
- bool ok = PROC->startTTY( fd, QProcessEnvironment::systemEnvironment().value("SHELL","/bin/sh") );
+ //int fd;
+ bool ok = PROC->startTTY( QProcessEnvironment::systemEnvironment().value("SHELL","/bin/sh") );
qDebug() << " - opened:" << ok;
this->setEnabled(PROC->isOpen());
//Connect the signals/slots
- //connect(PROC, SIGNAL(readyRead()), this, SLOT(UpdateText()) );
- connect(PROC, SIGNAL(aboutToClose()), this, SLOT(ShellClosed()) );
-
- sn= new QSocketNotifier(fd, QSocketNotifier::Read);
- sn->setEnabled(true);
- connect(sn, SIGNAL(activated(int)), this, SLOT(UpdateText()));
+ connect(PROC, SIGNAL(readyRead()), this, SLOT(UpdateText()) );
+ connect(PROC, SIGNAL(processClosed()), this, SLOT(ShellClosed()) );
- upTimer = new QTimer(this);
- upTimer->setInterval(1000);
- // connect(upTimer, SIGNAL(timeout()), this, SLOT(UpdateText()) );
-
- upTimer->start();
}
TerminalWidget::~TerminalWidget(){
@@ -44,8 +35,7 @@ TerminalWidget::~TerminalWidget(){
}
void TerminalWidget::aboutToClose(){
- if(PROC->isOpen()){ PROC->close(); } //TTY PORT
- //if(PROC->state()!=QProcess::NotRunning){ PROC->close(); PROC->kill(); } //QProcess
+ if(PROC->isOpen()){ PROC->closeTTY(); } //TTY PORT
}
// ==================
@@ -58,10 +48,11 @@ void TerminalWidget::UpdateText(){
//if ( PROC->bytesAvailable() <= 0 )
// return;
- qDebug() << "Reading all data";
+ /*qDebug() << "Reading all data";
char buffer[64];
ssize_t rtot = read(sn->socket(),&buffer,64);
- buffer[rtot]='\0';
+ buffer[rtot]='\0';*/
+ QByteArray buffer = PROC->readTTY();
qDebug() << "Process Data:" << QString(buffer);
this->insertPlainText(QString(buffer));
//adjust the scrollbar as needed
@@ -79,22 +70,22 @@ void TerminalWidget::keyPressEvent(QKeyEvent *ev){
//Check for special key combinations first
QString txt = ev->text();
if(txt.isEmpty()){ return; } // modifier key - nothing to send yet
- switch(ev->key()){
+ /*switch(ev->key()){
//case Qt::Key_Backspace:
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Up:
case Qt::Key_Down:
break;
- /*case Qt::Key_Return:
- case Qt::Key_Enter:
- txt = "\r";*/
- default:
+ //case Qt::Key_Return:
+ //case Qt::Key_Enter:
+ //txt = "\r";
+ //default:
//All other events can get echoed onto the widget (non-movement)
- QTextEdit::keyPressEvent(ev); //echo the input on the widget
- }
+ //QTextEdit::keyPressEvent(ev); //echo the input on the widget
+ }*/
QByteArray ba; ba.append(txt); //avoid any byte conversions
- qDebug() << "Forward Input:" << txt << ev->key();
+ qDebug() << "Forward Input:" << txt << ev->key() << ba;
PROC->writeTTY(ba);
}
diff --git a/desktop-utilities/lumina-terminal/TerminalWidget.h b/desktop-utilities/lumina-terminal/TerminalWidget.h
index 7e08226a..59d097d4 100644
--- a/desktop-utilities/lumina-terminal/TerminalWidget.h
+++ b/desktop-utilities/lumina-terminal/TerminalWidget.h
@@ -27,7 +27,6 @@ private:
//QProcess *PROC;
QSocketNotifier *sn;
- QTimer *upTimer;
private slots:
void UpdateText();
diff --git a/desktop-utilities/lumina-terminal/TtyProcess.cpp b/desktop-utilities/lumina-terminal/TtyProcess.cpp
index e0375410..b3c6aebc 100644
--- a/desktop-utilities/lumina-terminal/TtyProcess.cpp
+++ b/desktop-utilities/lumina-terminal/TtyProcess.cpp
@@ -1,24 +1,17 @@
#include "TtyProcess.h"
-//Standard C library functions for PTY access/setup
-#include <stdlib.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <signal.h>
-
-TTYProcess::TTYProcess(QObject *parent) : QFile(parent){
- childProc = 0;
+TTYProcess::TTYProcess(QObject *parent) : QObject(parent){
+ childProc = 0;
+ sn = 0;
+ ttyfd = 0;
}
TTYProcess::~TTYProcess(){
- kill(childProc, SIGKILL);
+ closeTTY(); //make sure everything is closed properly
}
// === PUBLIC ===
-bool TTYProcess::startTTY(int &retfd, QString prog, QStringList args){
+bool TTYProcess::startTTY(QString prog, QStringList args){
//Turn the program/arguments into C-compatible arrays
char cprog[prog.length()]; strcpy(cprog, prog.toLocal8Bit().data());
char *cargs[args.length()+2];
@@ -44,12 +37,28 @@ bool TTYProcess::startTTY(int &retfd, QString prog, QStringList args){
if(tmp<0){ return false; } //error
else{
childProc = tmp;
- this->setFileName( ptsname(FD) );
- retfd = FD;
+ //Load the file for close notifications
+ //TO-DO
+ //Watch the socket for activity
+ sn= new QSocketNotifier(FD, QSocketNotifier::Read);
+ sn->setEnabled(true);
+ connect(sn, SIGNAL(activated(int)), this, SLOT(checkStatus(int)) );
ttyfd = FD;
qDebug() << " - PTY:" << ptsname(FD);
- return this->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
- //return true;
+ return true;
+ }
+}
+
+void TTYProcess::closeTTY(){
+ int junk;
+ if(0==waitpid(childProc, &junk, WNOHANG)){
+ kill(childProc, SIGKILL);
+ }
+ if(ttyfd!=0 && sn!=0){
+ sn->setEnabled(false);
+ ::close(ttyfd);
+ ttyfd = 0;
+ emit processClosed();
}
}
@@ -58,6 +67,20 @@ void TTYProcess::writeTTY(QByteArray output){
qDebug() << "Wrote:" << written;
}
+QByteArray TTYProcess::readTTY(){
+ QByteArray BA;
+ if(sn==0){ return BA; } //not setup yet
+ char buffer[64];
+ ssize_t rtot = read(sn->socket(),&buffer,64);
+ buffer[rtot]='\0';
+ BA = QByteArray(buffer, rtot);
+ return BA;
+}
+
+bool TTYProcess::isOpen(){
+ return (ttyfd!=0);
+}
+
// === PRIVATE ===
pid_t TTYProcess::LaunchProcess(int& fd, char *prog, char **child_args){
//Returns: -1 for errors, positive value (file descriptor) for the master side of the TTY to watch
@@ -101,3 +124,18 @@ pid_t TTYProcess::LaunchProcess(int& fd, char *prog, char **child_args){
//MASTER thread (or error)
return PID;
}
+
+// === PRIVATE SLOTS ===
+void TTYProcess::checkStatus(int sock){
+ //This is run when the socket gets activated
+ if(sock!=ttyfd){
+
+ }
+ //Make sure the child PID is still active
+ int junk;
+ if(0!=waitpid(childProc, &junk, WNOHANG)){
+ this->closeTTY(); //clean up everything else
+ }else{
+ emit readyRead();
+ }
+}
diff --git a/desktop-utilities/lumina-terminal/TtyProcess.h b/desktop-utilities/lumina-terminal/TtyProcess.h
index 38cca5a4..45cdedd2 100644
--- a/desktop-utilities/lumina-terminal/TtyProcess.h
+++ b/desktop-utilities/lumina-terminal/TtyProcess.h
@@ -13,7 +13,7 @@
#define _LUMINA_DESKTOP_UTILITIES_TERMINAL_TTY_PROCESS_WIDGET_H
#include <QDebug>
-#include <QFile>
+#include <QSocketNotifier>
//Standard C library functions for PTY access/setup
#include <stdlib.h>
@@ -22,21 +22,29 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <signal.h>
-
-class TTYProcess : public QFile{
+class TTYProcess : public QObject{
Q_OBJECT
public:
TTYProcess(QObject *parent = 0);
~TTYProcess();
- bool startTTY(int &retfd, QString prog, QStringList args = QStringList());
+ bool startTTY(QString prog, QStringList args = QStringList());
+ void closeTTY();
+
+ //Primary read/write functions
void writeTTY(QByteArray output);
+ QByteArray readTTY();
+ //Status update checks
+ bool isOpen();
+
private:
pid_t childProc;
int ttyfd;
+ QSocketNotifier *sn;
//====================================
// C Library function for setting up the PTY
@@ -49,7 +57,12 @@ private:
//====================================
static pid_t LaunchProcess(int& fd, char *prog, char **child_args);
+private slots:
+ void checkStatus(int);
+signals:
+ void readyRead();
+ void processClosed();
};
#endif
bgstack15