1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-25 15:56:15 +02:00

Added Launcher class

Currently the launched application is exec-ed from deep within the menu
code. This means a lot of destructors are never run and as a result
for example file descriptors from the menu remain open in the launched
process.

This is a first step to move the launch invocation from a deep call
stack to the top level.
This commit is contained in:
Maarten ter Huurne 2014-08-07 16:48:30 +02:00
parent e32964bb50
commit 3e34124e68
5 changed files with 69 additions and 7 deletions

View File

@ -2,7 +2,7 @@ bin_PROGRAMS = gmenu2x
gmenu2x_SOURCES = font.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
filelister.cpp gmenu2x.cpp iconbutton.cpp imagedialog.cpp inputdialog.cpp \
inputmanager.cpp linkapp.cpp link.cpp \
inputmanager.cpp linkapp.cpp link.cpp launcher.cpp \
menu.cpp menusettingbool.cpp menusetting.cpp menusettingdir.cpp \
menusettingfile.cpp menusettingimage.cpp menusettingint.cpp \
menusettingmultistring.cpp menusettingrgba.cpp menusettingstring.cpp \

View File

@ -30,6 +30,7 @@
#include "helppopup.h"
#include "iconbutton.h"
#include "inputdialog.h"
#include "launcher.h"
#include "linkapp.h"
#include "mediamonitor.h"
#include "menu.h"
@ -648,7 +649,9 @@ void GMenu2X::explorer() {
#ifdef ENABLE_CPUFREQ
setClock(cpuFreqAppDefault);
#endif
execlp("/bin/sh","/bin/sh","-c",command.c_str(),NULL);
Launcher launcher(vector<string> { "/bin/sh", "-c", command });
launcher.exec();
//if execution continues then something went wrong and as we already called SDL_Quit we cannot continue
//try relaunching gmenu2x

33
src/launcher.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "launcher.h"
#include "debug.h"
#include <cerrno>
#include <cstring>
#include <unistd.h>
using namespace std;
Launcher::Launcher(vector<string> const& commandLine)
: commandLine(commandLine)
{
}
Launcher::Launcher(vector<string> && commandLine)
: commandLine(commandLine)
{
}
void Launcher::exec()
{
vector<const char *> args;
args.reserve(commandLine.size() + 1);
for (auto arg : commandLine) {
args.push_back(arg.c_str());
}
args.push_back(nullptr);
execvp(commandLine[0].c_str(), (char* const*)&args[0]);
WARNING("Failed to exec '%s': %s\n",
commandLine[0].c_str(), strerror(errno));
}

20
src/launcher.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef LAUNCHER_H
#define LAUNCHER_H
#include <string>
#include <vector>
class Launcher
{
public:
Launcher(std::vector<std::string> const& commandLine);
Launcher(std::vector<std::string> && commandLine);
void exec();
private:
std::vector<std::string> commandLine;
};
#endif // LAUNCHER_H

View File

@ -23,6 +23,7 @@
#include "debug.h"
#include "delegate.h"
#include "gmenu2x.h"
#include "launcher.h"
#include "menu.h"
#include "selector.h"
#include "surface.h"
@ -40,6 +41,7 @@
#include <array>
#include <fstream>
#include <sstream>
#include <utility>
#if defined(PLATFORM_A320) || defined(PLATFORM_GCW0)
#include <linux/vt.h>
@ -608,17 +610,21 @@ void LinkApp::launch(const string &selectedFile) {
}
#endif
vector<string> commandLine;
if (isOpk()) {
#ifdef HAVE_LIBOPK
execlp("opkrun", "opkrun", "-m", metadata.c_str(), opkFile.c_str(),
!params.empty() ? params.c_str() : NULL,
NULL);
commandLine = { "opkrun", "-m", metadata, opkFile };
if (!params.empty()) {
commandLine.push_back(params);
}
#endif
} else {
std::string command = exec + " " + params;
execlp("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL);
commandLine = { "/bin/sh", "-c", exec + " " + params };
}
Launcher launcher(move(commandLine));
launcher.exec();
//if execution continues then something went wrong and as we already called SDL_Quit we cannot continue
//try relaunching gmenu2x
gmenu2x->main();