📄 pipechan.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.42.8.1 2005/02/04 05:19:12 csoutheren * Backported patches from Atlas-devel * * Revision 1.43 2004/12/15 00:39:01 csoutheren * Fixed problem with passing arguments to PPipeChannel, thanks to Derek Smithies * * Revision 1.42 2003/04/22 23:43:51 craigs * MacOSX changes as per Hugo Santos * * Revision 1.41 2003/01/09 08:21:47 robertj * Fixed possibly handle leak if fork() fails. * Also added belt and braces checks for making sure no handle can leak in * other unknown logic. Plus do handle high water mark logging. * * Revision 1.40 2003/01/08 01:33:52 craigs * Fixed problem with not checking errno on return from waitpid * * Revision 1.39 2003/01/08 01:29:22 craigs * More changes for return code to waitpid * * Revision 1.38 2002/12/18 01:12:09 craigs * Remove erroneous WUNTRACED and added support for EINTR from waitpid * * Revision 1.37 2002/12/05 05:11:16 craigs * Fixed IsRunning and WaitForTermination to provide the correct return * codes from subprograms * * Revision 1.36 2002/12/02 03:57:18 robertj * More RTEMS support patches, thank you Vladimir Nesic. * * Revision 1.35 2002/11/22 10:14:07 robertj * QNX port, thanks Xiaodan Tang * * Revision 1.34 2002/10/17 13:44:27 robertj * Port to RTEMS, thanks Vladimir Nesic. * * Revision 1.33 2002/10/10 04:43:44 robertj * VxWorks port, thanks Martijn Roest * * Revision 1.32 2002/07/31 07:30:11 craigs * WaitForTermination now returns exit code of program, as required * * Revision 1.31 2001/10/11 02:20:54 robertj * Added IRIX support (no audio/video), thanks Andre Schulze. * * Revision 1.30 2001/08/16 11:58:22 rogerh * Add more Mac OS X changes from John Woods <jfw@jfwhome.funhouse.com> * * Revision 1.29 2001/08/12 06:32:04 rogerh * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com> * * Revision 1.28 2001/06/30 06:59:07 yurik * Jac Goudsmit from Be submit these changes 6/28. Implemented by Yuri Kiryanov * * 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#if defined(P_MACOSX)#include <crt_externs.h>#endif#include "../common/pipechan.cxx"int PX_NewHandle(const char *, int);//////////////////////////////////////////////////////////////////// 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){#if defined(P_VXWORKS) || defined(P_RTEMS) PAssertAlways("PPipeChannel::PlatformOpen"); return FALSE;#else subProgName = subProgram; // setup the pipe to the child if (mode == ReadOnly) toChildPipe[0] = toChildPipe[1] = -1; else { PAssert(pipe(toChildPipe) == 0, POperatingSystemError); PX_NewHandle("PPipeChannel toChildPipe", PMAX(toChildPipe[0], toChildPipe[1])); } // setup the pipe from the child if (mode == WriteOnly || mode == ReadWriteStd) fromChildPipe[0] = fromChildPipe[1] = -1; else { PAssert(pipe(fromChildPipe) == 0, POperatingSystemError); PX_NewHandle("PPipeChannel fromChildPipe", PMAX(fromChildPipe[0], fromChildPipe[1])); } if (stderrSeparate) PAssert(pipe(stderrChildPipe) == 0, POperatingSystemError); else { stderrChildPipe[0] = stderrChildPipe[1] = -1; PX_NewHandle("PPipeChannel stderrChildPipe", PMAX(stderrChildPipe[0], stderrChildPipe[1])); } // fork to allow us to execute the child#if defined(__BEOS__) || defined(P_IRIX) childPid = fork();#else childPid = vfork();#endif if (childPid < 0) return FALSE; if (childPid > 0) { // setup the pipe to the child if (toChildPipe[0] != -1) { ::close(toChildPipe[0]); toChildPipe[0] = -1; } if (fromChildPipe[1] != -1) { ::close(fromChildPipe[1]); fromChildPipe[1] = -1; } if (stderrChildPipe[1] != -1) { ::close(stderrChildPipe[1]); stderrChildPipe[1] = -1; } 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -