summaryrefslogtreecommitdiffstats
path: root/fastos
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2022-03-04 13:38:36 +0000
committerHåvard Pettersen <havardpe@oath.com>2022-03-05 15:00:58 +0000
commit2681bcd99a024d0e94c2cddd08b7636818773a73 (patch)
treefe8466205ba79ea6b7ab89008247070f88cd918f /fastos
parentbeed3becc8ec1abe88aea8aa88e6e703fb67dc3c (diff)
gc old process code
also added read_line function to new Process code
Diffstat (limited to 'fastos')
-rw-r--r--fastos/src/tests/CMakeLists.txt6
-rw-r--r--fastos/src/tests/filetest.cpp2
-rw-r--r--fastos/src/tests/processtest.cpp292
-rw-r--r--fastos/src/vespa/fastos/CMakeLists.txt3
-rw-r--r--fastos/src/vespa/fastos/app.cpp54
-rw-r--r--fastos/src/vespa/fastos/app.h17
-rw-r--r--fastos/src/vespa/fastos/process.cpp16
-rw-r--r--fastos/src/vespa/fastos/process.h180
-rw-r--r--fastos/src/vespa/fastos/unix_app.cpp53
-rw-r--r--fastos/src/vespa/fastos/unix_app.h12
-rw-r--r--fastos/src/vespa/fastos/unix_ipc.cpp547
-rw-r--r--fastos/src/vespa/fastos/unix_ipc.h41
-rw-r--r--fastos/src/vespa/fastos/unix_process.cpp985
-rw-r--r--fastos/src/vespa/fastos/unix_process.h172
14 files changed, 1 insertions, 2379 deletions
diff --git a/fastos/src/tests/CMakeLists.txt b/fastos/src/tests/CMakeLists.txt
index dce59650973..54341ff8e9a 100644
--- a/fastos/src/tests/CMakeLists.txt
+++ b/fastos/src/tests/CMakeLists.txt
@@ -1,10 +1,4 @@
# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-vespa_add_executable(fastos_processtest_app TEST
- SOURCES
- processtest.cpp
- DEPENDS
- fastos
-)
vespa_add_executable(fastos_filetest_app TEST
SOURCES
filetest.cpp
diff --git a/fastos/src/tests/filetest.cpp b/fastos/src/tests/filetest.cpp
index 80045269c9e..a3470810e2e 100644
--- a/fastos/src/tests/filetest.cpp
+++ b/fastos/src/tests/filetest.cpp
@@ -40,8 +40,6 @@ bool createFile(const char* fileName,
class FileTest : public BaseTest
{
-private:
- virtual bool useProcessStarter() const override { return true; }
public:
const std::string srcDir = getenv("SOURCE_DIRECTORY") ? getenv("SOURCE_DIRECTORY") : ".";
const std::string roFilename = srcDir + "/hello.txt";
diff --git a/fastos/src/tests/processtest.cpp b/fastos/src/tests/processtest.cpp
deleted file mode 100644
index 204b87938de..00000000000
--- a/fastos/src/tests/processtest.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "tests.h"
-#include <vespa/fastos/process.h>
-#include <thread>
-
-using namespace std::chrono_literals;
-using namespace std::chrono;
-
-class MyListener : public FastOS_ProcessRedirectListener
-{
-private:
- MyListener(const MyListener&);
- MyListener& operator=(const MyListener&);
-
- const char *_title;
- int _receivedBytes;
-
-public:
- static int _allocCount;
- static int _successCount;
- static int _failCount;
- static std::mutex *_counterLock;
-
- MyListener (const char *title)
- : _title(title),
- _receivedBytes(0)
- {
- std::lock_guard<std::mutex> guard(*_counterLock);
- _allocCount++;
- }
-
- virtual ~MyListener ()
- {
- bool isStdout = (strcmp(_title, "STDOUT") == 0);
-
- const int correctByteCount = 16;
-
- std::lock_guard<std::mutex> guard(*_counterLock);
- if(_receivedBytes == (isStdout ? correctByteCount : 0))
- _successCount++;
- else
- _failCount++;
-
- _allocCount--;
- }
-
- void OnReceiveData (const void *data, size_t length) override
- {
- _receivedBytes += length;
- if(data != nullptr)
- {
- }
- else
- delete(this);
- }
-};
-
-int MyListener::_allocCount = 0;
-int MyListener::_successCount = 0;
-int MyListener::_failCount = 0;
-std::mutex *MyListener::_counterLock = nullptr;
-
-class ProcessTest : public BaseTest
-{
-private:
- bool useProcessStarter() const override { return true; }
- bool useIPCHelper() const override { return true; }
- ProcessTest(const ProcessTest&);
- ProcessTest& operator=(const ProcessTest&);
- int GetLastError () const { return errno; }
-
- // Flag which indicates whether an IPC message is received
- // or not.
- bool _gotMessage;
- int _receivedMessages;
- std::mutex *_counterLock;
- bool _isChild;
-public:
- ProcessTest ()
- : _gotMessage(false),
- _receivedMessages(0),
- _counterLock(nullptr),
- _isChild(true)
- {
- }
-
- void PollWaitTest ()
- {
- TestHeader("PollWait Test");
-
- FastOS_Process *xproc = new FastOS_Process("sort");
-
- if(xproc->Create())
- {
- int i;
- for(i=0; i<10; i++)
- {
- bool stillRunning;
- int returnCode;
-
- if(!xproc->PollWait(&returnCode, &stillRunning))
- {
- Progress(false, "PollWait failure: %d",
- GetLastError());
- break;
- }
-
- if(i <= 5)
- Progress(stillRunning, "StillRunning = %s",
- stillRunning ? "true" : "false");
-
- if(!stillRunning)
- {
- Progress(returnCode == 0, "Process exit code: %d",
- returnCode);
- break;
- }
-
- if(i == 5)
- {
- // Make sort quit
- xproc->WriteStdin(nullptr, 0);
- }
-
- std::this_thread::sleep_for(1s);
- }
-
- if(i == 10)
- {
- Progress(false, "Timeout");
- xproc->Kill();
- }
- }
- delete xproc;
-
- PrintSeparator();
- }
-
- void ProcessTests (bool doKill, bool stdinPre, bool waitKill)
- {
- const int numLoops = 100;
- const int numEachTime = 40;
-
- MyListener::_counterLock = new std::mutex;
-
- char testHeader[200];
- strcpy(testHeader, "Process Test");
- if(doKill)
- strcat(testHeader, " w/Kill");
- if(!stdinPre)
- strcat(testHeader, " w/open stdin");
- if(waitKill)
- strcat(testHeader, " w/Wait timeout");
-
- TestHeader(testHeader);
-
- MyListener::_allocCount = 0;
- MyListener::_successCount = 0;
- MyListener::_failCount = 0;
-
- Progress(true, "Starting processes...");
-
- for(int i=0; i<numLoops; i++)
- {
- FastOS_ProcessInterface *procs[numEachTime];
-
- int j;
- for(j=0; j<numEachTime; j++)
- {
- FastOS_ProcessInterface *xproc =
- new FastOS_Process("sort",
- new MyListener("STDOUT"),
- new MyListener("STDERR"));
-
- if(xproc->Create())
- {
- const char *str = "Peter\nPaul\nMary\n";
-
- if(!waitKill && stdinPre)
- {
- xproc->WriteStdin(str, strlen(str));
- xproc->WriteStdin(nullptr, 0);
- }
-
- if(doKill)
- {
- if(!xproc->Kill())
- Progress(false, "Kill failure %d", GetLastError());
- }
-
- if(!waitKill && !stdinPre)
- {
- xproc->WriteStdin(str, strlen(str));
- xproc->WriteStdin(nullptr, 0);
- }
- }
- else
- {
- Progress(false, "Process.CreateWithShell failure %d",
- GetLastError());
- delete xproc;
- xproc = nullptr;
- }
- procs[j] = xproc;
- }
-
- for(j=0; j<numEachTime; j++)
- {
- FastOS_ProcessInterface *xproc = procs[j];
- if(xproc == nullptr)
- continue;
-
- int timeOut = -1;
- if(waitKill)
- timeOut = 1;
-
- steady_clock::time_point start = steady_clock::now();
-
- int returnCode;
- if(!xproc->Wait(&returnCode, timeOut))
- Progress(false, "Process.Wait failure %d", GetLastError());
- else
- {
- int checkReturnCode = 0;
- if(doKill || waitKill)
- checkReturnCode = FastOS_Process::KILL_EXITCODE;
- if(returnCode != checkReturnCode)
- Progress(false, "returnCode = %d", returnCode);
- }
-
- if (waitKill) {
- nanoseconds elapsed = steady_clock::now() - start;
- if((elapsed < 900ms) ||
- (elapsed > 3500ms))
- {
- Progress(false, "WaitKill time = %d", duration_cast<milliseconds>(elapsed).count());
- }
- }
-
- delete xproc;
-
- if(waitKill)
- Progress(true, "Started %d processes", i * numEachTime + j + 1);
- }
-
- if(!waitKill && ((i % 10) == 9))
- Progress(true, "Started %d processes", (i+1) * numEachTime);
-
- if(waitKill && (((i+1) * numEachTime) > 50))
- break;
- }
-
- Progress(MyListener::_allocCount == 0, "MyListener alloc count = %d", MyListener::_allocCount);
-
- if (!doKill && !waitKill) {
- Progress(MyListener::_successCount == (2 * numLoops * numEachTime),
- "MyListener _successCount = %d", MyListener::_successCount);
-
- Progress(MyListener::_failCount == 0,
- "MyListener _failCount = %d", MyListener::_failCount);
- }
-
- delete MyListener::_counterLock;
- MyListener::_counterLock = nullptr;
-
- PrintSeparator();
- }
-
- int Main () override
- {
- _isChild = false;
-
- printf("grep for the string '%s' to detect failures.\n\n", failString);
-
- PollWaitTest();
- ProcessTests(false, true, false);
- ProcessTests(true, true, false);
- ProcessTests(true, false, false);
- ProcessTests(false, true, true);
-
- printf("END OF TEST (%s)\n", _argv[0]);
-
- return allWasOk() ? 0 : 1;
- }
-};
-
-int main (int argc, char **argv)
-{
- ProcessTest app;
- setvbuf(stdout, nullptr, _IOLBF, 8192);
- return app.Entry(argc, argv);
-}
diff --git a/fastos/src/vespa/fastos/CMakeLists.txt b/fastos/src/vespa/fastos/CMakeLists.txt
index 466c4f775a4..623d931e999 100644
--- a/fastos/src/vespa/fastos/CMakeLists.txt
+++ b/fastos/src/vespa/fastos/CMakeLists.txt
@@ -6,13 +6,10 @@ vespa_add_library(fastos_objects OBJECT
file.cpp
file_rw_ops.cpp
linux_file.cpp
- process.cpp
thread.cpp
unix_app.cpp
unix_dynamiclibrary.cpp
unix_file.cpp
- unix_ipc.cpp
- unix_process.cpp
unix_thread.cpp
)
diff --git a/fastos/src/vespa/fastos/app.cpp b/fastos/src/vespa/fastos/app.cpp
index 0482cfea616..94e467d341d 100644
--- a/fastos/src/vespa/fastos/app.cpp
+++ b/fastos/src/vespa/fastos/app.cpp
@@ -8,13 +8,10 @@
#include "app.h"
#include "file.h"
-#include "process.h"
#include "thread.h"
#include <cstring>
#include <fcntl.h>
-FastOS_ApplicationInterface *FastOS_ProcessInterface::_app = nullptr;
-
FastOS_ThreadPool *FastOS_ApplicationInterface::GetThreadPool ()
{
return _threadPool;
@@ -22,12 +19,9 @@ FastOS_ThreadPool *FastOS_ApplicationInterface::GetThreadPool ()
FastOS_ApplicationInterface::FastOS_ApplicationInterface() :
_threadPool(nullptr),
- _processList(nullptr),
- _processListMutex(nullptr),
_argc(0),
_argv(nullptr)
{
- FastOS_ProcessInterface::_app = this;
#ifdef __linux__
char * fadvise = getenv("VESPA_FADVISE_OPTIONS");
if (fadvise != nullptr) {
@@ -51,7 +45,6 @@ bool FastOS_ApplicationInterface::Init ()
if (PreThreadInit()) {
if (FastOS_Thread::InitializeClass()) {
if (FastOS_File::InitializeClass()) {
- _processListMutex = new std::mutex;
_threadPool = new FastOS_ThreadPool(128 * 1024);
rc = true;
} else
@@ -72,12 +65,6 @@ void FastOS_ApplicationInterface::Cleanup ()
delete _threadPool;
_threadPool = nullptr;
}
-
- if(_processListMutex != nullptr) {
- delete _processListMutex;
- _processListMutex = nullptr;
- }
-
FastOS_File::CleanupClass();
FastOS_Thread::CleanupClass();
}
@@ -97,44 +84,3 @@ int FastOS_ApplicationInterface::Entry (int argc, char **argv)
return rc;
}
-
-void
-FastOS_ApplicationInterface::AddChildProcess (FastOS_ProcessInterface *node)
-{
- node->_prev = nullptr;
- node->_next = _processList;
-
- if(_processList != nullptr)
- _processList->_prev = node;
-
- _processList = node;
-}
-
-void
-FastOS_ApplicationInterface::RemoveChildProcess (FastOS_ProcessInterface *node)
-{
- if(node->_prev)
- node->_prev->_next = node->_next;
- else
- _processList = node->_next;
-
- if(node->_next)
- {
- node->_next->_prev = node->_prev;
- node->_next = nullptr;
- }
-
- if(node->_prev != nullptr)
- node->_prev = nullptr;
-}
-
-bool
-FastOS_ApplicationInterface::useProcessStarter() const
-{
- return false;
-}
-bool
-FastOS_ApplicationInterface::useIPCHelper() const
-{
- return useProcessStarter();
-}
diff --git a/fastos/src/vespa/fastos/app.h b/fastos/src/vespa/fastos/app.h
index 8d6a0b5ecbb..6aa7a9346ed 100644
--- a/fastos/src/vespa/fastos/app.h
+++ b/fastos/src/vespa/fastos/app.h
@@ -12,7 +12,6 @@
#include <vespa/fastos/types.h>
-class FastOS_ProcessInterface;
class FastOS_ThreadPool;
#include <mutex>
@@ -132,18 +131,7 @@ private:
FastOS_ApplicationInterface& operator=(const FastOS_ApplicationInterface&);
protected:
- /**
- *
- * Indicate if a process starter is going to be used.
- * Only override this one if you are going to start other processes.
- * @return true if you are going to use a process starter.
- */
- virtual bool useProcessStarter() const;
- virtual bool useIPCHelper() const;
-
FastOS_ThreadPool *_threadPool;
- FastOS_ProcessInterface *_processList;
- std::mutex *_processListMutex;
virtual bool PreThreadInit () { return true; }
@@ -195,11 +183,6 @@ public:
*/
virtual void Cleanup ();
- void AddChildProcess (FastOS_ProcessInterface *node);
- void RemoveChildProcess (FastOS_ProcessInterface *node);
- std::unique_lock<std::mutex> getProcessGuard() { return std::unique_lock<std::mutex>(*_processListMutex); }
- FastOS_ProcessInterface *GetProcessList () { return _processList; }
-
FastOS_ThreadPool *GetThreadPool ();
};
diff --git a/fastos/src/vespa/fastos/process.cpp b/fastos/src/vespa/fastos/process.cpp
deleted file mode 100644
index 8e4f4afdc98..00000000000
--- a/fastos/src/vespa/fastos/process.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-
-#include "process.h"
-
-FastOS_ProcessInterface::FastOS_ProcessInterface (const char *cmdLine,
- FastOS_ProcessRedirectListener *stdoutListener,
- FastOS_ProcessRedirectListener *stderrListener) :
- _cmdLine(cmdLine),
- _stdoutListener(stdoutListener),
- _stderrListener(stderrListener),
- _next(nullptr),
- _prev(nullptr)
-{
-}
-
-FastOS_ProcessInterface::~FastOS_ProcessInterface () = default;
diff --git a/fastos/src/vespa/fastos/process.h b/fastos/src/vespa/fastos/process.h
deleted file mode 100644
index f520fcd30f8..00000000000
--- a/fastos/src/vespa/fastos/process.h
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-//************************************************************************
-/**
- * @file
- * Class definitions for FastOS_ProcessInterface and
- * FastOS_ProcessRedirectListener.
- *
- * @author Oivind H. Danielsen
- */
-
-#pragma once
-
-#include "types.h"
-#include <cstddef>
-#include <string>
-
-/**
- * This class serves as a sink for redirected (piped) output from
- * subclasses of @ref FastOS_ProcessInterface.
- */
-class FastOS_ProcessRedirectListener
-{
-public:
- /**
- * This method is called when new data is available from the
- * process. Subclass this method to process the data.
- * You should assume that any thread can invoke this method.
- * For convenience the data buffer is always zero- terminated
- * (static_cast<uint8_t>(data[length]) = '\\0').
- * When the pipe closes, the method is invoked with data = nullptr
- * and length = 0.
- * @param data Pointer to data
- * @param length Length of data block in bytes
- */
- virtual void OnReceiveData (const void *data, size_t length) = 0;
-
- virtual ~FastOS_ProcessRedirectListener () {}
-};
-
-class FastOS_ThreadPool;
-class FastOS_ApplicationInterface;
-
-/**
- * This class can start a process, redirect standard input, output
- * and error streams, kill process, wait for process to exit
- * and send IPC messages to the process.
- */
-class FastOS_ProcessInterface
-{
-protected:
-
- std::string _cmdLine;
- FastOS_ProcessRedirectListener *_stdoutListener;
- FastOS_ProcessRedirectListener *_stderrListener;
-
-public:
- FastOS_ProcessInterface *_next, *_prev;
- static FastOS_ApplicationInterface *_app;
-
- enum Constants
- {
- KILL_EXITCODE = 65535, /* Process killed or failed */
- CONSTEND
- };
-
- /**
- * Constructor. Does not start the process, use @ref Create or
- * @ref CreateWithShell to actually start the process.
- * @param cmdLine Command line
- * @param stdoutListener non-nullptr to redirect stdout
- * @param stderrListener non-nullptr to redirect stderr
- * @param bufferSize Size of redirect buffers
- */
- FastOS_ProcessInterface (const char *cmdLine,
- FastOS_ProcessRedirectListener *stdoutListener = nullptr,
- FastOS_ProcessRedirectListener *stderrListener = nullptr);
-
- FastOS_ProcessInterface(const FastOS_ProcessInterface&) = delete;
- FastOS_ProcessInterface &operator=(const FastOS_ProcessInterface &) = delete;
- /**
- * Destructor.
- * If @ref Wait has not been called yet, it is called here.
- */
- virtual ~FastOS_ProcessInterface ();
-
- /**
- * Create and start the process. If your command line includes
- * commands specific to the shell use @ref CreateWithShell instead.
- *
- * IPC communication currently only supports direct parent/child
- * relationships. If you launch a FastOS application through
- * the shell or some other script/process, the FastOS application
- * might not be a direct child of your process and IPC communication
- * will not work (the rest will work ok, though).
- *
- * This limitation might be removed in the future.
- * @return Boolean success / failure
- */
- virtual bool Create() = 0;
-
- /**
- * Create and start the process using the default OS shell
- * (UNIX: /bin/sh).
- *
- * IPC communication currently only supports direct parent/child
- * relationships. If you launch a FastOS application through
- * the shell or some other script/process, the FastOS application
- * might not be a direct child of your process and IPC communication
- * will not work (the rest will work ok, though).
- *
- * This limitation might be removed in the future.
- * @return Boolean success / failure
- */
- virtual bool CreateWithShell() = 0;
-
- /**
- * If you are redirecting the standard input stream of the process,
- * use this method to write data. To close the input stream,
- * invoke @ref WriteStdin with data=nullptr. If the input stream
- * is not redirected, @ref WriteStdin will fail.
- * @param data Pointer to data
- * @param length Length of data block in bytes
- * @return Boolean success / failure
- */
- virtual bool WriteStdin (const void *data, size_t length) = 0;
-
- /**
- * Terminate the process. !!IMPORTANT LIMITATION!!: There is no guarantee
- * that child processes (of the process to be killed) will be killed
- * as well.
- * @return Boolean success / failure
- */
- virtual bool Kill () = 0;
-
- /**
- * Wait for the process to finish / terminate. This is called
- * automatically by the destructor, but it is recommended that
- * it is called as early as possible to free up resources.
- * @param returnCode Pointer to int which will receive
- * the process return code.
- * @param timeOutSeconds Number of seconds to wait before
- * the process is violently killed.
- * -1 = infinite wait / no timeout
- * @return Boolean success / failure
- */
- virtual bool Wait (int *returnCode, int timeOutSeconds = -1) = 0;
-
- /**
- * Poll version of @ref Wait.
- * This is basically @ref Wait with a timeout of 0 seconds.
- * The process is not killed if the "timeout" expires.
- * A boolean value, stillRunning, is set to indicate whether
- * the process is still running or not.
- * There is no need to invoke @ref Wait if @ref PollWait
- * indicates that the process is finished.
- * @param returnCode Pointer to int which will receive
- * the process return code.
- * @param stillRunning Pointer to boolean value which will
- * be set to indicate whether the
- * process is still running or not.
- * @return Boolean success / failure
- */
- virtual bool PollWait (int *returnCode, bool *stillRunning) = 0;
-
- /**
- * Get process identification number.
- * @return Process id
- */
- virtual unsigned int GetProcessId() = 0;
-
- /**
- * Get command line string.
- * @return Command line string
- */
- const char *GetCommandLine () const { return _cmdLine.c_str(); }
-};
-
-#include <vespa/fastos/unix_process.h>
-typedef FastOS_UNIX_Process FASTOS_PREFIX(Process);
-
diff --git a/fastos/src/vespa/fastos/unix_app.cpp b/fastos/src/vespa/fastos/unix_app.cpp
index b0baf3990ad..e94525fff22 100644
--- a/fastos/src/vespa/fastos/unix_app.cpp
+++ b/fastos/src/vespa/fastos/unix_app.cpp
@@ -9,19 +9,12 @@
#include "app.h"
#include "time.h"
-#include "process.h"
-#include "unix_ipc.h"
#include <unistd.h>
#include <csignal>
#include <getopt.h>
-FastOS_UNIX_Application::FastOS_UNIX_Application ()
- : _processStarter(),
- _ipcHelper(nullptr)
-{
-}
-
+FastOS_UNIX_Application::FastOS_UNIX_Application() = default;
FastOS_UNIX_Application::~FastOS_UNIX_Application() = default;
extern "C"
@@ -72,10 +65,6 @@ bool FastOS_UNIX_Application::PreThreadInit ()
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGPIPE, &act, nullptr);
-
- if (useProcessStarter()) {
- _processStarter = std::make_unique<FastOS_UNIX_ProcessStarter>(this);
- }
} else {
rc = false;
fprintf(stderr, "FastOS_ApplicationInterface::PreThreadInit failed\n");
@@ -89,13 +78,6 @@ bool FastOS_UNIX_Application::Init ()
if(FastOS_ApplicationInterface::Init())
{
- int ipcDescriptor = -1;
-
- if (useIPCHelper()) {
- _ipcHelper = new FastOS_UNIX_IPCHelper(this, ipcDescriptor);
- GetThreadPool()->NewThread(_ipcHelper);
- }
-
rc = true;
}
@@ -104,38 +86,5 @@ bool FastOS_UNIX_Application::Init ()
void FastOS_UNIX_Application::Cleanup ()
{
- if(_ipcHelper != nullptr)
- _ipcHelper->Exit();
-
- if (_processStarter) {
- {
- std::unique_lock<std::mutex> guard;
- if (_processListMutex) {
- guard = getProcessGuard();
- }
- }
- _processStarter.reset();
- }
-
FastOS_ApplicationInterface::Cleanup();
}
-
-FastOS_UNIX_ProcessStarter *
-FastOS_UNIX_Application::GetProcessStarter ()
-{
- return _processStarter.get();
-}
-
-void FastOS_UNIX_Application::
-AddToIPCComm (FastOS_UNIX_Process *process)
-{
- if(_ipcHelper != nullptr)
- _ipcHelper->AddProcess(process);
-}
-
-void FastOS_UNIX_Application::
-RemoveFromIPCComm (FastOS_UNIX_Process *process)
-{
- if(_ipcHelper != nullptr)
- _ipcHelper->RemoveProcess(process);
-}
diff --git a/fastos/src/vespa/fastos/unix_app.h b/fastos/src/vespa/fastos/unix_app.h
index 5bb6f14ad26..5e076f4482b 100644
--- a/fastos/src/vespa/fastos/unix_app.h
+++ b/fastos/src/vespa/fastos/unix_app.h
@@ -13,10 +13,6 @@
#include "app.h"
#include <memory>
-class FastOS_UNIX_ProcessStarter;
-class FastOS_UNIX_IPCHelper;
-class FastOS_UNIX_Process;
-
/**
* This is the generic UNIX implementation of @ref FastOS_ApplicationInterface
*/
@@ -26,9 +22,6 @@ private:
FastOS_UNIX_Application(const FastOS_UNIX_Application&);
FastOS_UNIX_Application& operator=(const FastOS_UNIX_Application&);
- std::unique_ptr<FastOS_UNIX_ProcessStarter> _processStarter;
- FastOS_UNIX_IPCHelper *_ipcHelper;
-
protected:
bool PreThreadInit () override;
public:
@@ -71,11 +64,6 @@ public:
*/
static void resetOptIndex(int OptionIndex);
- FastOS_UNIX_ProcessStarter *GetProcessStarter ();
bool Init () override;
void Cleanup () override;
- void AddToIPCComm (FastOS_UNIX_Process *process);
- void RemoveFromIPCComm (FastOS_UNIX_Process *process);
};
-
-
diff --git a/fastos/src/vespa/fastos/unix_ipc.cpp b/fastos/src/vespa/fastos/unix_ipc.cpp
deleted file mode 100644
index b75d07751fa..00000000000
--- a/fastos/src/vespa/fastos/unix_ipc.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "unix_ipc.h"
-#include "ringbuffer.h"
-#include <cassert>
-#include <cstring>
-#include <cstdlib>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory>
-#include <future>
-
-FastOS_UNIX_IPCHelper::
-FastOS_UNIX_IPCHelper (FastOS_ApplicationInterface *app, int)
- : _lock(),
- _exitFlag(false),
- _app(app)
-{
- _wakeupPipe[0] = -1;
- _wakeupPipe[1] = -1;
-
- if(pipe(_wakeupPipe) != 0) {
- perror("pipe wakeuppipe");
- std::_Exit(1);
- } else {
- SetBlocking(_wakeupPipe[0], false);
- SetBlocking(_wakeupPipe[1], true);
- }
-}
-
-FastOS_UNIX_IPCHelper::~FastOS_UNIX_IPCHelper ()
-{
- if(_wakeupPipe[0] != -1) {
- close(_wakeupPipe[0]);
- }
- if(_wakeupPipe[1] != -1) {
- close(_wakeupPipe[1]);
- }
-}
-
-
-bool FastOS_UNIX_IPCHelper::
-DoWrite(FastOS_UNIX_Process::DescriptorHandle &desc)
-{
- bool rc = true;
- FastOS_RingBuffer *buffer = desc._writeBuffer.get();
-
- auto bufferGuard = buffer->getGuard();
- int writeBytes = buffer->GetReadSpace();
- if(writeBytes > 0)
- {
- int bytesWritten;
- do
- {
- bytesWritten = write(desc._fd,
- buffer->GetReadPtr(),
- writeBytes);
- } while(bytesWritten < 0 && errno == EINTR);
-
- if(bytesWritten > 0)
- buffer->Consume(bytesWritten);
- else if(bytesWritten < 0)
- {
- desc.CloseHandle();
- perror("FastOS_UNIX_IPCHelper::DoWrite");
- rc = false;
- }
- else if(bytesWritten == 0)
- desc.CloseHandle();
- }
- return rc;
-}
-
-bool FastOS_UNIX_IPCHelper::
-DoRead (FastOS_UNIX_Process::DescriptorHandle &desc)
-{
- bool rc = true;
-
- FastOS_RingBuffer *buffer = desc._readBuffer.get();
-
- auto bufferGuard = buffer->getGuard();
- int readBytes = buffer->GetWriteSpace();
- if(readBytes > 0) {
- int bytesRead;
- do {
- bytesRead = read(desc._fd, buffer->GetWritePtr(), readBytes);
- } while(bytesRead < 0 && errno == EINTR);
-
- if (bytesRead > 0) {
- buffer->Produce(bytesRead);
- } else if(bytesRead < 0) {
- desc.CloseHandle();
- perror("FastOS_UNIX_IPCHelper::DoRead");
- rc = false;
- } else if(bytesRead == 0) {
- desc.CloseHandle();
- }
- }
-
- return rc;
-}
-
-bool FastOS_UNIX_IPCHelper::
-SetBlocking (int fileDescriptor, bool doBlock)
-{
- bool rc=false;
-
- int flags = fcntl(fileDescriptor, F_GETFL, nullptr);
- if (flags != -1)
- {
- if(doBlock)
- flags &= ~O_NONBLOCK;
- else
- flags |= O_NONBLOCK;
- rc = (fcntl(fileDescriptor, F_SETFL, flags) != -1);
- }
- return rc;
-}
-
-void FastOS_UNIX_IPCHelper::
-BuildPollCheck(bool isRead, int filedes,
- FastOS_RingBuffer *buffer, bool *check)
-{
- if(buffer == nullptr ||
- filedes < 0 ||
- buffer->GetCloseFlag()) {
- *check = false;
- return;
- }
-
- bool setIt = false;
- if(isRead)
- setIt = (buffer->GetWriteSpace() > 0);
- else
- setIt = (buffer->GetReadSpace() > 0);
- *check = setIt;
-}
-
-
-void FastOS_UNIX_IPCHelper::
-PerformAsyncIO()
-{
- FastOS_ProcessInterface *node;
- for(node = _app->GetProcessList(); node != nullptr; node = node->_next)
- {
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
-
- for(int type=0; type < int(FastOS_UNIX_Process::TYPE_READCOUNT); type++)
- {
- FastOS_UNIX_Process::DescriptorType type_ =
- FastOS_UNIX_Process::DescriptorType(type);
- FastOS_UNIX_Process::DescriptorHandle &desc =
- xproc->GetDescriptorHandle(type_);
- if (desc._canRead)
- (void) DoRead(desc);
- if (desc._canWrite)
- (void) DoWrite(desc);
- }
- }
-}
-
-
-void FastOS_UNIX_IPCHelper::
-BuildPollChecks()
-{
- FastOS_ProcessInterface *node;
- for(node = _app->GetProcessList(); node != nullptr; node = node->_next)
- {
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
-
- for(int type=0; type < int(FastOS_UNIX_Process::TYPE_READCOUNT); type++)
- {
- FastOS_UNIX_Process::DescriptorType type_ =
- FastOS_UNIX_Process::DescriptorType(type);
- FastOS_UNIX_Process::DescriptorHandle &desc =
- xproc->GetDescriptorHandle(type_);
- BuildPollCheck(false, desc._fd, desc._writeBuffer.get(), &desc._wantWrite);
- BuildPollCheck(true, desc._fd, desc._readBuffer.get(), &desc._wantRead);
- }
- }
-}
-
-
-static pollfd *
-__attribute__((__noinline__))
-ResizePollArray(pollfd **fds, unsigned int *allocnfds)
-{
- pollfd *newfds;
- unsigned int newallocnfds;
-
- if (*allocnfds == 0)
- newallocnfds = 16;
- else
- newallocnfds = *allocnfds * 2;
- newfds = static_cast<pollfd *>(malloc(newallocnfds * sizeof(pollfd)));
- assert(newfds != nullptr);
-
- if (*allocnfds > 0)
- memcpy(newfds, *fds, sizeof(pollfd) * *allocnfds);
-
- if (*fds != nullptr)
- free(*fds);
-
- *fds = newfds;
- newfds += *allocnfds;
- *allocnfds = newallocnfds;
- return newfds;
-}
-
-void
-FastOS_UNIX_IPCHelper::
-BuildPollArray(pollfd **fds, unsigned int *nfds, unsigned int *allocnfds)
-{
- FastOS_ProcessInterface *node;
- pollfd *rfds;
- const pollfd *rfdsEnd;
- int pollIdx;
-
- rfds = *fds;
- rfdsEnd = *fds + *allocnfds;
-
- if (rfds >= rfdsEnd) {
- rfds = ResizePollArray(fds,
- allocnfds);
- rfdsEnd = *fds + *allocnfds;
- }
- rfds->fd = _wakeupPipe[0];
- rfds->events = POLLIN;
- rfds->revents = 0;
- rfds++;
- pollIdx = 1;
- for(node = _app->GetProcessList(); node != nullptr; node = node->_next)
- {
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
-
- for(int type=0; type < int(FastOS_UNIX_Process::TYPE_READCOUNT); type++)
- {
- FastOS_UNIX_Process::DescriptorType type_ =
- FastOS_UNIX_Process::DescriptorType(type);
- FastOS_UNIX_Process::DescriptorHandle &desc =
- xproc->GetDescriptorHandle(type_);
-
- if (desc._fd >= 0 &&
- (desc._wantRead || desc._wantWrite)) {
- if (rfds >= rfdsEnd) {
- rfds = ResizePollArray(fds,
- allocnfds);
- rfdsEnd = *fds + *allocnfds;
- }
- rfds->fd = desc._fd;
- rfds->events = 0;
- if (desc._wantRead)
- rfds->events |= POLLRDNORM;
- if (desc._wantWrite)
- rfds->events |= POLLWRNORM;
- rfds->revents = 0;
- desc._pollIdx = pollIdx;
- rfds++;
- pollIdx++;
- } else {
- desc._pollIdx = -1;
- desc._canRead = false;
- desc._canWrite = false;
- }
- }
- }
-
- *nfds = rfds - *fds;
-}
-
-
-bool
-FastOS_UNIX_IPCHelper::
-SavePollArray(pollfd *fds, unsigned int nfds)
-{
- FastOS_ProcessInterface *node;
-
- for(node = _app->GetProcessList(); node != nullptr; node = node->_next)
- {
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
-
- for(int type=0; type < int(FastOS_UNIX_Process::TYPE_READCOUNT); type++)
- {
- FastOS_UNIX_Process::DescriptorType type_ =
- FastOS_UNIX_Process::DescriptorType(type);
- FastOS_UNIX_Process::DescriptorHandle &desc =
- xproc->GetDescriptorHandle(type_);
-
- if (desc._fd >= 0 &&
- static_cast<unsigned int>(desc._pollIdx) < nfds) {
- int revents = fds[desc._pollIdx].revents;
-
- if (desc._wantRead &&
- (revents &
- (POLLIN | POLLRDNORM | POLLERR | POLLHUP | POLLNVAL)) != 0)
- desc._canRead = true;
- else
- desc._canRead = false;
- if (desc._wantWrite &&
- (revents &
- (POLLOUT | POLLWRNORM | POLLWRBAND | POLLERR | POLLHUP |
- POLLNVAL)) != 0)
- desc._canWrite = true;
- else
- desc._canWrite = false;
- }
- }
- }
-
- if ((fds[0].revents & (POLLIN | POLLERR | POLLHUP)) != 0)
- return true;
- else
- return false;
-}
-
-
-void FastOS_UNIX_IPCHelper::
-RemoveClosingProcesses()
-{
- // We assume that not updating maxFD isn't harmless.
-
- FastOS_ProcessInterface *node, *next;
-
- for(node = _app->GetProcessList(); node != nullptr; node = next)
- {
- int type;
-
- next = node->_next;
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
-
- bool stillBusy = false;
- if(!xproc->GetKillFlag())
- for(type=0; type < FastOS_UNIX_Process::TYPE_READCOUNT; type++)
- {
- FastOS_UNIX_Process::DescriptorType type_;
-
- type_ = static_cast<FastOS_UNIX_Process::DescriptorType>(type);
-
- FastOS_UNIX_Process::DescriptorHandle &desc =
- xproc->GetDescriptorHandle(type_);
-
- if (desc._fd != -1)
- {
- if((type_ == FastOS_UNIX_Process::TYPE_STDOUT) ||
- (type_ == FastOS_UNIX_Process::TYPE_STDERR) ||
- desc._wantWrite)
- {
- // We still want to use this socket.
- // Make sure we don't close the socket yet.
- stillBusy = true;
- break;
- }
- }
- }
-
- if(!stillBusy)
- {
- if (xproc->_closing) {
- // We already have the process lock at this point,
- // so modifying the list is safe.
- _app->RemoveChildProcess(node);
-
- for(type=0; type < FastOS_UNIX_Process::TYPE_READCOUNT; type++)
- {
- FastOS_UNIX_Process::DescriptorHandle &desc =
- xproc->GetDescriptorHandle(FastOS_UNIX_Process::DescriptorType(type));
- if(desc._fd != -1)
- {
- // No more select on this one.
- // We already know wantWrite is not set
- if (desc._wantRead)
- desc._wantRead = false;
- }
- }
-
- // The process destructor can now proceed
- auto closingPromise(std::move(xproc->_closing));
- closingPromise->set_value();
- }
- }
- }
-}
-
-
-void FastOS_UNIX_IPCHelper::
-Run(FastOS_ThreadInterface *thisThread, void *arg)
-{
- (void)arg;
- (void)thisThread;
-
- FastOS_ProcessInterface *node;
- pollfd *fds;
- unsigned int nfds;
- unsigned int allocnfds;
-
- fds = nullptr;
- nfds = 0;
- allocnfds = 0;
- for(;;)
- {
- // Deliver messages to from child processes and parent.
- {
- auto guard = _app->getProcessGuard();
- for(node = _app->GetProcessList(); node != nullptr; node = node->_next)
- {
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
- PipeData(xproc, FastOS_UNIX_Process::TYPE_STDOUT);
- PipeData(xproc, FastOS_UNIX_Process::TYPE_STDERR);
- }
-
- // Setup file descriptor sets for the next select() call
- BuildPollChecks();
-
- // Close and signal closing processes
- RemoveClosingProcesses();
-
- BuildPollArray(&fds, &nfds, &allocnfds);
- }
- bool exitFlag = false;
- {
- std::lock_guard<std::mutex> guard(_lock);
- exitFlag = _exitFlag;
- }
- if (exitFlag)
- {
- break;
- }
-
- for (;;)
- {
- int pollRc =
- poll(fds, nfds, -1);
-
- if(pollRc == -1)
- {
- int wasErrno = errno;
-
- if(wasErrno == EINTR)
- {
- continue;
- }
-
- perror("FastOS_UNIX_IPCHelper::RunAsync select failure");
- printf("errno = %d\n", wasErrno);
- for(unsigned int i = 0; i < nfds; i++)
- {
- if ((fds[i].events & POLLIN) != 0)
- printf("Read %d\n", fds[i].fd);
- if ((fds[i].events & POLLOUT) != 0)
- printf("Write %d\n", fds[i].fd);
- }
- std::_Exit(1);
- } else {
- break;
- }
- }
-
- bool woken = false;
- {
- auto guard = _app->getProcessGuard();
- woken = SavePollArray(fds, nfds);
- // Do actual IO (based on file descriptor sets and buffer contents)
- PerformAsyncIO();
- }
-
- // Did someone want to wake us up from the poll() call?
- if (woken) {
- char dummy;
- ssize_t nbrfp = read(_wakeupPipe[0], &dummy, 1);
- if (nbrfp != 1) {
- perror("FastOS_UNIX_IPCHelper wakeupPipe read failed");
- }
- }
- }
- free(fds);
-
- delete this;
-}
-
-void
-FastOS_UNIX_IPCHelper::NotifyProcessListChange ()
-{
- char dummy = 'x';
- ssize_t nbwtp = write(_wakeupPipe[1], &dummy, 1);
- if (nbwtp != 1) {
- perror("FastOS_UNIX_IPCHelper: write to wakeupPipe failed");
- }
-}
-
-void
-FastOS_UNIX_IPCHelper::Exit ()
-{
- std::lock_guard<std::mutex> guard(_lock);
- _exitFlag = true;
- NotifyProcessListChange();
-}
-
-void
-FastOS_UNIX_IPCHelper::AddProcess (FastOS_UNIX_Process *xproc)
-{
- bool newStream = false;
- for(int type=0; type < int(FastOS_UNIX_Process::TYPE_READCOUNT); type++)
- {
- FastOS_UNIX_Process::DescriptorType type_ = FastOS_UNIX_Process::DescriptorType(type);
- FastOS_UNIX_Process::DescriptorHandle &desc = xproc->GetDescriptorHandle(type_);
-
- if (desc._fd != -1) {
- newStream = true;
- SetBlocking(desc._fd, false);
- }
- }
- if(newStream)
- NotifyProcessListChange();
-}
-
-void
-FastOS_UNIX_IPCHelper::RemoveProcess (FastOS_UNIX_Process *xproc)
-{
- auto closePromise = std::make_unique<std::promise<void>>();
- auto closeFuture = closePromise->get_future();
- xproc->_closing = std::move(closePromise);
- NotifyProcessListChange();
- closeFuture.wait();
-}
-
-void
-FastOS_UNIX_IPCHelper::PipeData(FastOS_UNIX_Process *process, FastOS_UNIX_Process::DescriptorType type)
-{
- FastOS_UNIX_Process::DescriptorHandle &desc = process->GetDescriptorHandle(type);
- FastOS_RingBuffer *buffer = desc._readBuffer.get();
- if(buffer == nullptr)
- return;
-
- FastOS_ProcessRedirectListener *listener = process->GetListener(type);
- if(listener == nullptr)
- return;
-
- auto bufferGuard = buffer->getGuard();
-
- unsigned int readSpace;
- while((readSpace = buffer->GetReadSpace()) > 0) {
- listener->OnReceiveData(buffer->GetReadPtr(), size_t(readSpace));
- buffer->Consume(readSpace);
- }
-
- if(buffer->GetCloseFlag())
- process->CloseListener(type);
-}
diff --git a/fastos/src/vespa/fastos/unix_ipc.h b/fastos/src/vespa/fastos/unix_ipc.h
deleted file mode 100644
index 13e92411011..00000000000
--- a/fastos/src/vespa/fastos/unix_ipc.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "app.h"
-#include "process.h"
-#include "thread.h"
-#include <poll.h>
-
-class FastOS_RingBuffer;
-
-class FastOS_UNIX_IPCHelper : public FastOS_Runnable
-{
-private:
- FastOS_UNIX_IPCHelper(const FastOS_UNIX_IPCHelper&);
- FastOS_UNIX_IPCHelper& operator=(const FastOS_UNIX_IPCHelper&);
-
-protected:
- std::mutex _lock;
- volatile bool _exitFlag;
- FastOS_ApplicationInterface *_app;
-
- int _wakeupPipe[2];
-
- bool DoWrite (FastOS_UNIX_Process::DescriptorHandle &desc);
- bool DoRead (FastOS_UNIX_Process::DescriptorHandle &desc);
- bool SetBlocking (int fileDescriptor, bool doBlock);
- void BuildPollCheck (bool isRead, int filedes, FastOS_RingBuffer *buffer, bool *check);
- void BuildPollArray(pollfd **fds, unsigned int *nfds, unsigned int *allocnfds);
- bool SavePollArray(pollfd *fds, unsigned int nfds);
- void PerformAsyncIO ();
- void BuildPollChecks();
- void PipeData (FastOS_UNIX_Process *process, FastOS_UNIX_Process::DescriptorType type);
- void RemoveClosingProcesses();
-
-public:
- FastOS_UNIX_IPCHelper (FastOS_ApplicationInterface *app, int appDescriptor);
- ~FastOS_UNIX_IPCHelper ();
- void Run (FastOS_ThreadInterface *thisThread, void *arg) override;
- void NotifyProcessListChange ();
- void AddProcess (FastOS_UNIX_Process *xproc);
- void RemoveProcess (FastOS_UNIX_Process *xproc);
- void Exit ();
-};
diff --git a/fastos/src/vespa/fastos/unix_process.cpp b/fastos/src/vespa/fastos/unix_process.cpp
deleted file mode 100644
index cd29108c3d6..00000000000
--- a/fastos/src/vespa/fastos/unix_process.cpp
+++ /dev/null
@@ -1,985 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-#include "process.h"
-#include "unix_ipc.h"
-#include "ringbuffer.h"
-#include <vector>
-#include <cstring>
-#include <cstdlib>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#ifndef __linux__
-#include <signal.h>
-#endif
-#include <thread>
-
-
-extern "C"
-{
-extern char **environ;
-}
-
-
-using namespace std::chrono_literals;
-using namespace std::chrono;
-
-static pid_t safe_fork ()
-{
- pid_t pid;
- int retry = 1;
- while((pid = fork()) == -1 && errno == EAGAIN) {
- sleep(retry);
- if (retry < 4) retry *= 2;
- }
- return pid;
-}
-
-static int
-normalizedWaitStatus(int status)
-{
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- else
- return (0x80000000 | status);
-}
-
-
-// The actual process launched in the proxy process
-class FastOS_UNIX_RealProcess
-{
-private:
- FastOS_UNIX_RealProcess(const FastOS_UNIX_RealProcess&);
- FastOS_UNIX_RealProcess& operator=(const FastOS_UNIX_RealProcess&);
-
-public:
- enum
- {
- STREAM_STDIN = (1 << 0),
- STREAM_STDOUT = (1 << 1),
- STREAM_STDERR = (1 << 2),
- EXEC_SHELL = (1 << 3)
- };
-
-private:
- pid_t _pid;
- bool _terse; // Set if using direct fork (bypassing proxy process)
- int _streamMask;
-
- int _stdinDes[2];
- int _stdoutDes[2];
- int _stderrDes[2];
- int _handshakeDes[2];
- std::string _runDir;
- std::string _stdoutRedirName;
- std::string _stderrRedirName;
- const char *_path;
- std::vector<char> _pathProgBuf;
-
- void CloseDescriptor(int fd);
- void CloseAndResetDescriptor(int *fd);
- void CloseDescriptors();
-
-public:
- void SetRunDir(const char * runDir) { _runDir = runDir; }
-
- int HandoverStdinDescriptor() {
- int ret = _stdinDes[1];
- _stdinDes[1] = -1;
- return ret;
- }
-
- int HandoverStdoutDescriptor() {
- int ret = _stdoutDes[0];
- _stdoutDes[0] = -1;
- return ret;
- }
-
- int HandoverStderrDescriptor() {
- int ret = _stderrDes[0];
- _stderrDes[0] = -1;
- return ret;
- }
-
- FastOS_UNIX_RealProcess *_prev, *_next;
-
- FastOS_UNIX_RealProcess (int streamMask);
- ~FastOS_UNIX_RealProcess();
- pid_t GetProcessID() const { return _pid; }
-
- bool IsStdinPiped() const {
- return (_streamMask & STREAM_STDIN ) != 0;
- }
-
- bool IsStdoutPiped() const {
- return (_streamMask & STREAM_STDOUT) != 0;
- }
-
- bool IsStderrPiped() const {
- return (_streamMask & STREAM_STDERR) != 0;
- }
-
- bool IsUsingShell() const {
- return (_streamMask & EXEC_SHELL) != 0;
- }
-
- void SetStdoutRedirName(const char *stdoutRedirName) {
- _stdoutRedirName = stdoutRedirName;
- }
-
- void SetStderrRedirName(const char *stderrRedirName) {
- _stderrRedirName = stderrRedirName;
- }
-
- void PrepareExecVPE (const char *prog);
-
- void
- ExecVPE (const char *prog,
- char *const args[],
- char *const env[]);
-
- static bool IsWhiteSpace (char c);
-
- static const char *
- NextArgument (const char *p,
- const char **endArg,
- int *length = nullptr);
-
- static int CountArguments (const char *commandLine);
-
- void
- RedirOut(const std::string & filename,
- int targetfd,
- int exitCodeOnFailure);
-
- bool
- ForkAndExec(const char *command,
- char **environmentVariables,
- FastOS_UNIX_Process *process);
-
- bool Setup();
- void SetTerse() { _terse = true; }
- ssize_t HandshakeRead(void *buf, size_t len);
- void HandshakeWrite(int val);
-};
-
-
-void
-FastOS_UNIX_RealProcess::CloseDescriptor(int fd)
-{
- close(fd);
-}
-
-
-void
-FastOS_UNIX_RealProcess::CloseAndResetDescriptor(int *fd)
-{
- if (*fd == -1)
- return;
- CloseDescriptor(*fd);
- *fd = -1;
-}
-
-
-void
-FastOS_UNIX_RealProcess::CloseDescriptors()
-{
- CloseAndResetDescriptor(&_stdinDes[0]);
- CloseAndResetDescriptor(&_stdinDes[1]);
- CloseAndResetDescriptor(&_stdoutDes[0]);
- CloseAndResetDescriptor(&_stdoutDes[1]);
- CloseAndResetDescriptor(&_stderrDes[0]);
- CloseAndResetDescriptor(&_stderrDes[1]);
- CloseAndResetDescriptor(&_handshakeDes[0]);
- CloseAndResetDescriptor(&_handshakeDes[1]);
-}
-
-
-FastOS_UNIX_RealProcess::FastOS_UNIX_RealProcess(int streamMask)
- : _pid(-1),
- _terse(false),
- _streamMask(streamMask),
- _runDir(),
- _stdoutRedirName(),
- _stderrRedirName(),
- _path(nullptr),
- _pathProgBuf(),
- _prev(nullptr),
- _next(nullptr)
-{
- _stdinDes[0] = _stdinDes[1] = -1;
- _stdoutDes[0] = _stdoutDes[1] = -1;
- _stderrDes[0] = _stderrDes[1] = -1;
- _handshakeDes[0] = _handshakeDes[1] = -1;
-}
-
-
-FastOS_UNIX_RealProcess::~FastOS_UNIX_RealProcess()
-{
- CloseDescriptors();
-}
-
-
-void
-FastOS_UNIX_RealProcess::PrepareExecVPE(const char *prog)
-{
- const char *path = nullptr;
-
- char defaultPath[] = ":/usr/ucb:/bin:/usr/bin";
-
- if (strchr(prog, '/') != nullptr) {
- path = "";
- } else {
- path = getenv("PATH");
- if (path == nullptr) path = defaultPath;
- }
- _path = path;
- _pathProgBuf.resize(strlen(prog) + 1 + strlen(path) + 1);
-}
-
-
-void
-FastOS_UNIX_RealProcess::ExecVPE (const char *prog,
- char *const args[],
- char *const env[])
-{
-
- char *fullPath = &_pathProgBuf[0];
- const char *path = _path;
-
- for(;;)
- {
- char *p;
- for (p = fullPath; (*path != '\0') && (*path != ':'); path++)
- *p++ = *path;
-
- if (p > fullPath) *p++ = '/';
-
- strcpy(p, prog);
- // fprintf(stdout, "Attempting execve [%s]\n", fullPath);
- // fflush(stdout);
- execve(fullPath, args, env);
-
- if ((errno == ENOEXEC) ||
- (errno == ENOMEM) ||
- (errno == E2BIG) ||
- (errno == ETXTBSY))
- break;
-
- if (*path == '\0') break;
- path++;
- }
-}
-
-
-bool
-FastOS_UNIX_RealProcess::IsWhiteSpace (char c)
-{
- return (c == ' ' || c == '\t');
-}
-
-
-const char *
-FastOS_UNIX_RealProcess::NextArgument (const char *p,
- const char **endArg,
- int *length)
-{
- while(*p != '\0')
- {
- if (!IsWhiteSpace(*p)) {
- char quoteChar = '\0';
- if ((*p == '\'') || (*p == '"')) {
- quoteChar = *p;
- p++;
- }
-
- const char *nextArg = p;
-
- // Find the end of the argument.
- for(;;)
- {
- if (*p == '\0') {
- if (length != nullptr)
- *length = p - nextArg;
- break;
- }
-
- if (quoteChar != '\0') {
- if (*p == quoteChar) {
- if (length != nullptr)
- *length = p - nextArg;
- p++;
- break;
- }
- }
- else
- {
- if (IsWhiteSpace(*p)) {
- if (length != nullptr)
- *length = p - nextArg;
- break;
- }
- }
- p++;
- }
-
- *endArg = p;
- return nextArg;
- }
- p++;
- }
- return nullptr;
-}
-
-
-int
-FastOS_UNIX_RealProcess::CountArguments (const char *commandLine)
-{
- int numArgs = 0;
- const char *nextArg = commandLine;
- while(NextArgument(nextArg, &nextArg))
- numArgs++;
-
- return numArgs;
-}
-
-
-void
-FastOS_UNIX_RealProcess::RedirOut(const std::string & filename,
- int targetfd,
- int exitCodeOnFailure)
-{
- if (filename.empty() || filename[0] != '>')
- return;
-
- int newfd;
- if (filename[1] == '>') {
- newfd = open(&filename[2],
- O_WRONLY | O_CREAT | O_APPEND,
- 0666);
- if (newfd < 0) {
- if (!_terse) {
- fprintf(stderr,
- "ERROR: Could not open %s for append: %s\n",
- &filename[2],
- strerror(errno));
- fflush(stderr);
- }
- _exit(exitCodeOnFailure);
- }
- } else {
- newfd = open(&filename[1],
- O_WRONLY | O_CREAT | O_TRUNC,
- 0666);
- if (newfd < 0) {
- if (!_terse) {
- fprintf(stderr,
- "ERROR: Could not open %s for write: %s\n",
- &filename[1],
- strerror(errno));
- fflush(stderr);
- }
- _exit(exitCodeOnFailure);
- }
- }
- if (newfd != targetfd) {
- dup2(newfd, targetfd);
- CloseDescriptor(newfd);
- }
-}
-
-
-bool
-FastOS_UNIX_RealProcess::
-ForkAndExec(const char *command,
- char **environmentVariables,
- FastOS_UNIX_Process *process)
-{
- bool rc = false;
- int numArguments = 0;
- char **execArgs = nullptr;
-
- if (!IsUsingShell()) {
- numArguments = CountArguments(command);
- if (numArguments > 0) {
- execArgs = new char *[numArguments + 1];
- const char *nextArg = command;
-
- for(int i=0; ; i++) {
- int length;
- const char *arg = NextArgument(nextArg, &nextArg, &length);
-
- if (arg == nullptr) {
- // printf("ARG nullptr\n");
- execArgs[i] = nullptr;
- break;
- }
- // printf("argLen = %d\n", length);
- execArgs[i] = new char[length + 1];
- memcpy(execArgs[i], arg, length);
- execArgs[i][length] = '\0';
- // printf("arg %d: [%s]\n", i, execArgs[i]);
- }
- PrepareExecVPE(execArgs[0]);
- }
- }
-
- _pid = safe_fork();
- if (_pid == static_cast<pid_t>(0)) {
- // Fork success, child side.
- if (IsStdinPiped() && _stdinDes[0] != STDIN_FILENO) {
- dup2(_stdinDes[0], STDIN_FILENO);
- CloseDescriptor(_stdinDes[0]);
- }
- _stdinDes[0] = -1;
- if (IsStdoutPiped() && _stdoutDes[1] != STDOUT_FILENO) {
- dup2(_stdoutDes[1], STDOUT_FILENO);
- CloseDescriptor(_stdoutDes[1]);
- }
- _stdoutDes[1] = -1;
- if (IsStderrPiped() && _stderrDes[1] != STDERR_FILENO) {
- dup2(_stderrDes[1], STDERR_FILENO);
- CloseDescriptor(_stderrDes[1]);
- }
- _stderrDes[1] = -1;
- // FIX! Check error codes for dup2, and do _exit(127) if trouble
-
- if ( ! _runDir.empty()) {
- if (chdir(_runDir.c_str())) {
- if (!_terse) {
- fprintf(stderr,
- "ERROR: Could not chdir to %s: %s\n",
- _runDir.c_str(),
- strerror(errno));
- fflush(stderr);
- }
- _exit(126);
- }
- }
- RedirOut(_stdoutRedirName.c_str(), STDOUT_FILENO, 124);
- RedirOut(_stderrRedirName.c_str(), STDERR_FILENO, 125);
-
- CloseDescriptor(_handshakeDes[0]);
- _handshakeDes[0] = -1;
- if (process != nullptr) {
- int fdlimit = sysconf(_SC_OPEN_MAX);
- // Close everything else
- // printf("fdlimit = %d\n", fdlimit);
- for(int fd = STDERR_FILENO + 1; fd < fdlimit; fd++)
- {
- if (fd != _handshakeDes[1])
- CloseDescriptor(fd);
- }
- }
- if (fcntl(_handshakeDes[1], F_SETFD, FD_CLOEXEC) != 0) _exit(127);
-
- HandshakeWrite(0);
-
- // printf("exev(p)e [%s]\n", command);
- if (IsUsingShell()) {
- const char *shExecArgs[4];
-
- shExecArgs[0] = "sh";
- shExecArgs[1] = "-c";
- shExecArgs[2] = command;
- shExecArgs[3] = nullptr;
- execve("/bin/sh",
- const_cast<char *const *>
- (reinterpret_cast<const char *const *>
- (shExecArgs)),
- environmentVariables);
- int error = errno;
- if (!_terse) {
- fprintf(stderr,
- "ERROR: Could not execv /bin/sh -c '%s': %s\n",
- command,
- strerror(error));
- fflush(stderr);
- }
- HandshakeWrite(error);
- }
- else
- {
- if (numArguments > 0) {
- // printf("Command: [%s]\n", execArgs[0]);
- ExecVPE(execArgs[0],
- static_cast<char *const *>(execArgs),
- environmentVariables);
- int error = errno;
- if (!_terse) {
- fprintf(stderr,
- "ERROR: Could not execve %s with "
- "path search: %s\n",
- execArgs[0],
- strerror(error));
- fflush(stderr);
- }
- HandshakeWrite(error);
- }
- }
- _exit(127); // If execve fails, we'll get it here
- }
- else if(_pid != static_cast<pid_t>(-1))
- {
- /* Fork success, parent side */
-
- // Close unused file descriptors
- if (IsStdinPiped()) {
- CloseAndResetDescriptor(&_stdinDes[0]);
- }
- if (IsStdoutPiped()) {
- CloseAndResetDescriptor(&_stdoutDes[1]);
- }
- if (IsStderrPiped()) {
- CloseAndResetDescriptor(&_stderrDes[1]);
- }
-
- CloseAndResetDescriptor(&_handshakeDes[1]);
-
- int flags = fcntl(_handshakeDes[0], F_GETFL, 0);
- if (flags != -1) {
- flags &= ~O_NONBLOCK;
- fcntl(_handshakeDes[0], F_SETFL, flags);
- }
- int phase1res = 0;
- ssize_t rgot = HandshakeRead(&phase1res, sizeof(int));
- bool wasError = false;
- int error = 0;
- if (static_cast<size_t>(rgot) != sizeof(int)) wasError = true;
- else if (phase1res != 0) {
- wasError = true;
- error = phase1res;
- } else {
- int phase2res = 0;
- rgot = HandshakeRead(&phase2res, sizeof(int));
- if (rgot >= 1) {
- if (static_cast<size_t>(rgot) >= sizeof(int))
- error = phase2res;
- wasError = true;
- }
- }
-
- if (wasError) {
- int status = 0;
- CloseDescriptors();
- pid_t wpid = waitpid(_pid, &status, 0);
- if (wpid <= 0) {
- fprintf(stderr, "ERROR: Could not start process %s\n", command);
- } else if (WIFEXITED(status)) {
- status = WEXITSTATUS(status);
- switch (status) {
- case 124:
- if ( ! _stdoutRedirName.empty() &&
- _stdoutRedirName[0] == '>') {
- if (_stdoutRedirName[1] == '>')
- fprintf(stderr, "ERROR: Could not open %s for append", &_stdoutRedirName[2]);
- else
- fprintf(stderr, "ERROR: Could not open %s for write", &_stdoutRedirName[1]);
- }
- break;
- case 125:
- if ( ! _stderrRedirName.empty() &&
- _stderrRedirName[0] == '>') {
- if (_stderrRedirName[1] == '>')
- fprintf(stderr, "ERROR: Could not open %s for append", &_stderrRedirName[2]);
- else
- fprintf(stderr, "ERROR: Could not open %s for write", &_stderrRedirName[1]);
- }
- break;
- case 126:
- if ( ! _runDir.empty()) {
- fprintf(stderr, "ERROR: Could not chdir to %s\n", _runDir.c_str());
- }
- break;
- case 127:
- if (error != 0) {
- std::error_code ec(error, std::system_category());
- fprintf(stderr, "ERROR: Could not execve %s: %s\n", command, ec.message().c_str());
- } else
- fprintf(stderr, "ERROR: Could not execve %s\n", command);
- break;
- default:
- fprintf(stderr, "ERROR: Could not start process %s\n", command);
- break;
- }
- } else {
- fprintf(stderr, "ERROR: Could not start process %s\n", command);
- }
- fflush(stderr);
- } else {
- rc = true;
- }
- }
- if (execArgs != nullptr) {
- char **arg = execArgs;
- while (*arg != nullptr) {
- delete [] *arg;
- arg++;
- }
- delete [] execArgs;
- }
-
- return rc;
-}
-
-
-void
-FastOS_UNIX_RealProcess::HandshakeWrite(int val)
-{
- if (_handshakeDes[1] == -1)
- return;
- const void *wbuf = &val;
- size_t residue = sizeof(val);
- for (;;) {
- /*
- * XXX: Might need to use syscall(SYS_write....) to avoid
- * thread library interference.
- */
- ssize_t wgot = write(_handshakeDes[1], wbuf, residue);
- if (wgot < 0 && errno == EINTR)
- continue;
- if (wgot <= 0)
- break;
- wbuf = static_cast<const char *>(wbuf) + wgot;
- residue -= wgot;
- if (residue == 0)
- break;
- }
-}
-
-
-ssize_t
-FastOS_UNIX_RealProcess::HandshakeRead(void *buf, size_t len)
-{
- if (_handshakeDes[0] == -1)
- return 0;
- size_t residue = len;
- ssize_t rgot = 0;
- void *rbuf = buf;
- for (;;) {
- rgot = read(_handshakeDes[0], rbuf, residue);
- if (rgot < 0 && errno == EINTR)
- continue;
- if (rgot <= 0)
- break;
- rbuf = static_cast<char *>(rbuf) + rgot;
- residue -= rgot;
- if (residue == 0)
- break;
- }
- return (residue == len) ? rgot : len - residue;
-}
-
-
-bool
-FastOS_UNIX_RealProcess::Setup()
-{
- bool rc = true;
-
- if (IsStdinPiped()) rc = rc && (pipe(_stdinDes) == 0);
- if (IsStdoutPiped()) rc = rc && (pipe(_stdoutDes) == 0);
- if (IsStderrPiped()) rc = rc && (pipe(_stderrDes) == 0);
- rc = rc && (pipe(_handshakeDes) == 0);
- return rc;
-}
-
-
-FastOS_UNIX_Process::
-FastOS_UNIX_Process (const char *cmdLine,
- FastOS_ProcessRedirectListener *stdoutListener,
- FastOS_ProcessRedirectListener *stderrListener) :
- FastOS_ProcessInterface(cmdLine, stdoutListener, stderrListener),
- _pid(0),
- _died(false),
- _returnCode(-1),
- _descriptor(),
- _runDir(),
- _stdoutRedirName(),
- _stderrRedirName(),
- _killed(false),
- _closing(nullptr)
-{
- constexpr uint32_t RING_BUFFER_SIZE = 0x10000;
- if (stdoutListener != nullptr)
- _descriptor[TYPE_STDOUT]._readBuffer = std::make_unique<FastOS_RingBuffer>(RING_BUFFER_SIZE);
- if (stderrListener != nullptr)
- _descriptor[TYPE_STDERR]._readBuffer = std::make_unique<FastOS_RingBuffer>(RING_BUFFER_SIZE);
-
- {
- auto guard = _app->getProcessGuard();
- _app->AddChildProcess(this);
- }
-
- // App::AddToIPCComm() is performed when the process is started
-}
-
-FastOS_UNIX_Process::~FastOS_UNIX_Process ()
-{
- Kill(); // Kill if not dead or detached.
-
- if ((GetDescriptorHandle(TYPE_STDOUT)._fd != -1) ||
- (GetDescriptorHandle(TYPE_STDERR)._fd != -1))
- {
- // Let the IPC helper flush write queues and remove us from the
- // process list before we disappear.
- static_cast<FastOS_UNIX_Application *>(_app)->RemoveFromIPCComm(this);
- } else {
- // No IPC descriptor, do it ourselves
- auto guard = _app->getProcessGuard();
- _app->RemoveChildProcess(this);
- }
-
- for(int i=0; i<int(TYPE_COUNT); i++) {
- _descriptor[i]._readBuffer.reset();
- _descriptor[i]._writeBuffer.reset();
- CloseDescriptor(DescriptorType(i));
- }
-
- CloseListener(TYPE_STDOUT);
- CloseListener(TYPE_STDERR);
-}
-
-bool FastOS_UNIX_Process::CreateInternal (bool useShell)
-{
- return GetProcessStarter()->CreateProcess(this, useShell,
- _stdoutListener != nullptr,
- _stderrListener != nullptr);
-}
-
-bool FastOS_UNIX_Process::WriteStdin (const void *data, size_t length)
-{
- bool rc = false;
- DescriptorHandle &desc = GetDescriptorHandle(TYPE_STDIN);
-
- if (desc._fd != -1) {
- if (data == nullptr) {
- CloseDescriptor(TYPE_STDIN);
- rc = true;
- }
- else
- {
- int writerc = write(desc._fd, data, length);
- if (writerc < int(length))
- CloseDescriptor(TYPE_STDIN);
- else
- rc = true;
- }
- }
-
- return rc;
-}
-
-bool FastOS_UNIX_Process::Signal(int sig)
-{
- bool rc = false;
- pid_t pid;
-
- auto guard = _app->getProcessGuard();
- pid = GetProcessId();
- if (pid == 0) {
- /* Do nothing */
- } else if (GetDeathFlag()) {
- rc = true; // The process is no longer around.
- } else if (kill(pid, sig) == 0) {
- if (sig == SIGKILL)
- _killed = true;
- rc = true;
- }
- return rc;
-}
-
-bool FastOS_UNIX_Process::Kill ()
-{
- return Signal(SIGKILL);
-}
-
-bool FastOS_UNIX_Process::InternalWait (int *returnCode,
- int timeOutSeconds,
- bool *pollStillRunning)
-{
- bool rc = GetProcessStarter()->Wait(this, timeOutSeconds,
- pollStillRunning);
- if (rc) {
- if (_killed)
- *returnCode = KILL_EXITCODE;
- else
- *returnCode = _returnCode;
- }
-
- return rc;
-}
-
-bool FastOS_UNIX_Process::Wait (int *returnCode, int timeOutSeconds)
-{
- return InternalWait(returnCode, timeOutSeconds, nullptr);
-}
-
-bool FastOS_UNIX_Process::PollWait (int *returnCode, bool *stillRunning)
-{
- return InternalWait(returnCode, -1, stillRunning);
-}
-
-int FastOS_UNIX_Process::BuildStreamMask (bool useShell)
-{
- int streamMask = FastOS_UNIX_RealProcess::STREAM_STDIN;
- if (_stdoutListener) streamMask |= FastOS_UNIX_RealProcess::STREAM_STDOUT;
- if (_stderrListener) streamMask |= FastOS_UNIX_RealProcess::STREAM_STDERR;
- if (useShell) streamMask |= FastOS_UNIX_RealProcess::EXEC_SHELL;
-
- return streamMask;
-}
-
-
-FastOS_UNIX_ProcessStarter::FastOS_UNIX_ProcessStarter (FastOS_ApplicationInterface *app)
- : _app(app),
- _hasDirectChildren(false)
-{
-}
-
-FastOS_UNIX_ProcessStarter::~FastOS_UNIX_ProcessStarter () = default;
-
-bool
-FastOS_UNIX_ProcessStarter::
-CreateProcess (FastOS_UNIX_Process *process, bool useShell, bool pipeStdout, bool pipeStderr)
-{
- bool rc = false;
-
- const char *cmdLine = process->GetCommandLine();
-
- auto guard = _app->getProcessGuard();
-
- _hasDirectChildren = true;
- FastOS_UNIX_RealProcess *rprocess = new FastOS_UNIX_RealProcess(process->BuildStreamMask(useShell));
- const char *runDir = process->GetRunDir();
- if (runDir != nullptr) {
- rprocess->SetRunDir(runDir); // Handover
- }
- const char *stdoutRedirName = process->GetStdoutRedirName();
- if (stdoutRedirName != nullptr) {
- rprocess->SetStdoutRedirName(stdoutRedirName);
- }
- const char *stderrRedirName = process->GetStderrRedirName();
- if (stderrRedirName != nullptr) {
- rprocess->SetStderrRedirName(stderrRedirName);
- }
- rprocess->SetTerse();
- rprocess->Setup();
- process->SetDescriptor(FastOS_UNIX_Process::TYPE_STDIN, rprocess->HandoverStdinDescriptor());
- if (pipeStdout)
- process->SetDescriptor(FastOS_UNIX_Process::TYPE_STDOUT, rprocess->HandoverStdoutDescriptor());
- if (pipeStderr)
- process->SetDescriptor(FastOS_UNIX_Process::TYPE_STDERR, rprocess->HandoverStderrDescriptor());
- pid_t processId = -1;
- if (rprocess->ForkAndExec(cmdLine, environ, process)) {
- processId = rprocess->GetProcessID();
- }
- if (processId != -1) {
- process->SetProcessId(static_cast<unsigned int>(processId));
- if (!useShell || pipeStdout || pipeStderr)
- static_cast<FastOS_UNIX_Application *>(_app)->AddToIPCComm(process);
- rc = true;
- } else {
- fprintf(stderr, "Forkandexec %s failed\n", cmdLine);
- }
- guard.unlock();
- delete rprocess;
- return rc;
-}
-
-
-void
-FastOS_UNIX_ProcessStarter::PollReapDirectChildren()
-{
- int status;
- pid_t pid;
-
- for (;;) {
- pid = waitpid(-1, &status, WNOHANG);
- if (pid <= 0)
- break;
-
- FastOS_ProcessInterface *node;
- for(node = _app->GetProcessList();
- node != nullptr; node = node->_next)
- {
- FastOS_UNIX_Process *xproc = static_cast<FastOS_UNIX_Process *>(node);
-
- if (xproc->GetProcessId() == static_cast<unsigned int>(pid))
- xproc->DeathNotification(normalizedWaitStatus(status));
- }
- }
-}
-
-
-bool
-FastOS_UNIX_ProcessStarter::Wait(FastOS_UNIX_Process *process,
- int timeOutSeconds,
- bool *pollStillRunning)
-{
- bool rc = true;
-
- bool timeOutKillAttempted = false;
-
- steady_clock::time_point start = steady_clock::now();
-
- if (pollStillRunning != nullptr)
- *pollStillRunning = true;
-
- for (;;) {
- {
- auto guard = process->_app->getProcessGuard();
-
- if (_hasDirectChildren) PollReapDirectChildren();
- }
-
- if (process->GetDeathFlag()) {
- if (pollStillRunning != nullptr)
- *pollStillRunning = false;
- break;
- }
-
- if (pollStillRunning != nullptr)
- break;
-
- if ((timeOutSeconds != -1) && !timeOutKillAttempted) {
-
- if ((steady_clock::now() - start) >= seconds(timeOutSeconds)) {
- process->Kill();
- timeOutKillAttempted = true;
- }
- }
-
- std::this_thread::sleep_for(100ms);
- }
-
- return rc;
-}
-
-FastOS_UNIX_Process::DescriptorHandle::DescriptorHandle()
- : _fd(-1),
- _wantRead(false),
- _wantWrite(false),
- _canRead(false),
- _canWrite(false),
- _pollIdx(-1),
- _readBuffer(),
- _writeBuffer()
-{
-}
-FastOS_UNIX_Process::DescriptorHandle::~DescriptorHandle() = default;
-void
-FastOS_UNIX_Process::DescriptorHandle::CloseHandle()
-{
- _wantRead = false;
- _wantWrite = false;
- _canRead = false;
- _canWrite = false;
- _pollIdx = -1;
- if (_fd != -1) {
- close(_fd);
- _fd = -1;
- }
- if (_readBuffer)
- _readBuffer->Close();
- if (_writeBuffer)
- _writeBuffer->Close();
-}
diff --git a/fastos/src/vespa/fastos/unix_process.h b/fastos/src/vespa/fastos/unix_process.h
deleted file mode 100644
index 43b4388e0c3..00000000000
--- a/fastos/src/vespa/fastos/unix_process.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-//************************************************************************
-/**
- * Class definitions for FastOS_UNIX_Process.
- *
- * @author Div, Oivind H. Danielsen
- */
-
-#pragma once
-
-#include "process.h"
-#include "app.h"
-#include <string>
-#include <memory>
-#include <future>
-
-class FastOS_UNIX_RealProcess;
-class FastOS_RingBuffer;
-
-class FastOS_UNIX_Process : public FastOS_ProcessInterface
-{
-private:
- FastOS_UNIX_Process(const FastOS_UNIX_Process&);
- FastOS_UNIX_Process& operator=(const FastOS_UNIX_Process&);
-
- unsigned int _pid;
- bool _died;
- int _returnCode;
-public:
- class DescriptorHandle
- {
- private:
- DescriptorHandle(const DescriptorHandle &);
- DescriptorHandle& operator=(const DescriptorHandle &);
-
- public:
- int _fd;
- bool _wantRead;
- bool _wantWrite;
- bool _canRead;
- bool _canWrite;
- int _pollIdx;
- std::unique_ptr<FastOS_RingBuffer> _readBuffer;
- std::unique_ptr<FastOS_RingBuffer> _writeBuffer;
- DescriptorHandle();
- ~DescriptorHandle();
- void CloseHandle();
- };
-private:
- DescriptorHandle _descriptor[4];
-
- std::string _runDir;
- std::string _stdoutRedirName;
- std::string _stderrRedirName;
- bool _killed;
-
- FastOS_UNIX_ProcessStarter *GetProcessStarter () {
- return static_cast<FastOS_UNIX_Application *>(_app)->GetProcessStarter();
- }
-
- bool InternalWait (int *returnCode, int timeOutSeconds, bool *pollStillRunning);
-public:
- enum DescriptorType
- {
- TYPE_STDOUT,
- TYPE_STDERR,
- TYPE_STDIN,
- TYPE_COUNT
- };
-
- enum Constants
- {
- TYPE_READCOUNT = 3
- };
- std::unique_ptr<std::promise<void>> _closing;
- FastOS_ProcessRedirectListener *GetListener (DescriptorType type)
- {
- if(type == TYPE_STDOUT)
- return _stdoutListener;
- else if(type == TYPE_STDERR)
- return _stderrListener;
-
- return nullptr;
- }
-
- void CloseListener (DescriptorType type)
- {
- if(type == TYPE_STDOUT)
- {
- if(_stdoutListener != nullptr)
- {
- _stdoutListener->OnReceiveData(nullptr, 0);
- _stdoutListener = nullptr;
- }
- }
- else if(type == TYPE_STDERR)
- {
- if(_stderrListener != nullptr)
- {
- _stderrListener->OnReceiveData(nullptr, 0);
- _stderrListener = nullptr;
- }
- }
- }
-
- FastOS_UNIX_Process (const char *cmdLine,
- FastOS_ProcessRedirectListener *stdoutListener = nullptr,
- FastOS_ProcessRedirectListener *stderrListener = nullptr);
- ~FastOS_UNIX_Process ();
- bool CreateInternal (bool useShell);
- bool Create () override { return CreateInternal(false); }
- bool CreateWithShell () override { return CreateInternal(true); }
- bool WriteStdin (const void *data, size_t length) override;
- bool Signal(int sig);
- bool Kill () override;
- bool Wait (int *returnCode, int timeOutSeconds = -1) override;
- bool PollWait (int *returnCode, bool *stillRunning) override;
- void SetProcessId (unsigned int pid) { _pid = pid; }
- unsigned int GetProcessId() override { return _pid; }
- void DeathNotification (int returnCode) {
- _returnCode = returnCode;
- _died = true;
- }
- bool GetDeathFlag () { return _died; }
- int BuildStreamMask (bool useShell);
-
- void CloseDescriptor (DescriptorType type)
- {
- _descriptor[type].CloseHandle();
- }
-
- void SetDescriptor (DescriptorType type, int descriptor)
- {
- _descriptor[type]._fd = descriptor;
- }
-
- DescriptorHandle &GetDescriptorHandle(DescriptorType type)
- {
- return _descriptor[type];
- }
-
- bool GetKillFlag () { return _killed; }
-
- const char *GetRunDir() const { return _runDir.c_str(); }
- const char *GetStdoutRedirName() const { return _stdoutRedirName.c_str(); }
- const char *GetStderrRedirName() const { return _stderrRedirName.c_str(); }
-};
-
-
-class FastOS_UNIX_RealProcess;
-class FastOS_UNIX_ProcessStarter
-{
-private:
- FastOS_UNIX_ProcessStarter(const FastOS_UNIX_ProcessStarter&);
- FastOS_UNIX_ProcessStarter& operator=(const FastOS_UNIX_ProcessStarter&);
-
-protected:
- FastOS_ApplicationInterface *_app;
- bool _hasDirectChildren;
-
- void PollReapDirectChildren();
-
-public:
- FastOS_UNIX_ProcessStarter (FastOS_ApplicationInterface *app);
- ~FastOS_UNIX_ProcessStarter ();
-
- bool CreateProcess (FastOS_UNIX_Process *process, bool useShell,
- bool pipeStdout, bool pipeStderr);
- bool Wait (FastOS_UNIX_Process *process, int timeOutSeconds, bool *pollStillRunning);
-};
-
-