diff libinterp/corefcn/oct-process.cc @ 27002:c04329ead503

new class for executing commands and getting result * oct-process.h, oct-process.cc: New files. * libinterp/corefcn/module.mk: Update.
author Andrew Janke <andrew@apjanke.net>
date Fri, 11 Jan 2019 21:24:26 -0500
parents
children 84ff9953faa1
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/oct-process.cc	Fri Jan 11 21:24:26 2019 -0500
@@ -0,0 +1,88 @@
+/*
+
+Copyright (C) 2019 Andrew Janke
+
+This file is part of Octave.
+
+Octave is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<https://www.gnu.org/licenses/>.
+
+*/
+
+#include <iostream>
+#include <sstream>
+
+#include "oct-process.h"
+#include "procstream.h"
+#include "sysdep.h"
+#include "oct-syscalls.h"
+
+namespace octave
+{
+  OCTINTERP_API
+  process_execution_result
+  process_execution_result::of_success (int exit_status,
+                                        const std::string& stdout_output)
+  {
+    return process_execution_result (0, exit_status, stdout_output, "");
+  }
+
+  OCTINTERP_API
+  process_execution_result
+  process_execution_result::of_error (int status, const std::string& err_msg)
+  {
+    return process_execution_result (status, -1, "", err_msg);
+  }
+
+  // Execute a shell command, returning results as a C++ object
+  OCTINTERP_API
+  process_execution_result
+  run_command_and_return_output (const std::string& cmd_str)
+  {
+    iprocstream cmd (cmd_str.c_str ());
+
+    if (! cmd)
+      {
+        std::string msg = "unable to start subprocess for '" + cmd_str + "'";
+
+        return process_execution_result::of_error (-1, msg);
+      }
+
+    std::ostringstream output_buf;
+
+    char ch;
+
+    for (;;)
+      {
+        if (cmd.get (ch))
+          output_buf.put (ch);
+        else
+          {
+            if (! cmd.eof () && errno == EAGAIN)
+              cmd.clear ();
+            else
+              break;
+          }
+      }
+
+    int cmd_status = cmd.close ();
+
+    if (octave::sys::wifexited (cmd_status))
+      cmd_status = octave::sys::wexitstatus (cmd_status);
+    else
+      cmd_status = 127;
+
+    return process_execution_result::of_success (cmd_status, output_buf.str ());
+  }
+}