⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipe.cxx

📁 pwlib源码库
💻 CXX
字号:
/* * pipe.cxx * * Sub-process communicating with pipe I/O channel class * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: pipe.cxx,v $ * Revision 1.5  2004/10/23 10:51:59  ykiryanov * Added ifdef _WIN32_WCE for PocketPC 2003 SDK port * * Revision 1.4  2004/04/03 06:54:30  rjongbloed * Many and various changes to support new Visual C++ 2003 * * Revision 1.3  2001/09/10 02:51:23  robertj * Major change to fix problem with error codes being corrupted in a *   PChannel when have simultaneous reads and writes in threads. * * Revision 1.2  1998/11/30 07:37:56  robertj * Fixed (previous bug) of incorrect handle values. * * Revision 1.1  1998/11/30 04:57:42  robertj * Initial revision * */#include <ptlib.h>#include <ptlib/pipechan.h>#include <ctype.h>///////////////////////////////////////////////////////////////////////////////// PPipeChannelPPipeChannel::PPipeChannel(){  hToChild = hFromChild = hStandardError = INVALID_HANDLE_VALUE;}BOOL PPipeChannel::PlatformOpen(const PString & subProgram,                                const PStringArray & argumentList,                                OpenMode mode,                                BOOL searchPath,                                BOOL stderrSeparate,                                const PStringToString * environment){  subProgName = subProgram;  const char * prog = NULL;  PStringStream cmdLine;  if (searchPath)    cmdLine << subProgram;  else    prog = subProgram;  for (PINDEX i = 0; i < argumentList.GetSize(); i++) {    cmdLine << ' ';    if (argumentList[i].Find(' ') == P_MAX_INDEX)      cmdLine << argumentList[i];    else if (argumentList[i].Find('"') == P_MAX_INDEX)      cmdLine << '"' << argumentList[i] << '"';    else      cmdLine << '\'' << argumentList[i] << '\'';  }  PCharArray envBuf;  char * envStr = NULL;  if (environment != NULL) {    PINDEX size = 0;    for (PINDEX e = 0; e < environment->GetSize(); e++) {      PString str = environment->GetKeyAt(e) + '=' + environment->GetDataAt(e);      PINDEX len = str.GetLength() + 1;      envBuf.SetSize(size + len);      memcpy(envBuf.GetPointer()+size, (const char *)str, len);      size += len;    }    envStr = envBuf.GetPointer();  }#ifndef _WIN32_WCE  STARTUPINFO startup;  memset(&startup, 0, sizeof(startup));  startup.cb = sizeof(startup);  startup.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;  startup.wShowWindow = SW_HIDE;  startup.hStdInput = INVALID_HANDLE_VALUE;  startup.hStdOutput = INVALID_HANDLE_VALUE;  startup.hStdError = INVALID_HANDLE_VALUE;  SECURITY_ATTRIBUTES security;  security.nLength = sizeof(security);  security.lpSecurityDescriptor = NULL;  security.bInheritHandle = TRUE;  if (mode == ReadOnly)    hToChild = INVALID_HANDLE_VALUE;  else {    HANDLE writeEnd;    PAssertOS(CreatePipe(&startup.hStdInput, &writeEnd, &security, 0));    PAssertOS(DuplicateHandle(GetCurrentProcess(), writeEnd,                              GetCurrentProcess(), &hToChild, 0, FALSE,                              DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS));  }  if (mode == WriteOnly)    hFromChild = INVALID_HANDLE_VALUE;  else if (mode == ReadWriteStd) {    hFromChild = INVALID_HANDLE_VALUE;    startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);    startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);  }  else {    PAssertOS(CreatePipe(&hFromChild, &startup.hStdOutput, &security, 0));    if (stderrSeparate)      PAssertOS(CreatePipe(&hStandardError, &startup.hStdError, &security, 0));    else {      startup.hStdError = startup.hStdOutput;      hStandardError = INVALID_HANDLE_VALUE;    }  }  if (ConvertOSError(CreateProcess(prog, cmdLine.GetPointer(),                                   NULL, NULL, TRUE, 0, envStr,                                   NULL, &startup, &info) ? 0 : -2))    os_handle = info.dwProcessId;  else {    if (hToChild != INVALID_HANDLE_VALUE)      CloseHandle(hToChild);    if (hFromChild != INVALID_HANDLE_VALUE)      CloseHandle(hFromChild);    if (hStandardError != INVALID_HANDLE_VALUE)      CloseHandle(hStandardError);  }  if (startup.hStdInput != INVALID_HANDLE_VALUE)    CloseHandle(startup.hStdInput);  if (mode != ReadWriteStd) {    if (startup.hStdOutput != INVALID_HANDLE_VALUE)      CloseHandle(startup.hStdOutput);    if (startup.hStdOutput != startup.hStdError)      CloseHandle(startup.hStdError);  }#endif // !_WIN32_WCE  return IsOpen();}PPipeChannel::~PPipeChannel(){  Close();}BOOL PPipeChannel::IsOpen() const{  return os_handle != -1;}int PPipeChannel::GetReturnCode() const{  DWORD code;  if (GetExitCodeProcess(info.hProcess, &code) && (code != STILL_ACTIVE))    return code;  ((PPipeChannel*)this)->ConvertOSError(-2);  return -1;}BOOL PPipeChannel::CanReadAndWrite(){  return TRUE;}BOOL PPipeChannel::IsRunning() const{  DWORD code;  return GetExitCodeProcess(info.hProcess, &code) && (code == STILL_ACTIVE);}int PPipeChannel::WaitForTermination(){  if (WaitForSingleObject(info.hProcess, INFINITE) == WAIT_OBJECT_0)    return GetReturnCode();  ConvertOSError(-2);  return -1;}int PPipeChannel::WaitForTermination(const PTimeInterval & timeout){  if (WaitForSingleObject(info.hProcess, timeout.GetInterval()) == WAIT_OBJECT_0)    return GetReturnCode();  ConvertOSError(-2);  return -1;}BOOL PPipeChannel::Kill(int signal){  return ConvertOSError(TerminateProcess(info.hProcess, signal) ? 0 : -2);}BOOL PPipeChannel::Read(void * buffer, PINDEX len){  lastReadCount = 0;  DWORD count;  if (!ConvertOSError(ReadFile(hFromChild, buffer, len, &count, NULL) ? 0 :-2, LastReadError))    return FALSE;  lastReadCount = count;  return lastReadCount > 0;}      BOOL PPipeChannel::Write(const void * buffer, PINDEX len){  lastWriteCount = 0;  DWORD count;  if (!ConvertOSError(WriteFile(hToChild, buffer, len, &count, NULL) ? 0 : -2, LastWriteError))    return FALSE;  lastWriteCount = count;  return lastWriteCount >= len;}BOOL PPipeChannel::Close(){  if (IsOpen()) {    os_handle = -1;    if (hToChild != INVALID_HANDLE_VALUE)      CloseHandle(hToChild);    if (hFromChild != INVALID_HANDLE_VALUE)      CloseHandle(hFromChild);    if (hStandardError != INVALID_HANDLE_VALUE)      CloseHandle(hStandardError);    if (!TerminateProcess(info.hProcess, 1))      return FALSE;  }  return TRUE;}BOOL PPipeChannel::Execute(){  flush();  clear();  if (hToChild != INVALID_HANDLE_VALUE)    CloseHandle(hToChild);  hToChild = INVALID_HANDLE_VALUE;  return TRUE;}BOOL PPipeChannel::ReadStandardError(PString & errors, BOOL wait){#ifndef _WIN32_WCE  DWORD available, bytesRead;  if (!PeekNamedPipe(hStandardError, NULL, 0, NULL, &available, NULL))    return ConvertOSError(-2, LastReadError);  if (available != 0)    return ConvertOSError(ReadFile(hStandardError,                          errors.GetPointer(available+1), available,                          &bytesRead, NULL) ? 0 : -2, LastReadError);  if (wait)    return FALSE;  char firstByte;  if (!ReadFile(hStandardError, &firstByte, 1, &bytesRead, NULL))    return ConvertOSError(-2, LastReadError);  errors = firstByte;  if (!PeekNamedPipe(hStandardError, NULL, 0, NULL, &available, NULL))    return ConvertOSError(-2, LastReadError);  if (available == 0)    return TRUE;  return ConvertOSError(ReadFile(hStandardError,                        errors.GetPointer(available+2)+1, available,                        &bytesRead, NULL) ? 0 : -2, LastReadError);#else  return FALSE;#endif // !_WIN32_WCE}// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -