153ca1f3190680f3e86aebe0f72f7918d63f71e0dCharles Davis//===- llvm/Support/Program.h ------------------------------------*- C++ -*-===//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
367d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer//                     The LLVM Compiler Infrastructure
467d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
867d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer//===----------------------------------------------------------------------===//
967d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer//
1067d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer// This file declares the llvm::sys::Program class.
1167d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer//
1267d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer//===----------------------------------------------------------------------===//
1367d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer
1467d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer#ifndef LLVM_SYSTEM_PROGRAM_H
1567d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer#define LLVM_SYSTEM_PROGRAM_H
1667d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer
171f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h"
1867d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer
1967d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencernamespace llvm {
20b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencerclass error_code;
2167d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencernamespace sys {
2267d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer
233140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov  // TODO: Add operations to communicate with the process, redirect its I/O,
243140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov  // etc.
253140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
2667d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer  /// This class provides an abstraction for programs that are executable by the
272565943289cf53ff1b8dd1dfa13b6068e4d31681Reid Spencer  /// operating system. It provides a platform generic way to find executable
28a077c9a0a2bd037bf119d80238f681afd2f9dfcfReid Spencer  /// programs from the path and to execute them in various ways. The sys::Path
29a077c9a0a2bd037bf119d80238f681afd2f9dfcfReid Spencer  /// class is used to specify the location of the Program.
3067d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer  /// @since 1.4
312565943289cf53ff1b8dd1dfa13b6068e4d31681Reid Spencer  /// @brief An abstraction for finding and executing programs.
322565943289cf53ff1b8dd1dfa13b6068e4d31681Reid Spencer  class Program {
3357d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    /// Opaque handle for target specific data.
3457d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    void *Data_;
353140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
3657d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    // Noncopyable.
3757d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    Program(const Program& other);
3857d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    Program& operator=(const Program& other);
394f51d99ca58f2dd14e44602652dcd3a0e126781aMikhail Glushenkov
402565943289cf53ff1b8dd1dfa13b6068e4d31681Reid Spencer    /// @name Methods
4167d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer    /// @{
423140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov  public:
433140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
4457d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    Program();
4557d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    ~Program();
46a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov
479dc87305db90a92a216041b928630b64878cf222Mikhail Glushenkov    /// Return process ID of this program.
4857d6903deae135ab39bf7d0e86ffae4029a938bdDaniel Dunbar    unsigned GetPid() const;
499dc87305db90a92a216041b928630b64878cf222Mikhail Glushenkov
503140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// This function executes the program using the \p arguments provided.  The
513140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// invoked program will inherit the stdin, stdout, and stderr file
523140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// descriptors, the environment and other configuration settings of the
533140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// invoking program. If Path::executable() does not return true when this
543140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// function is called then a std::string is thrown.
553140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @returns false in case of error, true otherwise.
563140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @see FindProgramByName
573140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @brief Executes the program with the given set of \p args.
583140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    bool Execute
593140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    ( const Path& path,  ///< sys::Path object providing the path of the
603140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< program to be executed. It is presumed this is the result of
613140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< the FindProgramByName method.
623140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      const char** args, ///< A vector of strings that are passed to the
633140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< program.  The first element should be the name of the program.
643140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< The list *must* be terminated by a null char* entry.
653140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      const char ** env = 0, ///< An optional vector of strings to use for
663140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< the program's environment. If not provided, the current program's
673140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< environment will be used.
683140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      const sys::Path** redirects = 0, ///< An optional array of pointers to
693140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< Paths. If the array is null, no redirection is done. The array
703140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< should have a size of at least three. If the pointer in the array
713140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< are not null, then the inferior process's stdin(0), stdout(1),
723140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< and stderr(2) will be redirected to the corresponding Paths.
733140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< When an empty Path is passed in, the corresponding file
743140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< descriptor will be disconnected (ie, /dev/null'd) in a portable
753140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< way.
763140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
773140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< of memory can be allocated by process. If memory usage will be
783140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< higher limit, the child is killed and this call returns. If zero
793140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< - no memory limit.
803140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
813140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< instance in which error messages will be returned. If the string
823140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< is non-empty upon return an error occurred while invoking the
833140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< program.
843140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      );
853140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
863140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// This function waits for the program to exit. This function will block
873140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// the current program until the invoked program exits.
883140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @returns an integer result code indicating the status of the program.
89dc5948d47205fd05184a25251e128db6a47b25c2Andrew Trick    /// A zero or positive value indicates the result code of the program.
90dc5948d47205fd05184a25251e128db6a47b25c2Andrew Trick    /// -1 indicates failure to execute
91dc5948d47205fd05184a25251e128db6a47b25c2Andrew Trick    /// -2 indicates a crash during execution or timeout
923140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @see Execute
933140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @brief Waits for the program to exit.
943140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    int Wait
95e5f77cda25169fcbadc32f0f0b3da2e00ba86b7cDan Gohman    ( const Path& path, ///< The path to the child process executable.
96e5f77cda25169fcbadc32f0f0b3da2e00ba86b7cDan Gohman      unsigned secondsToWait, ///< If non-zero, this specifies the amount
973140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< of time to wait for the child process to exit. If the time
983140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< expires, the child is killed and this call returns. If zero,
993140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< this function will wait until the child finishes or forever if
1003140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< it doesn't.
101dc5948d47205fd05184a25251e128db6a47b25c2Andrew Trick      std::string* ErrMsg ///< If non-zero, provides a pointer to a string
1023140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov      ///< instance in which error messages will be returned. If the string
103581af5f10a1a49979ff7bcc5f0fc48d5fc287b19Mikhail Glushenkov      ///< is non-empty upon return an error occurred while waiting.
104a077c9a0a2bd037bf119d80238f681afd2f9dfcfReid Spencer      );
1053140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
106a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov    /// This function terminates the program.
1077a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner    /// @returns true if an error occurred.
108a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov    /// @see Execute
109a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov    /// @brief Terminates the program.
110a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov    bool Kill
111a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov    ( std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
112a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov      ///< instance in which error messages will be returned. If the string
113581af5f10a1a49979ff7bcc5f0fc48d5fc287b19Mikhail Glushenkov      ///< is non-empty upon return an error occurred while killing the
114a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov      ///< program.
115a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov      );
116a607202a68085cee4d18894392be647d6cd4a53eMikhail Glushenkov
1173140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// This static constructor (factory) will attempt to locate a program in
1183140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// the operating system's file system using some pre-determined set of
1199cd59712289214225094b5b4108c2dbbf06a052cMikhail Glushenkov    /// locations to search (e.g. the PATH on Unix). Paths with slashes are
1209cd59712289214225094b5b4108c2dbbf06a052cMikhail Glushenkov    /// returned unmodified.
1213140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @returns A Path object initialized to the path of the program or a
1223140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// Path object that is empty (invalid) if the program could not be found.
1233140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @brief Construct a Program by finding it by name.
1243140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    static Path FindProgramByName(const std::string& name);
1253140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
126b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencer    // These methods change the specified standard stream (stdin, stdout, or
127b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencer    // stderr) to binary mode. They return errc::success if the specified stream
128b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencer    // was changed. Otherwise a platform dependent error is returned.
129b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencer    static error_code ChangeStdinToBinary();
130b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencer    static error_code ChangeStdoutToBinary();
131b92cb30cf547bf9a8590a981a49040f480c8eb82Michael J. Spencer    static error_code ChangeStderrToBinary();
1323140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
1333140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// A convenience function equivalent to Program prg; prg.Execute(..);
1343140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// prg.Wait(..);
1353140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @see Execute, Wait
1363140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    static int ExecuteAndWait(const Path& path,
1373140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              const char** args,
1383140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              const char ** env = 0,
1393140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              const sys::Path** redirects = 0,
1403140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              unsigned secondsToWait = 0,
1413140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              unsigned memoryLimit = 0,
142dc5948d47205fd05184a25251e128db6a47b25c2Andrew Trick                              std::string* ErrMsg = 0);
1433140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
1443140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// A convenience function equivalent to Program prg; prg.Execute(..);
1453140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    /// @see Execute
1463140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov    static void ExecuteNoWait(const Path& path,
1473140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              const char** args,
1483140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              const char ** env = 0,
1493140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              const sys::Path** redirects = 0,
1503140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              unsigned memoryLimit = 0,
1513140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov                              std::string* ErrMsg = 0);
1523140619c63d205d79b8eac1d88afa918981fa258Mikhail Glushenkov
153d2a8e656c504b0708e1343542d984e14b8eb948cReid Spencer    /// @}
15459629c1d8baeb7407b419cce3b59bea0bb4a2bd9David Greene
15567d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer  };
15667d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer}
15767d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer}
15867d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer
15967d556567f3fa759bfe5a38f56695c717743f4c4Reid Spencer#endif
160