aboutsummaryrefslogtreecommitdiff
path: root/bbot/agent.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bbot/agent.cxx')
-rw-r--r--bbot/agent.cxx102
1 files changed, 102 insertions, 0 deletions
diff --git a/bbot/agent.cxx b/bbot/agent.cxx
new file mode 100644
index 0000000..54940f4
--- /dev/null
+++ b/bbot/agent.cxx
@@ -0,0 +1,102 @@
+// file : bbot/agent.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef _WIN32
+# include <signal.h> // signal()
+#else
+# include <stdlib.h> // getenv(), _putenv()
+#endif
+
+#include <iostream>
+
+#include <butl/pager>
+
+#include <bbot/types>
+#include <bbot/utility>
+
+#include <bbot/diagnostics>
+#include <bbot/bbot-version>
+
+#include <bbot/agent-options>
+
+using namespace std;
+using namespace butl;
+using namespace bbot;
+
+int
+main (int argc, char* argv[])
+try
+{
+ // This is a little hack to make out baseutils for Windows work when called
+ // with absolute path. In a nutshell, MSYS2's exec*p() doesn't search in the
+ // parent's executable directory, only in PATH. And since we are running
+ // without a shell (that would read /etc/profile which sets PATH to some
+ // sensible values), we are only getting Win32 PATH values. And MSYS2 /bin
+ // is not one of them. So what we are going to do is add /bin at the end of
+ // PATH (which will be passed as is by the MSYS2 machinery). This will make
+ // MSYS2 search in /bin (where our baseutils live). And for everyone else
+ // this should be harmless since it is not a valid Win32 path.
+ //
+#ifdef _WIN32
+ {
+ string mp ("PATH=");
+ if (const char* p = getenv ("PATH"))
+ {
+ mp += p;
+ mp += ';';
+ }
+ mp += "/bin";
+
+ _putenv (mp.c_str ());
+ }
+#endif
+
+ // On POSIX ignore SIGPIPE which is signaled to a pipe-writing process if
+ // the pipe reading end is closed. Note that by default this signal
+ // terminates a process. Also note that there is no way to disable this
+ // behavior on a file descriptor basis or for the write() function call.
+ //
+#ifndef _WIN32
+ if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
+ fail << "unable to ignore broken pipe (SIGPIPE) signal: "
+ << system_error (errno, generic_category ()); // Sanitize.
+#endif
+
+ cli::argv_scanner scan (argc, argv, true);
+ agent_options ops (scan);
+
+ // Version.
+ //
+ if (ops.version ())
+ {
+ cout << "bbot-agent " << BBOT_VERSION_STR << endl
+ << "libbbot " << LIBBBOT_VERSION_STR << endl
+ << "libbutl " << LIBBUTL_VERSION_STR << endl
+ << "Copyright (c) 2014-2017 Code Synthesis Ltd" << endl
+ << "MIT; see accompanying LICENSE file" << endl;
+
+ return 0;
+ }
+
+ // Help.
+ //
+ if (ops.help ())
+ {
+ pager p ("bbot-agent help", false);
+ print_bbot_agent_usage (p.stream ());
+
+ // If the pager failed, assume it has issued some diagnostics.
+ //
+ return p.wait () ? 0 : 1;
+ }
+}
+catch (const failed&)
+{
+ return 1; // Diagnostics has already been issued.
+}
+catch (const cli::exception& e)
+{
+ error << e;
+ return 1;
+}