Cleanup and try to unify with the other code

This commit is contained in:
Andy Cedilnik 2002-10-02 17:16:56 -04:00
parent 4435bb091b
commit f549a2bac8
1 changed files with 208 additions and 194 deletions

View File

@ -68,13 +68,22 @@ bool cmWin32ProcessExecution::Wait(int timeout)
*/ */
static void *_PyPopenProcs = NULL; static void *_PyPopenProcs = NULL;
static bool IsWinNT()
//check if we're running NT
{
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize = sizeof(osv);
GetVersionEx(&osv);
return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
static BOOL RealPopenCreateProcess(const char *cmdstring, static BOOL RealPopenCreateProcess(const char *cmdstring,
const char *path, const char *path,
const char *szConsoleSpawn, const char *szConsoleSpawn,
HANDLE hStdin, HANDLE hStdin,
HANDLE hStdout, HANDLE hStdout,
HANDLE hStderr, HANDLE hStderr,
HANDLE *hProcess) HANDLE *hProcess)
{ {
PROCESS_INFORMATION piProcInfo; PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo; STARTUPINFO siStartInfo;
@ -100,7 +109,7 @@ static BOOL RealPopenCreateProcess(const char *cmdstring,
++comshell; ++comshell;
if (GetVersion() < 0x80000000 && if (GetVersion() < 0x80000000 &&
STRICMP(comshell, "command.com") != 0) STRICMP(comshell, "command.com") != 0)
{ {
/* NT/2000 and not using command.com. */ /* NT/2000 and not using command.com. */
x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1; x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1;
@ -118,62 +127,62 @@ static BOOL RealPopenCreateProcess(const char *cmdstring,
struct stat statinfo; struct stat statinfo;
GetModuleFileName(NULL, modulepath, sizeof(modulepath)); GetModuleFileName(NULL, modulepath, sizeof(modulepath));
for (i = x = 0; modulepath[i]; i++) for (i = x = 0; modulepath[i]; i++)
if (modulepath[i] == '\\') if (modulepath[i] == '\\')
x = i+1; x = i+1;
modulepath[x] = '\0'; modulepath[x] = '\0';
/* Create the full-name to w9xpopen, so we can test it exists */ /* Create the full-name to w9xpopen, so we can test it exists */
strncat(modulepath, strncat(modulepath,
szConsoleSpawn, szConsoleSpawn,
(sizeof(modulepath)/sizeof(modulepath[0])) (sizeof(modulepath)/sizeof(modulepath[0]))
-strlen(modulepath)); -strlen(modulepath));
if (stat(modulepath, &statinfo) != 0) if (stat(modulepath, &statinfo) != 0)
{ {
/* Eeek - file-not-found - possibly an embedding /* Eeek - file-not-found - possibly an embedding
situation - see if we can locate it in sys.prefix situation - see if we can locate it in sys.prefix
*/ */
strncpy(modulepath, strncpy(modulepath,
".", ".",
sizeof(modulepath)/sizeof(modulepath[0])); sizeof(modulepath)/sizeof(modulepath[0]));
if (modulepath[strlen(modulepath)-1] != '\\') if (modulepath[strlen(modulepath)-1] != '\\')
strcat(modulepath, "\\"); strcat(modulepath, "\\");
strncat(modulepath, strncat(modulepath,
szConsoleSpawn, szConsoleSpawn,
(sizeof(modulepath)/sizeof(modulepath[0])) (sizeof(modulepath)/sizeof(modulepath[0]))
-strlen(modulepath)); -strlen(modulepath));
/* No where else to look - raise an easily identifiable /* No where else to look - raise an easily identifiable
error, rather than leaving Windows to report error, rather than leaving Windows to report
"file not found" - as the user is probably blissfully "file not found" - as the user is probably blissfully
unaware this shim EXE is used, and it will confuse them. unaware this shim EXE is used, and it will confuse them.
(well, it confused me for a while ;-) (well, it confused me for a while ;-)
*/ */
if (stat(modulepath, &statinfo) != 0) if (stat(modulepath, &statinfo) != 0)
{ {
std::cout std::cout
<< "Can not locate '" << modulepath << "Can not locate '" << modulepath
<< "' which is needed " << "' which is needed "
"for popen to work with your shell " "for popen to work with your shell "
"or platform." << std::endl; "or platform." << std::endl;
return FALSE; return FALSE;
} }
} }
x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 + x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 +
(int)strlen(modulepath) + (int)strlen(modulepath) +
(int)strlen(szConsoleSpawn) + 1; (int)strlen(szConsoleSpawn) + 1;
s2 = (char *)_alloca(x); s2 = (char *)_alloca(x);
ZeroMemory(s2, x); ZeroMemory(s2, x);
sprintf( sprintf(
s2, s2,
"%s %s%s%s", "%s %s%s%s",
modulepath, modulepath,
s1, s1,
s3, s3,
cmdstring); cmdstring);
sprintf( sprintf(
s2, s2,
"%s %s", "%s %s",
modulepath, modulepath,
cmdstring); cmdstring);
} }
} }
@ -182,7 +191,7 @@ static BOOL RealPopenCreateProcess(const char *cmdstring,
else else
{ {
std::cout << "Cannot locate a COMSPEC environment variable to " std::cout << "Cannot locate a COMSPEC environment variable to "
<< "use as the shell" << std::endl; << "use as the shell" << std::endl;
return FALSE; return FALSE;
} }
@ -195,21 +204,20 @@ static BOOL RealPopenCreateProcess(const char *cmdstring,
siStartInfo.wShowWindow = SW_HIDE; siStartInfo.wShowWindow = SW_HIDE;
if (CreateProcess(NULL, if (CreateProcess(NULL,
s2, s2,
NULL, NULL,
NULL, NULL,
TRUE, TRUE,
CREATE_NEW_CONSOLE, CREATE_NEW_CONSOLE,
NULL, NULL,
path, path,
&siStartInfo, &siStartInfo,
&piProcInfo) ) &piProcInfo) )
{ {
/* Close the handles now so anyone waiting is woken. */ /* Close the handles now so anyone waiting is woken. */
CloseHandle(piProcInfo.hThread); CloseHandle(piProcInfo.hThread);
/* Return process handle */ /* Return process handle */
*hProcess = piProcInfo.hProcess; *hProcess = piProcInfo.hProcess;
//std::cout << "Process created..." << std::endl;
return TRUE; return TRUE;
} }
win32_error("CreateProcess", s2); win32_error("CreateProcess", s2);
@ -219,9 +227,9 @@ static BOOL RealPopenCreateProcess(const char *cmdstring,
/* The following code is based off of KB: Q190351 */ /* The following code is based off of KB: Q190351 */
bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
const char* path, const char* path,
int mode, int mode,
int n) int n)
{ {
HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr, HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup, hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
@ -232,9 +240,22 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
int fd1, fd2, fd3; int fd1, fd2, fd3;
//FILE *f1, *f2, *f3; //FILE *f1, *f2, *f3;
SECURITY_DESCRIPTOR sd;
if (IsWinNT())
//initialize security descriptor (Windows NT)
{
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, true, NULL, false);
saAttr.lpSecurityDescriptor = &sd;
}
else saAttr.lpSecurityDescriptor = NULL;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE; saAttr.bInheritHandle = true;
saAttr.lpSecurityDescriptor = NULL;
//saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
//saAttr.bInheritHandle = TRUE;
//saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
{ {
@ -246,9 +267,9 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
* the these handles; resulting in non-closeable handles to the pipes * the these handles; resulting in non-closeable handles to the pipes
* being created. */ * being created. */
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, 0, GetCurrentProcess(), &hChildStdinWrDup, 0,
FALSE, FALSE,
DUPLICATE_SAME_ACCESS); DUPLICATE_SAME_ACCESS);
if (!fSuccess) if (!fSuccess)
return win32_error("DuplicateHandle", NULL); return win32_error("DuplicateHandle", NULL);
@ -261,8 +282,8 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
return win32_error("CreatePipe", NULL); return win32_error("CreatePipe", NULL);
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup, 0, GetCurrentProcess(), &hChildStdoutRdDup, 0,
FALSE, DUPLICATE_SAME_ACCESS); FALSE, DUPLICATE_SAME_ACCESS);
if (!fSuccess) if (!fSuccess)
return win32_error("DuplicateHandle", NULL); return win32_error("DuplicateHandle", NULL);
@ -275,147 +296,147 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0)) if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
return win32_error("CreatePipe", NULL); return win32_error("CreatePipe", NULL);
fSuccess = DuplicateHandle(GetCurrentProcess(), fSuccess = DuplicateHandle(GetCurrentProcess(),
hChildStderrRd, hChildStderrRd,
GetCurrentProcess(), GetCurrentProcess(),
&hChildStderrRdDup, 0, &hChildStderrRdDup, 0,
FALSE, DUPLICATE_SAME_ACCESS); FALSE, DUPLICATE_SAME_ACCESS);
if (!fSuccess) if (!fSuccess)
return win32_error("DuplicateHandle", NULL); return win32_error("DuplicateHandle", NULL);
/* Close the inheritable version of ChildStdErr that we're using. */ /* Close the inheritable version of ChildStdErr that we're using. */
CloseHandle(hChildStderrRd); CloseHandle(hChildStderrRd);
} }
switch (n) switch (n)
{ {
case POPEN_1: case POPEN_1:
switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY))
{ {
case _O_WRONLY | _O_TEXT: case _O_WRONLY | _O_TEXT:
/* Case for writing to child Stdin in text mode. */ /* Case for writing to child Stdin in text mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode);
//f1 = _fdopen(fd1, "w"); //f1 = _fdopen(fd1, "w");
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
CloseHandle(hChildStdoutRdDup); CloseHandle(hChildStdoutRdDup);
CloseHandle(hChildStderrRdDup); CloseHandle(hChildStderrRdDup);
break; break;
case _O_RDONLY | _O_TEXT: case _O_RDONLY | _O_TEXT:
/* Case for reading from child Stdout in text mode. */ /* Case for reading from child Stdout in text mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd1 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode);
//f1 = _fdopen(fd1, "r"); //f1 = _fdopen(fd1, "r");
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
CloseHandle(hChildStdinWrDup); CloseHandle(hChildStdinWrDup);
CloseHandle(hChildStderrRdDup); CloseHandle(hChildStderrRdDup);
break; break;
case _O_RDONLY | _O_BINARY: case _O_RDONLY | _O_BINARY:
/* Case for readinig from child Stdout in /* Case for readinig from child Stdout in
binary mode. */ binary mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd1 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode);
//f1 = _fdopen(fd1, "rb"); //f1 = _fdopen(fd1, "rb");
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
CloseHandle(hChildStdinWrDup); CloseHandle(hChildStdinWrDup);
CloseHandle(hChildStderrRdDup); CloseHandle(hChildStderrRdDup);
break; break;
case _O_WRONLY | _O_BINARY: case _O_WRONLY | _O_BINARY:
/* Case for writing to child Stdin in binary mode. */ /* Case for writing to child Stdin in binary mode. */
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode);
//f1 = _fdopen(fd1, "wb"); //f1 = _fdopen(fd1, "wb");
/* We don't care about these pipes anymore, /* We don't care about these pipes anymore,
so close them. */ so close them. */
CloseHandle(hChildStdoutRdDup); CloseHandle(hChildStdoutRdDup);
CloseHandle(hChildStderrRdDup); CloseHandle(hChildStderrRdDup);
break; break;
} }
break; break;
case POPEN_2: case POPEN_2:
case POPEN_4: case POPEN_4:
if ( 1 ) if ( 1 )
{ {
// Comment this out. Maybe we will need it in the future. // Comment this out. Maybe we will need it in the future.
// file IO access to the process might be cool. // file IO access to the process might be cool.
//char *m1, *m2; //char *m1, *m2;
//if (mode && _O_TEXT) //if (mode && _O_TEXT)
// { // {
// m1 = "r"; // m1 = "r";
// m2 = "w"; // m2 = "w";
// } // }
//else //else
// { // {
// m1 = "rb"; // m1 = "rb";
// m2 = "wb"; // m2 = "wb";
// } // }
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode);
//f1 = _fdopen(fd1, m2); //f1 = _fdopen(fd1, m2);
fd2 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd2 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode);
//f2 = _fdopen(fd2, m1); //f2 = _fdopen(fd2, m1);
if (n != 4) if (n != 4)
{ {
CloseHandle(hChildStderrRdDup); CloseHandle(hChildStderrRdDup);
} }
break; break;
} }
case POPEN_3: case POPEN_3:
if ( 1) if ( 1)
{ {
// Comment this out. Maybe we will need it in the future. // Comment this out. Maybe we will need it in the future.
// file IO access to the process might be cool. // file IO access to the process might be cool.
//char *m1, *m2; //char *m1, *m2;
//if (mode && _O_TEXT) //if (mode && _O_TEXT)
// { // {
// m1 = "r"; // m1 = "r";
// m2 = "w"; // m2 = "w";
// } // }
//else //else
// { // {
// m1 = "rb"; // m1 = "rb";
// m2 = "wb"; // m2 = "wb";
// } // }
fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode); fd1 = _open_osfhandle(TO_INTPTR(hChildStdinWrDup), mode);
//f1 = _fdopen(fd1, m2); //f1 = _fdopen(fd1, m2);
fd2 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode); fd2 = _open_osfhandle(TO_INTPTR(hChildStdoutRdDup), mode);
//f2 = _fdopen(fd2, m1); //f2 = _fdopen(fd2, m1);
fd3 = _open_osfhandle(TO_INTPTR(hChildStderrRdDup), mode); fd3 = _open_osfhandle(TO_INTPTR(hChildStderrRdDup), mode);
//f3 = _fdopen(fd3, m1); //f3 = _fdopen(fd3, m1);
break; break;
} }
} }
if (n == POPEN_4) if (n == POPEN_4)
{ {
if (!RealPopenCreateProcess(cmdstring, if (!RealPopenCreateProcess(cmdstring,
path, path,
this->m_ConsoleSpawn.c_str(), this->m_ConsoleSpawn.c_str(),
hChildStdinRd, hChildStdinRd,
hChildStdoutWr, hChildStdoutWr,
hChildStdoutWr, hChildStdoutWr,
&hProcess)) &hProcess))
return NULL; return NULL;
} }
else else
{ {
if (!RealPopenCreateProcess(cmdstring, if (!RealPopenCreateProcess(cmdstring,
path, path,
this->m_ConsoleSpawn.c_str(), this->m_ConsoleSpawn.c_str(),
hChildStdinRd, hChildStdinRd,
hChildStdoutWr, hChildStdoutWr,
hChildStderrWr, hChildStderrWr,
&hProcess)) &hProcess))
return NULL; return NULL;
} }
@ -439,10 +460,10 @@ bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring,
if (!CloseHandle(hChildStdinRd)) if (!CloseHandle(hChildStdinRd))
return win32_error("CloseHandle", NULL); return win32_error("CloseHandle", NULL);
if (!CloseHandle(hChildStdoutWr)) if (!CloseHandle(hChildStdoutWr))
return win32_error("CloseHandle", NULL); return win32_error("CloseHandle", NULL);
if ((n != 4) && (!CloseHandle(hChildStderrWr))) if ((n != 4) && (!CloseHandle(hChildStderrWr)))
return win32_error("CloseHandle", NULL); return win32_error("CloseHandle", NULL);
@ -512,38 +533,31 @@ bool cmWin32ProcessExecution::PrivateClose(int timeout)
std::string output = ""; std::string output = "";
bool done = false; bool done = false;
while(!done) while(!done)
{ {
Sleep(10); char buffer[1023]="";
int len = 0;
Sleep(1);
bool have_some = false; bool have_some = false;
struct _stat fsout; len = read(this->m_pStdErr, buffer, 1023);
struct _stat fserr; if ( len > 0 )
int rout = _fstat(this->m_pStdOut, &fsout);
int rerr = _fstat(this->m_pStdErr, &fserr);
if ( rout && rerr )
{ {
break;
}
if (fserr.st_size > 0)
{
char buffer[1023];
int len = read(this->m_pStdErr, buffer, 1023);
buffer[len] = 0; buffer[len] = 0;
if ( this->m_Verbose ) if ( this->m_Verbose )
{ {
std::cout << buffer << std::flush; std::cout << buffer << std::flush;
} }
output += buffer; output += buffer;
have_some = true; have_some = true;
} }
if (fsout.st_size > 0) len = read(this->m_pStdOut, buffer, 1023);
if ( len > 0 )
{ {
char buffer[1023];
int len = read(this->m_pStdOut, buffer, 1023);
buffer[len] = 0; buffer[len] = 0;
if ( this->m_Verbose ) if ( this->m_Verbose )
{ {
std::cout << buffer << std::flush; std::cout << buffer << std::flush;
} }
output += buffer; output += buffer;
have_some = true; have_some = true;