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

📄 pipechan.cxx

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 CXX
字号:
/* * pipechan.cxx * * Sub-process commuicating with pip I/O channel implementation * * 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: pipechan.cxx,v $ * Revision 1.27  2000/06/21 01:01:22  robertj * AIX port, thanks Wolfgang Platzer (wolfgang.platzer@infonova.at). * * Revision 1.26  2000/04/09 18:19:23  rogerh * Add my changes for NetBSD support. * * Revision 1.25  2000/04/06 12:11:32  rogerh * MacOS X support submitted by Kevin Packard * * Revision 1.24  2000/03/08 12:17:09  rogerh * Add OpenBSD support * * Revision 1.23  1999/06/28 09:28:02  robertj * Portability issues, especially n BeOS (thanks Yuri!) * * Revision 1.22  1999/02/22 13:26:54  robertj * BeOS port changes. * * Revision 1.21  1998/11/30 21:51:46  robertj * New directory structure. * * Revision 1.20  1998/11/24 10:25:19  robertj * Fixed environment variable on FreeBSD * * Revision 1.19  1998/11/24 09:39:11  robertj * FreeBSD port. * * Revision 1.18  1998/11/06 01:06:05  robertj * Solaris environment variable name. * * Revision 1.17  1998/11/05 09:42:01  robertj * Fixed bug in direct stdout mode opening redirected stdout. * Solaris support, missing environ declaration. * Added assert for unsupported timeout in WaitForTermination() under solaris. * * Revision 1.16  1998/11/02 11:11:19  robertj * Added pipe output to stdout/stderr. * * Revision 1.15  1998/11/02 10:30:40  robertj * GNU v6 compatibility. * * Revision 1.14  1998/11/02 10:07:34  robertj * Added ReadStandardError implementation * * Revision 1.13  1998/10/30 13:02:50  robertj * New pipe channel enhancements. * * Revision 1.12  1998/10/26 11:09:56  robertj * added separation of stdout and stderr. * * Revision 1.11  1998/09/24 04:12:14  robertj * Added open software license. * */#pragma implementation "pipechan.h"#include <ptlib.h>#include <ptlib/pipechan.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/wait.h>#include <fcntl.h>#include <signal.h>#if defined(P_LINUX) || defined(P_SOLARIS)#include <termio.h>#endif#include "../common/pipechan.cxx"////////////////////////////////////////////////////////////////////  PPipeChannel//PPipeChannel::PPipeChannel(){  toChildPipe[0] = toChildPipe[1] = -1;  fromChildPipe[0] = fromChildPipe[1] = -1;  stderrChildPipe[0] = stderrChildPipe[1] = -1;}BOOL PPipeChannel::PlatformOpen(const PString & subProgram,                                const PStringArray & argumentList,                                OpenMode mode,                                BOOL searchPath,                                BOOL stderrSeparate,                                const PStringToString * environment){  subProgName = subProgram;  // setup the pipe to the child  if (mode == ReadOnly)    toChildPipe[0] = toChildPipe[1] = -1;  else     PAssert(pipe(toChildPipe) == 0, POperatingSystemError);   // setup the pipe from the child  if (mode == WriteOnly || mode == ReadWriteStd)    fromChildPipe[0] = fromChildPipe[1] = -1;  else    PAssert(pipe(fromChildPipe) == 0, POperatingSystemError);  if (stderrSeparate)    PAssert(pipe(stderrChildPipe) == 0, POperatingSystemError);  else    stderrChildPipe[0] = stderrChildPipe[1] = -1;  // fork to allow us to execute the child#ifdef __BEOS__  if ((childPid = fork()) != 0) {#else  if ((childPid = vfork()) != 0) {#endif    // setup the pipe to the child    if (toChildPipe[0] != -1)       ::close(toChildPipe[0]);    if (fromChildPipe[1] != -1)      ::close(fromChildPipe[1]);     if (stderrChildPipe[1] != -1)      ::close(stderrChildPipe[1]);     if (childPid < 0)      return FALSE;    os_handle = 0;    return TRUE;  }  // the following code is in the child process  // if we need to write to the child, make sure the child's stdin  // is redirected  if (toChildPipe[0] != -1) {    ::close(STDIN_FILENO);    ::dup(toChildPipe[0]);    ::close(toChildPipe[0]);    ::close(toChildPipe[1]);    } else {    int fd = open("/dev/null", O_RDONLY);    PAssertOS(fd >= 0);    ::close(STDIN_FILENO);    ::dup(fd);    ::close(fd);  }  // if we need to read from the child, make sure the child's stdout  // and stderr is redirected  if (fromChildPipe[1] != -1) {    ::close(STDOUT_FILENO);    ::dup(fromChildPipe[1]);    ::close(STDERR_FILENO);    if (!stderrSeparate)      ::dup(fromChildPipe[1]);    ::close(fromChildPipe[1]);    ::close(fromChildPipe[0]);   } else if (mode != ReadWriteStd) {    int fd = ::open("/dev/null", O_WRONLY);    PAssertOS(fd >= 0);    ::close(STDOUT_FILENO);    ::dup(fd);    ::close(STDERR_FILENO);    if (!stderrSeparate)      ::dup(fd);    ::close(fd);  }  if (stderrSeparate) {    ::dup(stderrChildPipe[1]);    ::close(stderrChildPipe[1]);    ::close(stderrChildPipe[0]);   }  // set the SIGINT and SIGQUIT to ignore so the child process doesn't  // inherit them from the parent  signal(SIGINT,  SIG_IGN);  signal(SIGQUIT, SIG_IGN);  // and set ourselves as out own process group so we don't get signals  // from our parent's terminal (hopefully!)  PSETPGRP();  // setup the arguments, not as we are about to execl or exit, we don't  // care about memory leaks, they are not real!  char ** args = (char **)calloc(argumentList.GetSize()+2, sizeof(char *));  args[0] = strdup(subProgName.GetTitle());  PINDEX i;  for (i = 0; i < argumentList.GetSize(); i++)     args[i+1] = argumentList[i].GetPointer();  // Set up new environment if one specified.  if (environment != NULL) {#if defined(P_SOLARIS) || defined(P_FREEBSD) || defined(P_OPENBSD) || defined (P_NETBSD) || defined(__BEOS__) || defined(P_MACOSX) || defined (P_AIX)    extern char ** environ;#define __environ environ#endif    __environ = (char **)calloc(environment->GetSize()+1, sizeof(char*));    for (i = 0; i < environment->GetSize(); i++) {      PString str = environment->GetKeyAt(i) + '=' + environment->GetDataAt(i);      __environ[i] = strdup(str);    }  }  // execute the child as required  if (searchPath)    execvp(subProgram, args);  else    execv(subProgram, args);  exit(2);  return FALSE;}BOOL PPipeChannel::Close(){  if (!IsOpen())    return TRUE;  // close pipe from child  if (fromChildPipe[0] != -1) {    ::close(fromChildPipe[0]);    fromChildPipe[0] = -1;  }  // close pipe to child  if (toChildPipe[1] != -1) {    ::close(toChildPipe[1]);    toChildPipe[1] = -1;  }  // close pipe to child  if (stderrChildPipe[0] != -1) {    ::close(stderrChildPipe[0]);    stderrChildPipe[0] = -1;  }  // kill the child process  if (IsRunning()) {    kill (childPid, SIGKILL);    WaitForTermination();  }  // ensure this channel looks like it is closed  os_handle = -1;  childPid  = 0;  return TRUE;}BOOL PPipeChannel::Read(void * buffer, PINDEX len){  PAssert(IsOpen(), "Attempt to read from closed pipe");  PAssert(fromChildPipe[0] != -1, "Attempt to read from write-only pipe");  os_handle = fromChildPipe[0];  BOOL status = PChannel::Read(buffer, len);  os_handle = 0;  return status;}BOOL PPipeChannel::Write(const void * buffer, PINDEX len){  PAssert(IsOpen(), "Attempt to write to closed pipe");  PAssert(toChildPipe[1] != -1, "Attempt to write to read-only pipe");  os_handle = toChildPipe[1];  BOOL status = PChannel::Write(buffer, len);  os_handle = 0;  return status;}BOOL PPipeChannel::Execute(){  flush();  clear();  if (toChildPipe[1] != -1) {    ::close(toChildPipe[1]);    toChildPipe[1] = -1;  }  return TRUE;}PPipeChannel::~PPipeChannel(){  Close();}int PPipeChannel::GetReturnCode() const{  return retVal;}BOOL PPipeChannel::IsRunning() const{  PAssert(childPid > 0, "IsRunning called for closed PPipeChannel");  return kill(childPid, 0) == 0;}int PPipeChannel::WaitForTermination(){#ifdef P_PTHREADS  if (kill (childPid, 0) == 0) {    while (wait3(NULL, WUNTRACED, NULL) != childPid)      ;  }#else  if (kill (childPid, 0) == 0)    return retVal = PThread::Current()->PXBlockOnChildTerminate(childPid, PMaxTimeInterval);#endif  ConvertOSError(-1);  return -1;}int PPipeChannel::WaitForTermination(const PTimeInterval & timeout){#ifdef P_PTHREADS  PAssert(timeout == PMaxTimeInterval, PUnimplementedFunction);  if (kill (childPid, 0) == 0) {    while (wait3(NULL, WUNTRACED, NULL) != childPid)      ;  }#else  if (kill (childPid, 0) == 0)    return retVal = PThread::Current()->PXBlockOnChildTerminate(childPid, timeout);#endif  ConvertOSError(-1);  return -1;}BOOL PPipeChannel::Kill(int killType){  return ConvertOSError(kill (childPid, killType));}BOOL PPipeChannel::CanReadAndWrite(){  return TRUE;}BOOL PPipeChannel::ReadStandardError(PString & errors, BOOL wait){  PAssert(IsOpen(), "Attempt to read from closed pipe");  PAssert(stderrChildPipe[0] != -1, "Attempt to read from write-only pipe");  os_handle = stderrChildPipe[0];    BOOL status = FALSE;#ifndef __BEOS__  int available;  if (ConvertOSError(ioctl(stderrChildPipe[0], FIONREAD, &available))) {    if (available != 0)      status = PChannel::Read(errors.GetPointer(available+1), available);    else if (wait) {      char firstByte;      status = PChannel::Read(&firstByte, 1);      if (status) {        errors = firstByte;        if (ConvertOSError(ioctl(stderrChildPipe[0], FIONREAD, &available))) {          if (available != 0)            status = PChannel::Read(errors.GetPointer(available+2)+1, available);        }      }    }  }#endif  os_handle = 0;  return status;}

⌨️ 快捷键说明

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