aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--SConstruct2
-rw-r--r--src/messaging/sendmail/sendmailTransport.cpp211
-rw-r--r--src/platforms/posix/posixChildProcess.cpp383
-rw-r--r--src/platforms/posix/posixHandler.cpp8
-rw-r--r--src/platforms/windows/windowsHandler.cpp7
-rw-r--r--vmime/platformDependant.hpp13
-rw-r--r--vmime/platforms/posix/posixChildProcess.hpp74
-rw-r--r--vmime/platforms/posix/posixHandler.hpp4
-rw-r--r--vmime/platforms/windows/windowsHandler.hpp4
10 files changed, 515 insertions, 196 deletions
diff --git a/ChangeLog b/ChangeLog
index 7e7e8aac..9b582a50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
VERSION 0.7.1cvs
================
+2005-04-30 Vincent Richard <[email protected]>
+
+ * utility/childProcess.{hpp|cpp}: added a 'childProcess' class to help
+ with spawning child processes (used in 'sendmail' implementation).
+
2005-04-28 Stefan Uhrig <[email protected]>
* README.msvc: added guide describing how to compile VMime using
diff --git a/SConstruct b/SConstruct
index b47344b3..0c0f7725 100644
--- a/SConstruct
+++ b/SConstruct
@@ -146,6 +146,7 @@ libvmime_sources = [
'types.hpp',
'word.cpp', 'word.hpp',
'vmime.hpp',
+ 'utility/childProcess.hpp',
'utility/file.hpp',
'utility/datetimeUtils.cpp', 'utility/datetimeUtils.hpp',
'utility/filteredStream.cpp', 'utility/filteredStream.hpp',
@@ -245,6 +246,7 @@ libvmime_messaging_proto_sources = [
libvmime_platforms_sources = {
'posix':
[
+ 'platforms/posix/posixChildProcess.cpp', 'platforms/posix/posixChildProcess.hpp',
'platforms/posix/posixFile.cpp', 'platforms/posix/posixFile.hpp',
'platforms/posix/posixHandler.cpp', 'platforms/posix/posixHandler.hpp',
'platforms/posix/posixSocket.cpp', 'platforms/posix/posixSocket.hpp'
diff --git a/src/messaging/sendmail/sendmailTransport.cpp b/src/messaging/sendmail/sendmailTransport.cpp
index 87d1637f..1d4d2361 100644
--- a/src/messaging/sendmail/sendmailTransport.cpp
+++ b/src/messaging/sendmail/sendmailTransport.cpp
@@ -24,22 +24,14 @@
#include "vmime/message.hpp"
#include "vmime/mailboxList.hpp"
-#include "vmime/messaging/authHelper.hpp"
-
#include "vmime/utility/filteredStream.hpp"
+#include "vmime/utility/childProcess.hpp"
+#include "vmime/utility/smartPtr.hpp"
#if VMIME_BUILTIN_PLATFORM_POSIX
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/wait.h>
-
-
namespace vmime {
namespace messaging {
namespace sendmail {
@@ -138,204 +130,33 @@ void sendmailTransport::send
}
-static const string getSignalMessage(const int num)
-{
- switch (num)
- {
- case SIGHUP: return "SIGHUP";
- case SIGINT: return "SIGINT";
- case SIGQUIT: return "SIGQUIT";
- case SIGILL: return "SIGILL";
- case SIGABRT: return "SIGABRT";
- case SIGFPE: return "SIGFPE";
- case SIGKILL: return "SIGKILL";
- case SIGSEGV: return "SIGSEGV";
- case SIGPIPE: return "SIGPIPE";
- case SIGALRM: return "SIGALRM";
- case SIGTERM: return "SIGTERM";
- case SIGUSR1: return "SIGUSR1";
- case SIGUSR2: return "SIGUSR2";
- case SIGCHLD: return "SIGCHLD";
- case SIGCONT: return "SIGCONT";
- case SIGSTOP: return "SIGSTOP";
- case SIGTSTP: return "SIGTSTP";
- case SIGTTIN: return "SIGTTIN";
- case SIGTTOU: return "SIGTTOU";
- }
-
- return "(unknown)";
-}
-
-
-static const string getErrorMessage(const int num)
-{
-#ifdef strerror_r
- char res[256];
- res[0] = '\0';
-
- strerror_r(num, res, sizeof(res));
-
- return string(res);
-#else
- return string(strerror(num));
-#endif
-}
-
-
-
-#ifndef VMIME_BUILDING_DOC
-
-// Output stream adapter for UNIX pipe
-
-class outputStreamPipeAdapter : public utility::outputStream
-{
-public:
-
- outputStreamPipeAdapter(const int desc)
- : m_desc(desc)
- {
- }
-
- void write(const value_type* const data, const size_type count)
- {
- if (::write(m_desc, data, count) == -1)
- {
- const string errorMsg = getErrorMessage(errno);
- throw exceptions::system_error(errorMsg);
- }
- }
-
-private:
-
- int m_desc;
-};
-
-#endif // VMIME_BUILDING_DOC
-
-
-
-// The following code is highly inspired and adapted from the 'sendmail'
-// provider module in Evolution data server code.
-//
-// Original authors: Dan Winship <[email protected]>
-// Copyright 2000 Ximian, Inc. (www.ximian.com)
-
void sendmailTransport::internalSend
(const std::vector <string> args, utility::inputStream& is,
const utility::stream::size_type size, utility::progressionListener* progress)
{
- // Construct C-style argument array
- const char** argv = new const char*[args.size() + 2];
+ const utility::file::path path = vmime::platformDependant::getHandler()->
+ getFileSystemFactory()->stringToPath(m_sendmailPath);
- argv[0] = "sendmail";
- argv[args.size()] = NULL;
+ utility::auto_ptr <utility::childProcess> proc =
+ vmime::platformDependant::getHandler()->
+ getChildProcessFactory()->create(path);
- for (unsigned int i = 0 ; i < args.size() ; ++i)
- argv[i + 1] = args[i].c_str();
-
- // Create a pipe to communicate with sendmail
- int fd[2];
-
- if (pipe(fd) == -1)
- {
- throw exceptions::system_error(getErrorMessage(errno));
- }
-
- // Block SIGCHLD so the calling application doesn't notice
- // sendmail exiting before we do
- sigset_t mask, oldMask;
-
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &mask, &oldMask);
-
- // Spawn 'sendmail' process
- pid_t pid = fork();
-
- if (pid == -1) // error
- {
- const string errorMsg = getErrorMessage(errno);
-
- sigprocmask(SIG_SETMASK, &oldMask, NULL);
-
- close(fd[0]);
- close(fd[1]);
-
- throw exceptions::system_error(errorMsg);
- }
- else if (pid == 0) // child process
- {
- dup2(fd[0], STDIN_FILENO);
- close(fd[1]);
-
- execv(m_sendmailPath.c_str(), const_cast <char**>(argv));
- _exit(255);
- }
-
- close(fd[0]);
+ proc->start(args, utility::childProcess::FLAG_REDIRECT_STDIN);
// Copy message data from input stream to output pipe
- try
- {
- outputStreamPipeAdapter pos(fd[1]);
-
- // Workaround for lame sendmail implementations that
- // can't handle CRLF eoln sequences: we transform CRLF
- // sequences into LF characters.
- utility::CRLFToLFFilteredOutputStream fos(pos);
+ utility::outputStream& os = *(proc->getStdIn());
- // TODO: remove 'Bcc:' field from message header
+ // Workaround for lame sendmail implementations that
+ // can't handle CRLF eoln sequences: we transform CRLF
+ // sequences into LF characters.
+ utility::CRLFToLFFilteredOutputStream fos(os);
- utility::bufferedStreamCopy(is, fos, size, progress);
- }
- catch (exception& e)
- {
- close(fd[1]);
+ // TODO: remove 'Bcc:' field from message header
- int wstat;
-
- while (waitpid(pid, &wstat, 0) == -1 && errno == EINTR)
- ;
-
- sigprocmask(SIG_SETMASK, &oldMask, NULL);
-
- throw;
- }
-
- close(fd[1]);
+ utility::bufferedStreamCopy(is, fos, size, progress);
// Wait for sendmail to exit
- int wstat;
-
- while (waitpid(pid, &wstat, 0) == -1 && errno == EINTR)
- ;
-
- sigprocmask(SIG_SETMASK, &oldMask, NULL);
-
- if (!WIFEXITED(wstat))
- {
- throw exceptions::system_error("sendmail exited with signal "
- + getSignalMessage(WTERMSIG(wstat)) + ", mail not sent");
- }
- else if (WEXITSTATUS(wstat) != 0)
- {
- if (WEXITSTATUS(wstat) == 255)
- {
- std::ostringstream oss;
- oss << "Could not execute '" << m_sendmailPath;
- oss << "', mail not sent";
-
- throw exceptions::system_error(oss.str());
- }
- else
- {
- std::ostringstream oss;
- oss << "sendmail exited with status " << WEXITSTATUS(wstat);
- oss << ", mail not sent";
-
- throw exceptions::system_error(oss.str());
- }
- }
+ proc->waitForFinish();
}
diff --git a/src/platforms/posix/posixChildProcess.cpp b/src/platforms/posix/posixChildProcess.cpp
new file mode 100644
index 00000000..c44e1549
--- /dev/null
+++ b/src/platforms/posix/posixChildProcess.cpp
@@ -0,0 +1,383 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// This program 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 2 of
+// the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#include "vmime/platforms/posix/posixChildProcess.hpp"
+#include "vmime/platforms/posix/posixFile.hpp"
+
+#include "vmime/exception.hpp"
+
+#include "vmime/utility/smartPtr.hpp"
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+// posixChildProcessFactory
+
+utility::childProcess* posixChildProcessFactory::create(const utility::file::path& path) const
+{
+ return new posixChildProcess(path);
+}
+
+
+
+#ifndef VMIME_BUILDING_DOC
+
+
+// getPosixSignalMessage
+// Returns the name of a POSIX signal.
+
+static const string getPosixSignalMessage(const int num)
+{
+ switch (num)
+ {
+ case SIGHUP: return "SIGHUP";
+ case SIGINT: return "SIGINT";
+ case SIGQUIT: return "SIGQUIT";
+ case SIGILL: return "SIGILL";
+ case SIGABRT: return "SIGABRT";
+ case SIGFPE: return "SIGFPE";
+ case SIGKILL: return "SIGKILL";
+ case SIGSEGV: return "SIGSEGV";
+ case SIGPIPE: return "SIGPIPE";
+ case SIGALRM: return "SIGALRM";
+ case SIGTERM: return "SIGTERM";
+ case SIGUSR1: return "SIGUSR1";
+ case SIGUSR2: return "SIGUSR2";
+ case SIGCHLD: return "SIGCHLD";
+ case SIGCONT: return "SIGCONT";
+ case SIGSTOP: return "SIGSTOP";
+ case SIGTSTP: return "SIGTSTP";
+ case SIGTTIN: return "SIGTTIN";
+ case SIGTTOU: return "SIGTTOU";
+ }
+
+ return "(unknown)";
+}
+
+
+// getPosixErrorMessage
+// Returns a message corresponding to an error code.
+
+static const string getPosixErrorMessage(const int num)
+{
+#ifdef strerror_r
+ char res[256];
+ res[0] = '\0';
+
+ strerror_r(num, res, sizeof(res));
+
+ return string(res);
+#else
+ return string(strerror(num));
+#endif
+}
+
+
+// Output stream adapter for POSIX pipe
+
+class outputStreamPosixPipeAdapter : public utility::outputStream
+{
+public:
+
+ outputStreamPosixPipeAdapter(const int desc)
+ : m_desc(desc)
+ {
+ }
+
+ void write(const value_type* const data, const size_type count)
+ {
+ if (::write(m_desc, data, count) == -1)
+ {
+ const string errorMsg = getPosixErrorMessage(errno);
+ throw exceptions::system_error(errorMsg);
+ }
+ }
+
+private:
+
+ const int m_desc;
+};
+
+
+// Input stream adapter for POSIX pipe
+
+class inputStreamPosixPipeAdapter : public utility::inputStream
+{
+public:
+
+ inputStreamPosixPipeAdapter(const int desc)
+ : m_desc(desc)
+ {
+ }
+
+ const bool eof() const
+ {
+ return (m_eof);
+ }
+
+ void reset()
+ {
+ // Do nothing: unsupported
+ }
+
+ const size_type skip(const size_type count)
+ {
+ // TODO: not tested
+ value_type buffer[4096];
+
+ int bytesSkipped = 0;
+ int bytesRead = 0;
+
+ while ((bytesRead = ::read(m_desc, buffer,
+ std::min(sizeof(buffer), count - bytesSkipped))) != 0)
+ {
+ if (bytesRead == -1)
+ {
+ const string errorMsg = getPosixErrorMessage(errno);
+ throw exceptions::system_error(errorMsg);
+ }
+
+ bytesSkipped += bytesRead;
+ }
+
+ return static_cast <size_type>(bytesSkipped);
+ }
+
+ const size_type read(value_type* const data, const size_type count)
+ {
+ int bytesRead = 0;
+
+ if ((bytesRead = ::read(m_desc, data, count)) == -1)
+ {
+ const string errorMsg = getPosixErrorMessage(errno);
+ throw exceptions::system_error(errorMsg);
+ }
+
+ m_eof = (bytesRead == 0);
+
+ return static_cast <size_type>(bytesRead);
+ }
+
+private:
+
+ const int m_desc;
+
+ bool m_eof;
+};
+
+
+#endif // VMIME_BUILDING_DOC
+
+
+
+// posixChildProcess
+
+posixChildProcess::posixChildProcess(const utility::file::path& path)
+ : m_processPath(path), m_started(false),
+ m_stdIn(NULL), m_stdOut(NULL), m_pid(0)
+{
+ m_pipe[0] = 0;
+ m_pipe[1] = 0;
+
+ sigemptyset(&m_oldProcMask);
+}
+
+
+posixChildProcess::~posixChildProcess()
+{
+ if (m_started)
+ sigprocmask(SIG_SETMASK, &m_oldProcMask, NULL);
+
+ if (m_pipe[0] != 0)
+ close(m_pipe[0]);
+
+ if (m_pipe[1] != 0)
+ close(m_pipe[1]);
+
+ delete (m_stdIn);
+ delete (m_stdOut);
+}
+
+
+// The following code is highly inspired and adapted from the 'sendmail'
+// provider module in Evolution data server code.
+//
+// Original authors: Dan Winship <[email protected]>
+// Copyright 2000 Ximian, Inc. (www.ximian.com)
+
+void posixChildProcess::start(const std::vector <string> args, const int flags)
+{
+ if (m_started)
+ return;
+
+ // Construct C-style argument array
+ const char** argv = new const char*[args.size() + 2];
+
+ argv[0] = m_processPath.getLastComponent().getBuffer().c_str();
+ argv[args.size()] = NULL;
+
+ for (unsigned int i = 0 ; i < args.size() ; ++i)
+ argv[i + 1] = args[i].c_str();
+
+ // Create a pipe to communicate with the child process
+ int fd[2];
+
+ if (pipe(fd) == -1)
+ {
+ throw exceptions::system_error(getPosixErrorMessage(errno));
+ }
+
+ m_pipe[0] = fd[0];
+ m_pipe[1] = fd[1];
+
+ // Block SIGCHLD so the calling application doesn't notice
+ // process exiting before we do
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &mask, &m_oldProcMask);
+
+ // Spawn process
+ const pid_t pid = fork();
+
+ if (pid == -1) // error
+ {
+ const string errorMsg = getPosixErrorMessage(errno);
+
+ sigprocmask(SIG_SETMASK, &m_oldProcMask, NULL);
+
+ close(fd[0]);
+ close(fd[1]);
+
+ throw exceptions::system_error(errorMsg);
+ }
+ else if (pid == 0) // child process
+ {
+ if (flags & FLAG_REDIRECT_STDIN)
+ dup2(fd[0], STDIN_FILENO);
+ else
+ close(fd[0]);
+
+ if (flags & FLAG_REDIRECT_STDOUT)
+ dup2(fd[1], STDOUT_FILENO);
+ else
+ close(fd[1]);
+
+ posixFileSystemFactory* pfsf = new posixFileSystemFactory();
+
+ const string path = pfsf->pathToString(m_processPath);
+
+ delete (pfsf);
+
+ execv(path.c_str(), const_cast <char**>(argv));
+ _exit(255);
+ }
+
+ if (flags & FLAG_REDIRECT_STDIN)
+ {
+ m_stdIn = new outputStreamPosixPipeAdapter(m_pipe[1]);
+ }
+ else
+ {
+ close(m_pipe[1]);
+ m_pipe[1] = 0;
+ }
+
+ if (flags & FLAG_REDIRECT_STDOUT)
+ {
+ m_stdOut = new inputStreamPosixPipeAdapter(m_pipe[0]);
+ }
+ else
+ {
+ close(m_pipe[0]);
+ m_pipe[0] = 0;
+ }
+
+ m_pid = pid;
+ m_started = true;
+}
+
+
+utility::outputStream* posixChildProcess::getStdIn()
+{
+ return (m_stdIn);
+}
+
+
+utility::inputStream* posixChildProcess::getStdOut()
+{
+ return (m_stdOut);
+}
+
+
+void posixChildProcess::waitForFinish()
+{
+ // Close stdin pipe
+ if (m_pipe[1] != 0)
+ {
+ close(m_pipe[1]);
+ m_pipe[1] = 0;
+ }
+
+ int wstat;
+
+ while (waitpid(m_pid, &wstat, 0) == -1 && errno == EINTR)
+ ;
+
+ if (!WIFEXITED(wstat))
+ {
+ throw exceptions::system_error("Process exited with signal "
+ + getPosixSignalMessage(WTERMSIG(wstat)));
+ }
+ else if (WEXITSTATUS(wstat) != 0)
+ {
+ if (WEXITSTATUS(wstat) == 255)
+ {
+ vmime::utility::auto_ptr <posixFileSystemFactory> pfsf
+ = new posixFileSystemFactory();
+
+ throw exceptions::system_error("Could not execute '"
+ + pfsf->pathToString(m_processPath) + "'");
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << "Process exited with status " << WEXITSTATUS(wstat);
+
+ throw exceptions::system_error(oss.str());
+ }
+ }
+}
+
+
+} // posix
+} // platforms
+} // vmime
+
diff --git a/src/platforms/posix/posixHandler.cpp b/src/platforms/posix/posixHandler.cpp
index c95d6f0e..cd7f35fa 100644
--- a/src/platforms/posix/posixHandler.cpp
+++ b/src/platforms/posix/posixHandler.cpp
@@ -46,6 +46,7 @@ posixHandler::posixHandler()
#endif
#if VMIME_HAVE_FILESYSTEM_FEATURES
m_fileSysFactory = new posixFileSystemFactory();
+ m_childProcFactory = new posixChildProcessFactory();
#endif
}
@@ -57,6 +58,7 @@ posixHandler::~posixHandler()
#endif
#if VMIME_HAVE_FILESYSTEM_FEATURES
delete (m_fileSysFactory);
+ delete (m_childProcFactory);
#endif
}
@@ -188,6 +190,12 @@ vmime::utility::fileSystemFactory* posixHandler::getFileSystemFactory() const
return (m_fileSysFactory);
}
+
+vmime::utility::childProcessFactory* posixHandler::getChildProcessFactory() const
+{
+ return (m_childProcFactory);
+}
+
#endif
diff --git a/src/platforms/windows/windowsHandler.cpp b/src/platforms/windows/windowsHandler.cpp
index bbdcc1b6..36741d25 100644
--- a/src/platforms/windows/windowsHandler.cpp
+++ b/src/platforms/windows/windowsHandler.cpp
@@ -257,6 +257,13 @@ vmime::utility::fileSystemFactory* windowsHandler::getFileSystemFactory() const
return (m_fileSysFactory);
}
+
+vmime::utility::childProcessFactory* windowsHandler::getChildProcessFactory() const
+{
+ // TODO: Not implemented
+ return (NULL);
+}
+
#endif
diff --git a/vmime/platformDependant.hpp b/vmime/platformDependant.hpp
index 673ff5ef..b6de8e76 100644
--- a/vmime/platformDependant.hpp
+++ b/vmime/platformDependant.hpp
@@ -33,6 +33,7 @@
#if VMIME_HAVE_FILESYSTEM_FEATURES
#include "vmime/utility/file.hpp"
+ #include "vmime/utility/childProcess.hpp"
#endif
@@ -126,8 +127,20 @@ public:
virtual messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const string& name = "default") const = 0;
#endif
#if VMIME_HAVE_FILESYSTEM_FEATURES
+ /** Return a pointer to a factory that creates file-system objects.
+ *
+ * @return file-system factory
+ */
virtual utility::fileSystemFactory* getFileSystemFactory() const = 0;
+
+ /** Return a pointer to a factory that creates child process objects,
+ * which are used to spawn processes (run executable files).
+ *
+ * @return child process factory
+ */
+ virtual utility::childProcessFactory* getChildProcessFactory() const = 0;
#endif
+
};
diff --git a/vmime/platforms/posix/posixChildProcess.hpp b/vmime/platforms/posix/posixChildProcess.hpp
new file mode 100644
index 00000000..96d50d5a
--- /dev/null
+++ b/vmime/platforms/posix/posixChildProcess.hpp
@@ -0,0 +1,74 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// This program 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 2 of
+// the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+
+#ifndef VMIME_PLATFORMS_POSIX_POSIXCHILDPROCESS_HPP_INCLUDED
+#define VMIME_PLATFORMS_POSIX_POSIXCHILDPROCESS_HPP_INCLUDED
+
+
+#include "vmime/utility/childProcess.hpp"
+
+
+namespace vmime {
+namespace platforms {
+namespace posix {
+
+
+class posixChildProcess : public utility::childProcess
+{
+public:
+
+ posixChildProcess(const utility::file::path& path);
+ ~posixChildProcess();
+
+ void start(const std::vector <string> args, const int flags = 0);
+
+ utility::outputStream* getStdIn();
+ utility::inputStream* getStdOut();
+
+ void waitForFinish();
+
+private:
+
+ utility::file::path m_processPath;
+ bool m_started;
+
+ utility::outputStream* m_stdIn;
+ utility::inputStream* m_stdOut;
+
+ sigset_t m_oldProcMask;
+ pid_t m_pid;
+ int m_pipe[2];
+};
+
+
+class posixChildProcessFactory : public utility::childProcessFactory
+{
+public:
+
+ utility::childProcess* create(const utility::file::path& path) const;
+};
+
+
+} // posix
+} // platforms
+} // vmime
+
+
+#endif // VMIME_PLATFORMS_POSIX_POSIXCHILDPROCESS_HPP_INCLUDED
+
diff --git a/vmime/platforms/posix/posixHandler.hpp b/vmime/platforms/posix/posixHandler.hpp
index ff4b7e97..62500d9a 100644
--- a/vmime/platforms/posix/posixHandler.hpp
+++ b/vmime/platforms/posix/posixHandler.hpp
@@ -30,6 +30,7 @@
#if VMIME_HAVE_FILESYSTEM_FEATURES
#include "vmime/platforms/posix/posixFile.hpp"
+ #include "vmime/platforms/posix/posixChildProcess.hpp"
#endif
@@ -63,6 +64,8 @@ public:
#if VMIME_HAVE_FILESYSTEM_FEATURES
vmime::utility::fileSystemFactory* getFileSystemFactory() const;
+
+ vmime::utility::childProcessFactory* getChildProcessFactory() const;
#endif
void wait() const;
@@ -75,6 +78,7 @@ private:
#if VMIME_HAVE_FILESYSTEM_FEATURES
posixFileSystemFactory* m_fileSysFactory;
+ posixChildProcessFactory* m_childProcFactory;
#endif
};
diff --git a/vmime/platforms/windows/windowsHandler.hpp b/vmime/platforms/windows/windowsHandler.hpp
index 7db854b7..0f2c5b88 100644
--- a/vmime/platforms/windows/windowsHandler.hpp
+++ b/vmime/platforms/windows/windowsHandler.hpp
@@ -29,7 +29,7 @@
#endif
#if VMIME_HAVE_FILESYSTEM_FEATURES
- #include "vmime/platforms/windows/windowsFile.hpp"
+ #include "vmime/platforms/windows/windowsFile.hpp"
#endif
@@ -63,6 +63,8 @@ public:
#if VMIME_HAVE_FILESYSTEM_FEATURES
vmime::utility::fileSystemFactory* getFileSystemFactory() const;
+
+ vmime::utility::childProcessFactory* getChildProcessFactory() const;
#endif
void wait() const;