- enhancement: redirect input to program in Linux

This commit is contained in:
Roy Qu 2021-12-29 19:15:50 +08:00
parent 3be06fe586
commit 88c5c836a6
2 changed files with 55 additions and 25 deletions

View File

@ -244,10 +244,19 @@ void CompilerManager::run(const QString &filename, const QString &arguments, con
#else #else
QString newArguments; QString newArguments;
if (consoleFlag!=0) { if (consoleFlag!=0) {
newArguments = QString(" -e \"%1\" %2 \"%3\" %4") if (redirectInput) {
newArguments = QString(" -e \"%1\" %2 \"%3\" \"%4\" %5")
.arg(includeTrailingPathDelimiter(pSettings->dirs().appDir())+"consolepauser")
.arg(consoleFlag)
.arg(redirectInputFilename)
.arg(localizePath(filename))
.arg(arguments);
} else {
newArguments = QString(" -e \"%1\" %2 \"%3\" %4")
.arg(includeTrailingPathDelimiter(pSettings->dirs().appDir())+"consolepauser") .arg(includeTrailingPathDelimiter(pSettings->dirs().appDir())+"consolepauser")
.arg(consoleFlag) .arg(consoleFlag)
.arg(localizePath(filename)).arg(arguments); .arg(localizePath(filename)).arg(arguments);
}
} else { } else {
newArguments = QString(" -e \"%1\" %2") newArguments = QString(" -e \"%1\" %2")
.arg(localizePath(filename)).arg(arguments); .arg(localizePath(filename)).arg(arguments);

View File

@ -17,7 +17,9 @@
*/ */
#include <string> #include <string>
#include <vector>
using std::string; using std::string;
using std::vector;
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -47,46 +49,65 @@ void PauseExit(int exitcode, bool reInp) {
exit(exitcode); exit(exitcode);
} }
string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) { vector<string> GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) {
string result; vector<string> result;
int flags = atoi(argv[1]); int flags = atoi(argv[1]);
reInp = flags & RPF_REDIRECT_INPUT; reInp = flags & RPF_REDIRECT_INPUT;
pauseAfterExit = flags & RPF_PAUSE_CONSOLE; pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
for(int i = 2;i < argc;i++) { for(int i = 2;i < argc;i++) {
//result += string("\"") + string(argv[i]) + string("\""); //result += string("\"") + string(argv[i]) + string("\"");
std::string s(argv[i]); std::string s(argv[i]);
if (i==2 || (reInp && i==3 ))
if (s.length()>2 && s[0]=='\"' && s[s.length()-1]=='\"') { if (s.length()>2 && s[0]=='\"' && s[s.length()-1]=='\"') {
s = s.substr(1,s.length()-2); s = s.substr(1,s.length()-2);
} }
result += s; result.push_back(s);
// Add a space except for the last argument
if(i != (argc-1)) {
result += string(" ");
}
}
if(result.length() > MAX_COMMAND_LENGTH) {
printf("\n--------------------------------");
printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH);
PauseExit(EXIT_FAILURE,reInp);
} }
return result; return result;
} }
int ExecuteCommand(string& command,bool reInp) { int ExecuteCommand(vector<string>& command,bool reInp) {
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) { if (pid == 0) {
//child process string path_to_command;
int pos = command.find_last_of('/'); char * * argv;
std::string file = command; int command_begin;
if (pos>=0) { int command_size;
file = command.substr(pos+1); if (reInp) {
if (command.size()<2) {
printf("not enough arguments1!\n");
exit(-1);
}
freopen(command[0].c_str(),"r",stdin);
path_to_command = command[1];
command_size = command.size()+1;
command_begin = 1;
} else {
if (command.size()<1) {
printf("not enough arguments2!\n");
exit(-1);
}
path_to_command = command[0];
command_size = command.size()+1;
command_begin = 0;
} }
int result=execl(command.c_str(),file.c_str(),NULL); argv = (char * *)malloc(sizeof(char *)*command_size);
for (int i=command_begin;i<command.size();i++) {
argv[i-command_begin] = (char *)command[i].c_str();
}
argv[command.size()-command_begin]=NULL;
//child process
int pos = path_to_command.find_last_of('/');
std::string file = path_to_command;
if (pos>=0) {
file = path_to_command.substr(pos+1);
}
argv[0]=(char *)file.c_str();
int result=execv(path_to_command.c_str(),argv);
if (result) { if (result) {
printf("Failed to start command %s %s!\n",command.c_str(), file.c_str()); printf("Failed to start command %s %s!\n",path_to_command.c_str(), file.c_str());
printf("errno %d: %s\n",errno,strerror(errno)); printf("errno %d: %s\n",errno,strerror(errno));
printf("current dir: %s",get_current_dir_name()); printf("current dir: %s",get_current_dir_name());
exit(-1); exit(-1);
@ -124,7 +145,7 @@ int main(int argc, char** argv) {
bool reInp; bool reInp;
bool pauseAfterExit; bool pauseAfterExit;
// Then build the to-run application command // Then build the to-run application command
string command = GetCommand(argc,argv,reInp, pauseAfterExit); vector<string> command = GetCommand(argc,argv,reInp, pauseAfterExit);
if (reInp) { if (reInp) {
freopen("/dev/tty","w+",stdout); freopen("/dev/tty","w+",stdout);
freopen("/dev/tty","w+",stderr); freopen("/dev/tty","w+",stderr);