- fix: wrong executable filename for source files in linux
- enhancement: console pauser for linux
This commit is contained in:
parent
7f02b4c6c3
commit
3be06fe586
2
NEWS.md
2
NEWS.md
|
@ -5,6 +5,8 @@ Version 0.12.5 For Dev-C++ 7 Beta
|
||||||
- enhancement: add option for setting astyle path
|
- enhancement: add option for setting astyle path
|
||||||
- fix: wrong file wildcard (*.*) in linux
|
- fix: wrong file wildcard (*.*) in linux
|
||||||
- fix: open terminal in linux
|
- fix: open terminal in linux
|
||||||
|
- fix: wrong executable filename for source files in linux
|
||||||
|
- enhancement: console pauser for linux
|
||||||
|
|
||||||
Version 0.12.4 For Dev-C++ 7 Beta
|
Version 0.12.4 For Dev-C++ 7 Beta
|
||||||
- change: add copyright infos to each source file
|
- change: add copyright infos to each source file
|
||||||
|
|
|
@ -320,7 +320,7 @@ win32: {
|
||||||
settingsdialog/projectversioninfowidget.cpp
|
settingsdialog/projectversioninfowidget.cpp
|
||||||
}
|
}
|
||||||
|
|
||||||
unix {
|
unix: {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
settingsdialog/formatterpathwidget.h \
|
settingsdialog/formatterpathwidget.h \
|
||||||
settingsdialog/environmentprogramswidget.h
|
settingsdialog/environmentprogramswidget.h
|
||||||
|
@ -333,6 +333,10 @@ unix {
|
||||||
settingsdialog/formatterpathwidget.ui \
|
settingsdialog/formatterpathwidget.ui \
|
||||||
settingsdialog/environmentprogramswidget.ui
|
settingsdialog/environmentprogramswidget.ui
|
||||||
}
|
}
|
||||||
|
linux: {
|
||||||
|
LIBS+= \
|
||||||
|
-lrt
|
||||||
|
}
|
||||||
|
|
||||||
TRANSLATIONS += \
|
TRANSLATIONS += \
|
||||||
RedPandaIDE_zh_CN.ts
|
RedPandaIDE_zh_CN.ts
|
||||||
|
|
|
@ -227,12 +227,12 @@ void CompilerManager::run(const QString &filename, const QString &arguments, con
|
||||||
}
|
}
|
||||||
ExecutableRunner * execRunner;
|
ExecutableRunner * execRunner;
|
||||||
if (programHasConsole(filename)) {
|
if (programHasConsole(filename)) {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
int consoleFlag=0;
|
int consoleFlag=0;
|
||||||
if (redirectInput)
|
if (redirectInput)
|
||||||
consoleFlag |= RPF_REDIRECT_INPUT;
|
consoleFlag |= RPF_REDIRECT_INPUT;
|
||||||
if (pSettings->executor().pauseConsole())
|
if (pSettings->executor().pauseConsole())
|
||||||
consoleFlag |= RPF_PAUSE_CONSOLE;
|
consoleFlag |= RPF_PAUSE_CONSOLE;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
if (consoleFlag!=0) {
|
if (consoleFlag!=0) {
|
||||||
QString newArguments = QString(" %1 \"%2\" %3")
|
QString newArguments = QString(" %1 \"%2\" %3")
|
||||||
.arg(consoleFlag)
|
.arg(consoleFlag)
|
||||||
|
@ -242,8 +242,16 @@ void CompilerManager::run(const QString &filename, const QString &arguments, con
|
||||||
execRunner = new ExecutableRunner(filename,arguments,workDir);
|
execRunner = new ExecutableRunner(filename,arguments,workDir);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
QString newArguments = QString(" -e \"%1\" %2")
|
QString newArguments;
|
||||||
|
if (consoleFlag!=0) {
|
||||||
|
newArguments = QString(" -e \"%1\" %2 \"%3\" %4")
|
||||||
|
.arg(includeTrailingPathDelimiter(pSettings->dirs().appDir())+"consolepauser")
|
||||||
|
.arg(consoleFlag)
|
||||||
|
.arg(localizePath(filename)).arg(arguments);
|
||||||
|
} else {
|
||||||
|
newArguments = QString(" -e \"%1\" %2")
|
||||||
.arg(localizePath(filename)).arg(arguments);
|
.arg(localizePath(filename)).arg(arguments);
|
||||||
|
}
|
||||||
execRunner = new ExecutableRunner(pSettings->environment().terminalPath(),newArguments,workDir);
|
execRunner = new ExecutableRunner(pSettings->environment().terminalPath(),newArguments,workDir);
|
||||||
#endif
|
#endif
|
||||||
execRunner->setStartConsole(true);
|
execRunner->setStartConsole(true);
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
#include "../systemconsts.h"
|
#include "../systemconsts.h"
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h> /* For mode constants */
|
||||||
|
#include <fcntl.h> /* For O_* constants */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,6 +140,23 @@ void ExecutableRunner::run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
int BUF_SIZE=1024;
|
||||||
|
char* pBuf=nullptr;
|
||||||
|
int fd_shm = shm_open("/REDPANDAIDECONSOLEPAUSER20211223",O_RDWR | O_CREAT,S_IRWXU);
|
||||||
|
if (fd_shm==-1) {
|
||||||
|
qDebug()<<QString("shm open failed %1:%2").arg(errno).arg(strerror(errno));
|
||||||
|
} else {
|
||||||
|
if (ftruncate(fd_shm,BUF_SIZE)==-1){
|
||||||
|
qDebug()<<QString("truncate failed %1:%2").arg(errno).arg(strerror(errno));
|
||||||
|
} else {
|
||||||
|
pBuf = (char*)mmap(NULL,BUF_SIZE,PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm,0);
|
||||||
|
if (pBuf == MAP_FAILED) {
|
||||||
|
qDebug()<<QString("mmap failed %1:%2").arg(errno).arg(strerror(errno));
|
||||||
|
pBuf = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// if (!redirectInput()) {
|
// if (!redirectInput()) {
|
||||||
// process.closeWriteChannel();
|
// process.closeWriteChannel();
|
||||||
|
@ -166,7 +189,7 @@ void ExecutableRunner::run()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WIN
|
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
|
||||||
if (mStartConsole && !mPausing && pBuf) {
|
if (mStartConsole && !mPausing && pBuf) {
|
||||||
if (strncmp(pBuf,"FINISHED",sizeof("FINISHED"))==0) {
|
if (strncmp(pBuf,"FINISHED",sizeof("FINISHED"))==0) {
|
||||||
setPausing(true);
|
setPausing(true);
|
||||||
|
@ -182,6 +205,13 @@ void ExecutableRunner::run()
|
||||||
UnmapViewOfFile(pBuf);
|
UnmapViewOfFile(pBuf);
|
||||||
if (hSharedMemory!=INVALID_HANDLE_VALUE)
|
if (hSharedMemory!=INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(hSharedMemory);
|
CloseHandle(hSharedMemory);
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
if (pBuf) {
|
||||||
|
munmap(pBuf,BUF_SIZE);
|
||||||
|
}
|
||||||
|
if (fd_shm!=-1) {
|
||||||
|
shm_unlink("/REDPANDAIDECONSOLEPAUSER20211223");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (errorOccurred) {
|
if (errorOccurred) {
|
||||||
//qDebug()<<"process error:"<<process.error();
|
//qDebug()<<"process error:"<<process.error();
|
||||||
|
|
|
@ -526,15 +526,16 @@ QString changeFileExt(const QString& filename, QString ext)
|
||||||
QString suffix = fileInfo.suffix();
|
QString suffix = fileInfo.suffix();
|
||||||
QString name = fileInfo.fileName();
|
QString name = fileInfo.fileName();
|
||||||
QString path;
|
QString path;
|
||||||
if (ext.startsWith("."))
|
if (!ext.isEmpty() && !ext.startsWith(".")) {
|
||||||
ext.remove(0,1);
|
ext = "."+ext;
|
||||||
|
}
|
||||||
if (fileInfo.path() != ".") {
|
if (fileInfo.path() != ".") {
|
||||||
path = includeTrailingPathDelimiter(fileInfo.path());
|
path = includeTrailingPathDelimiter(fileInfo.path());
|
||||||
}
|
}
|
||||||
if (suffix.isEmpty()) {
|
if (suffix.isEmpty()) {
|
||||||
return path+filename+"."+ext;
|
return path+filename+ext;
|
||||||
} else {
|
} else {
|
||||||
return path+fileInfo.completeBaseName()+"."+ext;
|
return path+fileInfo.completeBaseName()+ext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ SOURCES += \
|
||||||
unix: {
|
unix: {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.unix.cpp
|
main.unix.cpp
|
||||||
|
LIBS+= \
|
||||||
|
-lrt
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG += lrelease
|
CONFIG += lrelease
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Red Panda Dev-C++ 7
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
using std::string;
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h> /* For mode constants */
|
||||||
|
#include <fcntl.h> /* For O_* constants */
|
||||||
|
#include <chrono>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#define MAX_COMMAND_LENGTH 32768
|
||||||
|
#define MAX_ERROR_LENGTH 2048
|
||||||
|
|
||||||
|
enum RunProgramFlag {
|
||||||
|
RPF_PAUSE_CONSOLE = 0x0001,
|
||||||
|
RPF_REDIRECT_INPUT = 0x0002
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void PauseExit(int exitcode, bool reInp) {
|
||||||
|
if (reInp) {
|
||||||
|
freopen("/dev/tty","r",stdin);
|
||||||
|
}
|
||||||
|
fflush(stdin);
|
||||||
|
printf("\n");
|
||||||
|
printf("Press ANY key to exit...");
|
||||||
|
getchar();
|
||||||
|
exit(exitcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) {
|
||||||
|
string result;
|
||||||
|
int flags = atoi(argv[1]);
|
||||||
|
reInp = flags & RPF_REDIRECT_INPUT;
|
||||||
|
pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
|
||||||
|
for(int i = 2;i < argc;i++) {
|
||||||
|
//result += string("\"") + string(argv[i]) + string("\"");
|
||||||
|
std::string s(argv[i]);
|
||||||
|
if (s.length()>2 && s[0]=='\"' && s[s.length()-1]=='\"') {
|
||||||
|
s = s.substr(1,s.length()-2);
|
||||||
|
}
|
||||||
|
result += 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExecuteCommand(string& command,bool reInp) {
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
//child process
|
||||||
|
int pos = command.find_last_of('/');
|
||||||
|
std::string file = command;
|
||||||
|
if (pos>=0) {
|
||||||
|
file = command.substr(pos+1);
|
||||||
|
}
|
||||||
|
int result=execl(command.c_str(),file.c_str(),NULL);
|
||||||
|
if (result) {
|
||||||
|
printf("Failed to start command %s %s!\n",command.c_str(), file.c_str());
|
||||||
|
printf("errno %d: %s\n",errno,strerror(errno));
|
||||||
|
printf("current dir: %s",get_current_dir_name());
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int status;
|
||||||
|
pid_t w;
|
||||||
|
w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
|
||||||
|
if (w==-1) {
|
||||||
|
perror("waitpid failed!");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
} else {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
|
// First make sure we aren't going to read nonexistent arrays
|
||||||
|
if(argc < 3) {
|
||||||
|
printf("\n--------------------------------");
|
||||||
|
printf("\nUsage: ConsolePauser.exe <0|1> <filename> <parameters>\n");
|
||||||
|
printf("\n 1 means the STDIN is redirected by Dev-CPP;0 means not\n");
|
||||||
|
PauseExit(EXIT_SUCCESS,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make us look like the paused program
|
||||||
|
//SetConsoleTitleA(argv[2]);
|
||||||
|
|
||||||
|
bool reInp;
|
||||||
|
bool pauseAfterExit;
|
||||||
|
// Then build the to-run application command
|
||||||
|
string command = GetCommand(argc,argv,reInp, pauseAfterExit);
|
||||||
|
if (reInp) {
|
||||||
|
freopen("/dev/tty","w+",stdout);
|
||||||
|
freopen("/dev/tty","w+",stderr);
|
||||||
|
} else {
|
||||||
|
fflush(stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BUF_SIZE=1024;
|
||||||
|
char* pBuf=nullptr;
|
||||||
|
int fd_shm = shm_open("/REDPANDAIDECONSOLEPAUSER20211223",O_RDWR,S_IRWXU);
|
||||||
|
if (fd_shm==-1) {
|
||||||
|
//todo: handle error
|
||||||
|
printf("shm open failed %d:%s",errno,strerror(errno));
|
||||||
|
} else {
|
||||||
|
if (ftruncate(fd_shm,BUF_SIZE)==-1){
|
||||||
|
printf("ftruncate failed %d:%s",errno,strerror(errno));
|
||||||
|
//todo: set size error
|
||||||
|
} else {
|
||||||
|
pBuf = (char*)mmap(NULL,BUF_SIZE,PROT_READ | PROT_WRITE, MAP_SHARED, fd_shm,0);
|
||||||
|
if (pBuf == MAP_FAILED) {
|
||||||
|
printf("mmap failed %d:%s",errno,strerror(errno));
|
||||||
|
pBuf = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save starting timestamp
|
||||||
|
auto starttime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
// Execute the command
|
||||||
|
int returnvalue = ExecuteCommand(command,reInp);
|
||||||
|
|
||||||
|
// Get ending timestamp
|
||||||
|
auto endtime = std::chrono::high_resolution_clock::now();
|
||||||
|
auto difftime = endtime - starttime;
|
||||||
|
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(difftime);
|
||||||
|
double seconds = milliseconds.count()/1000;
|
||||||
|
|
||||||
|
if (pBuf) {
|
||||||
|
strcpy(pBuf,"FINISHED");
|
||||||
|
munmap(pBuf,BUF_SIZE);
|
||||||
|
}
|
||||||
|
if (fd_shm!=-1) {
|
||||||
|
shm_unlink("/REDPANDAIDECONSOLEPAUSER20211223");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done? Print return value of executed program
|
||||||
|
printf("\n--------------------------------");
|
||||||
|
printf("\nProcess exited after %.4g seconds with return value %lu\n",seconds,returnvalue);
|
||||||
|
if (pauseAfterExit)
|
||||||
|
PauseExit(returnvalue,reInp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -15,23 +15,6 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* This file is part of Red Panda Dev-C++ 7
|
|
||||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
Loading…
Reference in New Issue