mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-09-01 09:51:13 +02:00
CShellWindow/COPKGManager: rework shell shell mode handling
Modes were handled with bool values inside manager and this is not really
enough. Now we use the real parameters for more flexibility.
Origin commit data
------------------
Commit: e1e8cb0142
Author: Thilo Graf <dbt@novatux.de>
Date: 2015-05-28 (Thu, 28 May 2015)
This commit is contained in:
@@ -62,7 +62,7 @@ CShellWindow::CShellWindow(const std::string &Command, const int Mode, int *Res,
|
||||
void CShellWindow::exec()
|
||||
{
|
||||
std::string cmd;
|
||||
if (!(mode & VERBOSE)){
|
||||
if (mode == 0){
|
||||
cmd = "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin ; export PATH ; " + command + " 2>/dev/null >&2";
|
||||
int r = my_system(cmd.c_str());
|
||||
if (res) {
|
||||
@@ -72,148 +72,152 @@ void CShellWindow::exec()
|
||||
*res = WEXITSTATUS(r);
|
||||
dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! system returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
pid_t pid = 0;
|
||||
cmd = command + " 2>&1";
|
||||
FILE *f = my_popen(pid, cmd.c_str(), "r");
|
||||
if (!f) {
|
||||
if (res)
|
||||
*res = -1;
|
||||
dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! my_popen returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
pid_t pid = 0;
|
||||
cmd = command + " 2>&1";
|
||||
FILE *f = my_popen(pid, cmd.c_str(), "r");
|
||||
if (!f) {
|
||||
if (res)
|
||||
*res = -1;
|
||||
dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] Error! my_popen returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str());
|
||||
return;
|
||||
}
|
||||
Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO];
|
||||
int h_shell = frameBuffer->getScreenHeight();
|
||||
int w_shell = frameBuffer->getScreenWidth();
|
||||
unsigned int lines_max = h_shell / font->getHeight();
|
||||
list<std::string> lines;
|
||||
CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenX(), w_shell, h_shell);
|
||||
if (textBox == NULL){
|
||||
textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition);
|
||||
textBox->enableSaveScreen(false);
|
||||
}
|
||||
struct pollfd fds;
|
||||
fds.fd = fileno(f);
|
||||
fds.events = POLLIN | POLLHUP | POLLERR;
|
||||
fcntl(fds.fd, F_SETFL, fcntl(fds.fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
Font *font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO];
|
||||
int h_shell = frameBuffer->getScreenHeight();
|
||||
int w_shell = frameBuffer->getScreenWidth();
|
||||
unsigned int lines_max = h_shell / font->getHeight();
|
||||
list<std::string> lines;
|
||||
CBox textBoxPosition(frameBuffer->getScreenX(), frameBuffer->getScreenX(), w_shell, h_shell);
|
||||
textBox = new CTextBox(cmd.c_str(), font, CTextBox::BOTTOM, &textBoxPosition);
|
||||
textBox->enableSaveScreen(false);
|
||||
struct pollfd fds;
|
||||
fds.fd = fileno(f);
|
||||
fds.events = POLLIN | POLLHUP | POLLERR;
|
||||
fcntl(fds.fd, F_SETFL, fcntl(fds.fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
uint64_t lastPaint = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
|
||||
bool ok = true, nlseen = false, dirty = false, incomplete = false;
|
||||
char output[1024];
|
||||
std::string txt = "";
|
||||
std::string line = "";
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
uint64_t lastPaint = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
|
||||
bool ok = true, nlseen = false, dirty = false, incomplete = false;
|
||||
char output[1024];
|
||||
std::string txt = "";
|
||||
std::string line = "";
|
||||
do {
|
||||
uint64_t now;
|
||||
fds.revents = 0;
|
||||
int r = poll(&fds, 1, 300);
|
||||
if (r > 0) {
|
||||
if (!feof(f)) {
|
||||
gettimeofday(&tv,NULL);
|
||||
now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
|
||||
|
||||
do {
|
||||
uint64_t now;
|
||||
fds.revents = 0;
|
||||
int r = poll(&fds, 1, 300);
|
||||
if (r > 0) {
|
||||
if (!feof(f)) {
|
||||
gettimeofday(&tv,NULL);
|
||||
now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
|
||||
unsigned int lines_read = 0;
|
||||
while (fgets(output, sizeof(output), f)) {
|
||||
char *outputp = output;
|
||||
dirty = true;
|
||||
|
||||
unsigned int lines_read = 0;
|
||||
while (fgets(output, sizeof(output), f)) {
|
||||
char *outputp = output;
|
||||
dirty = true;
|
||||
for (int i = 0; output[i] && !nlseen; i++)
|
||||
switch (output[i]) {
|
||||
case '\b':
|
||||
if (outputp > output)
|
||||
outputp--;
|
||||
*outputp = 0;
|
||||
break;
|
||||
case '\r':
|
||||
outputp = output;
|
||||
break;
|
||||
case '\n':
|
||||
lines_read++;
|
||||
nlseen = true;
|
||||
*outputp = 0;
|
||||
break;
|
||||
default:
|
||||
*outputp++ = output[i];
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; output[i] && !nlseen; i++)
|
||||
switch (output[i]) {
|
||||
case '\b':
|
||||
if (outputp > output)
|
||||
outputp--;
|
||||
*outputp = 0;
|
||||
break;
|
||||
case '\r':
|
||||
outputp = output;
|
||||
break;
|
||||
case '\n':
|
||||
lines_read++;
|
||||
nlseen = true;
|
||||
*outputp = 0;
|
||||
break;
|
||||
default:
|
||||
*outputp++ = output[i];
|
||||
break;
|
||||
if (outputp < output + sizeof(output))
|
||||
*outputp = 0;
|
||||
line += std::string(output);
|
||||
if (incomplete)
|
||||
lines.pop_back();
|
||||
if (nlseen) {
|
||||
lines.push_back(line);
|
||||
line.clear();
|
||||
nlseen = false;
|
||||
incomplete = false;
|
||||
} else {
|
||||
lines.push_back(line);
|
||||
incomplete = true;
|
||||
}
|
||||
|
||||
if (outputp < output + sizeof(output))
|
||||
*outputp = 0;
|
||||
line += std::string(output);
|
||||
if (incomplete)
|
||||
lines.pop_back();
|
||||
if (nlseen) {
|
||||
lines.push_back(line);
|
||||
line.clear();
|
||||
nlseen = false;
|
||||
incomplete = false;
|
||||
} else {
|
||||
lines.push_back(line);
|
||||
incomplete = true;
|
||||
}
|
||||
//callback for line handler
|
||||
std::string s_output = std::string((output));
|
||||
OnShellOutputLoop(&s_output, res, &ok);
|
||||
dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d ok=%d\n", __func__, __LINE__, *res, ok);
|
||||
|
||||
//callback for line handler
|
||||
std::string s_output = std::string((output));
|
||||
OnShellOutputLoop(&s_output, res, &ok);
|
||||
dprintf(DEBUG_NORMAL, "[CShellWindow] [%s - %d] res=%d ok=%d\n", __func__, __LINE__, *res, ok);
|
||||
|
||||
if (lines.size() > lines_max)
|
||||
lines.pop_front();
|
||||
txt = "";
|
||||
bool first = true;
|
||||
for (std::list<std::string>::const_iterator it = lines.begin(), end = lines.end(); it != end; ++it) {
|
||||
if (!first)
|
||||
txt += '\n';
|
||||
first = false;
|
||||
txt += *it;
|
||||
if (lines.size() > lines_max)
|
||||
lines.pop_front();
|
||||
txt = "";
|
||||
bool first = true;
|
||||
for (std::list<std::string>::const_iterator it = lines.begin(), end = lines.end(); it != end; ++it) {
|
||||
if (!first)
|
||||
txt += '\n';
|
||||
first = false;
|
||||
txt += *it;
|
||||
}
|
||||
if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) {
|
||||
textBox->setText(&txt, textBox->getWindowsPos().iWidth, false);
|
||||
if (!textBox->isPainted())
|
||||
if (mode & VERBOSE) textBox->paint();
|
||||
lines_read = 0;
|
||||
lastPaint = now;
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) {
|
||||
textBox->setText(&txt, textBox->getWindowsPos().iWidth, false);
|
||||
if (!textBox->isPainted())
|
||||
textBox->paint();
|
||||
lines_read = 0;
|
||||
lastPaint = now;
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else
|
||||
ok = false;
|
||||
} else if (r < 0)
|
||||
ok = false;
|
||||
} else if (r < 0)
|
||||
ok = false;
|
||||
|
||||
gettimeofday(&tv,NULL);
|
||||
now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
|
||||
if (!ok || (r < 1 && dirty && lastPaint + 250000 < now)) {
|
||||
gettimeofday(&tv,NULL);
|
||||
now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000);
|
||||
if (!ok || (r < 1 && dirty && lastPaint + 250000 < now)) {
|
||||
textBox->setText(&txt, textBox->getWindowsPos().iWidth, false);
|
||||
if (!textBox->isPainted())
|
||||
if (mode & VERBOSE) textBox->paint();
|
||||
lastPaint = now;
|
||||
dirty = false;
|
||||
}
|
||||
} while(ok);
|
||||
|
||||
if (mode & VERBOSE) {
|
||||
txt += "\n...ready";
|
||||
textBox->setText(&txt, textBox->getWindowsPos().iWidth, false);
|
||||
if (!textBox->isPainted())
|
||||
textBox->paint();
|
||||
lastPaint = now;
|
||||
dirty = false;
|
||||
}
|
||||
} while(ok);
|
||||
|
||||
txt += "\n...ready";
|
||||
textBox->setText(&txt, textBox->getWindowsPos().iWidth, false);
|
||||
fclose(f);
|
||||
int s;
|
||||
errno = 0;
|
||||
int r = waitpid(pid, &s, 0);
|
||||
|
||||
fclose(f);
|
||||
int s;
|
||||
errno = 0;
|
||||
int r = waitpid(pid, &s, 0);
|
||||
|
||||
if (res){
|
||||
//if res value was generated inside signal, then use foreign res from signal instead own res value
|
||||
if (OnShellOutputLoop.empty()){
|
||||
if (r == -1)
|
||||
*res = errno;
|
||||
else
|
||||
*res = WEXITSTATUS(s);
|
||||
if (res){
|
||||
//if res value was generated inside signal, then use foreign res from signal instead own res value
|
||||
if (OnShellOutputLoop.empty()){
|
||||
if (r == -1)
|
||||
*res = errno;
|
||||
else
|
||||
*res = WEXITSTATUS(s);
|
||||
}
|
||||
}
|
||||
|
||||
showResult();
|
||||
}
|
||||
|
||||
showResult();
|
||||
}
|
||||
|
||||
void CShellWindow::showResult()
|
||||
@@ -233,31 +237,32 @@ void CShellWindow::showResult()
|
||||
show_button = true;
|
||||
}else{
|
||||
OnResultOk(res);
|
||||
exit = true;
|
||||
exit = true; //TODO: evaluate plausible statement
|
||||
}
|
||||
}
|
||||
|
||||
if (show_button){
|
||||
int b_width = 150;
|
||||
int b_height = 35;
|
||||
int xpos = frameBuffer->getScreenWidth() - b_width;
|
||||
int ypos = frameBuffer->getScreenHeight() - b_height;
|
||||
CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_BACK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true);
|
||||
btn.paint();
|
||||
if ((mode & VERBOSE)){
|
||||
if (show_button){
|
||||
int b_width = 150;
|
||||
int b_height = 35;
|
||||
int xpos = frameBuffer->getScreenWidth() - b_width;
|
||||
int ypos = frameBuffer->getScreenHeight() - b_height;
|
||||
CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_BACK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true);
|
||||
btn.paint();
|
||||
}
|
||||
|
||||
neutrino_msg_t msg;
|
||||
neutrino_msg_data_t data;
|
||||
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]);
|
||||
|
||||
if (!exit)
|
||||
{
|
||||
do
|
||||
g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd);
|
||||
while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout);
|
||||
}
|
||||
textBox->hide();
|
||||
}
|
||||
|
||||
neutrino_msg_t msg;
|
||||
neutrino_msg_data_t data;
|
||||
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]);
|
||||
|
||||
if (!exit)
|
||||
{
|
||||
do
|
||||
g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd);
|
||||
while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout);
|
||||
}
|
||||
|
||||
textBox->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -45,11 +45,14 @@ class CShellWindow : public sigc::trackable
|
||||
void showResult();
|
||||
|
||||
public:
|
||||
//shell window modes for handled shell output. //NOTE: mode 0 use only system calls, with unhandled return values and no handled shell output
|
||||
enum shellwindow_modes
|
||||
{
|
||||
VERBOSE = 1,
|
||||
ACKNOWLEDGE = 2,
|
||||
ACKNOWLEDGE_EVENT = 4
|
||||
/*SYSTEM = 0, */
|
||||
QUIET = 1, // no window
|
||||
VERBOSE = 2, // show window
|
||||
ACKNOWLEDGE = 4, // show result button inside window after execution, no message box NOTE: only in VERBOSE mode
|
||||
ACKNOWLEDGE_EVENT = 8 // same like ACKNOWLEDGE but shows a default error message box or a slot handled action instead default error message box
|
||||
};
|
||||
CShellWindow(const std::string &Command, const int Mode = 0, int* Res = NULL, bool auto_exec = true);
|
||||
~CShellWindow();
|
||||
|
Reference in New Issue
Block a user