Browse Source

Fixes to windows processing and some general processing issues.

merge-requests/365/head
U-olece-PC\olece 10 years ago
parent
commit
2b8e729447
  1. 2
      src/CMakeLists.txt
  2. 2
      src/process.cc
  3. 2
      src/process.h
  4. 69
      src/process_win.cc

2
src/CMakeLists.txt

@ -22,7 +22,7 @@ if(UNIX) #Checking if compiling on Ubuntu that has a buggy menu system
endif() endif()
if(MSYS) if(MSYS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJUCI_CMAKE_INSTALL_PREFIX=\\\"${CMAKE_INSTALL_PREFIX}\\\"") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMSYS2_PROCESS_USE_SH -DJUCI_CMAKE_INSTALL_PREFIX=\\\"${CMAKE_INSTALL_PREFIX}\\\"")
endif() endif()
INCLUDE(FindPkgConfig) INCLUDE(FindPkgConfig)

2
src/process.cc

@ -9,7 +9,7 @@ Process::Process(const std::string &command, const std::string &path,
bool use_stdin, size_t buffer_size): bool use_stdin, size_t buffer_size):
read_stdout(read_stdout), read_stderr(read_stderr), use_stdin(use_stdin), buffer_size(buffer_size) { read_stdout(read_stdout), read_stderr(read_stderr), use_stdin(use_stdin), buffer_size(buffer_size) {
id=open(command, path); id=open(command, path);
if(id>0) if(id!=0)
async_read(); async_read();
} }

2
src/process.h

@ -8,7 +8,7 @@
#include <thread> #include <thread>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
typedef HANDLE process_id_type; typedef DWORD process_id_type;
typedef HANDLE file_descriptor_type; typedef HANDLE file_descriptor_type;
#else #else
#include <sys/wait.h> #include <sys/wait.h>

69
src/process_win.cc

