aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2009-05-24 19:57:19 +0100
committerAvatar David Leverton <levertond@googlemail.com> 2009-05-24 19:57:19 +0100
commit35de93d04942375791298cde7f76bf48ac87f5b1 (patch)
treed824bd4ac5cdf3db1792189cdc8072db620c0f07
parent3608dd9c7775299143bda346f5344b8be1f8a7ae (diff)
downloadpaludis-35de93d04942375791298cde7f76bf48ac87f5b1.tar.gz
paludis-35de93d04942375791298cde7f76bf48ac87f5b1.tar.xz
Use ptys for output manager stuff
-rw-r--r--configure.ac8
-rw-r--r--paludis/repositories/cran/cran_repository.cc3
-rw-r--r--paludis/repositories/e/ebuild.cc6
-rw-r--r--paludis/repositories/e/fetch_visitor.cc3
-rw-r--r--paludis/syncer.cc3
-rw-r--r--paludis/util/channel.cc45
-rw-r--r--paludis/util/channel.hh89
-rw-r--r--paludis/util/files.m44
-rw-r--r--paludis/util/pipe.cc11
-rw-r--r--paludis/util/pipe.hh35
-rw-r--r--paludis/util/pty.cc91
-rw-r--r--paludis/util/pty.hh81
-rw-r--r--paludis/util/system.cc25
-rw-r--r--paludis/util/system.hh14
14 files changed, 367 insertions, 51 deletions
diff --git a/configure.ac b/configure.ac
index 9a0c560..1ee74a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -132,11 +132,17 @@ AC_CHECK_FUNCS([alarm], [], [AC_MSG_ERROR([I need alarm])])
AC_CHECK_FUNCS([strerror], [], [AC_MSG_ERROR([I need strerror])])
AC_CHECK_FUNCS([signal], [], [AC_MSG_ERROR([I need signal])])
AC_CHECK_FUNCS([popen], [], [AC_MSG_ERROR([I need popen])])
-AC_CHECK_FUNCS([ptsname], [], [AC_MSG_ERROR([I need ptsname])])
+AC_CHECK_FUNCS([posix_openpt], [], [AC_MSG_ERROR([I need posix_openpt])])
AC_CHECK_FUNCS([grantpt], [], [AC_MSG_ERROR([I need grantpt])])
AC_CHECK_FUNCS([unlockpt], [], [AC_MSG_ERROR([I need unlockpt])])
dnl }}}
+dnl {{{ check for ptsname_r or ptsname function
+AC_CHECK_FUNCS([ptsname_r], [],
+ [AC_CHECK_FUNCS([ptsname], [], [AC_MSG_ERROR([I need ptsname_r or ptsname])])])
+AM_CONDITIONAL(HAVE_PTSNAME_R, test x$ac_cv_func_ptsname_r = xyes)
+dnl }}}
+
dnl {{{ check for lchflags function
AC_CHECK_FUNCS([lchflags])
AM_CONDITIONAL(HAVE_LCHFLAGS, test x$ac_cv_func_lchflags = xyes)
diff --git a/paludis/repositories/cran/cran_repository.cc b/paludis/repositories/cran/cran_repository.cc
index ba1c2bf..4d6713b 100644
--- a/paludis/repositories/cran/cran_repository.cc
+++ b/paludis/repositories/cran/cran_repository.cc
@@ -381,6 +381,7 @@ CRANRepository::sync(const std::tr1::shared_ptr<OutputManager> & output_manager)
command1
.with_captured_stdout_stream(&output_manager->stdout_stream())
.with_captured_stderr_stream(&output_manager->stderr_stream())
+ .with_ptys()
;
if (0 != run_command(command1))
@@ -393,6 +394,7 @@ CRANRepository::sync(const std::tr1::shared_ptr<OutputManager> & output_manager)
command2
.with_captured_stdout_stream(&output_manager->stdout_stream())
.with_captured_stderr_stream(&output_manager->stderr_stream())
+ .with_ptys()
;
if (0 != run_command(command2))
@@ -405,6 +407,7 @@ CRANRepository::sync(const std::tr1::shared_ptr<OutputManager> & output_manager)
command3
.with_captured_stdout_stream(&output_manager->stdout_stream())
.with_captured_stderr_stream(&output_manager->stderr_stream())
+ .with_ptys()
;
if (0 != run_command(command3))
diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc
index 64103e7..970d737 100644
--- a/paludis/repositories/e/ebuild.cc
+++ b/paludis/repositories/e/ebuild.cc
@@ -269,7 +269,8 @@ EbuildCommand::operator() ()
if (params.maybe_output_manager())
cmd
.with_captured_stderr_stream(&params.maybe_output_manager()->stderr_stream())
- .with_captured_stdout_stream(&params.maybe_output_manager()->stdout_stream());
+ .with_captured_stdout_stream(&params.maybe_output_manager()->stdout_stream())
+ .with_ptys();
if (do_run_command(cmd))
return success();
@@ -948,7 +949,8 @@ WriteVDBEntryCommand::operator() ()
if (params.maybe_output_manager())
cmd
.with_captured_stderr_stream(&params.maybe_output_manager()->stderr_stream())
- .with_captured_stdout_stream(&params.maybe_output_manager()->stdout_stream());
+ .with_captured_stdout_stream(&params.maybe_output_manager()->stdout_stream())
+ .with_ptys();
std::string defined_phases(params.package_id()->eapi()->supported()->ebuild_metadata_variables()->defined_phases()->name());
if (! defined_phases.empty())
diff --git a/paludis/repositories/e/fetch_visitor.cc b/paludis/repositories/e/fetch_visitor.cc
index 53d9975..0cb5c8d 100644
--- a/paludis/repositories/e/fetch_visitor.cc
+++ b/paludis/repositories/e/fetch_visitor.cc
@@ -237,7 +237,8 @@ FetchVisitor::visit(const FetchableURISpecTree::NodeType<FetchableURIDepSpec>::T
cmd
.with_captured_stderr_stream(&_imp->output_manager->stderr_stream())
- .with_captured_stdout_stream(&_imp->output_manager->stdout_stream());
+ .with_captured_stdout_stream(&_imp->output_manager->stdout_stream())
+ .with_ptys();
_imp->output_manager->stdout_stream() << "Trying to fetch '" << i->first << "' to '" <<
i->second << "'..." << std::endl;
diff --git a/paludis/syncer.cc b/paludis/syncer.cc
index cf8e914..a1fddcf 100644
--- a/paludis/syncer.cc
+++ b/paludis/syncer.cc
@@ -101,7 +101,8 @@ DefaultSyncer::sync(const SyncOptions & opts) const
cmd
.with_captured_stderr_stream(&opts.output_manager()->stderr_stream())
- .with_captured_stdout_stream(&opts.output_manager()->stdout_stream());
+ .with_captured_stdout_stream(&opts.output_manager()->stdout_stream())
+ .with_ptys();
if (run_command(cmd))
throw SyncFailedError(_local, _remote);
diff --git a/paludis/util/channel.cc b/paludis/util/channel.cc
new file mode 100644
index 0000000..a745509
--- /dev/null
+++ b/paludis/util/channel.cc
@@ -0,0 +1,45 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007, 2008 Ciaran McCreesh
+ * Copyright (c) 2009 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "channel.hh"
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/log.hh>
+#include <unistd.h>
+#include <cstring>
+#include <errno.h>
+
+using namespace paludis;
+
+Channel::Channel()
+{
+}
+
+Channel::~Channel()
+{
+ Context context("When destroying channel FDs '" + stringify(read_fd()) + "', '" + stringify(write_fd()) + "'");
+ if (-1 != _fds[0])
+ if (-1 == close(_fds[0]))
+ Log::get_instance()->message("util.channel.close", ll_warning, lc_context) << "close(" << _fds[0] << ") -> " << strerror(errno);
+ if (-1 != _fds[1])
+ if (-1 == close(_fds[1]))
+ Log::get_instance()->message("util.channel.close", ll_warning, lc_context) << "close(" << _fds[1] << ") -> " << strerror(errno);
+}
+
diff --git a/paludis/util/channel.hh b/paludis/util/channel.hh
new file mode 100644
index 0000000..b65623a
--- /dev/null
+++ b/paludis/util/channel.hh
@@ -0,0 +1,89 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2009 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_CHANNEL_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_CHANNEL_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+
+/** \file
+ * Declaration for the Channel class.
+ *
+ * \ingroup g_system
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+namespace paludis
+{
+ /**
+ * Wrapper around a read/write file descriptor pair, such as a pipe.
+ *
+ * \ingroup g_system
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE Channel :
+ InstantiationPolicy<Channel, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ int _fds[2];
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ Channel();
+
+ virtual ~Channel();
+
+ ///\}
+
+ ///\name File descriptors
+ ///\{
+
+ int read_fd() const PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _fds[0];
+ }
+
+ int write_fd() const PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _fds[1];
+ }
+
+ void clear_read_fd()
+ {
+ _fds[0] = -1;
+ }
+
+ void clear_write_fd()
+ {
+ _fds[1] = -1;
+ }
+
+ ///\}
+
+ };
+
+}
+
+#endif
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index c74643f..e5d62ac 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -13,8 +13,9 @@ add(`action_queue', `hh', `cc', `test')
add(`active_object_ptr', `hh', `cc', `fwd', `test')
add(`attributes', `hh')
add(`byte_swap', `hh', `test')
-add(`config_file', `hh', `cc', `fwd', `se', `test', `testscript')
+add(`channel', `hh', `cc')
add(`clone', `hh', `impl')
+add(`config_file', `hh', `cc', `fwd', `se', `test', `testscript')
add(`condition_variable', `hh', `cc', `test')
add(`cookie', `hh', `cc')
add(`create_iterator', `hh', `fwd', `impl', `test')
@@ -51,6 +52,7 @@ add(`output_wrapper', `test', `testscript')
add(`pipe', `hh', `cc')
add(`pretty_print', `hh', `cc', `test')
add(`private_implementation_pattern', `hh', `impl')
+add(`pty', `hh', `cc')
add(`random', `hh', `cc', `test')
add(`remove_shared_ptr', `hh')
add(`rmd160', `hh', `cc', `test')
diff --git a/paludis/util/pipe.cc b/paludis/util/pipe.cc
index 7b1cf22..88f130f 100644
--- a/paludis/util/pipe.cc
+++ b/paludis/util/pipe.cc
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2006, 2007, 2008 Ciaran McCreesh
+ * Copyright (c) 2009 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -19,11 +20,8 @@
#include "pipe.hh"
#include <paludis/util/exception.hh>
-#include <paludis/util/stringify.hh>
#include <paludis/util/log.hh>
#include <unistd.h>
-#include <cstring>
-#include <errno.h>
using namespace paludis;
@@ -40,12 +38,5 @@ Pipe::Pipe()
Pipe::~Pipe()
{
- Context context("When destroying pipe FDs '" + stringify(read_fd()) + "', '" + stringify(write_fd()) + "'");
- if (-1 != _fds[0])
- if (-1 == close(_fds[0]))
- Log::get_instance()->message("util.pipe.close", ll_warning, lc_context) << "close(" << _fds[0] << ") -> " << strerror(errno);
- if (-1 != _fds[1])
- if (-1 == close(_fds[1]))
- Log::get_instance()->message("util.pipe.close", ll_warning, lc_context) << "close(" << _fds[1] << ") -> " << strerror(errno);
}
diff --git a/paludis/util/pipe.hh b/paludis/util/pipe.hh
index 8f24995..ae0184e 100644
--- a/paludis/util/pipe.hh
+++ b/paludis/util/pipe.hh
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2009 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -20,7 +21,7 @@
#ifndef PALUDIS_GUARD_PALUDIS_UTIL_PIPE_HH
#define PALUDIS_GUARD_PALUDIS_UTIL_PIPE_HH 1
-#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/channel.hh>
/** \file
* Declaration for the Pipe class.
@@ -41,43 +42,15 @@ namespace paludis
* \nosubgrouping
*/
class PALUDIS_VISIBLE Pipe :
- InstantiationPolicy<Pipe, instantiation_method::NonCopyableTag>
+ public Channel
{
- private:
- int _fds[2];
-
public:
///\name Basic operations
///\{
Pipe();
- ~Pipe();
-
- ///\}
-
- ///\name File descriptors
- ///\{
-
- int read_fd() const PALUDIS_ATTRIBUTE((warn_unused_result))
- {
- return _fds[0];
- }
-
- int write_fd() const PALUDIS_ATTRIBUTE((warn_unused_result))
- {
- return _fds[1];
- }
-
- void clear_read_fd()
- {
- _fds[0] = -1;
- }
-
- void clear_write_fd()
- {
- _fds[1] = -1;
- }
+ virtual ~Pipe();
///\}
diff --git a/paludis/util/pty.cc b/paludis/util/pty.cc
new file mode 100644
index 0000000..b5c97a8
--- /dev/null
+++ b/paludis/util/pty.cc
@@ -0,0 +1,91 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007, 2008 Ciaran McCreesh
+ * Copyright (c) 2009 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "pty.hh"
+#include <paludis/util/exception.hh>
+#include <paludis/util/log.hh>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <cstring>
+
+using namespace paludis;
+
+PtyError::PtyError(const std::string & our_message) throw () :
+ Exception(our_message)
+{
+}
+
+Pty::Pty()
+{
+ Context context("When creating pty FDs:");
+
+ _fds[0] = posix_openpt(O_RDWR | O_NOCTTY);
+ if (-1 == _fds[0])
+ throw PtyError("posix_openpt(3) failed: " + std::string(std::strerror(errno)));
+ if (-1 == grantpt(_fds[0]))
+ {
+ close(_fds[0]);
+ throw PtyError("grantpt(3) failed: " + std::string(std::strerror(errno)));
+ }
+ if (-1 == unlockpt(_fds[0]))
+ {
+ close(_fds[0]);
+ throw PtyError("unlockpt(3) failed: " + std::string(std::strerror(errno)));
+ }
+
+#ifdef HAVE_PTSNAME_R
+ std::vector<char> name;
+ name.resize(16);
+ while (-1 == ptsname_r(_fds[0], &name[0], name.length()))
+ {
+ if (ERANGE == errno)
+ name.resize(name.length() * 2);
+ else
+ {
+ close(_fds[0]);
+ throw PtyError("ptsname_r(3) failed: " + std::string(std::strerror(errno)));
+ }
+ }
+ _fds[1] = open(&name[0], O_WRONLY | O_NOCTTY);
+#else
+ const char * name(ptsname(_fds[0]));
+ if (0 == name)
+ {
+ close(_fds[0]);
+ throw PtyError("ptsname(3) failed: " + std::string(std::strerror(errno)));
+ }
+ _fds[1] = open(name, O_WRONLY | O_NOCTTY);
+#endif
+
+ if (-1 == _fds[1])
+ {
+ close(_fds[0]);
+ throw PtyError("open(2) failed: " + std::string(std::strerror(errno)));
+ }
+
+ Log::get_instance()->message("util.pty.fds", ll_debug, lc_context) << "Pty FDs are '" << read_fd() << "', '"
+ << write_fd() << "'";
+}
+
+Pty::~Pty()
+{
+}
+
diff --git a/paludis/util/pty.hh b/paludis/util/pty.hh
new file mode 100644
index 0000000..0870f9f
--- /dev/null
+++ b/paludis/util/pty.hh
@@ -0,0 +1,81 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2009 David Leverton
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_UTIL_PTY_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_PTY_HH 1
+
+#include <paludis/util/channel.hh>
+#include <paludis/util/exception.hh>
+
+/** \file
+ * Declaration for the Pty class.
+ *
+ * \ingroup g_system
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+namespace paludis
+{
+ /**
+ * Thrown if a pty cannot be allocated and opened.
+ *
+ * \ingroup g_exceptions
+ * \ingroup g_system
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE PtyError :
+ public Exception
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ PtyError(const std::string & message) throw ();
+
+ ///\}
+ };
+
+ /**
+ * Wrapper around pty file descriptors.
+ *
+ * \ingroup g_system
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE Pty :
+ public Channel
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ Pty();
+
+ virtual ~Pty();
+
+ ///\}
+
+ };
+
+}
+
+#endif
diff --git a/paludis/util/system.cc b/paludis/util/system.cc
index 88d187e..9f80bd8 100644
--- a/paludis/util/system.cc
+++ b/paludis/util/system.cc
@@ -29,6 +29,7 @@
#include <paludis/util/strip.hh>
#include <paludis/util/safe_ofstream.hh>
#include <paludis/util/pipe.hh>
+#include <paludis/util/pty.hh>
#include <sys/utsname.h>
#include <sys/types.h>
@@ -163,6 +164,7 @@ namespace paludis
std::tr1::function<std::string (const std::string &)> pipe_command_handler;
std::ostream * captured_stdout_stream;
std::ostream * captured_stderr_stream;
+ bool ptys;
Implementation(const std::string & c,
const std::map<std::string, std::string> & s = make_me_a_frickin_map_because_gcc_sucks(),
@@ -187,7 +189,8 @@ namespace paludis
prefix_blank_lines(bb),
pipe_command_handler(h),
captured_stdout_stream(cs),
- captured_stderr_stream(ds)
+ captured_stderr_stream(ds),
+ ptys(false)
{
}
};
@@ -283,6 +286,13 @@ Command::with_captured_stderr_stream(std::ostream * const c)
}
Command &
+Command::with_ptys()
+{
+ _imp->ptys = true;
+ return *this;
+}
+
+Command &
Command::with_sandbox()
{
#if HAVE_SANDBOX
@@ -358,16 +368,17 @@ paludis::run_command(const Command & cmd)
Log::get_instance()->message("util.system.execl", ll_debug, lc_no_context) << "execl /bin/sh -c " << command
<< " " << extras;
- std::tr1::shared_ptr<Pipe> internal_command_reader(new Pipe), pipe_command_reader, pipe_command_response, captured_stdout, captured_stderr;
+ std::tr1::shared_ptr<Pipe> internal_command_reader(new Pipe), pipe_command_reader, pipe_command_response;
+ std::tr1::shared_ptr<Channel> captured_stdout, captured_stderr;
if (cmd.pipe_command_handler())
{
pipe_command_reader.reset(new Pipe);
pipe_command_response.reset(new Pipe);
}
if (cmd.captured_stdout_stream())
- captured_stdout.reset(new Pipe);
+ captured_stdout.reset(cmd.ptys() ? static_cast<Channel *>(new Pty) : new Pipe);
if (cmd.captured_stderr_stream())
- captured_stderr.reset(new Pipe);
+ captured_stderr.reset(cmd.ptys() ? static_cast<Channel *>(new Pty) : new Pipe);
/* Why do we fork twice, rather than install a SIGCHLD handler that writes to a pipe that
* our pselect watches? Simple: Unix is retarded. APUE 12.8 says "Each thread has its own signal
@@ -920,6 +931,12 @@ Command::captured_stderr_stream() const
return _imp->captured_stderr_stream;
}
+bool
+Command::ptys() const
+{
+ return _imp->ptys;
+}
+
std::string
paludis::get_user_name(const uid_t u)
{
diff --git a/paludis/util/system.hh b/paludis/util/system.hh
index 6e2ccef..da8a28c 100644
--- a/paludis/util/system.hh
+++ b/paludis/util/system.hh
@@ -196,6 +196,13 @@ namespace paludis
*/
Command & with_captured_stderr_stream(std::ostream * const);
+ /**
+ * Use ptys instead of pipes to capture stdout and/or stderr.
+ *
+ * \since 0.38
+ */
+ Command & with_ptys();
+
///\}
///\name Fetch command execution options
@@ -265,6 +272,13 @@ namespace paludis
std::ostream * captured_stderr_stream() const;
/**
+ * Uses ptys instead of pipes?
+ *
+ * \since 0.38
+ */
+ bool ptys() const;
+
+ /**
* Should we clear existing environment variables?
*
* \since 0.36