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

📄 pipechan.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:

  // 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] = strdup(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_MACOS) || defined (P_AIX) || defined(P_IRIX) || defined(P_QNX)
    extern char ** environ;
#  if defined(P_MACOSX)
#    define environ (*_NSGetEnviron())
#  endif
#  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;
#endif // P_VXWORKS || P_RTEMS
}


BOOL PPipeChannel::Close()
{
  // close pipe from child
  if (fromChildPipe[0] != -1) {
    ::close(fromChildPipe[0]);
    fromChildPipe[0] = -1;
  }

  if (fromChildPipe[1] != -1) {
    ::close(fromChildPipe[1]);
    fromChildPipe[1] = -1;
  }

  // close pipe to child
  if (toChildPipe[0] != -1) {
    ::close(toChildPipe[0]);
    toChildPipe[0] = -1;
  }

  if (toChildPipe[1] != -1) {
    ::close(toChildPipe[1]);
    toChildPipe[1] = -1;
  }

  // close pipe to child
  if (stderrChildPipe[0] != -1) {
    ::close(stderrChildPipe[0]);
    stderrChildPipe[0] = -1;
  }

  if (stderrChildPipe[1] != -1) {
    ::close(stderrChildPipe[1]);
    stderrChildPipe[1] = -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
{
  if (childPid == 0)
    return FALSE;

#if defined(P_PTHREADS) || defined(P_MAC_MPTHREADS)

  int err;
  int status;
  if ((err = waitpid(childPid, &status, WNOHANG)) == 0)
    return TRUE;

  if (err != childPid)
    return FALSE;

  PPipeChannel * thisW = (PPipeChannel *)this;
  thisW->childPid = 0;

  if (WIFEXITED(status)) {
    thisW->retVal = WEXITSTATUS(status);
    PTRACE(2, "PipeChannel\tChild exited with code " << retVal);
  } else if (WIFSIGNALED(status)) {
    PTRACE(2, "PipeChannel\tChild was signalled with " << WTERMSIG(status));
    thisW->retVal = -1;
  } else if (WIFSTOPPED(status)) {
    PTRACE(2, "PipeChannel\tChild was stopped with " << WSTOPSIG(status));
    thisW->retVal = -1;
  } else {
    PTRACE(2, "PipeChannel\tChild was stopped with unknown status" << status);
    thisW->retVal = -1;
  }

  return FALSE;

#else
  return kill(childPid, 0) == 0;
#endif
}

int PPipeChannel::WaitForTermination()
{
  if (childPid == 0)
    return retVal;

  int err;

#if defined(P_PTHREADS) || defined(P_MAC_MPTHREADS)
  int status;
  do {
    err = waitpid(childPid, &status, 0);
    if (err == childPid) {
      childPid = 0;
      if (WIFEXITED(status)) {
        retVal = WEXITSTATUS(status);
        PTRACE(2, "PipeChannel\tChild exited with code " << retVal);
      } else if (WIFSIGNALED(status)) {
        PTRACE(2, "PipeChannel\tChild was signalled with " << WTERMSIG(status));
        retVal = -1;
      } else if (WIFSTOPPED(status)) {
        PTRACE(2, "PipeChannel\tChild was stopped with " << WSTOPSIG(status));
        retVal = -1;
      } else {
        PTRACE(2, "PipeChannel\tChild was stopped with unknown status" << status);
        retVal = -1;
      }
      return retVal;
    }
  } while (errno == EINTR);
#else
  if ((err = kill (childPid, 0)) == 0)
    return retVal = PThread::Current()->PXBlockOnChildTerminate(childPid, PMaxTimeInterval);
#endif

  ConvertOSError(err);
  return -1;
}

int PPipeChannel::WaitForTermination(const PTimeInterval & timeout)
{
  if (childPid == 0)
    return retVal;

  int err;

#if defined(P_PTHREADS) || defined(P_MAC_MPTHREADS)
  PAssert(timeout == PMaxTimeInterval, PUnimplementedFunction);
  int status;
  do {
    err = waitpid(childPid, &status, 0);
    if (err == childPid) {
      childPid = 0;
      if (WIFEXITED(status)) {
        retVal = WEXITSTATUS(status);
        PTRACE(2, "PipeChannel\tChild exited with code " << retVal);
      } else if (WIFSIGNALED(status)) {
        PTRACE(2, "PipeChannel\tChild was signalled with " << WTERMSIG(status));
        retVal = -1;
      } else if (WIFSTOPPED(status)) {
        PTRACE(2, "PipeChannel\tChild was stopped with " << WSTOPSIG(status));
        retVal = -1;
      } else {
        PTRACE(2, "PipeChannel\tChild was stopped with unknown status" << status);
        retVal = -1;
      }
      return retVal;
    }
  } while (errno == EINTR);
#else
  if ((err = kill (childPid, 0)) == 0)
    return retVal = PThread::Current()->PXBlockOnChildTerminate(childPid, timeout);
#endif

  ConvertOSError(err);
  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 BE_BONELESS
  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 + -