--- a/src/windows/execmd_w.cpp
+++ b/src/windows/execmd_w.cpp
@@ -147,8 +147,8 @@
{
struct stat st;
if (access(path.c_str(), X_OK) == 0 && stat(path.c_str(), &st) == 0 &&
- S_ISREG(st.st_mode)) {
- return true;
+ S_ISREG(st.st_mode)) {
+ return true;
}
return false;
}
@@ -194,22 +194,22 @@
static std::string pipeUniqueName(std::string nClass, std::string prefix)
{
- std::stringstream uName;
-
- long currCnt;
- // PID + multi-thread-protected static counter to be unique
- {
- static long cnt = 0;
- currCnt = InterlockedIncrement(&cnt);
- }
- DWORD pid = GetCurrentProcessId();
-
- // naming convention
- uName << "\\\\.\\" << nClass << "\\";
- uName << "pid-" << pid << "-cnt-" << currCnt << "-";
- uName << prefix;
-
- return uName.str();
+ std::stringstream uName;
+
+ long currCnt;
+ // PID + multi-thread-protected static counter to be unique
+ {
+ static long cnt = 0;
+ currCnt = InterlockedIncrement(&cnt);
+ }
+ DWORD pid = GetCurrentProcessId();
+
+ // naming convention
+ uName << "\\\\.\\" << nClass << "\\";
+ uName << "pid-" << pid << "-cnt-" << currCnt << "-";
+ uName << prefix;
+
+ return uName.str();
}
enum WaitResult {
@@ -269,7 +269,7 @@
int m_flags;
// We need buffered I/O for getline. The Unix version uses netcon's
- string m_buf; // Buffer. Only used when doing getline()s
+ string m_buf; // Buffer. Only used when doing getline()s
size_t m_bufoffs; // Pointer to current 1st byte of useful data
bool m_killRequest;
string m_stderrFile;
@@ -299,6 +299,58 @@
bool tooBig();
};
+// Sending a break to a subprocess is only possible if we share the
+// same console We temporarily ignore breaks, attach to the Console,
+// send the break, and restore normal break processing
+static bool sendIntr(int pid)
+{
+ LOGDEB(("execmd_w: sendIntr -> %d\n", pid));
+ bool needDetach = false;
+ if (GetConsoleWindow() == NULL) {
+ needDetach = true;
+ LOGDEB(("execmd_w: sendIntr attaching console\n"));
+ if (!AttachConsole((unsigned int) pid)) {
+ int err = GetLastError();
+ LOGERR(("execmd_w: sendIntr: AttachConsole failed: %d\n", err));
+ return false;
+ }
+ }
+
+#if 0
+ // Would need to do this for sending to all processes on this console
+ // Disable Ctrl-C handling for our program
+ if (!SetConsoleCtrlHandler(NULL, true)) {
+ int err = GetLastError();
+ LOGERR(("execmd_w:sendIntr:SetCons.Ctl.Hndlr.(NULL, true) failed: %d\n",
+ err));
+ return false;
+ }
+#endif
+
+ // Note: things don't work with CTRL_C (process not advised, sometimes
+ // stays apparently blocked), no idea why
+ bool ret = GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid);
+ if (!ret) {
+ int err = GetLastError();
+ LOGERR(("execmd_w:sendIntr:Gen.Cons.CtrlEvent failed: %d\n", err));
+ }
+
+#if 0
+ // Restore Ctrl-C handling for our program
+ SetConsoleCtrlHandler(NULL, false);
+#endif
+
+ if (needDetach) {
+ LOGDEB(("execmd_w: sendIntr detaching console\n"));
+ if (!FreeConsole()) {
+ int err = GetLastError();
+ LOGERR(("execmd_w: sendIntr: FreeConsole failed: %d\n", err));
+ }
+ }
+
+ return ret;
+}
+
// ExecCmd resource releaser class. Using a separate object makes it
// easier that resources are released under all circumstances,
// esp. exceptions
@@ -311,9 +363,9 @@
m_active = false;
}
~ExecCmdRsrc() {
- if (!m_active || !m_parent)
- return;
- LOGDEB1(("~ExecCmdRsrc: working. mypid: %d\n", (int)getpid()));
+ if (!m_active || !m_parent)
+ return;
+ LOGDEB1(("~ExecCmdRsrc: working. mypid: %d\n", (int)getpid()));
if (m_parent->m_hOutputRead)
CloseHandle(m_parent->m_hOutputRead);
if (m_parent->m_hInputWrite)
@@ -324,15 +376,10 @@
CloseHandle(m_parent->m_oInputWrite.hEvent);
if (m_parent->m_piProcInfo.hProcess) {
- LOGDEB(("ExecCmd: GenerateConsoleCtrlEvent -> %d\n",
- m_parent->m_piProcInfo.dwProcessId));
-
- BOOL bSuccess =
- GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
- m_parent->m_piProcInfo.dwProcessId);
- if (bSuccess) {
+ BOOL bSuccess = sendIntr(m_parent->m_piProcInfo.dwProcessId);
+ if (bSuccess) {
// Give it a chance, then terminate
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
WaitResult res = Wait(m_parent->m_piProcInfo.hProcess,
i == 0 ? 5 : (i == 1 ? 100 : 2000));
switch (res) {
@@ -345,17 +392,17 @@
0xffff);
}
}
- }
- } else {
+ }
+ } else {
TerminateProcess(m_parent->m_piProcInfo.hProcess,
0xffff);
}
- breakloop:
+ breakloop:
CloseHandle(m_parent->m_piProcInfo.hProcess);
- }
+ }
if (m_parent->m_piProcInfo.hThread)
CloseHandle(m_parent->m_piProcInfo.hThread);
- m_parent->reset();
+ m_parent->reset();
}
private:
ExecCmd::Internal *m_parent;
@@ -457,10 +504,7 @@
bool ExecCmd::requestChildExit()
{
if (m->m_piProcInfo.hProcess) {
- LOGDEB(("ExecCmd: GenerateConsoleCtrlEvent -> %d\n",
- m->m_piProcInfo.dwProcessId));
- return GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
- m->m_piProcInfo.dwProcessId);
+ return sendIntr(m->m_piProcInfo.dwProcessId);
}
return false;
}
@@ -490,7 +534,7 @@
int mbytes = getVMMBytes(m_piProcInfo.hProcess);
if (mbytes > m_rlimit_as_mbytes) {
LOGINFO(("ExecCmd:: process mbytes %d > set limit %d\n",
- mbytes, m_rlimit_as_mbytes));
+ mbytes, m_rlimit_as_mbytes));
m_killRequest = true;
return true;
}
@@ -986,8 +1030,8 @@
*status = -1;
if (m->m_piProcInfo.hProcess == NULL) {
- // Already waited for ??
- return true;
+ // Already waited for ??
+ return true;
}
WaitResult res = Wait(m->m_piProcInfo.hProcess, 1);
@@ -1005,8 +1049,8 @@
}
return true;
default:
- e.inactivate();
- return false;
+ e.inactivate();
+ return false;
}
}