system.hh

Go to the documentation of this file.
00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
00002 
00003 /*
00004  * Copyright (c) 2006, 2007, 2008, 2009 Ciaran McCreesh
00005  *
00006  * This file is part of the Paludis package manager. Paludis is free software;
00007  * you can redistribute it and/or modify it under the terms of the GNU General
00008  * Public License version 2, as published by the Free Software Foundation.
00009  *
00010  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
00011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00012  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00013  * details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017  * Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #ifndef PALUDIS_GUARD_PALUDIS_UTIL_SYSTEM_HH
00021 #define PALUDIS_GUARD_PALUDIS_UTIL_SYSTEM_HH 1
00022 
00023 #include <paludis/util/exception.hh>
00024 #include <paludis/util/private_implementation_pattern.hh>
00025 #include <paludis/util/wrapped_forward_iterator-fwd.hh>
00026 #include <tr1/memory>
00027 #include <tr1/functional>
00028 #include <string>
00029 #include <sys/types.h>
00030 
00031 /** \file
00032  * Various system utilities.
00033  *
00034  * \ingroup g_system
00035  *
00036  * \section Examples
00037  *
00038  * - None at this time.
00039  */
00040 
00041 namespace paludis
00042 {
00043     class FSEntry;
00044 
00045     /**
00046      * Thrown if getenv_or_error fails.
00047      *
00048      * \ingroup g_exceptions
00049      * \ingroup g_system
00050      * \nosubgrouping
00051      */
00052     class PALUDIS_VISIBLE GetenvError : public Exception
00053     {
00054         public:
00055             ///\name Basic operations
00056             ///\{
00057 
00058             GetenvError(const std::string & key) throw ();
00059 
00060             ///\}
00061     };
00062 
00063     /**
00064      * Thrown if fork, wait or chdir fail when running a command.
00065      *
00066      * \ingroup g_exceptions
00067      * \ingroup g_system
00068      * \nosubgrouping
00069      */
00070     class PALUDIS_VISIBLE RunCommandError : public Exception
00071     {
00072         public:
00073             /**
00074              * Constructor.
00075              */
00076             RunCommandError(const std::string & message) throw ();
00077     };
00078 
00079     /**
00080      * Fetch the value of environment variable key, or def if the variable is
00081      * not defined.
00082      *
00083      * \ingroup g_system
00084      */
00085     std::string getenv_with_default(const std::string & key, const std::string & def) PALUDIS_VISIBLE;
00086 
00087     /**
00088      * Fetch the value of environment variable key, or throw a GetenvError if
00089      * the variable is not defined.
00090      *
00091      * \ingroup g_system
00092      */
00093     std::string getenv_or_error(const std::string & key) PALUDIS_VISIBLE;
00094 
00095     /**
00096      * Fetch the kernel version, for $KV.
00097      *
00098      * \ingroup g_system
00099      */
00100     std::string kernel_version() PALUDIS_VISIBLE;
00101 
00102     /**
00103      * A command to be run.
00104      *
00105      * \see PStream
00106      * \see run_command
00107      * \ingroup g_system
00108      * \nosubgrouping
00109      */
00110     class PALUDIS_VISIBLE Command :
00111         private PrivateImplementationPattern<Command>
00112     {
00113         public:
00114             ///\name Basic operations
00115             ///\{
00116 
00117             Command(const std::string &);
00118             Command(const char * const);
00119             Command(const Command &);
00120             const Command & operator= (const Command &);
00121             ~Command();
00122 
00123             ///\}
00124 
00125             ///\name Change command execution options
00126             ///\{
00127 
00128             /**
00129              * Include a chdir before we run our command.
00130              */
00131             Command & with_chdir(const FSEntry &);
00132 
00133             /**
00134              * Add a setenv before we run our command.
00135              */
00136             Command & with_setenv(const std::string &, const std::string &);
00137 
00138             /**
00139              * Remove (most) existing environment variables before
00140              * setting those added with with_setenv.
00141              *
00142              * \since 0.36
00143              */
00144             Command & with_clearenv();
00145 
00146             /**
00147              * Run our command sandboxed.
00148              */
00149             Command & with_sandbox();
00150 
00151             /**
00152              * Run our command sydboxed
00153              *
00154              * \since 0.38
00155              */
00156             Command & with_sydbox();
00157 
00158             /**
00159              * Echo the command to be run to stderr before running it.
00160              */
00161             Command & with_echo_to_stderr();
00162 
00163             /**
00164              * Add a setuid and setgid before running our command.
00165              */
00166             Command & with_uid_gid(const uid_t, const gid_t);
00167 
00168             /**
00169              * Prefix stdout output with this.
00170              */
00171             Command & with_stdout_prefix(const std::string &);
00172 
00173             /**
00174              * Prefix stderr output with this.
00175              */
00176             Command & with_stderr_prefix(const std::string &);
00177 
00178             /**
00179              * If prefixing, and if the output contains only blanks, don't display
00180              * any output.
00181              */
00182             Command & with_prefix_discard_blank_output();
00183 
00184             /**
00185              * If prefixing, prefix blank lines too.
00186              */
00187             Command & with_prefix_blank_lines();
00188 
00189             /**
00190              * Specify a pipe command handler.
00191              */
00192             Command & with_pipe_command_handler(const std::tr1::function<std::string (const std::string &)> &);
00193 
00194             /**
00195              * Specify a stream to which stdout is captured and written.
00196              */
00197             Command & with_captured_stdout_stream(std::ostream * const);
00198 
00199             /**
00200              * Specify a stream to which stderr is captured and written.
00201              *
00202              * \since 0.30
00203              */
00204             Command & with_captured_stderr_stream(std::ostream * const);
00205 
00206             /**
00207              * Send the contents of a stream in via a particular FD.
00208              *
00209              * May only be called once.
00210              *
00211              * \param fd Send the stream to this FD. If -1, pick an unused FD.
00212              * \param env_var If not empty, put the FD chosen in this env var.
00213              *
00214              * \since 0.40
00215              */
00216             Command & with_input_stream(
00217                     std::istream * const,
00218                     int fd,
00219                     const std::string & env_var);
00220 
00221             /**
00222              * Use ptys instead of pipes to capture stdout and/or stderr.
00223              *
00224              * \since 0.38
00225              */
00226             Command & with_ptys();
00227 
00228             ///\}
00229 
00230             ///\name Fetch command execution options
00231             ///\{
00232 
00233             /**
00234              * Our command, as a string.
00235              */
00236             std::string command() const;
00237 
00238             /**
00239              * Where to chdir, as a string.
00240              */
00241             std::string chdir() const;
00242 
00243             /**
00244              * Echo ourself to stderr.
00245              */
00246             void echo_to_stderr() const;
00247 
00248             /**
00249              * The uid for setuid.
00250              */
00251             std::tr1::shared_ptr<const uid_t> uid() const;
00252 
00253             /**
00254              * The gid for setgid.
00255              */
00256             std::tr1::shared_ptr<const gid_t> gid() const;
00257 
00258             /**
00259              * The stdout prefix.
00260              */
00261             std::string stdout_prefix() const;
00262 
00263             /**
00264              * The stderr prefix.
00265              */
00266             std::string stderr_prefix() const;
00267 
00268             /**
00269              * If prefixing, and if the output contains only blanks, don't display
00270              * any output?
00271              */
00272             bool prefix_discard_blank_output() const;
00273 
00274             /**
00275              * Prefix blank lines?
00276              */
00277             bool prefix_blank_lines() const;
00278 
00279             /**
00280              * The pipe command handler.
00281              */
00282             const std::tr1::function<std::string (const std::string &)> & pipe_command_handler() const;
00283 
00284             /**
00285              * The captured stdout stream, or null.
00286              */
00287             std::ostream * captured_stdout_stream() const;
00288 
00289             /**
00290              * The captured stderr stream, or null.
00291              *
00292              * \since 0.30
00293              */
00294             std::ostream * captured_stderr_stream() const;
00295 
00296             /**
00297              * The input stream, or null.
00298              *
00299              * \since 0.40
00300              */
00301             std::istream * input_stream() const;
00302 
00303             /**
00304              * The input FD, if input_stream() not null.
00305              *
00306              * \since 0.40
00307              */
00308             int input_fd() const;
00309 
00310             /**
00311              * The input FD env var, if input_stream() not null.
00312              *
00313              * \since 0.40
00314              */
00315             const std::string input_fd_env_var() const;
00316 
00317             /**
00318              * Uses ptys instead of pipes?
00319              *
00320              * \since 0.38
00321              */
00322             bool ptys() const;
00323 
00324             /**
00325              * Should we clear existing environment variables?
00326              *
00327              * \since 0.36
00328              */
00329             bool clearenv() const;
00330 
00331             ///\}
00332 
00333             ///\name Iterate over our setenvs.
00334             ///\{
00335 
00336             struct ConstIteratorTag;
00337             typedef WrappedForwardIterator<ConstIteratorTag, const std::pair<const std::string, std::string> > ConstIterator;
00338             ConstIterator begin_setenvs() const;
00339             ConstIterator end_setenvs() const;
00340 
00341             ///\}
00342     };
00343 
00344     /**
00345      * Run a command, wait for it to terminate and return its exit status.
00346      *
00347      * \ingroup g_system
00348      */
00349     int run_command(const Command & cmd) PALUDIS_VISIBLE
00350         PALUDIS_ATTRIBUTE((warn_unused_result));
00351 
00352     /**
00353      * Become another command.
00354      *
00355      * Actions that change the initial state (uid / gid, env) work, as do input
00356      * streams, but output redirection does not. Pipe commands don't work, but
00357      * could be made to.
00358      *
00359      * \ingroup g_system
00360      * \since 0.40.1
00361      */
00362     void become_command(const Command & cmd) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((noreturn));
00363 
00364     /**
00365      * Set the stderr and close for stdout fds used by run_command and
00366      * run_command_in_directory.
00367      *
00368      * \ingroup g_system
00369      */
00370     void set_run_command_stdout_fds(const int, const int) PALUDIS_VISIBLE;
00371 
00372     /**
00373      * Set the stderr and close for stderr fds used by run_command and
00374      * run_command_in_directory.
00375      *
00376      * \ingroup g_system
00377      */
00378     void set_run_command_stderr_fds(const int, const int) PALUDIS_VISIBLE;
00379 
00380     /**
00381      * Fetch the username for a uid, or the uid as a string if not available.
00382      *
00383      * \ingroup g_system
00384      */
00385     std::string get_user_name(const uid_t) PALUDIS_VISIBLE;
00386 
00387     /**
00388      * Fetch the group name for a gid, or the gid as a string if not available.
00389      *
00390      * \ingroup g_system
00391      */
00392     std::string get_group_name(const gid_t) PALUDIS_VISIBLE;
00393 }
00394 
00395 #endif
00396 

Generated on Mon Sep 21 10:36:08 2009 for paludis by  doxygen 1.5.4