|
|
|
@ -831,6 +831,7 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static bool firstLaunchProgram = true;
|
|
|
|
|
|
|
|
|
|
if (firstLaunchProgram)
|
|
|
|
|
{
|
|
|
|
|
// The aim of this is to avoid defunct process.
|
|
|
|
@ -896,6 +897,110 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool launchProgramArray (const std::string &programName, const std::vector<std::string> &arguments, bool log)
|
|
|
|
|
{
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
PROCESS_INFORMATION pi;
|
|
|
|
|
|
|
|
|
|
std::string argumentsJoined = joinArguments(arguments);
|
|
|
|
|
|
|
|
|
|
if (!createProcess(programName, argumentsJoined, log, pi)) return false;
|
|
|
|
|
|
|
|
|
|
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str());
|
|
|
|
|
CloseHandle( pi.hProcess );
|
|
|
|
|
CloseHandle( pi.hThread );
|
|
|
|
|
return true;
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
#ifdef NL_OS_MAC
|
|
|
|
|
// special OS X case with bundles
|
|
|
|
|
if (toLower(programName).find(".app") != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
// we need to open bundles with "open" command
|
|
|
|
|
std::string command = NLMISC::toString("open \"%s\"", programName.c_str());
|
|
|
|
|
|
|
|
|
|
// append arguments if any
|
|
|
|
|
if (!arguments.empty())
|
|
|
|
|
{
|
|
|
|
|
command += NLMISC::toString(" --args %s", joinArguments(arguments).c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int res = system(command.c_str());
|
|
|
|
|
|
|
|
|
|
if (!res) return true;
|
|
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
|
{
|
|
|
|
|
nlwarning ("LAUNCH: Failed launched '%s' with arg '%s' return code %d", programName.c_str(), arguments.c_str(), res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static bool firstLaunchProgram = true;
|
|
|
|
|
|
|
|
|
|
if (firstLaunchProgram)
|
|
|
|
|
{
|
|
|
|
|
// The aim of this is to avoid defunct process.
|
|
|
|
|
//
|
|
|
|
|
// From "man signal":
|
|
|
|
|
//------
|
|
|
|
|
// According to POSIX (3.3.1.3) it is unspecified what happens when SIGCHLD is set to SIG_IGN. Here
|
|
|
|
|
// the BSD and SYSV behaviours differ, causing BSD software that sets the action for SIGCHLD to
|
|
|
|
|
// SIG_IGN to fail on Linux.
|
|
|
|
|
//------
|
|
|
|
|
//
|
|
|
|
|
// But it works fine on my GNU/Linux so I do this because it's easier :) and I don't know exactly
|
|
|
|
|
// what to do to be portable.
|
|
|
|
|
signal(SIGCHLD, SIG_IGN);
|
|
|
|
|
|
|
|
|
|
firstLaunchProgram = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Store the size of each arg
|
|
|
|
|
vector<char *> argv(arguments.size()+2);
|
|
|
|
|
uint i = 0;
|
|
|
|
|
argv[i] = (char *)programName.c_str();
|
|
|
|
|
for (; i < arguments.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
argv[i+1] = (char *) arguments[i].c_str();
|
|
|
|
|
}
|
|
|
|
|
argv[i+1] = NULL;
|
|
|
|
|
|
|
|
|
|
int status = vfork ();
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
|
/// WARNING : NO MORE INSTRUCTION AFTER VFORK !
|
|
|
|
|
/// READ VFORK manual
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
|
if (status == -1)
|
|
|
|
|
{
|
|
|
|
|
char *err = strerror (errno);
|
|
|
|
|
if (log)
|
|
|
|
|
nlwarning("LAUNCH: Failed launched '%s' with arg '%s' err %d: '%s'", programName.c_str(), arguments.c_str(), errno, err);
|
|
|
|
|
}
|
|
|
|
|
else if (status == 0)
|
|
|
|
|
{
|
|
|
|
|
// Exec (the only allowed instruction after vfork)
|
|
|
|
|
status = execvp(programName.c_str(), &argv.front());
|
|
|
|
|
|
|
|
|
|
if (status == -1)
|
|
|
|
|
{
|
|
|
|
|
perror("Failed launched");
|
|
|
|
|
_exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str());
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sint launchProgramAndWaitForResult(const std::string &programName, const std::string &arguments, bool log)
|
|
|
|
|
{
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|