@ -1,5 +1,6 @@
#include "process.h" #include "process.h"
#include <cstring> #include <cstring>
#include "TlHelp32.h"
#include <iostream> //TODO: remove #include <iostream> //TODO: remove
using namespace std; //TODO: remove using namespace std; //TODO: remove
@ -30,25 +31,25 @@ process_id_type Process::open(const std::string &command, const std::string &pat
if(stdin_fd) { if(stdin_fd) {
if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
return NULL; return 0;
if(!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) { if(!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) {
CloseHandle(g_hChildStd_IN_Rd); CloseHandle(g_hChildStd_IN_Rd);
CloseHandle(g_hChildStd_IN_Wr); CloseHandle(g_hChildStd_IN_Wr);
return NULL; return 0;
} }
} }
if(stdout_fd) { if(stdout_fd) {
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) { if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) {
if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd); if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd);
if(stdin_fd) CloseHandle(g_hChildStd_IN_Wr); if(stdin_fd) CloseHandle(g_hChildStd_IN_Wr);
return NULL; return 0;
} }
if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) { if(!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) {
if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd); if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd);
if(stdin_fd) CloseHandle(g_hChildStd_IN_Wr); if(stdin_fd) CloseHandle(g_hChildStd_IN_Wr);
CloseHandle(g_hChildStd_OUT_Rd); CloseHandle(g_hChildStd_OUT_Rd);
CloseHandle(g_hChildStd_OUT_Wr); CloseHandle(g_hChildStd_OUT_Wr);
return NULL; return 0;
} }
} }
if(stderr_fd) { if(stderr_fd) {
@ -57,7 +58,7 @@ process_id_type Process::open(const std::string &command, const std::string &pat
if(stdin_fd) CloseHandle(g_hChildStd_IN_Wr); if(stdin_fd) CloseHandle(g_hChildStd_IN_Wr);
if(stdout_fd) CloseHandle(g_hChildStd_OUT_Rd); if(stdout_fd) CloseHandle(g_hChildStd_OUT_Rd);
if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr); if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr);
return NULL; return 0;
} }
if(!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) { if(!SetHandleInformation(g_hChildStd_ERR_Rd, HANDLE_FLAG_INHERIT, 0)) {
if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd); if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd);
@ -66,7 +67,7 @@ process_id_type Process::open(const std::string &command, const std::string &pat
if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr); if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr);
CloseHandle(g_hChildStd_ERR_Rd); CloseHandle(g_hChildStd_ERR_Rd);
CloseHandle(g_hChildStd_ERR_Wr); CloseHandle(g_hChildStd_ERR_Wr);
return NULL; return 0;
} }
} }
@ -90,8 +91,27 @@ process_id_type Process::open(const std::string &command, const std::string &pat
path_ptr=new char[path.size()+1]; path_ptr=new char[path.size()+1];
std::strcpy(path_ptr, path.c_str()); std::strcpy(path_ptr, path.c_str());
} }
char* command_cstr=new char[command.size()+1];
char* command_cstr;
#ifdef MSYS2_PROCESS_USE_SH
size_t pos=0;
std::string sh_command=command;
while((pos=sh_command.find('\"', pos))!=std::string::npos) {
if(pos>0 && sh_command[pos-1]!='\\') {
sh_command.replace(pos, 1, "\\\"");
pos++;
}
pos++;
}
sh_command.insert(0, "sh -c \"");
sh_command+="\"";
command_cstr=new char[sh_command.size()+1];
std::strcpy(command_cstr, sh_command.c_str());
#else
command_cstr=new char[command.size()+1];
std::strcpy(command_cstr, command.c_str()); std::strcpy(command_cstr, command.c_str());
#endif
BOOL bSuccess = CreateProcess(NULL, BOOL bSuccess = CreateProcess(NULL,
command_cstr, // command line command_cstr, // command line
NULL, // process security attributes NULL, // process security attributes
@ -109,13 +129,9 @@ process_id_type Process::open(const std::string &command, const std::string &pat
if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd); if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd);
if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr); if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr);
if(stderr_fd) CloseHandle(g_hChildStd_ERR_Wr); if(stderr_fd) CloseHandle(g_hChildStd_ERR_Wr);
return NULL; return 0;
} }
else { else {
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(process_info.hThread); CloseHandle(process_info.hThread);
if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd); if(stdin_fd) CloseHandle(g_hChildStd_IN_Rd);
if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr); if(stdout_fd) CloseHandle(g_hChildStd_OUT_Wr);
@ -125,7 +141,8 @@ process_id_type Process::open(const std::string &command, const std::string &pat
if(stdin_fd) *stdin_fd=g_hChildStd_IN_Wr; if(stdin_fd) *stdin_fd=g_hChildStd_IN_Wr;
if(stdout_fd) *stdout_fd=g_hChildStd_OUT_Rd; if(stdout_fd) *stdout_fd=g_hChildStd_OUT_Rd;
if(stderr_fd) *stderr_fd=g_hChildStd_ERR_Rd; if(stderr_fd) *stderr_fd=g_hChildStd_ERR_Rd;
return process_info.hProcess;
return process_info.dwProcessId;
} }
void Process::async_read() { void Process::async_read() {
@ -157,9 +174,10 @@ void Process::async_read() {
int Process::get_exit_code() { int Process::get_exit_code() {
DWORD exit_code; DWORD exit_code;
WaitForSingleObject(id, INFINITE); HANDLE process_info = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
GetExitCodeProcess(id, &exit_code); WaitForSingleObject(process_info, INFINITE);
CloseHandle(id); GetExitCodeProcess(process_info, &exit_code);
CloseHandle(process_info);
if(stdout_thread.joinable()) if(stdout_thread.joinable())
stdout_thread.join(); stdout_thread.join();
@ -188,7 +206,7 @@ bool Process::write(const char *bytes, size_t n) {
stdin_mutex.lock(); stdin_mutex.lock();
if(stdin_fd) { if(stdin_fd) {
DWORD written; DWORD written;
BOOL bSuccess=WriteFile(id, bytes, static_cast<DWORD>(n), &written, NULL); BOOL bSuccess=WriteFile(*stdin_fd, bytes, static_cast<DWORD>(n), &written, NULL);
if(!bSuccess || written==0) { if(!bSuccess || written==0) {
stdin_mutex.unlock(); stdin_mutex.unlock();
return false; return false;
@ -203,5 +221,20 @@ bool Process::write(const char *bytes, size_t n) {
} }
void Process::kill(process_id_type id, bool force) { void Process::kill(process_id_type id, bool force) {
TerminateProcess(id, 2); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(snapshot) {
PROCESSENTRY32 process;
ZeroMemory(&process, sizeof(process));
process.dwSize = sizeof(process);
if(Process32First(snapshot, &process)) {
do {
if(process.th32ParentProcessID==id) {
HANDLE process_info = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
if(process_info) TerminateProcess(process_info, 2);
}
} while (Process32Next(snapshot, &process));
}
}
HANDLE process_info = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id);
if(process_info) TerminateProcess(process_info, 2);
} }

Loading…
Cancel
Save