You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2015/07/31 01:25:24 UTC

[1/4] mesos git commit: Header splitting continued (os/*.hpp).

Repository: mesos
Updated Branches:
  refs/heads/master 8661672d8 -> 5aa050bfa


http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/read.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/read.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/read.hpp
new file mode 100644
index 0000000..abde7a4
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/read.hpp
@@ -0,0 +1,129 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_READ_HPP__
+#define __STOUT_OS_POSIX_READ_HPP__
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <string>
+
+#ifdef __sun
+#include <fstream>
+#endif // __sun
+
+#include <stout/error.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+// Reads 'size' bytes from a file from its current offset.
+// If EOF is encountered before reading 'size' bytes then the result
+// will contain the bytes read and a subsequent read will return None.
+inline Result<std::string> read(int fd, size_t size)
+{
+  char* buffer = new char[size];
+  size_t offset = 0;
+
+  while (offset < size) {
+    ssize_t length = ::read(fd, buffer + offset, size - offset);
+
+    if (length < 0) {
+      // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
+      if (errno == EINTR) {
+        continue;
+      }
+      ErrnoError error; // Constructed before 'delete' to capture errno.
+      delete[] buffer;
+      return error;
+    } else if (length == 0) {
+      // Reached EOF before expected! Only return as much data as
+      // available or None if we haven't read anything yet.
+      if (offset > 0) {
+        std::string result(buffer, offset);
+        delete[] buffer;
+        return result;
+      }
+      delete[] buffer;
+      return None();
+    }
+
+    offset += length;
+  }
+
+  std::string result(buffer, size);
+  delete[] buffer;
+  return result;
+}
+
+
+// Returns the contents of the file.
+#ifdef __sun // getline is not available on Solaris, using STL.
+inline Try<std::string> read(const std::string& path)
+{
+  std::ifstream ifs(path.c_str());
+  if (!ifs.is_open())
+  {
+    return ErrnoError("Failed to open file '" + path + "'");
+  }
+  return std::string((std::istreambuf_iterator<char>(ifs)),
+                     (std::istreambuf_iterator<char>()));
+}
+#else
+inline Try<std::string> read(const std::string& path)
+{
+  FILE* file = fopen(path.c_str(), "r");
+  if (file == NULL) {
+    return ErrnoError("Failed to open file '" + path + "'");
+  }
+
+  // Initially the 'line' is NULL and length 0, getline() allocates
+  // ('malloc') a buffer for reading the line.
+  // In subsequent iterations, if the buffer is not large enough to
+  // hold the line, getline() resizes it with 'realloc' and updates
+  // 'line' and 'length' as necessary. See:
+  // - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html
+  // - http://man7.org/linux/man-pages/man3/getline.3.html
+  std::string result;
+  char* line = NULL;
+  size_t length = 0;
+  ssize_t read;
+
+  while ((read = getline(&line, &length, file)) != -1) {
+    result.append(line, read);
+  }
+
+  // getline() requires the line buffer to be freed by the caller.
+  free(line);
+
+  if (ferror(file)) {
+    ErrnoError error;
+    // NOTE: We ignore the error from fclose(). This is because
+    // users calling this function are interested in the return value
+    // of read(). Also an unsuccessful fclose() does not affect the
+    // read.
+    fclose(file);
+    return error;
+  }
+
+  fclose(file);
+  return result;
+}
+#endif // __sun
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_READ_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/sendfile.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/sendfile.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/sendfile.hpp
new file mode 100644
index 0000000..50ad49e
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/sendfile.hpp
@@ -0,0 +1,65 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_SENDFILE_HPP__
+#define __STOUT_OS_POSIX_SENDFILE_HPP__
+
+#include <errno.h>
+
+#if defined(__linux__) || defined(__sun)
+#include <sys/sendfile.h>
+#endif
+#ifdef __APPLE__
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#endif // __APPLE__
+
+#include <stout/os/signals.hpp>
+#include <stout/unreachable.hpp>
+
+namespace os {
+
+// Returns the amount of bytes written from the input file
+// descriptor to the output socket. On error, returns -1 and
+// errno indicates the error.
+// NOTE: The following limitations exist because of the OS X
+// implementation of sendfile:
+//   1. s must be a stream oriented socket descriptor.
+//   2. fd must be a regular file descriptor.
+inline ssize_t sendfile(int s, int fd, off_t offset, size_t length)
+{
+#if defined(__linux__) || defined(__sun)
+  suppress (SIGPIPE) {
+    // This will set errno to EPIPE if a SIGPIPE occurs.
+    return ::sendfile(s, fd, &offset, length);
+  }
+  UNREACHABLE();
+#elif defined __APPLE__
+  // On OS X, sendfile does not need to have SIGPIPE suppressed.
+  off_t _length = static_cast<off_t>(length);
+
+  if (::sendfile(fd, s, offset, &_length, NULL, 0) < 0) {
+    if (errno == EAGAIN && _length > 0) {
+      return _length;
+    }
+    return -1;
+  }
+
+  return _length;
+#endif // __APPLE__
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_SENDFILE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/shell.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/shell.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/shell.hpp
new file mode 100644
index 0000000..53f14e1
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/shell.hpp
@@ -0,0 +1,76 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_SHELL_HPP__
+#define __STOUT_OS_POSIX_SHELL_HPP__
+
+#include <stdarg.h> // For va_list, va_start, etc.
+#include <stdio.h> // For ferror, fgets, FILE, pclose, popen.
+
+#include <ostream>
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/format.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+// Runs a shell command formatted with varargs and return the return value
+// of the command. Optionally, the output is returned via an argument.
+// TODO(vinod): Pass an istream object that can provide input to the command.
+inline Try<int> shell(std::ostream* os, const std::string fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+
+  const Try<std::string> command = strings::internal::format(fmt, args);
+
+  va_end(args);
+
+  if (command.isError()) {
+    return Error(command.error());
+  }
+
+  FILE* file;
+
+  if ((file = popen(command.get().c_str(), "r")) == NULL) {
+    return Error("Failed to run '" + command.get() + "'");
+  }
+
+  char line[1024];
+  // NOTE(vinod): Ideally the if and while loops should be interchanged. But
+  // we get a broken pipe error if we don't read the output and simply close.
+  while (fgets(line, sizeof(line), file) != NULL) {
+    if (os != NULL) {
+      *os << line;
+    }
+  }
+
+  if (ferror(file) != 0) {
+    pclose(file); // Ignoring result since we already have an error.
+    return Error("Error reading output of '" + command.get() + "'");
+  }
+
+  int status;
+  if ((status = pclose(file)) == -1) {
+    return Error("Failed to get status of '" + command.get() + "'");
+  }
+
+  return status;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_SHELL_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/signals.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/signals.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/signals.hpp
new file mode 100644
index 0000000..420d5bb
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/signals.hpp
@@ -0,0 +1,185 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_SIGNALS_HPP__
+#define __STOUT_OS_POSIX_SIGNALS_HPP__
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+
+namespace os {
+
+namespace signals {
+
+// Installs the given signal handler.
+inline int install(int signal, void(*handler)(int))
+{
+  struct sigaction action;
+  memset(&action, 0, sizeof(action));
+  sigemptyset(&action.sa_mask);
+  action.sa_handler = handler;
+  return sigaction(signal, &action, NULL);
+}
+
+
+// Resets the signal handler to the default handler of the signal.
+inline int reset(int signal)
+{
+  struct sigaction action;
+  memset(&action, 0, sizeof(action));
+  sigemptyset(&action.sa_mask);
+  action.sa_handler = SIG_DFL;
+  return sigaction(signal, &action, NULL);
+}
+
+
+// Returns true iff the signal is pending.
+inline bool pending(int signal)
+{
+  sigset_t set;
+  sigemptyset(&set);
+  sigpending(&set);
+  return sigismember(&set, signal);
+}
+
+
+// Returns true if the signal has been blocked, or false if the
+// signal was already blocked.
+inline bool block(int signal)
+{
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, signal);
+
+  sigset_t oldset;
+  sigemptyset(&oldset);
+
+  // We ignore errors here as the only documented one is
+  // EINVAL due to a bad value of the SIG_* argument.
+  pthread_sigmask(SIG_BLOCK, &set, &oldset);
+
+  return !sigismember(&oldset, signal);
+}
+
+
+// Returns true if the signal has been unblocked, or false if the
+// signal was not previously blocked.
+inline bool unblock(int signal)
+{
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, signal);
+
+  sigset_t oldset;
+  sigemptyset(&oldset);
+
+  pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
+
+  return sigismember(&oldset, signal);
+}
+
+namespace internal {
+
+// Suppresses a signal on the current thread for the lifetime of
+// the Suppressor. The signal *must* be synchronous and delivered
+// per-thread. The suppression occurs only on the thread of
+// execution of the Suppressor.
+struct Suppressor
+{
+  Suppressor(int _signal)
+    : signal(_signal), pending(false), unblock(false)
+  {
+    // Check to see if the signal is already reported as pending.
+    // If pending, it means the thread already blocks the signal!
+    // Therefore, any new instances of the signal will also be
+    // blocked and merged with the pending one since there is no
+    // queuing for signals.
+    pending = signals::pending(signal);
+
+    if (!pending) {
+      // Block the signal for this thread only. If already blocked,
+      // there's no need to unblock it.
+      unblock = signals::block(signal);
+    }
+  }
+
+  ~Suppressor()
+  {
+    // We want to preserve errno when the Suppressor drops out of
+    // scope. Otherwise, one needs to potentially store errno when
+    // using the suppress() macro.
+    int _errno = errno;
+
+    // If the signal has become pending after we blocked it, we
+    // need to clear it before unblocking it.
+    if (!pending && signals::pending(signal)) {
+      // It is possible that in between having observed the pending
+      // signal with sigpending() and clearing it with sigwait(),
+      // the signal was delivered to another thread before we were
+      // able to clear it here. This can happen if the signal was
+      // generated for the whole process (e.g. a kill was issued).
+      // See 2.4.1 here:
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
+      // To handle the above scenario, one can either:
+      //   1. Use sigtimedwait() with a timeout of 0, to ensure we
+      //      don't block forever. However, this only works on Linux
+      //      and we may still swallow the signal intended for the
+      //      process.
+      //   2. After seeing the pending signal, signal ourselves with
+      //      pthread_kill prior to calling sigwait(). This can still
+      //      swallow the signal intended for the process.
+      // We chose to use the latter technique as it works on all
+      // POSIX systems and is less likely to swallow process signals,
+      // provided the thread signal and process signal are not merged.
+      pthread_kill(pthread_self(), signal);
+
+      sigset_t mask;
+      sigemptyset(&mask);
+      sigaddset(&mask, signal);
+
+      int result;
+      do {
+        int _ignored;
+        result = sigwait(&mask, &_ignored);
+      } while (result == -1 && errno == EINTR);
+    }
+
+    // Unblock the signal (only if we were the ones to block it).
+    if (unblock) {
+      signals::unblock(signal);
+    }
+
+    // Restore errno.
+    errno = _errno;
+  }
+
+  // Needed for the suppress() macro.
+  operator bool () { return true; }
+
+private:
+  const int signal;
+  bool pending; // Whether the signal is already pending.
+  bool unblock; // Whether to unblock the signal on destruction.
+};
+
+} // namespace internal {
+
+} // namespace signals {
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_SIGNALS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/stat.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/stat.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/stat.hpp
new file mode 100644
index 0000000..c7084f1
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/stat.hpp
@@ -0,0 +1,160 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_STAT_HPP__
+#define __STOUT_OS_POSIX_STAT_HPP__
+
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+
+#include <string>
+
+#include <stout/bytes.hpp>
+#include <stout/try.hpp>
+#include <stout/unreachable.hpp>
+
+
+namespace os {
+
+namespace stat {
+
+inline bool isdir(const std::string& path)
+{
+  struct stat s;
+
+  if (::stat(path.c_str(), &s) < 0) {
+    return false;
+  }
+  return S_ISDIR(s.st_mode);
+}
+
+
+inline bool isfile(const std::string& path)
+{
+  struct stat s;
+
+  if (::stat(path.c_str(), &s) < 0) {
+    return false;
+  }
+  return S_ISREG(s.st_mode);
+}
+
+
+inline bool islink(const std::string& path)
+{
+  struct stat s;
+
+  if (::lstat(path.c_str(), &s) < 0) {
+    return false;
+  }
+  return S_ISLNK(s.st_mode);
+}
+
+
+// Describes the different semantics supported for the implementation
+// of `size` defined below.
+enum FollowSymlink
+{
+  DO_NOT_FOLLOW_SYMLINK,
+  FOLLOW_SYMLINK
+};
+
+
+// Returns the size in Bytes of a given file system entry. When
+// applied to a symbolic link with `follow` set to
+// `DO_NOT_FOLLOW_SYMLINK`, this will return the length of the entry
+// name (strlen).
+inline Try<Bytes> size(
+    const std::string& path,
+    const FollowSymlink follow = FOLLOW_SYMLINK)
+{
+  struct stat s;
+
+  switch (follow) {
+    case DO_NOT_FOLLOW_SYMLINK: {
+      if (::lstat(path.c_str(), &s) < 0) {
+        return ErrnoError("Error invoking lstat for '" + path + "'");
+      }
+      break;
+    }
+    case FOLLOW_SYMLINK: {
+      if (::stat(path.c_str(), &s) < 0) {
+        return ErrnoError("Error invoking stat for '" + path + "'");
+      }
+      break;
+    }
+    default: {
+      UNREACHABLE();
+    }
+  }
+
+  return Bytes(s.st_size);
+}
+
+
+inline Try<long> mtime(const std::string& path)
+{
+  struct stat s;
+
+  if (::lstat(path.c_str(), &s) < 0) {
+    return ErrnoError("Error invoking stat for '" + path + "'");
+  }
+
+  return s.st_mtime;
+}
+
+
+inline Try<mode_t> mode(const std::string& path)
+{
+  struct stat s;
+
+  if (::stat(path.c_str(), &s) < 0) {
+    return ErrnoError("Error invoking stat for '" + path + "'");
+  }
+
+  return s.st_mode;
+}
+
+
+inline Try<dev_t> rdev(const std::string& path)
+{
+  struct stat s;
+
+  if (::stat(path.c_str(), &s) < 0) {
+    return ErrnoError("Error invoking stat for '" + path + "'");
+  }
+
+  if (!S_ISCHR(s.st_mode) && !S_ISBLK(s.st_mode)) {
+    return Error("Not a special file: " + path);
+  }
+
+  return s.st_rdev;
+}
+
+
+inline Try<ino_t> inode(const std::string& path)
+{
+  struct stat s;
+
+  if (::stat(path.c_str(), &s) < 0) {
+    return ErrnoError("Error invoking stat for '" + path + "'");
+  }
+
+  return s.st_ino;
+}
+
+} // namespace stat {
+
+} // namespace os {
+
+#endif // __STOUT_OS_STAT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/process.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/process.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/process.hpp
index 26f4fbe..204acaf 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/process.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/process.hpp
@@ -14,166 +14,14 @@
 #ifndef __STOUT_OS_PROCESS_HPP__
 #define __STOUT_OS_PROCESS_HPP__
 
-#include <sys/types.h> // For pid_t.
 
-#include <list>
-#include <ostream>
-#include <sstream>
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/process.hpp>
+#else
+#include <stout/os/posix/process.hpp>
+#endif // __WINDOWS__
 
-#include <stout/bytes.hpp>
-#include <stout/duration.hpp>
-#include <stout/none.hpp>
-#include <stout/option.hpp>
-#include <stout/strings.hpp>
-
-namespace os {
-
-struct Process
-{
-  Process(pid_t _pid,
-          pid_t _parent,
-          pid_t _group,
-          const Option<pid_t>& _session,
-          const Option<Bytes>& _rss,
-          const Option<Duration>& _utime,
-          const Option<Duration>& _stime,
-          const std::string& _command,
-          bool _zombie)
-    : pid(_pid),
-      parent(_parent),
-      group(_group),
-      session(_session),
-      rss(_rss),
-      utime(_utime),
-      stime(_stime),
-      command(_command),
-      zombie(_zombie) {}
-
-  const pid_t pid;
-  const pid_t parent;
-  const pid_t group;
-  const Option<pid_t> session;
-  const Option<Bytes> rss;
-  const Option<Duration> utime;
-  const Option<Duration> stime;
-  const std::string command;
-  const bool zombie;
-
-  // TODO(bmahler): Add additional data as needed.
-
-  bool operator <  (const Process& p) const { return pid <  p.pid; }
-  bool operator <= (const Process& p) const { return pid <= p.pid; }
-  bool operator >  (const Process& p) const { return pid >  p.pid; }
-  bool operator >= (const Process& p) const { return pid >= p.pid; }
-  bool operator == (const Process& p) const { return pid == p.pid; }
-  bool operator != (const Process& p) const { return pid != p.pid; }
-};
-
-
-class ProcessTree
-{
-public:
-  // Returns a process subtree rooted at the specified PID, or none if
-  // the specified pid could not be found in this process tree.
-  Option<ProcessTree> find(pid_t pid) const
-  {
-    if (process.pid == pid) {
-      return *this;
-    }
-
-    foreach (const ProcessTree& tree, children) {
-      Option<ProcessTree> option = tree.find(pid);
-      if (option.isSome()) {
-        return option;
-      }
-    }
-
-    return None();
-  }
-
-  // Checks if the specified pid is contained in this process tree.
-  bool contains(pid_t pid) const
-  {
-    return find(pid).isSome();
-  }
-
-  operator Process () const
-  {
-    return process;
-  }
-
-  operator pid_t () const
-  {
-    return process.pid;
-  }
-
-  const Process process;
-  const std::list<ProcessTree> children;
-
-private:
-  friend struct Fork;
-  friend Try<ProcessTree> pstree(pid_t, const std::list<Process>&);
-
-  ProcessTree(
-      const Process& _process,
-      const std::list<ProcessTree>& _children)
-    : process(_process),
-      children(_children) {}
-};
-
-
-inline std::ostream& operator << (
-    std::ostream& stream,
-    const ProcessTree& tree)
-{
-  if (tree.children.empty()) {
-    stream << "--- " << tree.process.pid << " ";
-    if (tree.process.zombie) {
-      stream << "(" << tree.process.command << ")";
-    } else {
-      stream << tree.process.command;
-    }
-  } else {
-    stream << "-+- " << tree.process.pid << " ";
-    if (tree.process.zombie) {
-      stream << "(" << tree.process.command << ")";
-    } else {
-      stream << tree.process.command;
-    }
-    size_t size = tree.children.size();
-    foreach (const ProcessTree& child, tree.children) {
-      std::ostringstream out;
-      out << child;
-      stream << "\n";
-      if (--size != 0) {
-        stream << " |" << strings::replace(out.str(), "\n", "\n |");
-      } else {
-        stream << " \\" << strings::replace(out.str(), "\n", "\n  ");
-      }
-    }
-  }
-  return stream;
-}
-
-} // namespace os {
-
-
-// An overload of stringify for printing a list of process trees
-// (since printing a process tree is rather particular).
-inline std::string stringify(const std::list<os::ProcessTree>& list)
-{
-  std::ostringstream out;
-  out << "[ " << std::endl;
-  std::list<os::ProcessTree>::const_iterator iterator = list.begin();
-  while (iterator != list.end()) {
-    out << stringify(*iterator);
-    if (++iterator != list.end()) {
-      out << std::endl << std::endl;
-    }
-  }
-  out << std::endl << "]";
-  return out.str();
-}
 
 #endif // __STOUT_OS_PROCESS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/pstree.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/pstree.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/pstree.hpp
index ba8e579..9baa2fb 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/pstree.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/pstree.hpp
@@ -14,119 +14,14 @@
 #ifndef __STOUT_OS_PSTREE_HPP__
 #define __STOUT_OS_PSTREE_HPP__
 
-#include <list>
-#include <set>
 
-#include <stout/error.hpp>
-#include <stout/foreach.hpp>
-#include <stout/none.hpp>
-#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/pstree.hpp>
+#else
+#include <stout/os/posix/pstree.hpp>
+#endif // __WINDOWS__
 
-#include <stout/os/process.hpp>
-
-namespace os {
-
-// Forward declaration.
-inline Try<std::list<Process> > processes();
-
-
-// Returns a process tree rooted at the specified pid using the
-// specified list of processes (or an error if one occurs).
-inline Try<ProcessTree> pstree(
-    pid_t pid,
-    const std::list<Process>& processes)
-{
-  std::list<ProcessTree> children;
-  foreach (const Process& process, processes) {
-    if (process.parent == pid) {
-      Try<ProcessTree> tree = pstree(process.pid, processes);
-      if (tree.isError()) {
-        return Error(tree.error());
-      }
-      children.push_back(tree.get());
-    }
-  }
-
-  foreach (const Process& process, processes) {
-    if (process.pid == pid) {
-      return ProcessTree(process, children);
-    }
-  }
-
-  return Error("No process found at " + stringify(pid));
-}
-
-
-// Returns a process tree for the specified pid (or all processes if
-// pid is none or the current process if pid is 0).
-inline Try<ProcessTree> pstree(Option<pid_t> pid = None())
-{
-  if (pid.isNone()) {
-    pid = 1;
-  } else if (pid.get() == 0) {
-    pid = getpid();
-  }
-
-  const Try<std::list<Process>> processes = os::processes();
-
-  if (processes.isError()) {
-    return Error(processes.error());
-  }
-
-  return pstree(pid.get(), processes.get());
-}
-
-
-// Returns the minimum list of process trees that include all of the
-// specified pids using the specified list of processes.
-inline Try<std::list<ProcessTree> > pstrees(
-    const std::set<pid_t>& pids,
-    const std::list<Process>& processes)
-{
-  std::list<ProcessTree> trees;
-
-  foreach (pid_t pid, pids) {
-    // First, check if the pid is already connected to one of the
-    // process trees we've constructed.
-    bool disconnected = true;
-    foreach (const ProcessTree& tree, trees) {
-      if (tree.contains(pid)) {
-        disconnected = false;
-        break;
-      }
-    }
-
-    if (disconnected) {
-      Try<ProcessTree> tree = pstree(pid, processes);
-      if (tree.isError()) {
-        return Error(tree.error());
-      }
-
-      // Now see if any of the existing process trees are actually
-      // contained within the process tree we just created and only
-      // include the disjoint process trees.
-      // C++11:
-      // trees = trees.filter([](const ProcessTree& t) {
-      //   return tree.get().contains(t);
-      // });
-      std::list<ProcessTree> trees_ = trees;
-      trees.clear();
-      foreach (const ProcessTree& t, trees_) {
-        if (tree.get().contains(t.process.pid)) {
-          continue;
-        }
-        trees.push_back(t);
-      }
-      trees.push_back(tree.get());
-    }
-  }
-
-  return trees;
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_PSTREE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/read.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/read.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/read.hpp
index fed005e..d5698a5 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/read.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/read.hpp
@@ -14,115 +14,14 @@
 #ifndef __STOUT_OS_READ_HPP__
 #define __STOUT_OS_READ_HPP__
 
-#include <stdio.h>
-#include <unistd.h>
 
-#include <string>
-
-#ifdef __sun
-#include <fstream>
-#endif // __sun
-
-#include <stout/error.hpp>
-#include <stout/result.hpp>
-#include <stout/try.hpp>
-
-namespace os {
-
-// Reads 'size' bytes from a file from its current offset.
-// If EOF is encountered before reading 'size' bytes then the result
-// will contain the bytes read and a subsequent read will return None.
-inline Result<std::string> read(int fd, size_t size)
-{
-  char* buffer = new char[size];
-  size_t offset = 0;
-
-  while (offset < size) {
-    ssize_t length = ::read(fd, buffer + offset, size - offset);
-
-    if (length < 0) {
-      // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
-      if (errno == EINTR) {
-        continue;
-      }
-      ErrnoError error; // Constructed before 'delete' to capture errno.
-      delete[] buffer;
-      return error;
-    } else if (length == 0) {
-      // Reached EOF before expected! Only return as much data as
-      // available or None if we haven't read anything yet.
-      if (offset > 0) {
-        std::string result(buffer, offset);
-        delete[] buffer;
-        return result;
-      }
-      delete[] buffer;
-      return None();
-    }
-
-    offset += length;
-  }
-
-  std::string result(buffer, size);
-  delete[] buffer;
-  return result;
-}
-
-
-// Returns the contents of the file.
-#ifdef __sun // getline is not available on Solaris, using STL.
-inline Try<std::string> read(const std::string& path)
-{
-  std::ifstream ifs(path.c_str());
-  if (!ifs.is_open())
-  {
-    return ErrnoError("Failed to open file '" + path + "'");
-  }
-  return std::string((std::istreambuf_iterator<char>(ifs)),
-                     (std::istreambuf_iterator<char>()));
-}
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/read.hpp>
 #else
-inline Try<std::string> read(const std::string& path)
-{
-  FILE* file = fopen(path.c_str(), "r");
-  if (file == NULL) {
-    return ErrnoError("Failed to open file '" + path + "'");
-  }
-
-  // Initially the 'line' is NULL and length 0, getline() allocates
-  // ('malloc') a buffer for reading the line.
-  // In subsequent iterations, if the buffer is not large enough to
-  // hold the line, getline() resizes it with 'realloc' and updates
-  // 'line' and 'length' as necessary. See:
-  // - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html
-  // - http://man7.org/linux/man-pages/man3/getline.3.html
-  std::string result;
-  char* line = NULL;
-  size_t length = 0;
-  ssize_t read;
-
-  while ((read = getline(&line, &length, file)) != -1) {
-    result.append(line, read);
-  }
-
-  // getline() requires the line buffer to be freed by the caller.
-  free(line);
-
-  if (ferror(file)) {
-    ErrnoError error;
-    // NOTE: We ignore the error from fclose(). This is because
-    // users calling this function are interested in the return value
-    // of read(). Also an unsuccessful fclose() does not affect the
-    // read.
-    fclose(file);
-    return error;
-  }
-
-  fclose(file);
-  return result;
-}
-#endif // __sun
+#include <stout/os/posix/read.hpp>
+#endif // __WINDOWS__
 
-} // namespace os {
 
 #endif // __STOUT_OS_READ_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/sendfile.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/sendfile.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/sendfile.hpp
index 4485e41..580df06 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/sendfile.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/sendfile.hpp
@@ -14,52 +14,14 @@
 #ifndef __STOUT_OS_SENDFILE_HPP__
 #define __STOUT_OS_SENDFILE_HPP__
 
-#include <errno.h>
 
-#if defined(__linux__) || defined(__sun)
-#include <sys/sendfile.h>
-#endif
-#ifdef __APPLE__
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#endif // __APPLE__
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/sendfile.hpp>
+#else
+#include <stout/os/posix/sendfile.hpp>
+#endif // __WINDOWS__
 
-#include <stout/os/signals.hpp>
-#include <stout/unreachable.hpp>
-
-namespace os {
-
-// Returns the amount of bytes written from the input file
-// descriptor to the output socket. On error, returns -1 and
-// errno indicates the error.
-// NOTE: The following limitations exist because of the OS X
-// implementation of sendfile:
-//   1. s must be a stream oriented socket descriptor.
-//   2. fd must be a regular file descriptor.
-inline ssize_t sendfile(int s, int fd, off_t offset, size_t length)
-{
-#if defined(__linux__) || defined(__sun)
-  suppress (SIGPIPE) {
-    // This will set errno to EPIPE if a SIGPIPE occurs.
-    return ::sendfile(s, fd, &offset, length);
-  }
-  UNREACHABLE();
-#elif defined __APPLE__
-  // On OS X, sendfile does not need to have SIGPIPE suppressed.
-  off_t _length = static_cast<off_t>(length);
-
-  if (::sendfile(fd, s, offset, &_length, NULL, 0) < 0) {
-    if (errno == EAGAIN && _length > 0) {
-      return _length;
-    }
-    return -1;
-  }
-
-  return _length;
-#endif // __APPLE__
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_SENDFILE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/shell.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/shell.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/shell.hpp
index f6d3b76..ca71645 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/shell.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/shell.hpp
@@ -14,62 +14,14 @@
 #ifndef __STOUT_OS_SHELL_HPP__
 #define __STOUT_OS_SHELL_HPP__
 
-#include <stdarg.h> // For va_list, va_start, etc.
-#include <stdio.h> // For ferror, fgets, FILE, pclose, popen.
 
-#include <ostream>
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/shell.hpp>
+#else
+#include <stout/os/posix/shell.hpp>
+#endif // __WINDOWS__
 
-#include <stout/error.hpp>
-#include <stout/format.hpp>
-#include <stout/try.hpp>
-
-namespace os {
-
-// Runs a shell command formatted with varargs and return the return value
-// of the command. Optionally, the output is returned via an argument.
-// TODO(vinod): Pass an istream object that can provide input to the command.
-inline Try<int> shell(std::ostream* os, const std::string fmt, ...)
-{
-  va_list args;
-  va_start(args, fmt);
-
-  const Try<std::string> command = strings::internal::format(fmt, args);
-
-  va_end(args);
-
-  if (command.isError()) {
-    return Error(command.error());
-  }
-
-  FILE* file;
-
-  if ((file = popen(command.get().c_str(), "r")) == NULL) {
-    return Error("Failed to run '" + command.get() + "'");
-  }
-
-  char line[1024];
-  // NOTE(vinod): Ideally the if and while loops should be interchanged. But
-  // we get a broken pipe error if we don't read the output and simply close.
-  while (fgets(line, sizeof(line), file) != NULL) {
-    if (os != NULL) {
-      *os << line;
-    }
-  }
-
-  if (ferror(file) != 0) {
-    pclose(file); // Ignoring result since we already have an error.
-    return Error("Error reading output of '" + command.get() + "'");
-  }
-
-  int status;
-  if ((status = pclose(file)) == -1) {
-    return Error("Failed to get status of '" + command.get() + "'");
-  }
-
-  return status;
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_SHELL_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/signals.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/signals.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/signals.hpp
index 3523070..7a79024 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/signals.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/signals.hpp
@@ -14,175 +14,19 @@
 #ifndef __STOUT_OS_SIGNALS_HPP__
 #define __STOUT_OS_SIGNALS_HPP__
 
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
 
-namespace os {
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/signals.hpp>
+#else
+#include <stout/os/posix/signals.hpp>
+#endif // __WINDOWS__
 
-namespace signals {
-
-// Installs the given signal handler.
-inline int install(int signal, void(*handler)(int))
-{
-  struct sigaction action;
-  memset(&action, 0, sizeof(action));
-  sigemptyset(&action.sa_mask);
-  action.sa_handler = handler;
-  return sigaction(signal, &action, NULL);
-}
-
-
-// Resets the signal handler to the default handler of the signal.
-inline int reset(int signal)
-{
-  struct sigaction action;
-  memset(&action, 0, sizeof(action));
-  sigemptyset(&action.sa_mask);
-  action.sa_handler = SIG_DFL;
-  return sigaction(signal, &action, NULL);
-}
-
-
-// Returns true iff the signal is pending.
-inline bool pending(int signal)
-{
-  sigset_t set;
-  sigemptyset(&set);
-  sigpending(&set);
-  return sigismember(&set, signal);
-}
-
-
-// Returns true if the signal has been blocked, or false if the
-// signal was already blocked.
-inline bool block(int signal)
-{
-  sigset_t set;
-  sigemptyset(&set);
-  sigaddset(&set, signal);
-
-  sigset_t oldset;
-  sigemptyset(&oldset);
-
-  // We ignore errors here as the only documented one is
-  // EINVAL due to a bad value of the SIG_* argument.
-  pthread_sigmask(SIG_BLOCK, &set, &oldset);
-
-  return !sigismember(&oldset, signal);
-}
-
-
-// Returns true if the signal has been unblocked, or false if the
-// signal was not previously blocked.
-inline bool unblock(int signal)
-{
-  sigset_t set;
-  sigemptyset(&set);
-  sigaddset(&set, signal);
-
-  sigset_t oldset;
-  sigemptyset(&oldset);
-
-  pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
-
-  return sigismember(&oldset, signal);
-}
-
-namespace internal {
-
-// Suppresses a signal on the current thread for the lifetime of
-// the Suppressor. The signal *must* be synchronous and delivered
-// per-thread. The suppression occurs only on the thread of
-// execution of the Suppressor.
-struct Suppressor
-{
-  Suppressor(int _signal)
-    : signal(_signal), pending(false), unblock(false)
-  {
-    // Check to see if the signal is already reported as pending.
-    // If pending, it means the thread already blocks the signal!
-    // Therefore, any new instances of the signal will also be
-    // blocked and merged with the pending one since there is no
-    // queuing for signals.
-    pending = signals::pending(signal);
-
-    if (!pending) {
-      // Block the signal for this thread only. If already blocked,
-      // there's no need to unblock it.
-      unblock = signals::block(signal);
-    }
-  }
-
-  ~Suppressor()
-  {
-    // We want to preserve errno when the Suppressor drops out of
-    // scope. Otherwise, one needs to potentially store errno when
-    // using the suppress() macro.
-    int _errno = errno;
-
-    // If the signal has become pending after we blocked it, we
-    // need to clear it before unblocking it.
-    if (!pending && signals::pending(signal)) {
-      // It is possible that in between having observed the pending
-      // signal with sigpending() and clearing it with sigwait(),
-      // the signal was delivered to another thread before we were
-      // able to clear it here. This can happen if the signal was
-      // generated for the whole process (e.g. a kill was issued).
-      // See 2.4.1 here:
-      // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
-      // To handle the above scenario, one can either:
-      //   1. Use sigtimedwait() with a timeout of 0, to ensure we
-      //      don't block forever. However, this only works on Linux
-      //      and we may still swallow the signal intended for the
-      //      process.
-      //   2. After seeing the pending signal, signal ourselves with
-      //      pthread_kill prior to calling sigwait(). This can still
-      //      swallow the signal intended for the process.
-      // We chose to use the latter technique as it works on all
-      // POSIX systems and is less likely to swallow process signals,
-      // provided the thread signal and process signal are not merged.
-      pthread_kill(pthread_self(), signal);
-
-      sigset_t mask;
-      sigemptyset(&mask);
-      sigaddset(&mask, signal);
-
-      int result;
-      do {
-        int _ignored;
-        result = sigwait(&mask, &_ignored);
-      } while (result == -1 && errno == EINTR);
-    }
-
-    // Unblock the signal (only if we were the ones to block it).
-    if (unblock) {
-      signals::unblock(signal);
-    }
-
-    // Restore errno.
-    errno = _errno;
-  }
-
-  // Needed for the suppress() macro.
-  operator bool () { return true; }
-
-private:
-  const int signal;
-  bool pending; // Whether the signal is already pending.
-  bool unblock; // Whether to unblock the signal on destruction.
-};
-
-} // namespace internal {
 
 #define suppress(signal) \
   if (os::signals::internal::Suppressor suppressor ## signal = \
       os::signals::internal::Suppressor(signal))
 
-} // namespace signals {
-
-} // namespace os {
 
 #endif // __STOUT_OS_SIGNALS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/stat.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/stat.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/stat.hpp
index c8203d6..45d4641 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/stat.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/stat.hpp
@@ -14,144 +14,14 @@
 #ifndef __STOUT_OS_STAT_HPP__
 #define __STOUT_OS_STAT_HPP__
 
-#include <sys/stat.h>
-#include <sys/statvfs.h>
 
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/stat.hpp>
+#else
+#include <stout/os/posix/stat.hpp>
+#endif // __WINDOWS__
 
-#include <stout/bytes.hpp>
-#include <stout/try.hpp>
-#include <stout/unreachable.hpp>
 
-namespace os {
-namespace stat {
-
-inline bool isdir(const std::string& path)
-{
-  struct stat s;
-
-  if (::stat(path.c_str(), &s) < 0) {
-    return false;
-  }
-  return S_ISDIR(s.st_mode);
-}
-
-
-inline bool isfile(const std::string& path)
-{
-  struct stat s;
-
-  if (::stat(path.c_str(), &s) < 0) {
-    return false;
-  }
-  return S_ISREG(s.st_mode);
-}
-
-
-
-inline bool islink(const std::string& path)
-{
-  struct stat s;
-
-  if (::lstat(path.c_str(), &s) < 0) {
-    return false;
-  }
-  return S_ISLNK(s.st_mode);
-}
-
-
-// Describes the different semantics supported for the implementation
-// of `size` defined below.
-enum FollowSymlink
-{
-  DO_NOT_FOLLOW_SYMLINK,
-  FOLLOW_SYMLINK
-};
-
-
-// Returns the size in Bytes of a given file system entry. When
-// applied to a symbolic link with `follow` set to
-// `DO_NOT_FOLLOW_SYMLINK`, this will return the length of the entry
-// name (strlen).
-inline Try<Bytes> size(
-    const std::string& path,
-    const FollowSymlink follow = FOLLOW_SYMLINK)
-{
-  struct stat s;
-
-  switch (follow) {
-    case DO_NOT_FOLLOW_SYMLINK: {
-      if (::lstat(path.c_str(), &s) < 0) {
-        return ErrnoError("Error invoking lstat for '" + path + "'");
-      }
-      break;
-    }
-    case FOLLOW_SYMLINK: {
-      if (::stat(path.c_str(), &s) < 0) {
-        return ErrnoError("Error invoking stat for '" + path + "'");
-      }
-      break;
-    }
-    default: {
-      UNREACHABLE();
-    }
-  }
-
-  return Bytes(s.st_size);
-}
-
-
-inline Try<long> mtime(const std::string& path)
-{
-  struct stat s;
-
-  if (::lstat(path.c_str(), &s) < 0) {
-    return ErrnoError("Error invoking stat for '" + path + "'");
-  }
-
-  return s.st_mtime;
-}
-
-
-inline Try<mode_t> mode(const std::string& path)
-{
-  struct stat s;
-
-  if (::stat(path.c_str(), &s) < 0) {
-    return ErrnoError("Error invoking stat for '" + path + "'");
-  }
-
-  return s.st_mode;
-}
-
-
-inline Try<dev_t> rdev(const std::string& path)
-{
-  struct stat s;
-
-  if (::stat(path.c_str(), &s) < 0) {
-    return ErrnoError("Error invoking stat for '" + path + "'");
-  }
-
-  if (!S_ISCHR(s.st_mode) && !S_ISBLK(s.st_mode)) {
-    return Error("Not a special file: " + path);
-  }
-
-  return s.st_rdev;
-}
-
-
-inline Try<ino_t> inode(const std::string& path)
-{
-  struct stat s;
-
-  if (::stat(path.c_str(), &s) < 0) {
-    return ErrnoError("Error invoking stat for '" + path + "'");
-  }
-
-  return s.st_ino;
-}
-
-} // namespace stat {
-} // namespace os {
 #endif // __STOUT_OS_STAT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/close.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/close.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/close.hpp
new file mode 100644
index 0000000..134a26b
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/close.hpp
@@ -0,0 +1,31 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STOUT_OS_WINDOWS_CLOSE_HPP__
+#define __STOUT_OS_WINDOWS_CLOSE_HPP__
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> close(int fd)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_CLOSE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
new file mode 100644
index 0000000..46f8fd2
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
@@ -0,0 +1,38 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_EXISTS_HPP__
+#define __STOUT_OS_WINDOWS_EXISTS_HPP__
+
+#include <string>
+
+
+namespace os {
+
+inline bool exists(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Determine if the process identified by pid exists.
+// NOTE: Zombie processes have a pid and therefore exist. See os::process(pid)
+// to get details of a process.
+inline bool exists(pid_t pid)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_EXISTS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fcntl.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fcntl.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fcntl.hpp
new file mode 100644
index 0000000..0bad615
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fcntl.hpp
@@ -0,0 +1,49 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STOUT_OS_WINDOWS_FCNTL_HPP__
+#define __STOUT_OS_WINDOWS_FCNTL_HPP__
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> cloexec(int fd)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<bool> isCloexec(int fd)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> nonblock(int fd)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<bool> isNonblock(int fd)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_FCNTL_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fork.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fork.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fork.hpp
new file mode 100644
index 0000000..3b92eb8
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/fork.hpp
@@ -0,0 +1,34 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_FORK_HPP__
+#define __STOUT_OS_WINDOWS_FORK_HPP__
+
+
+struct Exec
+{
+  UNIMPLEMENTED;
+};
+
+
+struct Wait {};
+
+
+struct Fork
+{
+  UNIMPLEMENTED;
+};
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_FORK_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/killtree.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/killtree.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/killtree.hpp
new file mode 100644
index 0000000..ec645ca
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/killtree.hpp
@@ -0,0 +1,50 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_KILLTREE_HPP__
+#define __STOUT_OS_WINDOWS_KILLTREE_HPP__
+
+#include <stdlib.h>
+
+
+namespace os {
+
+// Sends a signal to a process tree rooted at the specified pid.
+// If groups is true, this also sends the signal to all encountered
+// process groups.
+// If sessions is true, this also sends the signal to all encountered
+// process sessions.
+// Note that processes of the group and session of the parent of the
+// root process is not included unless they are part of the root
+// process tree.
+// Note that if the process 'pid' has exited we'll signal the process
+// tree(s) rooted at pids in the group or session led by the process
+// if groups = true or sessions = true, respectively.
+// Returns the process trees that were succesfully or unsuccessfully
+// signaled. Note that the process trees can be stringified.
+// TODO(benh): Allow excluding the root pid from stopping, killing,
+// and continuing so as to provide a means for expressing "kill all of
+// my children". This is non-trivial because of the current
+// implementation.
+inline Try<std::list<ProcessTree>> killtree(
+    pid_t pid,
+    int signal,
+    bool groups = false,
+    bool sessions = false)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_KILLTREE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/ls.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/ls.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/ls.hpp
new file mode 100644
index 0000000..5b6fba1
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/ls.hpp
@@ -0,0 +1,30 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_LS_HPP__
+#define __STOUT_OS_WINDOWS_LS_HPP__
+
+#include <list>
+#include <string>
+
+
+namespace os {
+
+inline Try<std::list<std::string>> ls(const std::string& directory)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_LS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/open.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/open.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/open.hpp
new file mode 100644
index 0000000..14fa117
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/open.hpp
@@ -0,0 +1,34 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STOUT_OS_WINDOWS_OPEN_HPP__
+#define __STOUT_OS_WINDOWS_OPEN_HPP__
+
+#include <sys/types.h>
+
+#include <string>
+
+#include <stout/try.hpp>
+
+
+namespace os {
+
+inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_OPEN_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/permissions.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/permissions.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/permissions.hpp
new file mode 100644
index 0000000..daed4b4
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/permissions.hpp
@@ -0,0 +1,41 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_PERMISSIONS_HPP__
+#define __STOUT_OS_WINDOWS_PERMISSIONS_HPP__
+
+#include <sys/stat.h>
+
+#include <string>
+
+
+namespace os {
+
+// Forward declaration.
+struct Permissions
+{
+  explicit Permissions(mode_t mode)
+  {
+    UNIMPLEMENTED;
+  }
+};
+
+
+inline Try<Permissions> permissions(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_PERMISSIONS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/process.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/process.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/process.hpp
new file mode 100644
index 0000000..bbb796d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/process.hpp
@@ -0,0 +1,54 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_PROCESS_HPP__
+#define __STOUT_OS_WINDOWS_PROCESS_HPP__
+
+#include <list>
+#include <ostream>
+#include <string>
+
+
+namespace os {
+
+struct Process
+{
+  UNIMPLEMENTED;
+};
+
+
+class ProcessTree
+{
+  UNIMPLEMENTED;
+};
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ProcessTree& tree)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+
+// An overload of stringify for printing a list of process trees
+// (since printing a process tree is rather particular).
+inline std::string stringify(const std::list<os::ProcessTree>& list)
+{
+  UNIMPLEMENTED;
+}
+
+
+#endif // __STOUT_OS_WINDOWS_PROCESS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/pstree.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/pstree.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/pstree.hpp
new file mode 100644
index 0000000..f75a77f
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/pstree.hpp
@@ -0,0 +1,57 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_PSTREE_HPP__
+#define __STOUT_OS_WINDOWS_PSTREE_HPP__
+
+#include <list>
+#include <set>
+
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+#include <stout/os/process.hpp>
+
+
+namespace os {
+
+// Returns a process tree rooted at the specified pid using the
+// specified list of processes (or an error if one occurs).
+inline Try<ProcessTree> pstree(
+    pid_t pid,
+    const std::list<Process>& processes)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns a process tree for the specified pid (or all processes if
+// pid is none or the current process if pid is 0).
+inline Try<ProcessTree> pstree(Option<pid_t> pid = None())
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns the minimum list of process trees that include all of the
+// specified pids using the specified list of processes.
+inline Try<std::list<ProcessTree>> pstrees(
+    const std::set<pid_t>& pids,
+    const std::list<Process>& processes)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_PSTREE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/read.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/read.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/read.hpp
new file mode 100644
index 0000000..09d6332
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/read.hpp
@@ -0,0 +1,44 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_READ_HPP__
+#define __STOUT_OS_WINDOWS_READ_HPP__
+
+#include <stdio.h>
+
+#include <string>
+
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+// Reads 'size' bytes from a file from its current offset.
+// If EOF is encountered before reading 'size' bytes then the result
+// will contain the bytes read and a subsequent read will return None.
+inline Result<std::string> read(int fd, size_t size)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns the contents of the file.
+inline Try<std::string> read(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_READ_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/sendfile.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/sendfile.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/sendfile.hpp
new file mode 100644
index 0000000..9658bb8
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/sendfile.hpp
@@ -0,0 +1,36 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_SENDFILE_HPP__
+#define __STOUT_OS_WINDOWS_SENDFILE_HPP__
+
+#include <errno.h>
+
+
+namespace os {
+
+// Returns the amount of bytes written from the input file
+// descriptor to the output socket. On error, returns -1 and
+// errno indicates the error.
+// NOTE: The following limitations exist because of the OS X
+// implementation of sendfile:
+//   1. s must be a stream oriented socket descriptor.
+//   2. fd must be a regular file descriptor.
+inline ssize_t sendfile(int s, int fd, off_t offset, size_t length)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_SENDFILE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/shell.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/shell.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/shell.hpp
new file mode 100644
index 0000000..4b7a7ba
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/shell.hpp
@@ -0,0 +1,37 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_SHELL_HPP__
+#define __STOUT_OS_WINDOWS_SHELL_HPP__
+
+#include <stdarg.h> // For va_list, va_start, etc.
+
+#include <ostream>
+#include <string>
+
+#include <stout/try.hpp>
+
+
+namespace os {
+
+// Runs a shell command formatted with varargs and return the return value
+// of the command. Optionally, the output is returned via an argument.
+// TODO(vinod): Pass an istream object that can provide input to the command.
+inline Try<int> shell(std::ostream* os, const std::string fmt, ...)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_SHELL_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/signals.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/signals.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/signals.hpp
new file mode 100644
index 0000000..70e9b15
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/signals.hpp
@@ -0,0 +1,92 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_SIGNALS_HPP__
+#define __STOUT_OS_WINDOWS_SIGNALS_HPP__
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+
+
+namespace os {
+
+namespace signals {
+
+// Installs the given signal handler.
+inline int install(int signal, void(*handler)(int))
+{
+  UNIMPLEMENTED;
+}
+
+
+// Resets the signal handler to the default handler of the signal.
+inline int reset(int signal)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns true iff the signal is pending.
+inline bool pending(int signal)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns true if the signal has been blocked, or false if the
+// signal was already blocked.
+inline bool block(int signal)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns true if the signal has been unblocked, or false if the
+// signal was not previously blocked.
+inline bool unblock(int signal)
+{
+  UNIMPLEMENTED;
+}
+
+namespace internal {
+
+// Suppresses a signal on the current thread for the lifetime of
+// the Suppressor. The signal *must* be synchronous and delivered
+// per-thread. The suppression occurs only on the thread of
+// execution of the Suppressor.
+struct Suppressor
+{
+  Suppressor(int _signal)
+    : signal(_signal), pending(false), unblock(false)
+  {
+    UNIMPLEMENTED;
+  }
+
+  ~Suppressor()
+  {
+    UNIMPLEMENTED;
+  }
+
+  // Needed for the suppress() macro.
+  operator bool () { return true; }
+};
+
+} // namespace internal {
+
+} // namespace signals {
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_SIGNALS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/stat.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/stat.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/stat.hpp
new file mode 100644
index 0000000..675b2e7
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/stat.hpp
@@ -0,0 +1,93 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_WINDOWS_STAT_HPP__
+#define __STOUT_OS_WINDOWS_STAT_HPP__
+
+#include <string>
+
+#include <stout/try.hpp>
+
+
+namespace os {
+
+namespace stat {
+
+inline bool isdir(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline bool isfile(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+
+inline bool islink(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Describes the different semantics supported for the implementation
+// of `size` defined below.
+enum FollowSymlink
+{
+  DO_NOT_FOLLOW_SYMLINK,
+  FOLLOW_SYMLINK
+};
+
+
+// Returns the size in Bytes of a given file system entry. When
+// applied to a symbolic link with `follow` set to
+// `DO_NOT_FOLLOW_SYMLINK`, this will return the length of the entry
+// name (strlen).
+inline Try<Bytes> size(
+    const std::string& path,
+    const FollowSymlink follow = FOLLOW_SYMLINK)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<long> mtime(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<mode_t> mode(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<dev_t> rdev(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<ino_t> inode(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace stat {
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_STAT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/windows.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows.hpp
new file mode 100644
index 0000000..7ab75ec
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows.hpp
@@ -0,0 +1,61 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_WINDOWS_PREPROCESSOR_HPP__
+#define __STOUT_WINDOWS_PREPROCESSOR_HPP__
+
+// Provides aliases to Windows-specific nuances.
+
+// Normally defined in unistd.h.
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+// Alias for method in stdio.h.
+#define write(fd, buf, count) _write(fd, buf, count)
+
+// Aliases for 'inet_pton' and 'inet_ntop'.
+#define inet_pton(af, cp, buf) InetPton(af, cp, buf)
+#define inet_ntop(af, cp, buf, len) InetNtop(af, cp, buf, len)
+
+// TODO(aclemmer): Not defined on Windows.  This value is temporary.
+#define MAXHOSTNAMELEN 64
+
+// Macros associated with ::access, usually defined in unistd.h.
+#define access(path, how) _access(path, how)
+#define R_OK 0x4
+#define W_OK 0x2
+#define X_OK 0x0 // No such permission on Windows
+#define F_OK 0x0
+
+// Aliases for file access modes (defined in fcntl.h).
+#define O_RDONLY _O_RDONLY
+#define O_WRONLY _O_WRONLY
+#define O_RDWR _O_RDWR
+#define O_CREAT _O_CREAT
+#define O_TRUNC _O_TRUNC
+#define O_APPEND _O_APPEND
+// TODO(josephw): No equivalent for O_NONBLOCK or O_SYNC
+
+// Alias for mkstemp (requires io.h).
+#define mkstemp(path) _mktemp_s(path, strlen(path) + 1)
+
+// Alias for realpath.
+#define PATH_MAX MAX_PATH
+#define realpath(path, resolved) _fullpath(resolved, path, PATH_MAX)
+
+// Alias for mkdir (requires direct.h).
+#define mkdir(path, mode) _mkdir(path)
+
+
+#endif // __STOUT_WINDOWS_PREPROCESSOR_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
index 7e1b0f8..2b09668 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
@@ -17,7 +17,6 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 
 #include <sys/types.h>
 
@@ -32,7 +31,7 @@
 #include <stout/option.hpp>
 #include <stout/path.hpp>
 #include <stout/try.hpp>
-#include <stout/windows/preprocessor.hpp>
+#include <stout/windows.hpp>
 
 
 namespace os {

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
deleted file mode 100644
index 7ab75ec..0000000
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef __STOUT_WINDOWS_PREPROCESSOR_HPP__
-#define __STOUT_WINDOWS_PREPROCESSOR_HPP__
-
-// Provides aliases to Windows-specific nuances.
-
-// Normally defined in unistd.h.
-#define STDIN_FILENO 0
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-
-// Alias for method in stdio.h.
-#define write(fd, buf, count) _write(fd, buf, count)
-
-// Aliases for 'inet_pton' and 'inet_ntop'.
-#define inet_pton(af, cp, buf) InetPton(af, cp, buf)
-#define inet_ntop(af, cp, buf, len) InetNtop(af, cp, buf, len)
-
-// TODO(aclemmer): Not defined on Windows.  This value is temporary.
-#define MAXHOSTNAMELEN 64
-
-// Macros associated with ::access, usually defined in unistd.h.
-#define access(path, how) _access(path, how)
-#define R_OK 0x4
-#define W_OK 0x2
-#define X_OK 0x0 // No such permission on Windows
-#define F_OK 0x0
-
-// Aliases for file access modes (defined in fcntl.h).
-#define O_RDONLY _O_RDONLY
-#define O_WRONLY _O_WRONLY
-#define O_RDWR _O_RDWR
-#define O_CREAT _O_CREAT
-#define O_TRUNC _O_TRUNC
-#define O_APPEND _O_APPEND
-// TODO(josephw): No equivalent for O_NONBLOCK or O_SYNC
-
-// Alias for mkstemp (requires io.h).
-#define mkstemp(path) _mktemp_s(path, strlen(path) + 1)
-
-// Alias for realpath.
-#define PATH_MAX MAX_PATH
-#define realpath(path, resolved) _fullpath(resolved, path, PATH_MAX)
-
-// Alias for mkdir (requires direct.h).
-#define mkdir(path, mode) _mkdir(path)
-
-
-#endif // __STOUT_WINDOWS_PREPROCESSOR_HPP__


[3/4] mesos git commit: Header splitting continued (stout/os.hpp).

Posted by be...@apache.org.
Header splitting continued (stout/os.hpp).

MESOS-3102: Stout library header splitting, to support the Windows
Containerizer. Splits apart os.hpp only.

See the prior review in the chain for the pattern.

Review: https://reviews.apache.org/r/36783


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/66fa10db
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/66fa10db
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/66fa10db

Branch: refs/heads/master
Commit: 66fa10db99420d73ae7abd8dc78b54bee0710e49
Parents: f8dd73d
Author: Joseph Wu <jo...@mesosphere.io>
Authored: Thu Jul 30 16:07:36 2015 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Thu Jul 30 16:25:05 2015 -0700

----------------------------------------------------------------------
 .../3rdparty/stout/include/Makefile.am          |   3 +
 .../3rdparty/stout/include/stout/os.hpp         | 812 +-----------------
 .../3rdparty/stout/include/stout/os/os.hpp      |  55 ++
 .../3rdparty/stout/include/stout/posix/os.hpp   | 840 +++++++++++++++++++
 .../3rdparty/stout/include/stout/windows/os.hpp | 274 ++++++
 .../include/stout/windows/preprocessor.hpp      |  27 +
 6 files changed, 1218 insertions(+), 793 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/66fa10db/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index cb40231..60339e1 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -43,6 +43,7 @@ nobase_include_HEADERS =		\
   stout/linkedhashmap.hpp		\
   stout/posix/gzip.hpp			\
   stout/posix/net.hpp			\
+  stout/posix/os.hpp			\
   stout/list.hpp			\
   stout/mac.hpp				\
   stout/multihashmap.hpp		\
@@ -61,6 +62,7 @@ nobase_include_HEADERS =		\
   stout/os/linux.hpp			\
   stout/os/ls.hpp			\
   stout/os/open.hpp			\
+  stout/os/os.hpp			\
   stout/os/osx.hpp			\
   stout/os/process.hpp			\
   stout/os/read.hpp			\
@@ -96,4 +98,5 @@ nobase_include_HEADERS =		\
   stout/windows/format.hpp		\
   stout/windows/gzip.hpp		\
   stout/windows/net.hpp			\
+  stout/windows/os.hpp			\
   stout/windows/preprocessor.hpp	\

http://git-wip-us.apache.org/repos/asf/mesos/blob/66fa10db/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
index 818560f..3ffda48 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
@@ -14,11 +14,9 @@
 #ifndef __STOUT_OS_HPP__
 #define __STOUT_OS_HPP__
 
-#ifdef __APPLE__
-#include <crt_externs.h> // For _NSGetEnviron().
-#endif
-#include <dirent.h>
-#include <errno.h>
+#ifdef __WINDOWS__
+#include <direct.h>
+#endif // __WINDOWS__
 #ifdef __sun
 #include <sys/loadavg.h>
 #define dirfd(dir) ((dir)->d_fd)
@@ -28,8 +26,12 @@
 #else
 #include <fts.h>
 #endif // __sun
+#include <fcntl.h>
 #include <glob.h>
 #include <grp.h>
+#ifdef __WINDOWS__
+#include <io.h>
+#endif // __WINDOWS__
 #include <limits.h>
 #include <netdb.h>
 #include <pwd.h>
@@ -50,48 +52,33 @@
 #include <sys/sysinfo.h>
 #endif // __linux__
 #include <sys/types.h>
+#ifdef __WINDOWS__
+#include <sys/utime.h>
+#endif // __WINDOWS
 #include <sys/utsname.h>
 #include <sys/wait.h>
 
 #include <list>
-#include <map>
 #include <queue>
 #include <set>
 #include <string>
-#include <vector>
 
-#include <stout/bytes.hpp>
-#include <stout/duration.hpp>
 #include <stout/error.hpp>
 #include <stout/foreach.hpp>
 #include <stout/none.hpp>
 #include <stout/nothing.hpp>
 #include <stout/option.hpp>
 #include <stout/path.hpp>
-#include <stout/result.hpp>
 #include <stout/strings.hpp>
 #include <stout/try.hpp>
 #include <stout/unreachable.hpp>
 #include <stout/version.hpp>
 
-#include <stout/os/close.hpp>
-#include <stout/os/exists.hpp>
-#include <stout/os/fcntl.hpp>
 #include <stout/os/fork.hpp>
 #include <stout/os/killtree.hpp>
-#ifdef __linux__
-#include <stout/os/linux.hpp>
-#endif // __linux__
 #include <stout/os/ls.hpp>
-#include <stout/os/open.hpp>
-#ifdef __APPLE__
-#include <stout/os/osx.hpp>
-#endif // __APPLE__
 #include <stout/os/permissions.hpp>
-#ifdef __sun
-#include <stout/os/sunos.hpp>
-#endif // __sun
-#include <stout/os/pstree.hpp>
+#include <stout/os/os.hpp>
 #include <stout/os/read.hpp>
 #include <stout/os/rename.hpp>
 #include <stout/os/sendfile.hpp>
@@ -102,43 +89,18 @@
 #include <stout/os/sysctl.hpp>
 #endif // __APPLE__
 
-// Need to declare 'environ' pointer for non OS X platforms.
-#ifndef __APPLE__
-extern char** environ;
-#endif
-
-namespace os {
 
-inline char** environ()
-{
-  // Accessing the list of environment variables is platform-specific.
-  // On OS X, the 'environ' symbol isn't visible to shared libraries,
-  // so we must use the _NSGetEnviron() function (see 'man environ' on
-  // OS X). On other platforms, it's fine to access 'environ' from
-  // shared libraries.
-#ifdef __APPLE__
-  return *_NSGetEnviron();
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/windows/os.hpp>
+#include <stout/windows/preprocessor.hpp>
 #else
-  return ::environ;
-#endif
-}
+#include <stout/posix/os.hpp>
+#endif // __WINDOWS__
 
 
-// Returns the address of os::environ().
-inline char*** environp()
-{
-  // Accessing the list of environment variables is platform-specific.
-  // On OS X, the 'environ' symbol isn't visible to shared libraries,
-  // so we must use the _NSGetEnviron() function (see 'man environ' on
-  // OS X). On other platforms, it's fine to access 'environ' from
-  // shared libraries.
-#ifdef __APPLE__
-  return _NSGetEnviron();
-#else
-  return &::environ;
-#endif
-}
-
+namespace os {
 
 inline std::map<std::string, std::string> environment()
 {
@@ -174,24 +136,6 @@ inline Option<std::string> getenv(const std::string& key)
 }
 
 
-// Sets the value associated with the specified key in the set of
-// environment variables.
-inline void setenv(const std::string& key,
-                   const std::string& value,
-                   bool overwrite = true)
-{
-  ::setenv(key.c_str(), value.c_str(), overwrite ? 1 : 0);
-}
-
-
-// Unsets the value associated with the specified key in the set of
-// environment variables.
-inline void unsetenv(const std::string& key)
-{
-  ::unsetenv(key.c_str());
-}
-
-
 inline Try<bool> access(const std::string& path, int how)
 {
   if (::access(path.c_str(), how) < 0) {
@@ -216,26 +160,6 @@ inline Try<Nothing> utime(const std::string& path)
 }
 
 
-inline Try<Nothing> touch(const std::string& path)
-{
-  if (!exists(path)) {
-    Try<int> fd = open(
-        path,
-        O_RDWR | O_CREAT,
-        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-    if (fd.isError()) {
-      return Error("Failed to open file: " + fd.error());
-    }
-
-    return close(fd.get());
-  }
-
-  // Update the access and modification times.
-  return utime(path);
-}
-
-
 // Creates a temporary file using the specified path template. The
 // template may be any path with _6_ `Xs' appended to it, for example
 // /tmp/temp.XXXXXX. The trailing `Xs' are replaced with a unique
@@ -285,40 +209,6 @@ inline Try<Nothing> write(int fd, const std::string& message)
 }
 
 
-// A wrapper function that wraps the above write() with
-// open and closing the file.
-inline Try<Nothing> write(const std::string& path, const std::string& message)
-{
-  Try<int> fd = os::open(
-      path,
-      O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
-      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-  if (fd.isError()) {
-    return ErrnoError("Failed to open file '" + path + "'");
-  }
-
-  Try<Nothing> result = write(fd.get(), message);
-
-  // We ignore the return value of close(). This is because users
-  // calling this function are interested in the return value of
-  // write(). Also an unsuccessful close() doesn't affect the write.
-  os::close(fd.get());
-
-  return result;
-}
-
-
-inline Try<Nothing> rm(const std::string& path)
-{
-  if (::remove(path.c_str()) != 0) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
 inline Result<std::string> realpath(const std::string& path)
 {
   char temp[PATH_MAX];
@@ -359,375 +249,6 @@ inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
   return Nothing();
 }
 
-// Creates a temporary directory using the specified path
-// template. The template may be any path with _6_ `Xs' appended to
-// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
-// with a unique alphanumeric combination.
-inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
-{
-  char* temp = new char[path.size() + 1];
-  if (::mkdtemp(::strcpy(temp, path.c_str())) != NULL) {
-    std::string result(temp);
-    delete[] temp;
-    return result;
-  } else {
-    delete[] temp;
-    return ErrnoError();
-  }
-}
-
-// By default, recursively deletes a directory akin to: 'rm -r'. If the
-// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
-// Note that this function expects an absolute path.
-#ifndef __sun // FTS is not available on Solaris.
-inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
-{
-  if (!recursive) {
-    if (::rmdir(directory.c_str()) < 0) {
-      return ErrnoError();
-    }
-  } else {
-    char* paths[] = {const_cast<char*>(directory.c_str()), NULL};
-
-    FTS* tree = fts_open(paths, FTS_NOCHDIR, NULL);
-    if (tree == NULL) {
-      return ErrnoError();
-    }
-
-    FTSENT* node;
-    while ((node = fts_read(tree)) != NULL) {
-      switch (node->fts_info) {
-        case FTS_DP:
-          if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
-            return ErrnoError();
-          }
-          break;
-        case FTS_F:
-        case FTS_SL:
-          if (::unlink(node->fts_path) < 0 && errno != ENOENT) {
-            return ErrnoError();
-          }
-          break;
-        default:
-          break;
-      }
-    }
-
-    if (errno != 0) {
-      return ErrnoError();
-    }
-
-    if (fts_close(tree) < 0) {
-      return ErrnoError();
-    }
-  }
-
-  return Nothing();
-}
-#endif // __sun
-
-
-// Executes a command by calling "/bin/sh -c <command>", and returns
-// after the command has been completed. Returns 0 if succeeds, and
-// return -1 on error (e.g., fork/exec/waitpid failed). This function
-// is async signal safe. We return int instead of returning a Try
-// because Try involves 'new', which is not async signal safe.
-inline int system(const std::string& command)
-{
-  pid_t pid = ::fork();
-
-  if (pid == -1) {
-    return -1;
-  } else if (pid == 0) {
-    // In child process.
-    ::execl("/bin/sh", "sh", "-c", command.c_str(), (char*) NULL);
-    ::exit(127);
-  } else {
-    // In parent process.
-    int status;
-    while (::waitpid(pid, &status, 0) == -1) {
-      if (errno != EINTR) {
-        return -1;
-      }
-    }
-
-    return status;
-  }
-}
-
-
-// This function is a portable version of execvpe ('p' means searching
-// executable from PATH and 'e' means setting environments). We add
-// this function because it is not available on all systems.
-//
-// NOTE: This function is not thread safe. It is supposed to be used
-// only after fork (when there is only one thread). This function is
-// async signal safe.
-inline int execvpe(const char* file, char** argv, char** envp)
-{
-  char** saved = os::environ();
-
-  *os::environp() = envp;
-
-  int result = execvp(file, argv);
-
-  *os::environp() = saved;
-
-  return result;
-}
-
-
-inline Try<Nothing> chown(
-    uid_t uid,
-    gid_t gid,
-    const std::string& path,
-    bool recursive)
-{
-  if (recursive) {
-    // TODO(bmahler): Consider walking the file tree instead. We would need
-    // to be careful to not miss dotfiles.
-    std::string command =
-      "chown -R " + stringify(uid) + ':' + stringify(gid) + " '" + path + "'";
-
-    int status = os::system(command);
-    if (status != 0) {
-      return ErrnoError(
-          "Failed to execute '" + command +
-          "' (exit status: " + stringify(status) + ")");
-    }
-  } else {
-    if (::chown(path.c_str(), uid, gid) < 0) {
-      return ErrnoError();
-    }
-  }
-
-  return Nothing();
-}
-
-
-// Changes the specified path's user and group ownership to that of
-// the specified user.
-inline Try<Nothing> chown(
-    const std::string& user,
-    const std::string& path,
-    bool recursive = true)
-{
-  passwd* passwd;
-  if ((passwd = ::getpwnam(user.c_str())) == NULL) {
-    return ErrnoError("Failed to get user information for '" + user + "'");
-  }
-
-  return chown(passwd->pw_uid, passwd->pw_gid, path, recursive);
-}
-
-
-inline Try<Nothing> chmod(const std::string& path, int mode)
-{
-  if (::chmod(path.c_str(), mode) < 0) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
-inline Try<Nothing> chdir(const std::string& directory)
-{
-  if (::chdir(directory.c_str()) < 0) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
-inline Try<Nothing> chroot(const std::string& directory)
-{
-  if (::chroot(directory.c_str()) < 0) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
-inline Try<Nothing> mknod(
-    const std::string& path,
-    mode_t mode,
-    dev_t dev)
-{
-  if (::mknod(path.c_str(), mode, dev) < 0) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
-inline Result<uid_t> getuid(const Option<std::string>& user = None())
-{
-  if (user.isNone()) {
-    return ::getuid();
-  }
-
-  struct passwd passwd;
-  struct passwd* result = NULL;
-
-  int size = sysconf(_SC_GETPW_R_SIZE_MAX);
-  if (size == -1) {
-    // Initial value for buffer size.
-    size = 1024;
-  }
-
-  while (true) {
-    char* buffer = new char[size];
-
-    if (getpwnam_r(user.get().c_str(), &passwd, buffer, size, &result) == 0) {
-      // The usual interpretation of POSIX is that getpwnam_r will
-      // return 0 but set result == NULL if the user is not found.
-      if (result == NULL) {
-        delete[] buffer;
-        return None();
-      }
-
-      uid_t uid = passwd.pw_uid;
-      delete[] buffer;
-      return uid;
-    } else {
-      // RHEL7 (and possibly other systems) will return non-zero and
-      // set one of the following errors for "The given name or uid
-      // was not found." See 'man getpwnam_r'. We only check for the
-      // errors explicitly listed, and do not consider the ellipsis.
-      if (errno == ENOENT ||
-          errno == ESRCH ||
-          errno == EBADF ||
-          errno == EPERM) {
-        delete[] buffer;
-        return None();
-      }
-
-      if (errno != ERANGE) {
-        delete[] buffer;
-        return ErrnoError("Failed to get username information");
-      }
-      // getpwnam_r set ERANGE so try again with a larger buffer.
-      size *= 2;
-      delete[] buffer;
-    }
-  }
-
-  UNREACHABLE();
-}
-
-
-inline Result<gid_t> getgid(const Option<std::string>& user = None())
-{
-  if (user.isNone()) {
-    return ::getgid();
-  }
-
-  struct passwd passwd;
-  struct passwd* result = NULL;
-
-  int size = sysconf(_SC_GETPW_R_SIZE_MAX);
-  if (size == -1) {
-    // Initial value for buffer size.
-    size = 1024;
-  }
-
-  while (true) {
-    char* buffer = new char[size];
-
-    if (getpwnam_r(user.get().c_str(), &passwd, buffer, size, &result) == 0) {
-      // The usual interpretation of POSIX is that getpwnam_r will
-      // return 0 but set result == NULL if the group is not found.
-      if (result == NULL) {
-        delete[] buffer;
-        return None();
-      }
-
-      gid_t gid = passwd.pw_gid;
-      delete[] buffer;
-      return gid;
-    } else {
-      // RHEL7 (and possibly other systems) will return non-zero and
-      // set one of the following errors for "The given name or uid
-      // was not found." See 'man getpwnam_r'. We only check for the
-      // errors explicitly listed, and do not consider the ellipsis.
-      if (errno == ENOENT ||
-          errno == ESRCH ||
-          errno == EBADF ||
-          errno == EPERM) {
-        delete[] buffer;
-        return None();
-      }
-
-      if (errno != ERANGE) {
-        delete[] buffer;
-        return ErrnoError("Failed to get username information");
-      }
-      // getpwnam_r set ERANGE so try again with a larger buffer.
-      size *= 2;
-      delete[] buffer;
-    }
-  }
-
-  UNREACHABLE();
-}
-
-
-inline Try<Nothing> su(const std::string& user)
-{
-  Result<gid_t> gid = os::getgid(user);
-  if (gid.isError() || gid.isNone()) {
-    return Error("Failed to getgid: " +
-        (gid.isError() ? gid.error() : "unknown user"));
-  } else if (::setgid(gid.get())) {
-    return ErrnoError("Failed to set gid");
-  }
-
-  // Set the supplementary group list. We ignore EPERM because
-  // performing a no-op call (switching to same group) still
-  // requires being privileged, unlike 'setgid' and 'setuid'.
-  if (::initgroups(user.c_str(), gid.get()) == -1 && errno != EPERM) {
-    return ErrnoError("Failed to set supplementary groups");
-  }
-
-  Result<uid_t> uid = os::getuid(user);
-  if (uid.isError() || uid.isNone()) {
-    return Error("Failed to getuid: " +
-        (uid.isError() ? uid.error() : "unknown user"));
-  } else if (::setuid(uid.get())) {
-    return ErrnoError("Failed to setuid");
-  }
-
-  return Nothing();
-}
-
-
-inline std::string getcwd()
-{
-  size_t size = 100;
-
-  while (true) {
-    char* temp = new char[size];
-    if (::getcwd(temp, size) == temp) {
-      std::string result(temp);
-      delete[] temp;
-      return result;
-    } else {
-      if (errno != ERANGE) {
-        delete[] temp;
-        return std::string();
-      }
-      size *= 2;
-      delete[] temp;
-    }
-  }
-
-  return std::string();
-}
-
 
 // Return the list of file paths that match the given pattern by recursively
 // searching the given directory. A match is successful if the pattern is a
@@ -771,69 +292,6 @@ inline Try<std::list<std::string> > find(
 }
 
 
-inline Result<std::string> user(Option<uid_t> uid = None())
-{
-  if (uid.isNone()) {
-    uid = ::getuid();
-  }
-
-  int size = sysconf(_SC_GETPW_R_SIZE_MAX);
-  if (size == -1) {
-    // Initial value for buffer size.
-    size = 1024;
-  }
-
-  struct passwd passwd;
-  struct passwd* result = NULL;
-
-  while (true) {
-    char* buffer = new char[size];
-
-    if (getpwuid_r(uid.get(), &passwd, buffer, size, &result) == 0) {
-      // getpwuid_r will return 0 but set result == NULL if the uid is
-      // not found.
-      if (result == NULL) {
-        delete[] buffer;
-        return None();
-      }
-
-      std::string user(passwd.pw_name);
-      delete[] buffer;
-      return user;
-    } else {
-      if (errno != ERANGE) {
-        delete[] buffer;
-        return ErrnoError();
-      }
-
-      // getpwuid_r set ERANGE so try again with a larger buffer.
-      size *= 2;
-      delete[] buffer;
-    }
-  }
-}
-
-
-// Suspends execution for the given duration.
-inline Try<Nothing> sleep(const Duration& duration)
-{
-  timespec remaining;
-  remaining.tv_sec = static_cast<long>(duration.secs());
-  remaining.tv_nsec =
-    static_cast<long>((duration - Seconds(remaining.tv_sec)).ns());
-
-  while (nanosleep(&remaining, &remaining) == -1) {
-    if (errno == EINTR) {
-      continue;
-    } else {
-      return ErrnoError();
-    }
-  }
-
-  return Nothing();
-}
-
-
 // Creates a tar 'archive' with gzip compression, of the given 'path'.
 inline Try<Nothing> tar(const std::string& path, const std::string& archive)
 {
@@ -851,139 +309,6 @@ inline Try<Nothing> tar(const std::string& path, const std::string& archive)
 }
 
 
-// Returns the list of files that match the given (shell) pattern.
-inline Try<std::list<std::string> > glob(const std::string& pattern)
-{
-  glob_t g;
-  int status = ::glob(pattern.c_str(), GLOB_NOSORT, NULL, &g);
-
-  std::list<std::string> result;
-
-  if (status != 0) {
-    if (status == GLOB_NOMATCH) {
-      return result; // Empty list.
-    } else {
-      return ErrnoError();
-    }
-  }
-
-  for (size_t i = 0; i < g.gl_pathc; ++i) {
-    result.push_back(g.gl_pathv[i]);
-  }
-
-  globfree(&g); // Best-effort free of dynamically allocated memory.
-
-  return result;
-}
-
-
-// Returns the total number of cpus (cores).
-inline Try<long> cpus()
-{
-  long cpus = sysconf(_SC_NPROCESSORS_ONLN);
-
-  if (cpus < 0) {
-    return ErrnoError();
-  }
-  return cpus;
-}
-
-
-// Structure returned by loadavg(). Encodes system load average
-// for the last 1, 5 and 15 minutes.
-struct Load {
-  double one;
-  double five;
-  double fifteen;
-};
-
-
-// Returns load struct with average system loads for the last
-// 1, 5 and 15 minutes respectively.
-// Load values should be interpreted as usual average loads from
-// uptime(1).
-inline Try<Load> loadavg()
-{
-  double loadArray[3];
-  if (getloadavg(loadArray, 3) == -1) {
-    return ErrnoError("Failed to determine system load averages");
-  }
-
-  Load load;
-  load.one = loadArray[0];
-  load.five = loadArray[1];
-  load.fifteen = loadArray[2];
-
-  return load;
-}
-
-
-// Structure returned by memory() containing the total size of main
-// and free memory.
-struct Memory
-{
-  Bytes total;
-  Bytes free;
-};
-
-
-// Returns the total size of main and free memory.
-inline Try<Memory> memory()
-{
-  Memory memory;
-
-#ifdef __linux__
-  struct sysinfo info;
-  if (sysinfo(&info) != 0) {
-    return ErrnoError();
-  }
-
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
-  memory.total = Bytes(info.totalram * info.mem_unit);
-  memory.free = Bytes(info.freeram * info.mem_unit);
-# else
-  memory.total = Bytes(info.totalram);
-  memory.free = Bytes(info.freeram);
-# endif
-
-  return memory;
-
-#elif defined __APPLE__
-  const Try<int64_t> totalMemory = os::sysctl(CTL_HW, HW_MEMSIZE).integer();
-
-  if (totalMemory.isError()) {
-    return Error(totalMemory.error());
-  }
-  memory.total = Bytes(totalMemory.get());
-
-  // Size of free memory is available in terms of number of
-  // free pages on Mac OS X.
-  const long pageSize = sysconf(_SC_PAGESIZE);
-  if (pageSize < 0) {
-    return ErrnoError();
-  }
-
-  unsigned int freeCount;
-  size_t length = sizeof(freeCount);
-
-  if (sysctlbyname(
-      "vm.page_free_count",
-      &freeCount,
-      &length,
-      NULL,
-      0) != 0) {
-    return ErrnoError();
-  }
-  memory.free = Bytes(freeCount * pageSize);
-
-  return memory;
-
-#else
-  return Error("Cannot determine the size of total and free memory");
-#endif
-}
-
-
 inline Try<std::string> bootId()
 {
 #ifdef __linux__
@@ -1006,36 +331,6 @@ inline Try<std::string> bootId()
 }
 
 
-// The structure returned by uname describing the currently running system.
-struct UTSInfo
-{
-  std::string sysname;    // Operating system name (e.g. Linux).
-  std::string nodename;   // Network name of this machine.
-  std::string release;    // Release level of the operating system.
-  std::string version;    // Version level of the operating system.
-  std::string machine;    // Machine hardware platform.
-};
-
-
-// Return the system information.
-inline Try<UTSInfo> uname()
-{
-  struct utsname name;
-
-  if (::uname(&name) < 0) {
-    return ErrnoError();
-  }
-
-  UTSInfo info;
-  info.sysname = name.sysname;
-  info.nodename = name.nodename;
-  info.release = name.release;
-  info.version = name.version;
-  info.machine = name.machine;
-  return info;
-}
-
-
 // Return the operating system name (e.g. Linux).
 inline Try<std::string> sysname()
 {
@@ -1072,27 +367,6 @@ inline Try<Version> release()
 }
 
 
-inline Try<std::list<Process> > processes()
-{
-  const Try<std::set<pid_t>> pids = os::pids();
-
-  if (pids.isError()) {
-    return Error(pids.error());
-  }
-
-  std::list<Process> result;
-  foreach (pid_t pid, pids.get()) {
-    const Result<Process> process = os::process(pid);
-
-    // Ignore any processes that disappear.
-    if (process.isSome()) {
-      result.push_back(process.get());
-    }
-  }
-  return result;
-}
-
-
 inline Option<Process> process(
     pid_t pid,
     const std::list<Process>& processes)
@@ -1147,54 +421,6 @@ inline Try<std::set<pid_t> > children(pid_t pid, bool recursive = true)
 }
 
 
-// Overload of os::pids for filtering by groups and sessions.
-// A group / session id of 0 will fitler on the group / session ID
-// of the calling process.
-inline Try<std::set<pid_t> > pids(Option<pid_t> group, Option<pid_t> session)
-{
-  if (group.isNone() && session.isNone()) {
-    return os::pids();
-  } else if (group.isSome() && group.get() < 0) {
-    return Error("Invalid group");
-  } else if (session.isSome() && session.get() < 0) {
-    return Error("Invalid session");
-  }
-
-  const Try<std::list<Process>> processes = os::processes();
-
-  if (processes.isError()) {
-    return Error(processes.error());
-  }
-
-  // Obtain the calling process group / session ID when 0 is provided.
-  if (group.isSome() && group.get() == 0) {
-    group = getpgid(0);
-  }
-  if (session.isSome() && session.get() == 0) {
-    session = getsid(0);
-  }
-
-  std::set<pid_t> result;
-  foreach (const Process& process, processes.get()) {
-    // Group AND Session (intersection).
-    if (group.isSome() && session.isSome()) {
-      if (group.get() == process.group &&
-          process.session.isSome() &&
-          session.get() == process.session.get()) {
-        result.insert(process.pid);
-      }
-    } else if (group.isSome() && group.get() == process.group) {
-      result.insert(process.pid);
-    } else if (session.isSome() && process.session.isSome() &&
-               session.get() == process.session.get()) {
-      result.insert(process.pid);
-    }
-  }
-
-  return result;
-}
-
-
 namespace libraries {
 
 // Returns the full library name by adding prefix and extension to

http://git-wip-us.apache.org/repos/asf/mesos/blob/66fa10db/3rdparty/libprocess/3rdparty/stout/include/stout/os/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/os.hpp
new file mode 100644
index 0000000..82ccd76
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/os.hpp
@@ -0,0 +1,55 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_OS_HPP__
+#define __STOUT_OS_OS_HPP__
+
+#include <string>
+
+#include <stout/bytes.hpp>
+
+
+namespace os {
+
+// Structure returned by loadavg(). Encodes system load average
+// for the last 1, 5 and 15 minutes.
+struct Load {
+  double one;
+  double five;
+  double fifteen;
+};
+
+
+// Structure returned by memory() containing the total size of main
+// and free memory.
+struct Memory
+{
+  Bytes total;
+  Bytes free;
+};
+
+
+// The structure returned by uname describing the currently running system.
+struct UTSInfo
+{
+  std::string sysname;    // Operating system name (e.g. Linux).
+  std::string nodename;   // Network name of this machine.
+  std::string release;    // Release level of the operating system.
+  std::string version;    // Version level of the operating system.
+  std::string machine;    // Machine hardware platform.
+};
+
+
+} // namespace os {
+
+#endif // __STOUT_OS_OS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/66fa10db/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
new file mode 100644
index 0000000..c848268
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/os.hpp
@@ -0,0 +1,840 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_POSIX_OS_HPP__
+#define __STOUT_POSIX_OS_HPP__
+
+#ifdef __APPLE__
+#include <crt_externs.h> // For _NSGetEnviron().
+#endif
+#include <errno.h>
+#ifdef __sun
+#include <sys/loadavg.h>
+#else
+#include <fts.h>
+#endif // __sun
+#include <glob.h>
+#include <grp.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include <glog/logging.h>
+
+#ifdef __linux__
+#include <linux/version.h>
+#endif // __linux__
+
+#ifdef __linux__
+#include <sys/sysinfo.h>
+#endif // __linux__
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <stout/bytes.hpp>
+#include <stout/duration.hpp>
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/path.hpp>
+#include <stout/result.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+#include <stout/unreachable.hpp>
+
+#include <stout/os/close.hpp>
+#include <stout/os/exists.hpp>
+#include <stout/os/fcntl.hpp>
+#include <stout/os/fork.hpp>
+#ifdef __linux__
+#include <stout/os/linux.hpp>
+#endif // __linux__
+#include <stout/os/open.hpp>
+#ifdef __APPLE__
+#include <stout/os/osx.hpp>
+#endif // __APPLE__
+#ifdef __sun
+#include <stout/os/sunos.hpp>
+#endif // __sun
+#ifdef __APPLE__
+#include <stout/os/sysctl.hpp>
+#endif // __APPLE__
+
+// Need to declare 'environ' pointer for non OS X platforms.
+#ifndef __APPLE__
+extern char** environ;
+#endif
+
+namespace os {
+
+// Forward declarations.
+inline Try<Nothing> utime(const std::string&);
+inline Try<Nothing> write(int, const std::string&);
+
+inline char** environ()
+{
+  // Accessing the list of environment variables is platform-specific.
+  // On OS X, the 'environ' symbol isn't visible to shared libraries,
+  // so we must use the _NSGetEnviron() function (see 'man environ' on
+  // OS X). On other platforms, it's fine to access 'environ' from
+  // shared libraries.
+#ifdef __APPLE__
+  return *_NSGetEnviron();
+#else
+  return ::environ;
+#endif
+}
+
+
+// Returns the address of os::environ().
+inline char*** environp()
+{
+  // Accessing the list of environment variables is platform-specific.
+  // On OS X, the 'environ' symbol isn't visible to shared libraries,
+  // so we must use the _NSGetEnviron() function (see 'man environ' on
+  // OS X). On other platforms, it's fine to access 'environ' from
+  // shared libraries.
+#ifdef __APPLE__
+  return _NSGetEnviron();
+#else
+  return &::environ;
+#endif
+}
+
+
+// Sets the value associated with the specified key in the set of
+// environment variables.
+inline void setenv(const std::string& key,
+                   const std::string& value,
+                   bool overwrite = true)
+{
+  ::setenv(key.c_str(), value.c_str(), overwrite ? 1 : 0);
+}
+
+
+// Unsets the value associated with the specified key in the set of
+// environment variables.
+inline void unsetenv(const std::string& key)
+{
+  ::unsetenv(key.c_str());
+}
+
+
+inline Try<Nothing> touch(const std::string& path)
+{
+  if (!exists(path)) {
+    Try<int> fd = open(
+        path,
+        O_RDWR | O_CREAT,
+        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+    if (fd.isError()) {
+      return Error("Failed to open file: " + fd.error());
+    }
+
+    return close(fd.get());
+  }
+
+  // Update the access and modification times.
+  return utime(path);
+}
+
+
+// A wrapper function that wraps the above write() with
+// open and closing the file.
+inline Try<Nothing> write(const std::string& path, const std::string& message)
+{
+  Try<int> fd = os::open(
+      path,
+      O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
+      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+  if (fd.isError()) {
+    return ErrnoError("Failed to open file '" + path + "'");
+  }
+
+  Try<Nothing> result = write(fd.get(), message);
+
+  // We ignore the return value of close(). This is because users
+  // calling this function are interested in the return value of
+  // write(). Also an unsuccessful close() doesn't affect the write.
+  os::close(fd.get());
+
+  return result;
+}
+
+
+inline Try<Nothing> rm(const std::string& path)
+{
+  if (::remove(path.c_str()) != 0) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+// Creates a temporary directory using the specified path
+// template. The template may be any path with _6_ `Xs' appended to
+// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
+// with a unique alphanumeric combination.
+inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
+{
+  char* temp = new char[path.size() + 1];
+  if (::mkdtemp(::strcpy(temp, path.c_str())) != NULL) {
+    std::string result(temp);
+    delete[] temp;
+    return result;
+  } else {
+    delete[] temp;
+    return ErrnoError();
+  }
+}
+
+
+// By default, recursively deletes a directory akin to: 'rm -r'. If the
+// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
+// Note that this function expects an absolute path.
+#ifndef __sun // FTS is not available on Solaris.
+inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
+{
+  if (!recursive) {
+    if (::rmdir(directory.c_str()) < 0) {
+      return ErrnoError();
+    }
+  } else {
+    char* paths[] = {const_cast<char*>(directory.c_str()), NULL};
+
+    FTS* tree = fts_open(paths, FTS_NOCHDIR, NULL);
+    if (tree == NULL) {
+      return ErrnoError();
+    }
+
+    FTSENT* node;
+    while ((node = fts_read(tree)) != NULL) {
+      switch (node->fts_info) {
+        case FTS_DP:
+          if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
+            return ErrnoError();
+          }
+          break;
+        case FTS_F:
+        case FTS_SL:
+          if (::unlink(node->fts_path) < 0 && errno != ENOENT) {
+            return ErrnoError();
+          }
+          break;
+        default:
+          break;
+      }
+    }
+
+    if (errno != 0) {
+      return ErrnoError();
+    }
+
+    if (fts_close(tree) < 0) {
+      return ErrnoError();
+    }
+  }
+
+  return Nothing();
+}
+#endif // __sun
+
+
+// Executes a command by calling "/bin/sh -c <command>", and returns
+// after the command has been completed. Returns 0 if succeeds, and
+// return -1 on error (e.g., fork/exec/waitpid failed). This function
+// is async signal safe. We return int instead of returning a Try
+// because Try involves 'new', which is not async signal safe.
+inline int system(const std::string& command)
+{
+  pid_t pid = ::fork();
+
+  if (pid == -1) {
+    return -1;
+  } else if (pid == 0) {
+    // In child process.
+    ::execl("/bin/sh", "sh", "-c", command.c_str(), (char*) NULL);
+    ::exit(127);
+  } else {
+    // In parent process.
+    int status;
+    while (::waitpid(pid, &status, 0) == -1) {
+      if (errno != EINTR) {
+        return -1;
+      }
+    }
+
+    return status;
+  }
+}
+
+
+// This function is a portable version of execvpe ('p' means searching
+// executable from PATH and 'e' means setting environments). We add
+// this function because it is not available on all systems.
+//
+// NOTE: This function is not thread safe. It is supposed to be used
+// only after fork (when there is only one thread). This function is
+// async signal safe.
+inline int execvpe(const char* file, char** argv, char** envp)
+{
+  char** saved = os::environ();
+
+  *os::environp() = envp;
+
+  int result = execvp(file, argv);
+
+  *os::environp() = saved;
+
+  return result;
+}
+
+
+inline Try<Nothing> chown(
+    uid_t uid,
+    gid_t gid,
+    const std::string& path,
+    bool recursive)
+{
+  if (recursive) {
+    // TODO(bmahler): Consider walking the file tree instead. We would need
+    // to be careful to not miss dotfiles.
+    std::string command =
+      "chown -R " + stringify(uid) + ':' + stringify(gid) + " '" + path + "'";
+
+    int status = os::system(command);
+    if (status != 0) {
+      return ErrnoError(
+          "Failed to execute '" + command +
+          "' (exit status: " + stringify(status) + ")");
+    }
+  } else {
+    if (::chown(path.c_str(), uid, gid) < 0) {
+      return ErrnoError();
+    }
+  }
+
+  return Nothing();
+}
+
+
+// Changes the specified path's user and group ownership to that of
+// the specified user.
+inline Try<Nothing> chown(
+    const std::string& user,
+    const std::string& path,
+    bool recursive = true)
+{
+  passwd* passwd;
+  if ((passwd = ::getpwnam(user.c_str())) == NULL) {
+    return ErrnoError("Failed to get user information for '" + user + "'");
+  }
+
+  return chown(passwd->pw_uid, passwd->pw_gid, path, recursive);
+}
+
+
+inline Try<Nothing> chmod(const std::string& path, int mode)
+{
+  if (::chmod(path.c_str(), mode) < 0) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+inline Try<Nothing> chdir(const std::string& directory)
+{
+  if (::chdir(directory.c_str()) < 0) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+inline Try<Nothing> chroot(const std::string& directory)
+{
+  if (::chroot(directory.c_str()) < 0) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+inline Try<Nothing> mknod(
+    const std::string& path,
+    mode_t mode,
+    dev_t dev)
+{
+  if (::mknod(path.c_str(), mode, dev) < 0) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+inline Result<uid_t> getuid(const Option<std::string>& user = None())
+{
+  if (user.isNone()) {
+    return ::getuid();
+  }
+
+  struct passwd passwd;
+  struct passwd* result = NULL;
+
+  int size = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (size == -1) {
+    // Initial value for buffer size.
+    size = 1024;
+  }
+
+  while (true) {
+    char* buffer = new char[size];
+
+    if (getpwnam_r(user.get().c_str(), &passwd, buffer, size, &result) == 0) {
+      // The usual interpretation of POSIX is that getpwnam_r will
+      // return 0 but set result == NULL if the user is not found.
+      if (result == NULL) {
+        delete[] buffer;
+        return None();
+      }
+
+      uid_t uid = passwd.pw_uid;
+      delete[] buffer;
+      return uid;
+    } else {
+      // RHEL7 (and possibly other systems) will return non-zero and
+      // set one of the following errors for "The given name or uid
+      // was not found." See 'man getpwnam_r'. We only check for the
+      // errors explicitly listed, and do not consider the ellipsis.
+      if (errno == ENOENT ||
+          errno == ESRCH ||
+          errno == EBADF ||
+          errno == EPERM) {
+        delete[] buffer;
+        return None();
+      }
+
+      if (errno != ERANGE) {
+        delete[] buffer;
+        return ErrnoError("Failed to get username information");
+      }
+      // getpwnam_r set ERANGE so try again with a larger buffer.
+      size *= 2;
+      delete[] buffer;
+    }
+  }
+
+  UNREACHABLE();
+}
+
+
+inline Result<gid_t> getgid(const Option<std::string>& user = None())
+{
+  if (user.isNone()) {
+    return ::getgid();
+  }
+
+  struct passwd passwd;
+  struct passwd* result = NULL;
+
+  int size = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (size == -1) {
+    // Initial value for buffer size.
+    size = 1024;
+  }
+
+  while (true) {
+    char* buffer = new char[size];
+
+    if (getpwnam_r(user.get().c_str(), &passwd, buffer, size, &result) == 0) {
+      // The usual interpretation of POSIX is that getpwnam_r will
+      // return 0 but set result == NULL if the group is not found.
+      if (result == NULL) {
+        delete[] buffer;
+        return None();
+      }
+
+      gid_t gid = passwd.pw_gid;
+      delete[] buffer;
+      return gid;
+    } else {
+      // RHEL7 (and possibly other systems) will return non-zero and
+      // set one of the following errors for "The given name or uid
+      // was not found." See 'man getpwnam_r'. We only check for the
+      // errors explicitly listed, and do not consider the ellipsis.
+      if (errno == ENOENT ||
+          errno == ESRCH ||
+          errno == EBADF ||
+          errno == EPERM) {
+        delete[] buffer;
+        return None();
+      }
+
+      if (errno != ERANGE) {
+        delete[] buffer;
+        return ErrnoError("Failed to get username information");
+      }
+      // getpwnam_r set ERANGE so try again with a larger buffer.
+      size *= 2;
+      delete[] buffer;
+    }
+  }
+
+  UNREACHABLE();
+}
+
+
+inline Try<Nothing> su(const std::string& user)
+{
+  Result<gid_t> gid = os::getgid(user);
+  if (gid.isError() || gid.isNone()) {
+    return Error("Failed to getgid: " +
+        (gid.isError() ? gid.error() : "unknown user"));
+  } else if (::setgid(gid.get())) {
+    return ErrnoError("Failed to set gid");
+  }
+
+  // Set the supplementary group list. We ignore EPERM because
+  // performing a no-op call (switching to same group) still
+  // requires being privileged, unlike 'setgid' and 'setuid'.
+  if (::initgroups(user.c_str(), gid.get()) == -1 && errno != EPERM) {
+    return ErrnoError("Failed to set supplementary groups");
+  }
+
+  Result<uid_t> uid = os::getuid(user);
+  if (uid.isError() || uid.isNone()) {
+    return Error("Failed to getuid: " +
+        (uid.isError() ? uid.error() : "unknown user"));
+  } else if (::setuid(uid.get())) {
+    return ErrnoError("Failed to setuid");
+  }
+
+  return Nothing();
+}
+
+
+inline std::string getcwd()
+{
+  size_t size = 100;
+
+  while (true) {
+    char* temp = new char[size];
+    if (::getcwd(temp, size) == temp) {
+      std::string result(temp);
+      delete[] temp;
+      return result;
+    } else {
+      if (errno != ERANGE) {
+        delete[] temp;
+        return std::string();
+      }
+      size *= 2;
+      delete[] temp;
+    }
+  }
+
+  return std::string();
+}
+
+
+inline Result<std::string> user(Option<uid_t> uid = None())
+{
+  if (uid.isNone()) {
+    uid = ::getuid();
+  }
+
+  int size = sysconf(_SC_GETPW_R_SIZE_MAX);
+  if (size == -1) {
+    // Initial value for buffer size.
+    size = 1024;
+  }
+
+  struct passwd passwd;
+  struct passwd* result = NULL;
+
+  while (true) {
+    char* buffer = new char[size];
+
+    if (getpwuid_r(uid.get(), &passwd, buffer, size, &result) == 0) {
+      // getpwuid_r will return 0 but set result == NULL if the uid is
+      // not found.
+      if (result == NULL) {
+        delete[] buffer;
+        return None();
+      }
+
+      std::string user(passwd.pw_name);
+      delete[] buffer;
+      return user;
+    } else {
+      if (errno != ERANGE) {
+        delete[] buffer;
+        return ErrnoError();
+      }
+
+      // getpwuid_r set ERANGE so try again with a larger buffer.
+      size *= 2;
+      delete[] buffer;
+    }
+  }
+}
+
+
+// Suspends execution for the given duration.
+inline Try<Nothing> sleep(const Duration& duration)
+{
+  timespec remaining;
+  remaining.tv_sec = static_cast<long>(duration.secs());
+  remaining.tv_nsec =
+    static_cast<long>((duration - Seconds(remaining.tv_sec)).ns());
+
+  while (nanosleep(&remaining, &remaining) == -1) {
+    if (errno == EINTR) {
+      continue;
+    } else {
+      return ErrnoError();
+    }
+  }
+
+  return Nothing();
+}
+
+
+// Returns the list of files that match the given (shell) pattern.
+inline Try<std::list<std::string>> glob(const std::string& pattern)
+{
+  glob_t g;
+  int status = ::glob(pattern.c_str(), GLOB_NOSORT, NULL, &g);
+
+  std::list<std::string> result;
+
+  if (status != 0) {
+    if (status == GLOB_NOMATCH) {
+      return result; // Empty list.
+    } else {
+      return ErrnoError();
+    }
+  }
+
+  for (size_t i = 0; i < g.gl_pathc; ++i) {
+    result.push_back(g.gl_pathv[i]);
+  }
+
+  globfree(&g); // Best-effort free of dynamically allocated memory.
+
+  return result;
+}
+
+
+// Returns the total number of cpus (cores).
+inline Try<long> cpus()
+{
+  long cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+  if (cpus < 0) {
+    return ErrnoError();
+  }
+  return cpus;
+}
+
+
+// Returns load struct with average system loads for the last
+// 1, 5 and 15 minutes respectively.
+// Load values should be interpreted as usual average loads from
+// uptime(1).
+inline Try<Load> loadavg()
+{
+  double loadArray[3];
+  if (getloadavg(loadArray, 3) == -1) {
+    return ErrnoError("Failed to determine system load averages");
+  }
+
+  Load load;
+  load.one = loadArray[0];
+  load.five = loadArray[1];
+  load.fifteen = loadArray[2];
+
+  return load;
+}
+
+
+// Returns the total size of main and free memory.
+inline Try<Memory> memory()
+{
+  Memory memory;
+
+#ifdef __linux__
+  struct sysinfo info;
+  if (sysinfo(&info) != 0) {
+    return ErrnoError();
+  }
+
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
+  memory.total = Bytes(info.totalram * info.mem_unit);
+  memory.free = Bytes(info.freeram * info.mem_unit);
+# else
+  memory.total = Bytes(info.totalram);
+  memory.free = Bytes(info.freeram);
+# endif
+
+  return memory;
+
+#elif defined __APPLE__
+  const Try<int64_t> totalMemory = os::sysctl(CTL_HW, HW_MEMSIZE).integer();
+
+  if (totalMemory.isError()) {
+    return Error(totalMemory.error());
+  }
+  memory.total = Bytes(totalMemory.get());
+
+  // Size of free memory is available in terms of number of
+  // free pages on Mac OS X.
+  const long pageSize = sysconf(_SC_PAGESIZE);
+  if (pageSize < 0) {
+    return ErrnoError();
+  }
+
+  unsigned int freeCount;
+  size_t length = sizeof(freeCount);
+
+  if (sysctlbyname(
+      "vm.page_free_count",
+      &freeCount,
+      &length,
+      NULL,
+      0) != 0) {
+    return ErrnoError();
+  }
+  memory.free = Bytes(freeCount * pageSize);
+
+  return memory;
+
+#else
+  return Error("Cannot determine the size of total and free memory");
+#endif
+}
+
+
+// Return the system information.
+inline Try<UTSInfo> uname()
+{
+  struct utsname name;
+
+  if (::uname(&name) < 0) {
+    return ErrnoError();
+  }
+
+  UTSInfo info;
+  info.sysname = name.sysname;
+  info.nodename = name.nodename;
+  info.release = name.release;
+  info.version = name.version;
+  info.machine = name.machine;
+  return info;
+}
+
+
+inline Try<std::list<Process>> processes()
+{
+  const Try<std::set<pid_t>> pids = os::pids();
+
+  if (pids.isError()) {
+    return Error(pids.error());
+  }
+
+  std::list<Process> result;
+  foreach (pid_t pid, pids.get()) {
+    const Result<Process> process = os::process(pid);
+
+    // Ignore any processes that disappear.
+    if (process.isSome()) {
+      result.push_back(process.get());
+    }
+  }
+  return result;
+}
+
+
+// Overload of os::pids for filtering by groups and sessions.
+// A group / session id of 0 will fitler on the group / session ID
+// of the calling process.
+inline Try<std::set<pid_t>> pids(Option<pid_t> group, Option<pid_t> session)
+{
+  if (group.isNone() && session.isNone()) {
+    return os::pids();
+  } else if (group.isSome() && group.get() < 0) {
+    return Error("Invalid group");
+  } else if (session.isSome() && session.get() < 0) {
+    return Error("Invalid session");
+  }
+
+  const Try<std::list<Process>> processes = os::processes();
+
+  if (processes.isError()) {
+    return Error(processes.error());
+  }
+
+  // Obtain the calling process group / session ID when 0 is provided.
+  if (group.isSome() && group.get() == 0) {
+    group = getpgid(0);
+  }
+  if (session.isSome() && session.get() == 0) {
+    session = getsid(0);
+  }
+
+  std::set<pid_t> result;
+  foreach (const Process& process, processes.get()) {
+    // Group AND Session (intersection).
+    if (group.isSome() && session.isSome()) {
+      if (group.get() == process.group &&
+          process.session.isSome() &&
+          session.get() == process.session.get()) {
+        result.insert(process.pid);
+      }
+    } else if (group.isSome() && group.get() == process.group) {
+      result.insert(process.pid);
+    } else if (session.isSome() && process.session.isSome() &&
+               session.get() == process.session.get()) {
+      result.insert(process.pid);
+    }
+  }
+
+  return result;
+}
+
+} // namespace os {
+
+#endif // __STOUT_POSIX_OS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/66fa10db/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
new file mode 100644
index 0000000..7e1b0f8
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/os.hpp
@@ -0,0 +1,274 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_WINDOWS_OS_HPP__
+#define __STOUT_WINDOWS_OS_HPP__
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+
+#include <stout/duration.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/path.hpp>
+#include <stout/try.hpp>
+#include <stout/windows/preprocessor.hpp>
+
+
+namespace os {
+
+inline char** environ()
+{
+  // Defined in stdlib.h.
+  return ::_environ;
+}
+
+
+// Returns the address of os::environ().
+inline char*** environp()
+{
+  return &::_environ;
+}
+
+
+// Sets the value associated with the specified key in the set of
+// environment variables.
+inline void setenv(const std::string& key,
+                   const std::string& value,
+                   bool overwrite = true)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Unsets the value associated with the specified key in the set of
+// environment variables.
+inline void unsetenv(const std::string& key)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> touch(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+// A wrapper function that wraps the above write() with
+// open and closing the file.
+inline Try<Nothing> write(const std::string& path, const std::string& message)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> rm(const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Creates a temporary directory using the specified path
+// template. The template may be any path with _6_ `Xs' appended to
+// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
+// with a unique alphanumeric combination.
+inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
+{
+  UNIMPLEMENTED;
+}
+
+
+// By default, recursively deletes a directory akin to: 'rm -r'. If the
+// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
+// Note that this function expects an absolute path.
+inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Executes a command by calling "/bin/sh -c <command>", and returns
+// after the command has been completed. Returns 0 if succeeds, and
+// return -1 on error (e.g., fork/exec/waitpid failed). This function
+// is async signal safe. We return int instead of returning a Try
+// because Try involves 'new', which is not async signal safe.
+inline int system(const std::string& command)
+{
+  UNIMPLEMENTED;
+}
+
+
+// This function is a portable version of execvpe ('p' means searching
+// executable from PATH and 'e' means setting environments). We add
+// this function because it is not available on all systems.
+//
+// NOTE: This function is not thread safe. It is supposed to be used
+// only after fork (when there is only one thread). This function is
+// async signal safe.
+inline int execvpe(const char* file, char** argv, char** envp)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> chown(
+    uid_t uid,
+    gid_t gid,
+    const std::string& path,
+    bool recursive)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Changes the specified path's user and group ownership to that of
+// the specified user.
+inline Try<Nothing> chown(
+    const std::string& user,
+    const std::string& path,
+    bool recursive = true)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> chmod(const std::string& path, int mode)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> chdir(const std::string& directory)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> chroot(const std::string& directory)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> mknod(
+    const std::string& path,
+    mode_t mode,
+    dev_t dev)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Result<uid_t> getuid(const Option<std::string>& user = None())
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Result<gid_t> getgid(const Option<std::string>& user = None())
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<Nothing> su(const std::string& user)
+{
+  UNIMPLEMENTED;
+}
+
+
+inline std::string getcwd()
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Result<std::string> user(Option<uid_t> uid = None())
+{
+  UNIMPLEMENTED;
+}
+
+
+// Suspends execution for the given duration.
+inline Try<Nothing> sleep(const Duration& duration)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns the list of files that match the given (shell) pattern.
+inline Try<std::list<std::string>> glob(const std::string& pattern)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns the total number of cpus (cores).
+inline Try<long> cpus()
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns load struct with average system loads for the last
+// 1, 5 and 15 minutes respectively.
+// Load values should be interpreted as usual average loads from
+// uptime(1).
+inline Try<Load> loadavg()
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns the total size of main and free memory.
+inline Try<Memory> memory()
+{
+  UNIMPLEMENTED;
+}
+
+
+// Return the system information.
+inline Try<UTSInfo> uname()
+{
+  UNIMPLEMENTED;
+}
+
+
+inline Try<std::list<Process>> processes()
+{
+  UNIMPLEMENTED;
+}
+
+
+// Overload of os::pids for filtering by groups and sessions.
+// A group / session id of 0 will fitler on the group / session ID
+// of the calling process.
+inline Try<std::set<pid_t>> pids(Option<pid_t> group, Option<pid_t> session)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace os {
+
+#endif // __STOUT_WINDOWS_OS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/66fa10db/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
index de41db6..7ab75ec 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
@@ -31,4 +31,31 @@
 // TODO(aclemmer): Not defined on Windows.  This value is temporary.
 #define MAXHOSTNAMELEN 64
 
+// Macros associated with ::access, usually defined in unistd.h.
+#define access(path, how) _access(path, how)
+#define R_OK 0x4
+#define W_OK 0x2
+#define X_OK 0x0 // No such permission on Windows
+#define F_OK 0x0
+
+// Aliases for file access modes (defined in fcntl.h).
+#define O_RDONLY _O_RDONLY
+#define O_WRONLY _O_WRONLY
+#define O_RDWR _O_RDWR
+#define O_CREAT _O_CREAT
+#define O_TRUNC _O_TRUNC
+#define O_APPEND _O_APPEND
+// TODO(josephw): No equivalent for O_NONBLOCK or O_SYNC
+
+// Alias for mkstemp (requires io.h).
+#define mkstemp(path) _mktemp_s(path, strlen(path) + 1)
+
+// Alias for realpath.
+#define PATH_MAX MAX_PATH
+#define realpath(path, resolved) _fullpath(resolved, path, PATH_MAX)
+
+// Alias for mkdir (requires direct.h).
+#define mkdir(path, mode) _mkdir(path)
+
+
 #endif // __STOUT_WINDOWS_PREPROCESSOR_HPP__


[4/4] mesos git commit: Split up platform specific functions into separate headers.

Posted by be...@apache.org.
Split up platform specific functions into separate headers.

To support the upcoming Windows Containerizer (MESOS-3094), we're
splitting up (refactoring) platform specific functions into separate
files.

We will avoid having `#ifdef __WINDOWS__` all over the stout/libprcess
code by separating Posix/Windows versions. This first patch is to
establish a pattern in splitting up the headers.

Patterns:

* gzip.hpp, thread.hpp - Functions are moved to a Posix folder; copied
  to a Windows folder and gutted for later implementation.
* abort.hpp, exit.hpp, unreachable.hpp - Added macro for
  `__attribute__((noreturn))`.
* duration.hpp - An #ifdef for one of the headers (time.h vs
  Winsock2.h). No need to split the header.
* format.hpp - Missing Windows function (vasprintf) implementation
  added.
* ip.hpp - Added aliases for Windows functions.
* net.hpp - Curl functions were moved to Posix/Windows folders.

Other:

* Instances of #include "local file.hpp" were changed to #include
  <stout/local file.hpp>" to match os.hpp.
* Some missing #endif comments (i.e. `// __APPLE__`) were added.

Review: https://reviews.apache.org/r/36625


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f8dd73df
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f8dd73df
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f8dd73df

Branch: refs/heads/master
Commit: f8dd73dfd1621f0da883a1e65f4fa73c9ddff23f
Parents: 8661672
Author: Joseph Wu <jo...@mesosphere.io>
Authored: Thu Jul 30 15:40:42 2015 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Thu Jul 30 16:25:05 2015 -0700

----------------------------------------------------------------------
 .../3rdparty/stout/include/Makefile.am          |   9 +-
 .../3rdparty/stout/include/stout/abort.hpp      |  19 +-
 .../3rdparty/stout/include/stout/attributes.hpp |  25 +++
 .../3rdparty/stout/include/stout/duration.hpp   |   8 +-
 .../3rdparty/stout/include/stout/exit.hpp       |   7 +-
 .../3rdparty/stout/include/stout/format.hpp     |  14 +-
 .../3rdparty/stout/include/stout/gzip.hpp       | 136 +------------
 .../3rdparty/stout/include/stout/ip.hpp         |  44 ++--
 .../3rdparty/stout/include/stout/net.hpp        | 200 +++++--------------
 .../3rdparty/stout/include/stout/posix/gzip.hpp | 150 ++++++++++++++
 .../3rdparty/stout/include/stout/posix/net.hpp  | 166 +++++++++++++++
 .../stout/include/stout/unreachable.hpp         |   9 +-
 .../stout/include/stout/windows/format.hpp      |  69 +++++++
 .../stout/include/stout/windows/gzip.hpp        |  47 +++++
 .../stout/include/stout/windows/net.hpp         |  46 +++++
 .../include/stout/windows/preprocessor.hpp      |  34 ++++
 16 files changed, 675 insertions(+), 308 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index b299ce8..cb40231 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -13,6 +13,7 @@
 # Headers.
 nobase_include_HEADERS =		\
   stout/abort.hpp			\
+  stout/attributes.hpp			\
   stout/base64.hpp			\
   stout/bits.hpp			\
   stout/bytes.hpp			\
@@ -40,6 +41,8 @@ nobase_include_HEADERS =		\
   stout/json.hpp			\
   stout/lambda.hpp			\
   stout/linkedhashmap.hpp		\
+  stout/posix/gzip.hpp			\
+  stout/posix/net.hpp			\
   stout/list.hpp			\
   stout/mac.hpp				\
   stout/multihashmap.hpp		\
@@ -89,4 +92,8 @@ nobase_include_HEADERS =		\
   stout/unreachable.hpp			\
   stout/utils.hpp			\
   stout/uuid.hpp			\
-  stout/version.hpp
+  stout/version.hpp			\
+  stout/windows/format.hpp		\
+  stout/windows/gzip.hpp		\
+  stout/windows/net.hpp			\
+  stout/windows/preprocessor.hpp	\

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
index 3aa9487..f620f39 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
@@ -18,10 +18,18 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifdef __WINDOWS__
+#include <stout/windows/preprocessor.hpp>
+#else
 #include <unistd.h>
+#endif // __WINDOWS__
 
 #include <string>
 
+#include <stout/attributes.hpp>
+
+
 // Signal safe abort which prints a message.
 #define __STRINGIZE(x) #x
 #define _STRINGIZE(x) __STRINGIZE(x)
@@ -29,9 +37,8 @@
 
 #define ABORT(...) _Abort(_ABORT_PREFIX, __VA_ARGS__)
 
-inline __attribute__((noreturn)) void _Abort(
-    const char* prefix,
-    const char* message)
+
+inline NORETURN void _Abort(const char* prefix, const char* message)
 {
   // Write the failure message in an async-signal safe manner,
   // assuming strlen is async-signal safe or optimized out.
@@ -47,10 +54,10 @@ inline __attribute__((noreturn)) void _Abort(
 }
 
 
-inline __attribute__((noreturn)) void _Abort(
-  const char* prefix,
-  const std::string& message) {
+inline NORETURN void _Abort(const char* prefix, const std::string& message)
+{
   _Abort(prefix, message.c_str());
 }
 
+
 #endif // __STOUT_ABORT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/attributes.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/attributes.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/attributes.hpp
new file mode 100644
index 0000000..2708704
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/attributes.hpp
@@ -0,0 +1,25 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_ATTRIBUTES_HPP__
+#define __STOUT_ATTRIBUTES_HPP__
+
+
+#ifdef __WINDOWS__
+#define NORETURN __declspec(noreturn)
+#else
+#define NORETURN __attribute__((noreturn))
+#endif // __WINDOWS__
+
+
+#endif // __STOUT_ATTRIBUTES_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
index bba8303..35fb034 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
@@ -16,7 +16,13 @@
 
 #include <ctype.h> // For 'isdigit'.
 #include <limits.h> // For 'LLONG_(MAX|MIN)'.
-#include <time.h> // For 'timeval'.
+
+// For 'timeval'.
+#ifdef __WINDOWS__
+#include <Winsock2.h>
+#else
+#include <time.h>
+#endif // __WINDOWS__
 
 #include <iomanip>
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
index 8c16a22..38dabd4 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
@@ -21,6 +21,9 @@
 #include <sstream>
 #include <string>
 
+#include <stout/attributes.hpp>
+
+
 // Exit takes an exit status and provides a stream for output prior to
 // exiting. This is like glog's LOG(FATAL) or CHECK, except that it
 // does _not_ print a stack trace.
@@ -28,11 +31,12 @@
 // Ex: EXIT(1) << "Cgroups are not present in this system.";
 #define EXIT(status) __Exit(status).stream()
 
+
 struct __Exit
 {
   __Exit(int _status) : status(_status) {}
 
-  __attribute__((noreturn)) ~__Exit()
+  NORETURN ~__Exit()
   {
     std::cerr << out.str() << std::endl;
     exit(status);
@@ -47,4 +51,5 @@ struct __Exit
   const int status;
 };
 
+
 #endif // __STOUT_EXIT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
index 4e8c3bd..6926756 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
@@ -15,14 +15,20 @@
 #define __STOUT_FORMAT_HPP__
 
 #include <stdarg.h> // For 'va_list', 'va_start', 'va_end'.
-#include <stdio.h> // For 'vasprintf'.
+
+// For 'vasprintf'.
+#ifdef __WINDOWS__
+#include <stout/windows/format.hpp>
+#else
+#include <stdio.h>
+#endif // __WINDOWS__
 
 #include <string>
 #include <type_traits> // For 'is_pod'.
 
-#include "error.hpp"
-#include "stringify.hpp"
-#include "try.hpp"
+#include <stout/error.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
 
 
 // The 'strings::format' functions produces strings based on the

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
index 0b95819..85c773a 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
@@ -14,136 +14,14 @@
 #ifndef __STOUT_GZIP_HPP__
 #define __STOUT_GZIP_HPP__
 
-#include <zlib.h>
 
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/windows/gzip.hpp>
+#else
+#include <stout/posix/gzip.hpp>
+#endif // __WINDOWS__
 
-#include "error.hpp"
-#include "stringify.hpp"
-#include "try.hpp"
-
-// Compression utilities.
-// TODO(bmahler): Provide streaming compression / decompression as well.
-namespace gzip {
-
-// We use a 16KB buffer with zlib compression / decompression.
-#define GZIP_BUFFER_SIZE 16384
-
-// Returns a gzip compressed version of the provided string.
-// The compression level should be within the range [-1, 9].
-// See zlib.h:
-//   #define Z_NO_COMPRESSION         0
-//   #define Z_BEST_SPEED             1
-//   #define Z_BEST_COMPRESSION       9
-//   #define Z_DEFAULT_COMPRESSION  (-1)
-inline Try<std::string> compress(
-    const std::string& decompressed,
-    int level = Z_DEFAULT_COMPRESSION)
-{
-  // Verify the level is within range.
-  if (!(level == Z_DEFAULT_COMPRESSION ||
-      (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION))) {
-    return Error("Invalid compression level: " + stringify(level));
-  }
-
-  z_stream_s stream;
-  stream.next_in =
-    const_cast<Bytef*>(reinterpret_cast<const Bytef*>(decompressed.data()));
-  stream.avail_in = decompressed.length();
-  stream.zalloc = Z_NULL;
-  stream.zfree = Z_NULL;
-  stream.opaque = Z_NULL;
-
-  int code = deflateInit2(
-      &stream,
-      level,          // Compression level.
-      Z_DEFLATED,     // Compression method.
-      MAX_WBITS + 16, // Zlib magic for gzip compression / decompression.
-      8,              // Default memLevel value.
-      Z_DEFAULT_STRATEGY);
-
-  if (code != Z_OK) {
-    return Error("Failed to initialize zlib: " + std::string(stream.msg));
-  }
-
-  // Build up the compressed result.
-  Bytef buffer[GZIP_BUFFER_SIZE];
-  std::string result = "";
-  do {
-    stream.next_out = buffer;
-    stream.avail_out = GZIP_BUFFER_SIZE;
-    code = deflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
-
-    if (code != Z_OK && code != Z_STREAM_END) {
-      Error error(std::string(stream.msg));
-      deflateEnd(&stream);
-      return error;
-    }
-
-    // Consume output and reset the buffer.
-    result.append(
-        reinterpret_cast<char*>(buffer),
-        GZIP_BUFFER_SIZE - stream.avail_out);
-    stream.next_out = buffer;
-    stream.avail_out = GZIP_BUFFER_SIZE;
-  } while (code != Z_STREAM_END);
-
-  code = deflateEnd(&stream);
-  if (code != Z_OK) {
-    return Error("Failed to clean up zlib: " + std::string(stream.msg));
-  }
-  return result;
-}
-
-
-// Returns a gzip decompressed version of the provided string.
-inline Try<std::string> decompress(const std::string& compressed)
-{
-  z_stream_s stream;
-  stream.next_in =
-    const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
-  stream.avail_in = compressed.length();
-  stream.zalloc = Z_NULL;
-  stream.zfree = Z_NULL;
-  stream.opaque = Z_NULL;
-
-  int code = inflateInit2(
-      &stream,
-      MAX_WBITS + 16); // Zlib magic for gzip compression / decompression.
-
-  if (code != Z_OK) {
-    return Error("Failed to initialize zlib: " + std::string(stream.msg));
-  }
-
-  // Build up the decompressed result.
-  Bytef buffer[GZIP_BUFFER_SIZE];
-  std::string result = "";
-  do {
-    stream.next_out = buffer;
-    stream.avail_out = GZIP_BUFFER_SIZE;
-    code = inflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
-
-    if (code != Z_OK && code != Z_STREAM_END) {
-      Error error(std::string(stream.msg));
-      inflateEnd(&stream);
-      return error;
-    }
-
-    // Consume output and reset the buffer.
-    result.append(
-        reinterpret_cast<char*>(buffer),
-        GZIP_BUFFER_SIZE - stream.avail_out);
-    stream.next_out = buffer;
-    stream.avail_out = GZIP_BUFFER_SIZE;
-  } while (code != Z_STREAM_END);
-
-  code = inflateEnd(&stream);
-  if (code != Z_OK) {
-    return Error("Failed to clean up zlib: " + std::string(stream.msg));
-  }
-  return result;
-}
-
-} // namespace gzip {
 
 #endif // __STOUT_GZIP_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
index a0ea237..41ceb2e 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
@@ -14,11 +14,16 @@
 #ifndef __STOUT_IP_HPP__
 #define __STOUT_IP_HPP__
 
+// For 'sockaddr'.
+#ifdef __WINDOWS__
+#include <Winsock2.h>
+#else
 #include <arpa/inet.h>
+#endif // __WINDOWS__
 
 #if defined(__linux__) || defined(__APPLE__)
 #include <ifaddrs.h>
-#endif
+#endif // __linux__ || __APPLE__
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
@@ -27,11 +32,18 @@
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
-#endif
+#endif // __APPLE__
 
+// Note: Header grouping and ordering is considered before
+// inclusion/exclusion by platform.
+// For 'inet_pton', 'inet_ntop'.
+#ifdef __WINDOWS__
+#include <Ws2tcpip.h>
+#else
 #include <netinet/in.h>
-
 #include <sys/socket.h>
+#endif // __WINDOWS__
+
 #include <sys/types.h>
 
 #include <iostream>
@@ -39,17 +51,21 @@
 #include <vector>
 
 
-#include "abort.hpp"
-#include "bits.hpp"
-#include "error.hpp"
-#include "none.hpp"
-#include "numify.hpp"
-#include "option.hpp"
-#include "result.hpp"
-#include "stringify.hpp"
-#include "strings.hpp"
-#include "try.hpp"
-#include "unreachable.hpp"
+#include <stout/abort.hpp>
+#include <stout/bits.hpp>
+#include <stout/error.hpp>
+#include <stout/none.hpp>
+#include <stout/numify.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+#include <stout/unreachable.hpp>
+
+#ifdef __WINDOWS__
+#include <stout/windows/preprocessor.hpp>
+#endif // __WINDOWS__
 
 
 namespace net {

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
index a538fb1..3f829ba 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
@@ -14,33 +14,50 @@
 #ifndef __STOUT_NET_HPP__
 #define __STOUT_NET_HPP__
 
+#ifndef __WINDOWS__
 #include <netdb.h>
+#endif // __WINDOWS__
+
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 
+#ifndef __WINDOWS__
 #include <arpa/inet.h>
+#endif // __WINDOWS__
 
 #ifdef __APPLE__
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
-#endif
+#endif // __APPLE__
 
+// Note: Header grouping and ordering is considered before
+// inclusion/exclusion by platform.
+#ifndef __WINDOWS__
 #include <sys/param.h>
 
 #include <curl/curl.h>
+#endif // __WINDOWS__
 
 #include <iostream>
 #include <set>
 #include <string>
 
-#include "error.hpp"
-#include "ip.hpp"
-#include "option.hpp"
-#include "os.hpp"
-#include "stringify.hpp"
-#include "try.hpp"
+#include <stout/error.hpp>
+#include <stout/ip.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/windows/net.hpp>
+#else
+#include <stout/posix/net.hpp>
+#endif // __WINDOWS__
 
 
 // Network utilities.
@@ -84,125 +101,6 @@ inline struct sockaddr_storage createSockaddrStorage(const IP& ip, int port)
 }
 
 
-// Initializes libraries that net:: functions depend on, in a
-// thread-safe way. This does not have to be called explicitly by
-// the user of any functions in question. They will call this
-// themselves by need.
-inline void initialize()
-{
-  // We use a static struct variable to initialize in a thread-safe
-  // way, at least with respect to calls within net::*, since there
-  // is no way to guarantee that another library is not concurrently
-  // initializing CURL. Thread safety is provided by the fact that
-  // the value 'curl' should get constructed (i.e., the CURL
-  // constructor invoked) in a thread safe way (as of GCC 4.3 and
-  // required for C++11).
-  struct CURL
-  {
-    CURL()
-    {
-      // This is the only one function in libcurl that is not deemed
-      // thread-safe. (And it must be called at least once before any
-      // other libcurl function is used.)
-      curl_global_init(CURL_GLOBAL_ALL);
-    }
-  };
-
-  static CURL curl;
-}
-
-
-// Downloads the header of the specified HTTP URL with a HEAD request
-// and queries its "content-length" field. (Note that according to the
-// HTTP specification there is no guarantee that this field contains
-// any useful value.)
-inline Try<Bytes> contentLength(const std::string& url)
-{
-  initialize();
-
-  CURL* curl = curl_easy_init();
-  if (curl == NULL) {
-    curl_easy_cleanup(curl);
-    return Error("Failed to initialize libcurl");
-  }
-
-  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
-  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
-  curl_easy_setopt(curl, CURLOPT_HEADER, 1);
-  curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
-
-  CURLcode curlErrorCode = curl_easy_perform(curl);
-  if (curlErrorCode != 0) {
-    curl_easy_cleanup(curl);
-    return Error(curl_easy_strerror(curlErrorCode));
-  }
-
-  double result;
-  curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &result);
-
-  curl_easy_cleanup(curl);
-
-  if (result < 0) {
-    return Error("No URL content-length available");
-  }
-
-  return Bytes(uint64_t(result));
-}
-
-
-// Returns the HTTP response code resulting from attempting to
-// download the specified HTTP or FTP URL into a file at the specified
-// path.
-inline Try<int> download(const std::string& url, const std::string& path)
-{
-  initialize();
-
-  Try<int> fd = os::open(
-      path,
-      O_CREAT | O_WRONLY | O_CLOEXEC,
-      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-  if (fd.isError()) {
-    return Error(fd.error());
-  }
-
-  CURL* curl = curl_easy_init();
-
-  if (curl == NULL) {
-    curl_easy_cleanup(curl);
-    os::close(fd.get());
-    return Error("Failed to initialize libcurl");
-  }
-
-  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
-  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
-  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
-
-  FILE* file = fdopen(fd.get(), "w");
-  if (file == NULL) {
-    return ErrnoError("Failed to open file handle of '" + path + "'");
-  }
-  curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
-
-  CURLcode curlErrorCode = curl_easy_perform(curl);
-  if (curlErrorCode != 0) {
-    curl_easy_cleanup(curl);
-    fclose(file);
-    return Error(curl_easy_strerror(curlErrorCode));
-  }
-
-  long code;
-  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
-  curl_easy_cleanup(curl);
-
-  if (fclose(file) != 0) {
-    return ErrnoError("Failed to close file handle of '" + path + "'");
-  }
-
-  return Try<int>::some(code);
-}
-
-
 inline Try<std::string> hostname()
 {
   char host[512];
@@ -211,7 +109,7 @@ inline Try<std::string> hostname()
     return ErrnoError();
   }
 
-  // TODO(evelinad): Add AF_UNSPEC when we will support IPv6
+  // TODO(evelinad): Add AF_UNSPEC when we will support IPv6.
   struct addrinfo hints = createAddrInfo(SOCK_STREAM, AF_INET, AI_CANONNAME);
   struct addrinfo* result = NULL;
 
@@ -253,6 +151,30 @@ inline Try<std::string> getHostname(const IP& ip)
 }
 
 
+// Returns the names of all the link devices in the system.
+inline Try<std::set<std::string>> links()
+{
+#if !defined(__linux__) && !defined(__APPLE__)
+  return Error("Not implemented");
+#else
+  struct ifaddrs* ifaddr = NULL;
+  if (getifaddrs(&ifaddr) == -1) {
+    return ErrnoError();
+  }
+
+  std::set<std::string> names;
+  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ifa->ifa_name != NULL) {
+      names.insert(ifa->ifa_name);
+    }
+  }
+
+  freeifaddrs(ifaddr);
+  return names;
+#endif
+}
+
+
 // Returns a Try of the IP for the provided hostname or an error if no IP is
 // obtained.
 inline Try<IP> getIP(const std::string& hostname, int family)
@@ -282,30 +204,6 @@ inline Try<IP> getIP(const std::string& hostname, int family)
   return ip.get();
 }
 
-
-// Returns the names of all the link devices in the system.
-inline Try<std::set<std::string> > links()
-{
-#if !defined(__linux__) && !defined(__APPLE__)
-  return Error("Not implemented");
-#else
-  struct ifaddrs* ifaddr = NULL;
-  if (getifaddrs(&ifaddr) == -1) {
-    return ErrnoError();
-  }
-
-  std::set<std::string> names;
-  for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
-    if (ifa->ifa_name != NULL) {
-      names.insert(ifa->ifa_name);
-    }
-  }
-
-  freeifaddrs(ifaddr);
-  return names;
-#endif
-}
-
 } // namespace net {
 
 #endif // __STOUT_NET_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/posix/gzip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/posix/gzip.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/gzip.hpp
new file mode 100644
index 0000000..d5abf41
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/gzip.hpp
@@ -0,0 +1,150 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_POSIX_GZIP_HPP__
+#define __STOUT_POSIX_GZIP_HPP__
+
+#include <zlib.h>
+
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+
+// Compression utilities.
+// TODO(bmahler): Provide streaming compression / decompression as well.
+namespace gzip {
+
+// We use a 16KB buffer with zlib compression / decompression.
+#define GZIP_BUFFER_SIZE 16384
+
+// Returns a gzip compressed version of the provided string.
+// The compression level should be within the range [-1, 9].
+// See zlib.h:
+//   #define Z_NO_COMPRESSION         0
+//   #define Z_BEST_SPEED             1
+//   #define Z_BEST_COMPRESSION       9
+//   #define Z_DEFAULT_COMPRESSION  (-1)
+inline Try<std::string> compress(
+    const std::string& decompressed,
+    int level = Z_DEFAULT_COMPRESSION)
+{
+  // Verify the level is within range.
+  if (!(level == Z_DEFAULT_COMPRESSION ||
+      (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION))) {
+    return Error("Invalid compression level: " + stringify(level));
+  }
+
+  z_stream_s stream;
+  stream.next_in =
+    const_cast<Bytef*>(reinterpret_cast<const Bytef*>(decompressed.data()));
+  stream.avail_in = decompressed.length();
+  stream.zalloc = Z_NULL;
+  stream.zfree = Z_NULL;
+  stream.opaque = Z_NULL;
+
+  int code = deflateInit2(
+      &stream,
+      level,          // Compression level.
+      Z_DEFLATED,     // Compression method.
+      MAX_WBITS + 16, // Zlib magic for gzip compression / decompression.
+      8,              // Default memLevel value.
+      Z_DEFAULT_STRATEGY);
+
+  if (code != Z_OK) {
+    return Error("Failed to initialize zlib: " + std::string(stream.msg));
+  }
+
+  // Build up the compressed result.
+  Bytef buffer[GZIP_BUFFER_SIZE];
+  std::string result = "";
+  do {
+    stream.next_out = buffer;
+    stream.avail_out = GZIP_BUFFER_SIZE;
+    code = deflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+    if (code != Z_OK && code != Z_STREAM_END) {
+      Error error(std::string(stream.msg));
+      deflateEnd(&stream);
+      return error;
+    }
+
+    // Consume output and reset the buffer.
+    result.append(
+        reinterpret_cast<char*>(buffer),
+        GZIP_BUFFER_SIZE - stream.avail_out);
+    stream.next_out = buffer;
+    stream.avail_out = GZIP_BUFFER_SIZE;
+  } while (code != Z_STREAM_END);
+
+  code = deflateEnd(&stream);
+  if (code != Z_OK) {
+    return Error("Failed to clean up zlib: " + std::string(stream.msg));
+  }
+  return result;
+}
+
+
+// Returns a gzip decompressed version of the provided string.
+inline Try<std::string> decompress(const std::string& compressed)
+{
+  z_stream_s stream;
+  stream.next_in =
+    const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
+  stream.avail_in = compressed.length();
+  stream.zalloc = Z_NULL;
+  stream.zfree = Z_NULL;
+  stream.opaque = Z_NULL;
+
+  int code = inflateInit2(
+      &stream,
+      MAX_WBITS + 16); // Zlib magic for gzip compression / decompression.
+
+  if (code != Z_OK) {
+    return Error("Failed to initialize zlib: " + std::string(stream.msg));
+  }
+
+  // Build up the decompressed result.
+  Bytef buffer[GZIP_BUFFER_SIZE];
+  std::string result = "";
+  do {
+    stream.next_out = buffer;
+    stream.avail_out = GZIP_BUFFER_SIZE;
+    code = inflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+    if (code != Z_OK && code != Z_STREAM_END) {
+      Error error(std::string(stream.msg));
+      inflateEnd(&stream);
+      return error;
+    }
+
+    // Consume output and reset the buffer.
+    result.append(
+        reinterpret_cast<char*>(buffer),
+        GZIP_BUFFER_SIZE - stream.avail_out);
+    stream.next_out = buffer;
+    stream.avail_out = GZIP_BUFFER_SIZE;
+  } while (code != Z_STREAM_END);
+
+  code = inflateEnd(&stream);
+  if (code != Z_OK) {
+    return Error("Failed to clean up zlib: " + std::string(stream.msg));
+  }
+  return result;
+}
+
+} // namespace gzip {
+
+#endif // __STOUT_POSIX_GZIP_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/posix/net.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/posix/net.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/net.hpp
new file mode 100644
index 0000000..11e3895
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/net.hpp
@@ -0,0 +1,166 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_POSIX_NET_HPP__
+#define __STOUT_POSIX_NET_HPP__
+
+#include <netdb.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+
+#ifdef __APPLE__
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#endif // __APPLE__
+
+#include <sys/param.h>
+
+#include <curl/curl.h>
+
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/ip.hpp>
+#include <stout/os.hpp>
+#include <stout/try.hpp>
+
+
+// Network utilities.
+namespace net {
+
+// Initializes libraries that net:: functions depend on, in a
+// thread-safe way. This does not have to be called explicitly by
+// the user of any functions in question. They will call this
+// themselves by need.
+inline void initialize()
+{
+  // We use a static struct variable to initialize in a thread-safe
+  // way, at least with respect to calls within net::*, since there
+  // is no way to guarantee that another library is not concurrently
+  // initializing CURL. Thread safety is provided by the fact that
+  // the value 'curl' should get constructed (i.e., the CURL
+  // constructor invoked) in a thread safe way (as of GCC 4.3 and
+  // required for C++11).
+  struct CURL
+  {
+    CURL()
+    {
+      // This is the only one function in libcurl that is not deemed
+      // thread-safe. (And it must be called at least once before any
+      // other libcurl function is used.)
+      curl_global_init(CURL_GLOBAL_ALL);
+    }
+  };
+
+  static CURL curl;
+}
+
+
+// Downloads the header of the specified HTTP URL with a HEAD request
+// and queries its "content-length" field. (Note that according to the
+// HTTP specification there is no guarantee that this field contains
+// any useful value.)
+inline Try<Bytes> contentLength(const std::string& url)
+{
+  initialize();
+
+  CURL* curl = curl_easy_init();
+  if (curl == NULL) {
+    curl_easy_cleanup(curl);
+    return Error("Failed to initialize libcurl");
+  }
+
+  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
+  curl_easy_setopt(curl, CURLOPT_HEADER, 1);
+  curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
+
+  CURLcode curlErrorCode = curl_easy_perform(curl);
+  if (curlErrorCode != 0) {
+    curl_easy_cleanup(curl);
+    return Error(curl_easy_strerror(curlErrorCode));
+  }
+
+  double result;
+  curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &result);
+
+  curl_easy_cleanup(curl);
+
+  if (result < 0) {
+    return Error("No URL content-length available");
+  }
+
+  return Bytes(uint64_t(result));
+}
+
+
+// Returns the HTTP response code resulting from attempting to
+// download the specified HTTP or FTP URL into a file at the specified
+// path.
+inline Try<int> download(const std::string& url, const std::string& path)
+{
+  initialize();
+
+  Try<int> fd = os::open(
+      path,
+      O_CREAT | O_WRONLY | O_CLOEXEC,
+      S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+  if (fd.isError()) {
+    return Error(fd.error());
+  }
+
+  CURL* curl = curl_easy_init();
+
+  if (curl == NULL) {
+    curl_easy_cleanup(curl);
+    os::close(fd.get());
+    return Error("Failed to initialize libcurl");
+  }
+
+  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
+  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true);
+
+  FILE* file = fdopen(fd.get(), "w");
+  if (file == NULL) {
+    return ErrnoError("Failed to open file handle of '" + path + "'");
+  }
+  curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
+
+  CURLcode curlErrorCode = curl_easy_perform(curl);
+  if (curlErrorCode != 0) {
+    curl_easy_cleanup(curl);
+    fclose(file);
+    return Error(curl_easy_strerror(curlErrorCode));
+  }
+
+  long code;
+  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
+  curl_easy_cleanup(curl);
+
+  if (fclose(file) != 0) {
+    return ErrnoError("Failed to close file handle of '" + path + "'");
+  }
+
+  return Try<int>::some(code);
+}
+
+} // namespace net {
+
+#endif // __STOUT_POSIX_NET_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/unreachable.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/unreachable.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/unreachable.hpp
index fed0a7b..cd4caf6 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/unreachable.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/unreachable.hpp
@@ -16,12 +16,19 @@
 
 #include <iostream>
 
+#include <stout/abort.hpp>
+#include <stout/attributes.hpp>
+
+
 #define UNREACHABLE() Unreachable(__FILE__, __LINE__)
 
-inline __attribute__((noreturn)) void Unreachable(const char *file, int line) {
+
+inline NORETURN void Unreachable(const char* file, int line)
+{
   std::cerr << "Reached unreachable statement at " << file << ':'
             << line << std::endl;
   abort();
 }
 
+
 #endif // __STOUT_UNREACHABLE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/windows/format.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/format.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/format.hpp
new file mode 100644
index 0000000..dcf5097
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/format.hpp
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2015 Mesosphere, Inc.
+ *
+ * This file has been modified from its original form by Mesosphere, Inc.
+ * All modifications made to this file by Mesosphere (the “Modifications”)
+ * are copyright 2015 Mesosphere, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ---
+ *
+ * The original file on which the Modifications have been made were
+ * provided to Mesosphere pursuant to the following terms:
+ *
+ * Copyright (C) 2014 insane coder (http://insanecoding.blogspot.com/,
+ * http://asprintf.insanecoding.org/)
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __STOUT_WINDOWS_FORMAT_HPP__
+#define __STOUT_WINDOWS_FORMAT_HPP__
+
+#include <stdio.h> // For '_vscprintf', 'vsnprintf'.
+#include <stdlib.h> // For 'malloc', 'free'.
+#include <limits.h> // For 'INT_MAX'.
+
+
+inline int vasprintf(char** buffer, const char* format, va_list args)
+{
+  int result = -1;
+  int size = _vscprintf(format, args) + 1;
+
+  if (size >= 0 && size < INT_MAX) {
+    *buffer = (char*) malloc(size);
+
+    if (*buffer) {
+      result = vsnprintf(*buffer, size, format, args);
+
+      if (result < 0) {
+        free(*buffer);
+      }
+    }
+  }
+
+  return result;
+}
+
+
+#endif // __STOUT_WINDOWS_FORMAT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/windows/gzip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/gzip.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/gzip.hpp
new file mode 100644
index 0000000..017cfb3
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/gzip.hpp
@@ -0,0 +1,47 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_WINDOWS_GZIP_HPP__
+#define __STOUT_WINDOWS_GZIP_HPP__
+
+#include <string>
+
+#include <stout/try.hpp>
+
+
+namespace gzip {
+
+// Returns a gzip compressed version of the provided string.
+// The compression level should be within the range [-1, 9].
+// See zlib.h:
+//   #define Z_NO_COMPRESSION         0
+//   #define Z_BEST_SPEED             1
+//   #define Z_BEST_COMPRESSION       9
+//   #define Z_DEFAULT_COMPRESSION  (-1)
+inline Try<std::string> compress(
+    const std::string& decompressed,
+    int level = Z_DEFAULT_COMPRESSION)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns a gzip decompressed version of the provided string.
+inline Try<std::string> decompress(const std::string& compressed)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace gzip {
+
+#endif // __STOUT_WINDOWS_GZIP_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/windows/net.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/net.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/net.hpp
new file mode 100644
index 0000000..4f82796
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/net.hpp
@@ -0,0 +1,46 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_WINDOWS_NET_HPP__
+#define __STOUT_WINDOWS_NET_HPP__
+
+#include <string>
+
+#include <stout/ip.hpp>
+#include <stout/try.hpp>
+
+
+// Network utilities.
+namespace net {
+
+// Downloads the header of the specified HTTP URL with a HEAD request
+// and queries its "content-length" field. (Note that according to the
+// HTTP specification there is no guarantee that this field contains
+// any useful value.)
+inline Try<Bytes> contentLength(const std::string& url)
+{
+  UNIMPLEMENTED;
+}
+
+
+// Returns the HTTP response code resulting from attempting to
+// download the specified HTTP or FTP URL into a file at the specified
+// path.
+inline Try<int> download(const std::string& url, const std::string& path)
+{
+  UNIMPLEMENTED;
+}
+
+} // namespace net {
+
+#endif // __STOUT_WINDOWS_NET_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f8dd73df/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
new file mode 100644
index 0000000..de41db6
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/preprocessor.hpp
@@ -0,0 +1,34 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_WINDOWS_PREPROCESSOR_HPP__
+#define __STOUT_WINDOWS_PREPROCESSOR_HPP__
+
+// Provides aliases to Windows-specific nuances.
+
+// Normally defined in unistd.h.
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+// Alias for method in stdio.h.
+#define write(fd, buf, count) _write(fd, buf, count)
+
+// Aliases for 'inet_pton' and 'inet_ntop'.
+#define inet_pton(af, cp, buf) InetPton(af, cp, buf)
+#define inet_ntop(af, cp, buf, len) InetNtop(af, cp, buf, len)
+
+// TODO(aclemmer): Not defined on Windows.  This value is temporary.
+#define MAXHOSTNAMELEN 64
+
+#endif // __STOUT_WINDOWS_PREPROCESSOR_HPP__


[2/4] mesos git commit: Header splitting continued (os/*.hpp).

Posted by be...@apache.org.
Header splitting continued (os/*.hpp).

MESOS-3102: Splits apart the headers found in the stout/os folder.

A majority of the changes involve moving (os/*) to (os/linux/*).

Some entire portions of the Windows versions were completely gutted
(including struct definitions) since some concepts don't even exist in
Windows.

Review: https://reviews.apache.org/r/36798


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5aa050bf
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5aa050bf
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5aa050bf

Branch: refs/heads/master
Commit: 5aa050bfaa7338b010b1a522406bde0f15015259
Parents: 66fa10d
Author: Joseph Wu <jo...@mesosphere.io>
Authored: Thu Jul 30 16:11:41 2015 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Thu Jul 30 16:25:05 2015 -0700

----------------------------------------------------------------------
 .../3rdparty/stout/include/Makefile.am          |  34 +-
 .../3rdparty/stout/include/stout/abort.hpp      |   2 +-
 .../3rdparty/stout/include/stout/ip.hpp         |   2 +-
 .../3rdparty/stout/include/stout/os.hpp         |   2 +-
 .../3rdparty/stout/include/stout/os/close.hpp   |  24 +-
 .../3rdparty/stout/include/stout/os/exists.hpp  |  40 +-
 .../3rdparty/stout/include/stout/os/fcntl.hpp   |  73 +--
 .../3rdparty/stout/include/stout/os/fork.hpp    | 434 +-----------------
 .../stout/include/stout/os/killtree.hpp         | 213 +--------
 .../3rdparty/stout/include/stout/os/linux.hpp   |   6 +-
 .../3rdparty/stout/include/stout/os/ls.hpp      |  67 +--
 .../3rdparty/stout/include/stout/os/open.hpp    |  74 +--
 .../stout/include/stout/os/permissions.hpp      |  54 +--
 .../stout/include/stout/os/posix/close.hpp      |  37 ++
 .../stout/include/stout/os/posix/exists.hpp     |  53 +++
 .../stout/include/stout/os/posix/fcntl.hpp      |  86 ++++
 .../stout/include/stout/os/posix/fork.hpp       | 446 +++++++++++++++++++
 .../stout/include/stout/os/posix/killtree.hpp   | 227 ++++++++++
 .../stout/include/stout/os/posix/ls.hpp         |  81 ++++
 .../stout/include/stout/os/posix/open.hpp       |  88 ++++
 .../include/stout/os/posix/permissions.hpp      |  69 +++
 .../stout/include/stout/os/posix/process.hpp    | 180 ++++++++
 .../stout/include/stout/os/posix/pstree.hpp     | 132 ++++++
 .../stout/include/stout/os/posix/read.hpp       | 129 ++++++
 .../stout/include/stout/os/posix/sendfile.hpp   |  65 +++
 .../stout/include/stout/os/posix/shell.hpp      |  76 ++++
 .../stout/include/stout/os/posix/signals.hpp    | 185 ++++++++
 .../stout/include/stout/os/posix/stat.hpp       | 160 +++++++
 .../3rdparty/stout/include/stout/os/process.hpp | 166 +------
 .../3rdparty/stout/include/stout/os/pstree.hpp  | 119 +----
 .../3rdparty/stout/include/stout/os/read.hpp    | 113 +----
 .../stout/include/stout/os/sendfile.hpp         |  52 +--
 .../3rdparty/stout/include/stout/os/shell.hpp   |  62 +--
 .../3rdparty/stout/include/stout/os/signals.hpp | 170 +------
 .../3rdparty/stout/include/stout/os/stat.hpp    | 144 +-----
 .../stout/include/stout/os/windows/close.hpp    |  31 ++
 .../stout/include/stout/os/windows/exists.hpp   |  38 ++
 .../stout/include/stout/os/windows/fcntl.hpp    |  49 ++
 .../stout/include/stout/os/windows/fork.hpp     |  34 ++
 .../stout/include/stout/os/windows/killtree.hpp |  50 +++
 .../stout/include/stout/os/windows/ls.hpp       |  30 ++
 .../stout/include/stout/os/windows/open.hpp     |  34 ++
 .../include/stout/os/windows/permissions.hpp    |  41 ++
 .../stout/include/stout/os/windows/process.hpp  |  54 +++
 .../stout/include/stout/os/windows/pstree.hpp   |  57 +++
 .../stout/include/stout/os/windows/read.hpp     |  44 ++
 .../stout/include/stout/os/windows/sendfile.hpp |  36 ++
 .../stout/include/stout/os/windows/shell.hpp    |  37 ++
 .../stout/include/stout/os/windows/signals.hpp  |  92 ++++
 .../stout/include/stout/os/windows/stat.hpp     |  93 ++++
 .../3rdparty/stout/include/stout/windows.hpp    |  61 +++
 .../3rdparty/stout/include/stout/windows/os.hpp |   3 +-
 .../include/stout/windows/preprocessor.hpp      |  61 ---
 53 files changed, 2938 insertions(+), 1772 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index 60339e1..2752fc4 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -60,6 +60,21 @@ nobase_include_HEADERS =		\
   stout/os/fork.hpp			\
   stout/os/killtree.hpp			\
   stout/os/linux.hpp			\
+  stout/os/posix/close.hpp		\
+  stout/os/posix/exists.hpp		\
+  stout/os/posix/fcntl.hpp		\
+  stout/os/posix/fork.hpp		\
+  stout/os/posix/killtree.hpp		\
+  stout/os/posix/ls.hpp			\
+  stout/os/posix/open.hpp		\
+  stout/os/posix/permissions.hpp	\
+  stout/os/posix/process.hpp		\
+  stout/os/posix/pstree.hpp		\
+  stout/os/posix/read.hpp		\
+  stout/os/posix/sendfile.hpp		\
+  stout/os/posix/shell.hpp		\
+  stout/os/posix/signals.hpp		\
+  stout/os/posix/stat.hpp		\
   stout/os/ls.hpp			\
   stout/os/open.hpp			\
   stout/os/os.hpp			\
@@ -74,6 +89,21 @@ nobase_include_HEADERS =		\
   stout/os/permissions.hpp		\
   stout/os/pstree.hpp			\
   stout/os/sysctl.hpp			\
+  stout/os/windows/close.hpp		\
+  stout/os/windows/exists.hpp		\
+  stout/os/windows/fcntl.hpp		\
+  stout/os/windows/fork.hpp		\
+  stout/os/windows/killtree.hpp		\
+  stout/os/windows/ls.hpp		\
+  stout/os/windows/open.hpp		\
+  stout/os/windows/permissions.hpp	\
+  stout/os/windows/process.hpp		\
+  stout/os/windows/pstree.hpp		\
+  stout/os/windows/read.hpp		\
+  stout/os/windows/sendfile.hpp		\
+  stout/os/windows/shell.hpp		\
+  stout/os/windows/signals.hpp		\
+  stout/os/windows/stat.hpp		\
   stout/path.hpp			\
   stout/preprocessor.hpp		\
   stout/proc.hpp			\
@@ -95,8 +125,8 @@ nobase_include_HEADERS =		\
   stout/utils.hpp			\
   stout/uuid.hpp			\
   stout/version.hpp			\
+  stout/windows.hpp			\
   stout/windows/format.hpp		\
   stout/windows/gzip.hpp		\
   stout/windows/net.hpp			\
-  stout/windows/os.hpp			\
-  stout/windows/preprocessor.hpp	\
+  stout/windows/os.hpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
index f620f39..2b003d2 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/abort.hpp
@@ -20,7 +20,7 @@
 #include <string.h>
 
 #ifdef __WINDOWS__
-#include <stout/windows/preprocessor.hpp>
+#include <stout/windows.hpp>
 #else
 #include <unistd.h>
 #endif // __WINDOWS__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
index 41ceb2e..4910ca3 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
@@ -64,7 +64,7 @@
 #include <stout/unreachable.hpp>
 
 #ifdef __WINDOWS__
-#include <stout/windows/preprocessor.hpp>
+#include <stout/windows.hpp>
 #endif // __WINDOWS__
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
index 3ffda48..ab767cc 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
@@ -93,8 +93,8 @@
 // For readability, we minimize the number of #ifdef blocks in the code by
 // splitting platform specifc system calls into separate directories.
 #ifdef __WINDOWS__
+#include <stout/windows.hpp>
 #include <stout/windows/os.hpp>
-#include <stout/windows/preprocessor.hpp>
 #else
 #include <stout/posix/os.hpp>
 #endif // __WINDOWS__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/close.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/close.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/close.hpp
index fad82e8..972f833 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/close.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/close.hpp
@@ -11,27 +11,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __STOUT_OS_CLOSE_HPP__
 #define __STOUT_OS_CLOSE_HPP__
 
-#include <unistd.h>
-
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-namespace os {
-
-inline Try<Nothing> close(int fd)
-{
-  if (::close(fd) != 0) {
-    return ErrnoError();
-  }
 
-  return Nothing();
-}
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/close.hpp>
+#else
+#include <stout/os/posix/close.hpp>
+#endif // __WINDOWS__
 
-} // namespace os {
 
 #endif // __STOUT_OS_CLOSE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/exists.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/exists.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/exists.hpp
index 9035e57..6eb7f8f 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/exists.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/exists.hpp
@@ -14,40 +14,14 @@
 #ifndef __STOUT_OS_EXISTS_HPP__
 #define __STOUT_OS_EXISTS_HPP__
 
-#include <errno.h>
-#include <signal.h>
 
-#include <sys/stat.h>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/exists.hpp>
+#else
+#include <stout/os/posix/exists.hpp>
+#endif // __WINDOWS__
 
-#include <string>
-
-namespace os {
-
-inline bool exists(const std::string& path)
-{
-  struct stat s;
-  if (::lstat(path.c_str(), &s) < 0) {
-    return false;
-  }
-  return true;
-}
-
-
-// Determine if the process identified by pid exists.
-// NOTE: Zombie processes have a pid and therefore exist. See os::process(pid)
-// to get details of a process.
-inline bool exists(pid_t pid)
-{
-  // The special signal 0 is used to check if the process exists; see kill(2).
-  // If the current user does not have permission to signal pid, but it does
-  // exist, then ::kill will return -1 and set errno == EPERM.
-  if (::kill(pid, 0) == 0 || errno == EPERM) {
-    return true;
-  }
-
-  return false;
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_EXISTS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/fcntl.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/fcntl.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/fcntl.hpp
index bc8ffed..3728bc4 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/fcntl.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/fcntl.hpp
@@ -11,76 +11,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __STOUT_OS_FCNTL_HPP__
 #define __STOUT_OS_FCNTL_HPP__
 
-#include <fcntl.h>
-
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-// TODO(jieyu): Consider introducing a general os::fcntl function
-// which allows us to get/set multiple flags in one call.
-
-namespace os {
-
-inline Try<Nothing> cloexec(int fd)
-{
-  int flags = ::fcntl(fd, F_GETFD);
-
-  if (flags == -1) {
-    return ErrnoError();
-  }
-
-  if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
-inline Try<bool> isCloexec(int fd)
-{
-  int flags = ::fcntl(fd, F_GETFD);
-
-  if (flags == -1) {
-    return ErrnoError();
-  }
-
-  return (flags & FD_CLOEXEC) != 0;
-}
-
-
-inline Try<Nothing> nonblock(int fd)
-{
-  int flags = ::fcntl(fd, F_GETFL);
-
-  if (flags == -1) {
-    return ErrnoError();
-  }
-
-  if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
-    return ErrnoError();
-  }
-
-  return Nothing();
-}
-
-
-inline Try<bool> isNonblock(int fd)
-{
-  int flags = ::fcntl(fd, F_GETFL);
-
-  if (flags == -1) {
-    return ErrnoError();
-  }
 
-  return (flags & O_NONBLOCK) != 0;
-}
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/fcntl.hpp>
+#else
+#include <stout/os/posix/fcntl.hpp>
+#endif // __WINDOWS__
 
-} // namespace os {
 
 #endif // __STOUT_OS_FCNTL_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/fork.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/fork.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/fork.hpp
index c6cfb60..8ea971f 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/fork.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/fork.hpp
@@ -14,434 +14,14 @@
 #ifndef __STOUT_OS_FORK_HPP__
 #define __STOUT_OS_FORK_HPP__
 
-#include <fcntl.h>
-#include <unistd.h>
 
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/wait.h>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/fork.hpp>
+#else
+#include <stout/os/posix/fork.hpp>
+#endif // __WINDOWS__
 
-#include <list>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <stout/abort.hpp>
-#include <stout/error.hpp>
-#include <stout/exit.hpp>
-#include <stout/foreach.hpp>
-#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-
-#include <stout/os/process.hpp>
-
-// Abstractions around forking process trees. You can declare a
-// process tree "template" using 'Fork', 'Exec', and 'Wait'. For
-// example, to describe a simple "fork/exec" you can do:
-//
-//   Fork f = Fork(Exec("sleep 10));
-//
-// The command passed to an 'Exec' is run via 'sh -c'. You can
-// construct more complicated templates via nesting, for example:
-//
-//   Fork f =
-//     Fork(None(),
-//          Fork(Exec("echo 'grandchild 1'")),
-//          Fork(None(),
-//               Fork(Exec("echo 'great-grandchild'")),
-//               Exec("echo 'grandchild 2'"))
-//          Exec("echo 'child'"));
-//
-// Note that the first argument to 'Fork' here is an optional function
-// that can be invoked before forking any more children or executing a
-// command. THIS FUNCTION SHOULD BE ASYNC SIGNAL SAFE.
-//
-// To wait for children, you can use 'Wait' instead of 'Exec', for
-// example:
-//
-//   Fork f =
-//     Fork(None(),
-//          Fork(Exec("echo 'grandchild 1'")),
-//          Fork(Exec("echo 'grandchild 2'")),
-//          Wait());
-//
-// You can also omit either an 'Exec' or a 'Wait' and the forked
-// process will just 'exit(0)'. For example, the following will cause
-// to processes to get reparented by 'init'.
-//
-//   Fork f =
-//     Fork(None(),
-//          Fork(Exec("echo 'grandchild 1'")),
-//          Fork(Exec("echo 'grandchild 2'")));
-//
-// A template can be instantiated by invoking the 'Fork' as a
-// functor. For example, using any of the templates above we can do:
-//
-//   Try<ProcessTree> tree = f();
-//
-// It's important to note that the process tree returned represents
-// the instant in time after the forking has completed but before
-// 'Exec', 'Wait' or 'exit(0)' has occured (i.e., the process tree
-// will be complete).
-
-namespace os {
-
-// Forward declaration.
-inline Result<Process> process(pid_t);
-
-
-struct Exec
-{
-  Exec(const std::string& _command)
-    : command(_command) {}
-
-  const std::string command;
-};
-
-
-struct Wait {};
-
-
-struct Fork
-{
-  //  -+- parent.
-  Fork(const Option<void(*)(void)>& _function,
-       const Exec& _exec)
-    : function(_function),
-      exec(_exec) {}
-
-  Fork(const Exec& _exec) : exec(_exec) {}
-
-  //  -+- parent
-  //   \--- child.
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1)
-    : function(_function)
-  {
-    children.push_back(fork1);
-  }
-
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Exec& _exec)
-    : function(_function),
-      exec(_exec)
-  {
-    children.push_back(fork1);
-  }
-
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Wait& _wait)
-    : function(_function),
-      wait(_wait)
-  {
-    children.push_back(fork1);
-  }
-
-
-  // -+- parent
-  //   |--- child
-  //   \--- child.
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Fork& fork2)
-    : function(_function)
-  {
-    children.push_back(fork1);
-    children.push_back(fork2);
-  }
-
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Fork& fork2,
-       const Exec& _exec)
-    : function(_function),
-      exec(_exec)
-  {
-    children.push_back(fork1);
-    children.push_back(fork2);
-  }
-
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Fork& fork2,
-       const Wait& _wait)
-    : function(_function),
-      wait(_wait)
-  {
-    children.push_back(fork1);
-    children.push_back(fork2);
-  }
-
-
-  // -+- parent
-  //   |--- child
-  //   |--- child
-  //   \--- child.
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Fork& fork2,
-       const Fork& fork3)
-    : function(_function)
-  {
-    children.push_back(fork1);
-    children.push_back(fork2);
-    children.push_back(fork3);
-  }
-
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Fork& fork2,
-       const Fork& fork3,
-       const Exec& _exec)
-    : function(_function),
-      exec(_exec)
-  {
-    children.push_back(fork1);
-    children.push_back(fork2);
-    children.push_back(fork3);
-  }
-
-  Fork(const Option<void(*)(void)>& _function,
-       const Fork& fork1,
-       const Fork& fork2,
-       const Fork& fork3,
-       const Wait& _wait)
-    : function(_function),
-      wait(_wait)
-  {
-    children.push_back(fork1);
-    children.push_back(fork2);
-    children.push_back(fork3);
-  }
-
-private:
-  // Represents the "tree" of descendants where each node has a
-  // pointer (into shared memory) from which we can read the
-  // descendants process information as well as a vector of children.
-  struct Tree
-  {
-    // NOTE: This struct is stored in shared memory and thus cannot
-    // hold any pointers to heap allocated memory.
-    struct Memory {
-      pid_t pid;
-      pid_t parent;
-      pid_t group;
-      pid_t session;
-
-      bool set; // Has this been initialized?
-    };
-
-    std::shared_ptr<Memory> memory;
-    std::vector<Tree> children;
-  };
-
-  // We use shared memory to "share" the pids of forked descendants.
-  // The benefit of shared memory over pipes is that each forked
-  // process can read its descendants' pids leading to a simpler
-  // implementation (with pipes, only one reader can ever read the
-  // value from the pipe, forcing much more complicated coordination).
-  //
-  // Shared memory works like a file (in memory) that gets deleted by
-  // "unlinking" it, but it won't get completely deleted until all
-  // open file descriptors referencing it have been closed. Each
-  // forked process has the shared memory mapped into it as well as an
-  // open file descriptor, both of which should get cleaned up
-  // automagically when the process exits, but we use a special
-  // "deleter" (in combination with shared_ptr) in order to clean this
-  // stuff up when we are actually finished using the shared memory.
-  struct SharedMemoryDeleter
-  {
-    SharedMemoryDeleter(int _fd) : fd(_fd) {}
-
-    void operator () (Tree::Memory* process) const
-    {
-      if (munmap(process, sizeof(Tree::Memory)) == -1) {
-        ABORT(std::string("Failed to unmap memory: ") + strerror(errno));
-      }
-      if (::close(fd) == -1) {
-        ABORT(std::string("Failed to close shared memory file descriptor: ") +
-              strerror(errno));
-      }
-    }
-
-    const int fd;
-  };
-
-  // Constructs a Tree (see above) from this fork template.
-  Try<Tree> prepare() const
-  {
-    static int forks = 0;
-
-    // Each "instance" of an instantiated Fork needs a unique name for
-    // creating shared memory.
-    int instance = __sync_fetch_and_add(&forks, 1);
-
-    std::string name =
-      "/stout-forks-" + stringify(getpid()) + stringify(instance);
-
-    int fd = shm_open(name.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
-
-    if (fd == -1) {
-      return ErrnoError("Failed to open a shared memory object");
-    }
-
-    if (ftruncate(fd, sizeof(Tree::Memory)) == -1) {
-      return ErrnoError("Failed to set size of shared memory object");
-    }
-
-    void* memory = mmap(
-        NULL,
-        sizeof(Tree::Memory),
-        PROT_READ | PROT_WRITE, MAP_SHARED,
-        fd,
-        0);
-
-    if (memory == MAP_FAILED) {
-      return ErrnoError("Failed to map shared memory object");
-    }
-
-    if (shm_unlink(name.c_str()) == -1) {
-      return ErrnoError("Failed to unlink shared memory object");
-    }
-
-    SharedMemoryDeleter deleter(fd);
-
-    Tree tree;
-    tree.memory = std::shared_ptr<Tree::Memory>((Tree::Memory*)memory, deleter);
-    tree.memory->set = false;
-
-    for (size_t i = 0; i < children.size(); i++) {
-      Try<Tree> tree_ = children[i].prepare();
-      if (tree_.isError()) {
-        return Error(tree_.error());
-      }
-      tree.children.push_back(tree_.get());
-    }
-
-    return tree;
-  }
-
-  // Performs the fork, executes the function, recursively
-  // instantiates any children, and then executes/waits/exits.
-  pid_t instantiate(const Tree& tree) const
-  {
-    pid_t pid = ::fork();
-    if (pid > 0) {
-      return pid;
-    }
-
-    // Set the basic process information.
-    Tree::Memory process;
-    process.pid = getpid();
-    process.parent = getppid();
-    process.group = getpgid(0);
-    process.session = getsid(0);
-    process.set = true;
-
-    // Copy it into shared memory.
-    memcpy(tree.memory.get(), &process, sizeof(Tree::Memory));
-
-    // Execute the function, if any.
-    if (function.isSome()) {
-      function.get()();
-    }
-
-    // Fork the children, if any.
-    CHECK(children.size() == tree.children.size());
-    std::set<pid_t> pids;
-    for (size_t i = 0; i < children.size(); i++) {
-      pids.insert(children[i].instantiate(tree.children[i]));
-    }
-
-    // Execute or wait.
-    if (exec.isSome()) {
-      // Execute the command (via '/bin/sh -c command').
-      const char* command = exec.get().command.c_str();
-      execl("/bin/sh", "sh", "-c", command, (char*) NULL);
-      EXIT(1) << "Failed to execute '" << command << "': " << strerror(errno);
-    } else if (wait.isSome()) {
-      foreach (pid_t pid, pids) {
-        // TODO(benh): Check for signal interruption or other errors.
-        waitpid(pid, NULL, 0);
-      }
-    }
-
-    exit(0);
-    return -1;
-  }
-
-  // Waits for all of the descendant processes in the tree to update
-  // their pids and constructs a ProcessTree using the Tree::Memory
-  // information from shared memory.
-  static Try<ProcessTree> coordinate(const Tree& tree)
-  {
-    // Wait for the forked process.
-    // TODO(benh): Don't wait forever?
-    while (!tree.memory->set) {
-      // Make sure we don't keep reading the value from a register.
-      __sync_synchronize();
-    }
-
-    // All processes in the returned ProcessTree will have the
-    // command-line of the top level process, since we construct the
-    // tree using post-fork pre-exec information. So, we'll grab the
-    // command of the current process here.
-    Result<Process> self = os::process(getpid());
-
-    Process process = Process(
-        tree.memory->pid,
-        tree.memory->parent,
-        tree.memory->group,
-        tree.memory->session,
-        None(),
-        None(),
-        None(),
-        self.isSome() ? self.get().command : "",
-        false);
-
-    std::list<ProcessTree> children;
-    for (size_t i = 0; i < tree.children.size(); i++) {
-      Try<ProcessTree> child = coordinate(tree.children[i]);
-      if (child.isError()) {
-        return Error(child.error());
-      }
-      children.push_back(child.get());
-    }
-
-    return ProcessTree(process, children);
-  }
-
-public:
-  // Prepares and instantiates the process tree.
-  Try<ProcessTree> operator () () const
-  {
-    Try<Tree> tree = prepare();
-
-    if (tree.isError()) {
-      return Error(tree.error());
-    }
-
-    Try<pid_t> pid = instantiate(tree.get());
-
-    if (pid.isError()) {
-      return Error(pid.error());
-    }
-
-    return coordinate(tree.get());
-  }
-
-private:
-  Option<void(*)(void)> function;
-  Option<const Exec> exec;
-  Option<const Wait> wait;
-  std::vector<Fork> children;
-};
-
-} // namespace os {
 
 #endif // __STOUT_OS_FORK_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/killtree.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/killtree.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/killtree.hpp
index 933a5c9..de11bda 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/killtree.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/killtree.hpp
@@ -14,213 +14,14 @@
 #ifndef __STOUT_OS_KILLTREE_HPP__
 #define __STOUT_OS_KILLTREE_HPP__
 
-#include <dirent.h>
-#include <stdlib.h>
-#include <unistd.h>
 
-#include <list>
-#include <ostream>
-#include <queue>
-#include <set>
-#include <sstream>
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/killtree.hpp>
+#else
+#include <stout/os/posix/killtree.hpp>
+#endif // __WINDOWS__
 
-#include <stout/check.hpp>
-#include <stout/os.hpp>
-#include <stout/stringify.hpp>
-
-#include <stout/os/pstree.hpp>
-
-namespace os {
-
-// Forward declarations from os.hpp.
-inline std::set<pid_t> children(pid_t, const std::list<Process>&, bool);
-inline Option<Process> process(pid_t, const std::list<Process>&);
-
-
-// Sends a signal to a process tree rooted at the specified pid.
-// If groups is true, this also sends the signal to all encountered
-// process groups.
-// If sessions is true, this also sends the signal to all encountered
-// process sessions.
-// Note that processes of the group and session of the parent of the
-// root process is not included unless they are part of the root
-// process tree.
-// Note that if the process 'pid' has exited we'll signal the process
-// tree(s) rooted at pids in the group or session led by the process
-// if groups = true or sessions = true, respectively.
-// Returns the process trees that were succesfully or unsuccessfully
-// signaled. Note that the process trees can be stringified.
-// TODO(benh): Allow excluding the root pid from stopping, killing,
-// and continuing so as to provide a means for expressing "kill all of
-// my children". This is non-trivial because of the current
-// implementation.
-inline Try<std::list<ProcessTree> > killtree(
-    pid_t pid,
-    int signal,
-    bool groups = false,
-    bool sessions = false)
-{
-  Try<std::list<Process> > processes = os::processes();
-
-  if (processes.isError()) {
-    return Error(processes.error());
-  }
-
-  Result<Process> process = os::process(pid, processes.get());
-
-  std::queue<pid_t> queue;
-
-  // If the root process has already terminated we'll add in any pids
-  // that are in the process group originally led by pid or in the
-  // session originally led by pid, if instructed.
-  if (process.isNone()) {
-    foreach (const Process& _process, processes.get()) {
-      if (groups && _process.group == pid) {
-        queue.push(_process.pid);
-      } else if (sessions &&
-                 _process.session.isSome() &&
-                 _process.session.get() == pid) {
-        queue.push(_process.pid);
-      }
-    }
-
-    // Root process is not running and no processes found in the
-    // process group or session so nothing we can do.
-    if (queue.empty()) {
-      return std::list<ProcessTree>();
-    }
-  } else {
-    // Start the traversal from pid as the root.
-    queue.push(pid);
-  }
-
-  struct {
-    std::set<pid_t> pids;
-    std::set<pid_t> groups;
-    std::set<pid_t> sessions;
-    std::list<Process> processes;
-  } visited;
-
-  // If we are following groups and/or sessions then we try and make
-  // the group and session of the parent process "already visited" so
-  // that we don't kill "up the tree". This can only be done if the
-  // process is present.
-  if (process.isSome() && (groups || sessions)) {
-    Option<Process> parent =
-      os::process(process.get().parent, processes.get());
-
-    if (parent.isSome()) {
-      if (groups) {
-        visited.groups.insert(parent.get().group);
-      }
-      if (sessions && parent.get().session.isSome()) {
-        visited.sessions.insert(parent.get().session.get());
-      }
-    }
-  }
-
-  while (!queue.empty()) {
-    pid_t pid = queue.front();
-    queue.pop();
-
-    if (visited.pids.count(pid) != 0) {
-      continue;
-    }
-
-    // Make sure this process still exists.
-    process = os::process(pid);
-
-    if (process.isError()) {
-      return Error(process.error());
-    } else if (process.isNone()) {
-      continue;
-    }
-
-    // Stop the process to keep it from forking while we are killing
-    // it since a forked child might get re-parented by init and
-    // become impossible to find.
-    kill(pid, SIGSTOP);
-
-    visited.pids.insert(pid);
-    visited.processes.push_back(process.get());
-
-    // Now refresh the process list knowing that the current process
-    // can't fork any more children (since it's stopped).
-    processes = os::processes();
-
-    if (processes.isError()) {
-      return Error(processes.error());
-    }
-
-    // Enqueue the children for visiting.
-    foreach (pid_t child, os::children(pid, processes.get(), false)) {
-      queue.push(child);
-    }
-
-    // Now "visit" the group and/or session of the current process.
-    if (groups) {
-      pid_t group = process.get().group;
-      if (visited.groups.count(group) == 0) {
-        foreach (const Process& process, processes.get()) {
-          if (process.group == group) {
-            queue.push(process.pid);
-          }
-        }
-        visited.groups.insert(group);
-      }
-    }
-
-    // If we do not have a session for the process, it's likely
-    // because the process is a zombie on OS X. This implies it has
-    // not been reaped and thus is located somewhere in the tree we
-    // are trying to kill. Therefore, we should discover it from our
-    // tree traversal, or through its group (which is always present).
-    if (sessions && process.get().session.isSome()) {
-      pid_t session = process.get().session.get();
-      if (visited.sessions.count(session) == 0) {
-        foreach (const Process& process, processes.get()) {
-          if (process.session.isSome() && process.session.get() == session) {
-            queue.push(process.pid);
-          }
-        }
-        visited.sessions.insert(session);
-      }
-    }
-  }
-
-  // Now that all processes are stopped, we send the signal.
-  foreach (pid_t pid, visited.pids) {
-    kill(pid, signal);
-  }
-
-  // There is a concern that even though some process is stopped,
-  // sending a signal to any of it's children may cause a SIGCLD to
-  // be delivered to it which wakes it up (or any other signal maybe
-  // delivered). However, from the Open Group standards on "Signal
-  // Concepts":
-  //
-  //   "While a process is stopped, any additional signals that are
-  //    sent to the process shall not be delivered until the process
-  //    is continued, except SIGKILL which always terminates the
-  //    receiving process."
-  //
-  // In practice, this is not what has been witnessed. Rather, a
-  // process that has been stopped will respond to SIGTERM, SIGINT,
-  // etc. That being said, we still continue the process below in the
-  // event that it doesn't terminate from the sending signal but it
-  // also doesn't get continued (as per the specifications above).
-
-  // Try and continue the processes in case the signal is
-  // non-terminating but doesn't continue the process.
-  foreach (pid_t pid, visited.pids) {
-    kill(pid, SIGCONT);
-  }
-
-  // Return the process trees representing the visited pids.
-  return pstrees(visited.pids, visited.processes);
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_KILLTREE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/linux.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/linux.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/linux.hpp
index 5570d62..b994b13 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/linux.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/linux.hpp
@@ -11,8 +11,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __STOUT_OS_LINUX_HPP__
-#define __STOUT_OS_LINUX_HPP__
+#ifndef __STOUT_OS_POSIX_HPP__
+#define __STOUT_OS_POSIX_HPP__
 
 // This file contains Linux-only OS utilities.
 #ifndef __linux__
@@ -98,4 +98,4 @@ inline Try<std::set<pid_t> > pids()
 
 } // namespace os {
 
-#endif // __STOUT_OS_LINUX_HPP__
+#endif // __STOUT_OS_POSIX_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/ls.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/ls.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/ls.hpp
index 7cd4a40..e80d885 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/ls.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/ls.hpp
@@ -14,67 +14,14 @@
 #ifndef __STOUT_OS_LS_HPP__
 #define __STOUT_OS_LS_HPP__
 
-#include <dirent.h>
-#include <stdlib.h>
-#include <unistd.h>
 
-#include <list>
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/ls.hpp>
+#else
+#include <stout/os/posix/ls.hpp>
+#endif // __WINDOWS__
 
-namespace os {
-
-inline Try<std::list<std::string> > ls(const std::string& directory)
-{
-  DIR* dir = opendir(directory.c_str());
-
-  if (dir == NULL) {
-    return ErrnoError("Failed to opendir '" + directory + "'");
-  }
-
-  // Calculate the size for a "directory entry".
-  long name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
-
-  // If we don't get a valid size, check NAME_MAX, but fall back on
-  // 255 in the worst case ... Danger, Will Robinson!
-  if (name_max == -1) {
-    name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
-  }
-
-  size_t name_end = (size_t) offsetof(dirent, d_name) + name_max + 1;
-
-  size_t size = (name_end > sizeof(dirent) ? name_end : sizeof(dirent));
-
-  dirent* temp = (dirent*) malloc(size);
-
-  if (temp == NULL) {
-    // Preserve malloc error.
-    ErrnoError error("Failed to allocate directory entries");
-    closedir(dir);
-    return error;
-  }
-
-  std::list<std::string> result;
-  struct dirent* entry;
-  int error;
-
-  while ((error = readdir_r(dir, temp, &entry)) == 0 && entry != NULL) {
-    if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
-      continue;
-    }
-    result.push_back(entry->d_name);
-  }
-
-  free(temp);
-  closedir(dir);
-
-  if (error != 0) {
-    errno = error;
-    return ErrnoError("Failed to read directories");
-  }
-
-  return result;
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_LS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/open.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/open.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/open.hpp
index 134453e..43f261f 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/open.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/open.hpp
@@ -11,77 +11,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __STOUT_OS_OPEN_HPP__
 #define __STOUT_OS_OPEN_HPP__
 
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <string>
-
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-#include <stout/os/close.hpp>
-#include <stout/os/fcntl.hpp>
-
-namespace os {
-
-// For old systems that do not support O_CLOEXEC, we still want
-// os::open to accept that flag so that we can simplify the code.
-#ifndef O_CLOEXEC
-// Since we will define O_CLOEXEC if it is not yet defined, we use a
-// special symbol to tell if the flag is truly unavailable or not.
-#define O_CLOEXEC_UNDEFINED
-
-// NOTE: For backward compatibility concern, kernel usually does not
-// change the constant values for symbols like O_CLOEXEC.
-#if defined(__APPLE__)
-// Copied from '/usr/include/sys/fcntl.h'
-#define O_CLOEXEC 0x1000000
-#elif defined(__linux__)
-// Copied from '/usr/include/asm-generic/fcntl.h'.
-#define O_CLOEXEC 02000000
-#elif defined(__sun)
-// Not defined on Solaris, taking a spare flag.
-#define O_CLOEXEC 0x1000000
-#endif
-#endif
-
-
-inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
-{
-#ifdef O_CLOEXEC_UNDEFINED
-  // Before we passing oflag to ::open, we need to strip the O_CLOEXEC
-  // flag since it's not supported.
-  bool cloexec = false;
-  if ((oflag & O_CLOEXEC) != 0) {
-    oflag &= ~O_CLOEXEC;
-    cloexec = true;
-  }
-#endif
-
-  int fd = ::open(path.c_str(), oflag, mode);
-
-  if (fd < 0) {
-    return ErrnoError();
-  }
-
-#ifdef O_CLOEXEC_UNDEFINED
-  if (cloexec) {
-    Try<Nothing> result = os::cloexec(fd);
-    if (result.isError()) {
-      os::close(fd);
-      return Error("Failed to set cloexec: " + result.error());
-    }
-  }
-#endif
 
-  return fd;
-}
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/open.hpp>
+#else
+#include <stout/os/posix/open.hpp>
+#endif // __WINDOWS__
 
-} // namespace os {
 
 #endif // __STOUT_OS_OPEN_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/permissions.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/permissions.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/permissions.hpp
index ba8463c..196c3f5 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/permissions.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/permissions.hpp
@@ -14,54 +14,14 @@
 #ifndef __STOUT_OS_PERMISSIONS_HPP__
 #define __STOUT_OS_PERMISSIONS_HPP__
 
-#include <sys/stat.h>
 
-#include <string>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/permissions.hpp>
+#else
+#include <stout/os/posix/permissions.hpp>
+#endif // __WINDOWS__
 
-namespace os {
-
-struct Permissions
-{
-  explicit Permissions(mode_t mode)
-  {
-    owner.r = mode & S_IRUSR;
-    owner.w = mode & S_IWUSR;
-    owner.x = mode & S_IXUSR;
-    owner.rwx = mode & S_IRWXU;
-    group.r = mode & S_IRGRP;
-    group.w = mode & S_IWGRP;
-    group.x = mode & S_IXGRP;
-    group.rwx = mode & S_IRWXG;
-    others.r = mode & S_IROTH;
-    others.w = mode & S_IWOTH;
-    others.x = mode & S_IXOTH;
-    others.rwx = mode & S_IRWXO;
-    setuid = mode & S_ISUID;
-    setgid = mode & S_ISGID;
-    sticky = mode & S_ISVTX;
-  }
-
-  struct {
-    bool r;
-    bool w;
-    bool x;
-    bool rwx;
-  } owner, group, others;
-
-  bool setuid;
-  bool setgid;
-  bool sticky;
-};
-
-inline Try<Permissions> permissions(const std::string& path)
-{
-  struct stat s;
-  if (::stat(path.c_str(), &s) < 0) {
-    return ErrnoError();
-  }
-  return Permissions(s.st_mode);
-}
-
-} // namespace os {
 
 #endif // __STOUT_OS_PERMISSIONS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/close.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/close.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/close.hpp
new file mode 100644
index 0000000..d8679ca
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/close.hpp
@@ -0,0 +1,37 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_CLOSE_HPP__
+#define __STOUT_OS_POSIX_CLOSE_HPP__
+
+#include <unistd.h>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> close(int fd)
+{
+  if (::close(fd) != 0) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_CLOSE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/exists.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/exists.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/exists.hpp
new file mode 100644
index 0000000..835466b
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/exists.hpp
@@ -0,0 +1,53 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_EXISTS_HPP__
+#define __STOUT_OS_POSIX_EXISTS_HPP__
+
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/stat.h>
+
+#include <string>
+
+namespace os {
+
+inline bool exists(const std::string& path)
+{
+  struct stat s;
+  if (::lstat(path.c_str(), &s) < 0) {
+    return false;
+  }
+  return true;
+}
+
+
+// Determine if the process identified by pid exists.
+// NOTE: Zombie processes have a pid and therefore exist. See os::process(pid)
+// to get details of a process.
+inline bool exists(pid_t pid)
+{
+  // The special signal 0 is used to check if the process exists; see kill(2).
+  // If the current user does not have permission to signal pid, but it does
+  // exist, then ::kill will return -1 and set errno == EPERM.
+  if (::kill(pid, 0) == 0 || errno == EPERM) {
+    return true;
+  }
+
+  return false;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_EXISTS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fcntl.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fcntl.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fcntl.hpp
new file mode 100644
index 0000000..a9cb07e
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fcntl.hpp
@@ -0,0 +1,86 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STOUT_OS_POSIX_FCNTL_HPP__
+#define __STOUT_OS_POSIX_FCNTL_HPP__
+
+#include <fcntl.h>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+
+// TODO(jieyu): Consider introducing a general os::fcntl function
+// which allows us to get/set multiple flags in one call.
+namespace os {
+
+inline Try<Nothing> cloexec(int fd)
+{
+  int flags = ::fcntl(fd, F_GETFD);
+
+  if (flags == -1) {
+    return ErrnoError();
+  }
+
+  if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+inline Try<bool> isCloexec(int fd)
+{
+  int flags = ::fcntl(fd, F_GETFD);
+
+  if (flags == -1) {
+    return ErrnoError();
+  }
+
+  return (flags & FD_CLOEXEC) != 0;
+}
+
+
+inline Try<Nothing> nonblock(int fd)
+{
+  int flags = ::fcntl(fd, F_GETFL);
+
+  if (flags == -1) {
+    return ErrnoError();
+  }
+
+  if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+    return ErrnoError();
+  }
+
+  return Nothing();
+}
+
+
+inline Try<bool> isNonblock(int fd)
+{
+  int flags = ::fcntl(fd, F_GETFL);
+
+  if (flags == -1) {
+    return ErrnoError();
+  }
+
+  return (flags & O_NONBLOCK) != 0;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_FCNTL_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fork.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fork.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fork.hpp
new file mode 100644
index 0000000..24c26e9
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/fork.hpp
@@ -0,0 +1,446 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_FORK_HPP__
+#define __STOUT_OS_POSIX_FORK_HPP__
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <list>
+#include <memory>
+#include <set>
+#include <string>
+
+#include <stout/abort.hpp>
+#include <stout/error.hpp>
+#include <stout/exit.hpp>
+#include <stout/foreach.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+#include <stout/os/close.hpp>
+#include <stout/os/process.hpp>
+
+
+// Abstractions around forking process trees. You can declare a
+// process tree "template" using 'Fork', 'Exec', and 'Wait'. For
+// example, to describe a simple "fork/exec" you can do:
+//
+//   Fork f = Fork(Exec("sleep 10));
+//
+// The command passed to an 'Exec' is run via 'sh -c'. You can
+// construct more complicated templates via nesting, for example:
+//
+//   Fork f =
+//     Fork(None(),
+//          Fork(Exec("echo 'grandchild 1'")),
+//          Fork(None(),
+//               Fork(Exec("echo 'great-grandchild'")),
+//               Exec("echo 'grandchild 2'"))
+//          Exec("echo 'child'"));
+//
+// Note that the first argument to 'Fork' here is an optional function
+// that can be invoked before forking any more children or executing a
+// command. THIS FUNCTION SHOULD BE ASYNC SIGNAL SAFE.
+//
+// To wait for children, you can use 'Wait' instead of 'Exec', for
+// example:
+//
+//   Fork f =
+//     Fork(None(),
+//          Fork(Exec("echo 'grandchild 1'")),
+//          Fork(Exec("echo 'grandchild 2'")),
+//          Wait());
+//
+// You can also omit either an 'Exec' or a 'Wait' and the forked
+// process will just 'exit(0)'. For example, the following will cause
+// to processes to get reparented by 'init'.
+//
+//   Fork f =
+//     Fork(None(),
+//          Fork(Exec("echo 'grandchild 1'")),
+//          Fork(Exec("echo 'grandchild 2'")));
+//
+// A template can be instantiated by invoking the 'Fork' as a
+// functor. For example, using any of the templates above we can do:
+//
+//   Try<ProcessTree> tree = f();
+//
+// It's important to note that the process tree returned represents
+// the instant in time after the forking has completed but before
+// 'Exec', 'Wait' or 'exit(0)' has occured (i.e., the process tree
+// will be complete).
+
+namespace os {
+
+// Forward declaration.
+inline Result<Process> process(pid_t);
+
+
+struct Exec
+{
+  Exec(const std::string& _command)
+    : command(_command) {}
+
+  const std::string command;
+};
+
+
+struct Wait {};
+
+
+struct Fork
+{
+  //  -+- parent.
+  Fork(const Option<void(*)(void)>& _function,
+       const Exec& _exec)
+    : function(_function),
+      exec(_exec) {}
+
+  Fork(const Exec& _exec) : exec(_exec) {}
+
+  //  -+- parent
+  //   \--- child.
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1)
+    : function(_function)
+  {
+    children.push_back(fork1);
+  }
+
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Exec& _exec)
+    : function(_function),
+      exec(_exec)
+  {
+    children.push_back(fork1);
+  }
+
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Wait& _wait)
+    : function(_function),
+      wait(_wait)
+  {
+    children.push_back(fork1);
+  }
+
+
+  // -+- parent
+  //   |--- child
+  //   \--- child.
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Fork& fork2)
+    : function(_function)
+  {
+    children.push_back(fork1);
+    children.push_back(fork2);
+  }
+
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Fork& fork2,
+       const Exec& _exec)
+    : function(_function),
+      exec(_exec)
+  {
+    children.push_back(fork1);
+    children.push_back(fork2);
+  }
+
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Fork& fork2,
+       const Wait& _wait)
+    : function(_function),
+      wait(_wait)
+  {
+    children.push_back(fork1);
+    children.push_back(fork2);
+  }
+
+
+  // -+- parent
+  //   |--- child
+  //   |--- child
+  //   \--- child.
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Fork& fork2,
+       const Fork& fork3)
+    : function(_function)
+  {
+    children.push_back(fork1);
+    children.push_back(fork2);
+    children.push_back(fork3);
+  }
+
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Fork& fork2,
+       const Fork& fork3,
+       const Exec& _exec)
+    : function(_function),
+      exec(_exec)
+  {
+    children.push_back(fork1);
+    children.push_back(fork2);
+    children.push_back(fork3);
+  }
+
+  Fork(const Option<void(*)(void)>& _function,
+       const Fork& fork1,
+       const Fork& fork2,
+       const Fork& fork3,
+       const Wait& _wait)
+    : function(_function),
+      wait(_wait)
+  {
+    children.push_back(fork1);
+    children.push_back(fork2);
+    children.push_back(fork3);
+  }
+
+private:
+  // Represents the "tree" of descendants where each node has a
+  // pointer (into shared memory) from which we can read the
+  // descendants process information as well as a vector of children.
+  struct Tree
+  {
+    // NOTE: This struct is stored in shared memory and thus cannot
+    // hold any pointers to heap allocated memory.
+    struct Memory {
+      pid_t pid;
+      pid_t parent;
+      pid_t group;
+      pid_t session;
+
+      bool set; // Has this been initialized?
+    };
+
+    std::shared_ptr<Memory> memory;
+    std::vector<Tree> children;
+  };
+
+  // We use shared memory to "share" the pids of forked descendants.
+  // The benefit of shared memory over pipes is that each forked
+  // process can read its descendants' pids leading to a simpler
+  // implementation (with pipes, only one reader can ever read the
+  // value from the pipe, forcing much more complicated coordination).
+  //
+  // Shared memory works like a file (in memory) that gets deleted by
+  // "unlinking" it, but it won't get completely deleted until all
+  // open file descriptors referencing it have been closed. Each
+  // forked process has the shared memory mapped into it as well as an
+  // open file descriptor, both of which should get cleaned up
+  // automagically when the process exits, but we use a special
+  // "deleter" (in combination with shared_ptr) in order to clean this
+  // stuff up when we are actually finished using the shared memory.
+  struct SharedMemoryDeleter
+  {
+    SharedMemoryDeleter(int _fd) : fd(_fd) {}
+
+    void operator () (Tree::Memory* process) const
+    {
+      if (munmap(process, sizeof(Tree::Memory)) == -1) {
+        ABORT(std::string("Failed to unmap memory: ") + strerror(errno));
+      }
+      if (::close(fd) == -1) {
+        ABORT(std::string("Failed to close shared memory file descriptor: ") +
+              strerror(errno));
+      }
+    }
+
+    const int fd;
+  };
+
+  // Constructs a Tree (see above) from this fork template.
+  Try<Tree> prepare() const
+  {
+    static int forks = 0;
+
+    // Each "instance" of an instantiated Fork needs a unique name for
+    // creating shared memory.
+    int instance = __sync_fetch_and_add(&forks, 1);
+
+    std::string name =
+      "/stout-forks-" + stringify(getpid()) + stringify(instance);
+
+    int fd = shm_open(name.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+
+    if (fd == -1) {
+      return ErrnoError("Failed to open a shared memory object");
+    }
+
+    if (ftruncate(fd, sizeof(Tree::Memory)) == -1) {
+      return ErrnoError("Failed to set size of shared memory object");
+    }
+
+    void* memory = mmap(
+        NULL,
+        sizeof(Tree::Memory),
+        PROT_READ | PROT_WRITE, MAP_SHARED,
+        fd,
+        0);
+
+    if (memory == MAP_FAILED) {
+      return ErrnoError("Failed to map shared memory object");
+    }
+
+    if (shm_unlink(name.c_str()) == -1) {
+      return ErrnoError("Failed to unlink shared memory object");
+    }
+
+    SharedMemoryDeleter deleter(fd);
+
+    Tree tree;
+    tree.memory = std::shared_ptr<Tree::Memory>((Tree::Memory*)memory, deleter);
+    tree.memory->set = false;
+
+    for (size_t i = 0; i < children.size(); i++) {
+      Try<Tree> tree_ = children[i].prepare();
+      if (tree_.isError()) {
+        return Error(tree_.error());
+      }
+      tree.children.push_back(tree_.get());
+    }
+
+    return tree;
+  }
+
+  // Performs the fork, executes the function, recursively
+  // instantiates any children, and then executes/waits/exits.
+  pid_t instantiate(const Tree& tree) const
+  {
+    pid_t pid = ::fork();
+    if (pid > 0) {
+      return pid;
+    }
+
+    // Set the basic process information.
+    Tree::Memory process;
+    process.pid = getpid();
+    process.parent = getppid();
+    process.group = getpgid(0);
+    process.session = getsid(0);
+    process.set = true;
+
+    // Copy it into shared memory.
+    memcpy(tree.memory.get(), &process, sizeof(Tree::Memory));
+
+    // Execute the function, if any.
+    if (function.isSome()) {
+      function.get()();
+    }
+
+    // Fork the children, if any.
+    CHECK(children.size() == tree.children.size());
+    std::set<pid_t> pids;
+    for (size_t i = 0; i < children.size(); i++) {
+      pids.insert(children[i].instantiate(tree.children[i]));
+    }
+
+    // Execute or wait.
+    if (exec.isSome()) {
+      // Execute the command (via '/bin/sh -c command').
+      const char* command = exec.get().command.c_str();
+      execl("/bin/sh", "sh", "-c", command, (char*) NULL);
+      EXIT(1) << "Failed to execute '" << command << "': " << strerror(errno);
+    } else if (wait.isSome()) {
+      foreach (pid_t pid, pids) {
+        // TODO(benh): Check for signal interruption or other errors.
+        waitpid(pid, NULL, 0);
+      }
+    }
+
+    exit(0);
+    return -1;
+  }
+
+  // Waits for all of the descendant processes in the tree to update
+  // their pids and constructs a ProcessTree using the Tree::Memory
+  // information from shared memory.
+  static Try<ProcessTree> coordinate(const Tree& tree)
+  {
+    // Wait for the forked process.
+    // TODO(benh): Don't wait forever?
+    while (!tree.memory->set) {
+      // Make sure we don't keep reading the value from a register.
+      __sync_synchronize();
+    }
+
+    // All processes in the returned ProcessTree will have the
+    // command-line of the top level process, since we construct the
+    // tree using post-fork pre-exec information. So, we'll grab the
+    // command of the current process here.
+    Result<Process> self = os::process(getpid());
+
+    Process process = Process(
+        tree.memory->pid,
+        tree.memory->parent,
+        tree.memory->group,
+        tree.memory->session,
+        None(),
+        None(),
+        None(),
+        self.isSome() ? self.get().command : "",
+        false);
+
+    std::list<ProcessTree> children;
+    for (size_t i = 0; i < tree.children.size(); i++) {
+      Try<ProcessTree> child = coordinate(tree.children[i]);
+      if (child.isError()) {
+        return Error(child.error());
+      }
+      children.push_back(child.get());
+    }
+
+    return ProcessTree(process, children);
+  }
+
+public:
+  // Prepares and instantiates the process tree.
+  Try<ProcessTree> operator () () const
+  {
+    Try<Tree> tree = prepare();
+
+    if (tree.isError()) {
+      return Error(tree.error());
+    }
+
+    Try<pid_t> pid = instantiate(tree.get());
+
+    if (pid.isError()) {
+      return Error(pid.error());
+    }
+
+    return coordinate(tree.get());
+  }
+
+private:
+  Option<void(*)(void)> function;
+  Option<const Exec> exec;
+  Option<const Wait> wait;
+  std::vector<Fork> children;
+};
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_FORK_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/killtree.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/killtree.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/killtree.hpp
new file mode 100644
index 0000000..6b16e18
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/killtree.hpp
@@ -0,0 +1,227 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_KILLTREE_HPP__
+#define __STOUT_OS_POSIX_KILLTREE_HPP__
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <list>
+#include <queue>
+#include <set>
+
+#include <stout/check.hpp>
+#include <stout/os.hpp>
+
+#include <stout/os/pstree.hpp>
+
+
+namespace os {
+
+// Forward declarations from os.hpp.
+inline std::set<pid_t> children(pid_t, const std::list<Process>&, bool);
+inline Result<Process> process(pid_t);
+inline Option<Process> process(pid_t, const std::list<Process>&);
+inline Try<std::list<Process>> processes();
+inline Try<std::list<ProcessTree>> pstrees(
+    const std::set<pid_t>&,
+    const std::list<Process>&);
+
+
+// Sends a signal to a process tree rooted at the specified pid.
+// If groups is true, this also sends the signal to all encountered
+// process groups.
+// If sessions is true, this also sends the signal to all encountered
+// process sessions.
+// Note that processes of the group and session of the parent of the
+// root process is not included unless they are part of the root
+// process tree.
+// Note that if the process 'pid' has exited we'll signal the process
+// tree(s) rooted at pids in the group or session led by the process
+// if groups = true or sessions = true, respectively.
+// Returns the process trees that were succesfully or unsuccessfully
+// signaled. Note that the process trees can be stringified.
+// TODO(benh): Allow excluding the root pid from stopping, killing,
+// and continuing so as to provide a means for expressing "kill all of
+// my children". This is non-trivial because of the current
+// implementation.
+inline Try<std::list<ProcessTree>> killtree(
+    pid_t pid,
+    int signal,
+    bool groups = false,
+    bool sessions = false)
+{
+  Try<std::list<Process>> processes = os::processes();
+
+  if (processes.isError()) {
+    return Error(processes.error());
+  }
+
+  Result<Process> process = os::process(pid, processes.get());
+
+  std::queue<pid_t> queue;
+
+  // If the root process has already terminated we'll add in any pids
+  // that are in the process group originally led by pid or in the
+  // session originally led by pid, if instructed.
+  if (process.isNone()) {
+    foreach (const Process& _process, processes.get()) {
+      if (groups && _process.group == pid) {
+        queue.push(_process.pid);
+      } else if (sessions &&
+                 _process.session.isSome() &&
+                 _process.session.get() == pid) {
+        queue.push(_process.pid);
+      }
+    }
+
+    // Root process is not running and no processes found in the
+    // process group or session so nothing we can do.
+    if (queue.empty()) {
+      return std::list<ProcessTree>();
+    }
+  } else {
+    // Start the traversal from pid as the root.
+    queue.push(pid);
+  }
+
+  struct {
+    std::set<pid_t> pids;
+    std::set<pid_t> groups;
+    std::set<pid_t> sessions;
+    std::list<Process> processes;
+  } visited;
+
+  // If we are following groups and/or sessions then we try and make
+  // the group and session of the parent process "already visited" so
+  // that we don't kill "up the tree". This can only be done if the
+  // process is present.
+  if (process.isSome() && (groups || sessions)) {
+    Option<Process> parent =
+      os::process(process.get().parent, processes.get());
+
+    if (parent.isSome()) {
+      if (groups) {
+        visited.groups.insert(parent.get().group);
+      }
+      if (sessions && parent.get().session.isSome()) {
+        visited.sessions.insert(parent.get().session.get());
+      }
+    }
+  }
+
+  while (!queue.empty()) {
+    pid_t pid = queue.front();
+    queue.pop();
+
+    if (visited.pids.count(pid) != 0) {
+      continue;
+    }
+
+    // Make sure this process still exists.
+    process = os::process(pid);
+
+    if (process.isError()) {
+      return Error(process.error());
+    } else if (process.isNone()) {
+      continue;
+    }
+
+    // Stop the process to keep it from forking while we are killing
+    // it since a forked child might get re-parented by init and
+    // become impossible to find.
+    kill(pid, SIGSTOP);
+
+    visited.pids.insert(pid);
+    visited.processes.push_back(process.get());
+
+    // Now refresh the process list knowing that the current process
+    // can't fork any more children (since it's stopped).
+    processes = os::processes();
+
+    if (processes.isError()) {
+      return Error(processes.error());
+    }
+
+    // Enqueue the children for visiting.
+    foreach (pid_t child, os::children(pid, processes.get(), false)) {
+      queue.push(child);
+    }
+
+    // Now "visit" the group and/or session of the current process.
+    if (groups) {
+      pid_t group = process.get().group;
+      if (visited.groups.count(group) == 0) {
+        foreach (const Process& process, processes.get()) {
+          if (process.group == group) {
+            queue.push(process.pid);
+          }
+        }
+        visited.groups.insert(group);
+      }
+    }
+
+    // If we do not have a session for the process, it's likely
+    // because the process is a zombie on OS X. This implies it has
+    // not been reaped and thus is located somewhere in the tree we
+    // are trying to kill. Therefore, we should discover it from our
+    // tree traversal, or through its group (which is always present).
+    if (sessions && process.get().session.isSome()) {
+      pid_t session = process.get().session.get();
+      if (visited.sessions.count(session) == 0) {
+        foreach (const Process& process, processes.get()) {
+          if (process.session.isSome() && process.session.get() == session) {
+            queue.push(process.pid);
+          }
+        }
+        visited.sessions.insert(session);
+      }
+    }
+  }
+
+  // Now that all processes are stopped, we send the signal.
+  foreach (pid_t pid, visited.pids) {
+    kill(pid, signal);
+  }
+
+  // There is a concern that even though some process is stopped,
+  // sending a signal to any of it's children may cause a SIGCLD to
+  // be delivered to it which wakes it up (or any other signal maybe
+  // delivered). However, from the Open Group standards on "Signal
+  // Concepts":
+  //
+  //   "While a process is stopped, any additional signals that are
+  //    sent to the process shall not be delivered until the process
+  //    is continued, except SIGKILL which always terminates the
+  //    receiving process."
+  //
+  // In practice, this is not what has been witnessed. Rather, a
+  // process that has been stopped will respond to SIGTERM, SIGINT,
+  // etc. That being said, we still continue the process below in the
+  // event that it doesn't terminate from the sending signal but it
+  // also doesn't get continued (as per the specifications above).
+
+  // Try and continue the processes in case the signal is
+  // non-terminating but doesn't continue the process.
+  foreach (pid_t pid, visited.pids) {
+    kill(pid, SIGCONT);
+  }
+
+  // Return the process trees representing the visited pids.
+  return pstrees(visited.pids, visited.processes);
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_KILLTREE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/ls.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/ls.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/ls.hpp
new file mode 100644
index 0000000..7dba79d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/ls.hpp
@@ -0,0 +1,81 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_LS_HPP__
+#define __STOUT_OS_POSIX_LS_HPP__
+
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <list>
+#include <string>
+
+
+namespace os {
+
+inline Try<std::list<std::string>> ls(const std::string& directory)
+{
+  DIR* dir = opendir(directory.c_str());
+
+  if (dir == NULL) {
+    return ErrnoError("Failed to opendir '" + directory + "'");
+  }
+
+  // Calculate the size for a "directory entry".
+  long name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
+
+  // If we don't get a valid size, check NAME_MAX, but fall back on
+  // 255 in the worst case ... Danger, Will Robinson!
+  if (name_max == -1) {
+    name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+  }
+
+  size_t name_end = (size_t) offsetof(dirent, d_name) + name_max + 1;
+
+  size_t size = (name_end > sizeof(dirent) ? name_end : sizeof(dirent));
+
+  dirent* temp = (dirent*) malloc(size);
+
+  if (temp == NULL) {
+    // Preserve malloc error.
+    ErrnoError error("Failed to allocate directory entries");
+    closedir(dir);
+    return error;
+  }
+
+  std::list<std::string> result;
+  struct dirent* entry;
+  int error;
+
+  while ((error = readdir_r(dir, temp, &entry)) == 0 && entry != NULL) {
+    if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+      continue;
+    }
+    result.push_back(entry->d_name);
+  }
+
+  free(temp);
+  closedir(dir);
+
+  if (error != 0) {
+    errno = error;
+    return ErrnoError("Failed to read directories");
+  }
+
+  return result;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_LS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/open.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/open.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/open.hpp
new file mode 100644
index 0000000..023993d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/open.hpp
@@ -0,0 +1,88 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STOUT_OS_POSIX_OPEN_HPP__
+#define __STOUT_OS_POSIX_OPEN_HPP__
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+#include <stout/os/close.hpp>
+#include <stout/os/fcntl.hpp>
+
+
+namespace os {
+
+// For old systems that do not support O_CLOEXEC, we still want
+// os::open to accept that flag so that we can simplify the code.
+#ifndef O_CLOEXEC
+// Since we will define O_CLOEXEC if it is not yet defined, we use a
+// special symbol to tell if the flag is truly unavailable or not.
+#define O_CLOEXEC_UNDEFINED
+
+// NOTE: For backward compatibility concern, kernel usually does not
+// change the constant values for symbols like O_CLOEXEC.
+#if defined(__APPLE__)
+// Copied from '/usr/include/sys/fcntl.h'
+#define O_CLOEXEC 0x1000000
+#elif defined(__linux__)
+// Copied from '/usr/include/asm-generic/fcntl.h'.
+#define O_CLOEXEC 02000000
+#elif defined(__sun)
+// Not defined on Solaris, taking a spare flag.
+#define O_CLOEXEC 0x1000000
+#endif
+#endif
+
+
+inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
+{
+#ifdef O_CLOEXEC_UNDEFINED
+  // Before we passing oflag to ::open, we need to strip the O_CLOEXEC
+  // flag since it's not supported.
+  bool cloexec = false;
+  if ((oflag & O_CLOEXEC) != 0) {
+    oflag &= ~O_CLOEXEC;
+    cloexec = true;
+  }
+#endif
+
+  int fd = ::open(path.c_str(), oflag, mode);
+
+  if (fd < 0) {
+    return ErrnoError();
+  }
+
+#ifdef O_CLOEXEC_UNDEFINED
+  if (cloexec) {
+    Try<Nothing> result = os::cloexec(fd);
+    if (result.isError()) {
+      os::close(fd);
+      return Error("Failed to set cloexec: " + result.error());
+    }
+  }
+#endif
+
+  return fd;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_OPEN_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/permissions.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/permissions.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/permissions.hpp
new file mode 100644
index 0000000..98f0b3c
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/permissions.hpp
@@ -0,0 +1,69 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_PERMISSIONS_HPP__
+#define __STOUT_OS_POSIX_PERMISSIONS_HPP__
+
+#include <sys/stat.h>
+
+#include <string>
+
+
+namespace os {
+
+struct Permissions
+{
+  explicit Permissions(mode_t mode)
+  {
+    owner.r = mode & S_IRUSR;
+    owner.w = mode & S_IWUSR;
+    owner.x = mode & S_IXUSR;
+    owner.rwx = mode & S_IRWXU;
+    group.r = mode & S_IRGRP;
+    group.w = mode & S_IWGRP;
+    group.x = mode & S_IXGRP;
+    group.rwx = mode & S_IRWXG;
+    others.r = mode & S_IROTH;
+    others.w = mode & S_IWOTH;
+    others.x = mode & S_IXOTH;
+    others.rwx = mode & S_IRWXO;
+    setuid = mode & S_ISUID;
+    setgid = mode & S_ISGID;
+    sticky = mode & S_ISVTX;
+  }
+
+  struct {
+    bool r;
+    bool w;
+    bool x;
+    bool rwx;
+  } owner, group, others;
+
+  bool setuid;
+  bool setgid;
+  bool sticky;
+};
+
+
+inline Try<Permissions> permissions(const std::string& path)
+{
+  struct stat s;
+  if (::stat(path.c_str(), &s) < 0) {
+    return ErrnoError();
+  }
+  return Permissions(s.st_mode);
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_PERMISSIONS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/process.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/process.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/process.hpp
new file mode 100644
index 0000000..5d7404b
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/process.hpp
@@ -0,0 +1,180 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_PROCESS_HPP__
+#define __STOUT_OS_POSIX_PROCESS_HPP__
+
+#include <sys/types.h> // For pid_t.
+
+#include <list>
+#include <ostream>
+#include <sstream>
+#include <string>
+
+#include <stout/bytes.hpp>
+#include <stout/duration.hpp>
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/strings.hpp>
+
+
+namespace os {
+
+struct Process
+{
+  Process(pid_t _pid,
+          pid_t _parent,
+          pid_t _group,
+          const Option<pid_t>& _session,
+          const Option<Bytes>& _rss,
+          const Option<Duration>& _utime,
+          const Option<Duration>& _stime,
+          const std::string& _command,
+          bool _zombie)
+    : pid(_pid),
+      parent(_parent),
+      group(_group),
+      session(_session),
+      rss(_rss),
+      utime(_utime),
+      stime(_stime),
+      command(_command),
+      zombie(_zombie) {}
+
+  const pid_t pid;
+  const pid_t parent;
+  const pid_t group;
+  const Option<pid_t> session;
+  const Option<Bytes> rss;
+  const Option<Duration> utime;
+  const Option<Duration> stime;
+  const std::string command;
+  const bool zombie;
+
+  // TODO(bmahler): Add additional data as needed.
+
+  bool operator <  (const Process& p) const { return pid <  p.pid; }
+  bool operator <= (const Process& p) const { return pid <= p.pid; }
+  bool operator >  (const Process& p) const { return pid >  p.pid; }
+  bool operator >= (const Process& p) const { return pid >= p.pid; }
+  bool operator == (const Process& p) const { return pid == p.pid; }
+  bool operator != (const Process& p) const { return pid != p.pid; }
+};
+
+
+class ProcessTree
+{
+public:
+  // Returns a process subtree rooted at the specified PID, or none if
+  // the specified pid could not be found in this process tree.
+  Option<ProcessTree> find(pid_t pid) const
+  {
+    if (process.pid == pid) {
+      return *this;
+    }
+
+    foreach (const ProcessTree& tree, children) {
+      Option<ProcessTree> option = tree.find(pid);
+      if (option.isSome()) {
+        return option;
+      }
+    }
+
+    return None();
+  }
+
+  // Checks if the specified pid is contained in this process tree.
+  bool contains(pid_t pid) const
+  {
+    return find(pid).isSome();
+  }
+
+  operator Process () const
+  {
+    return process;
+  }
+
+  operator pid_t () const
+  {
+    return process.pid;
+  }
+
+  const Process process;
+  const std::list<ProcessTree> children;
+
+private:
+  friend struct Fork;
+  friend Try<ProcessTree> pstree(pid_t, const std::list<Process>&);
+
+  ProcessTree(
+      const Process& _process,
+      const std::list<ProcessTree>& _children)
+    : process(_process),
+      children(_children) {}
+};
+
+
+inline std::ostream& operator << (
+    std::ostream& stream,
+    const ProcessTree& tree)
+{
+  if (tree.children.empty()) {
+    stream << "--- " << tree.process.pid << " ";
+    if (tree.process.zombie) {
+      stream << "(" << tree.process.command << ")";
+    } else {
+      stream << tree.process.command;
+    }
+  } else {
+    stream << "-+- " << tree.process.pid << " ";
+    if (tree.process.zombie) {
+      stream << "(" << tree.process.command << ")";
+    } else {
+      stream << tree.process.command;
+    }
+    size_t size = tree.children.size();
+    foreach (const ProcessTree& child, tree.children) {
+      std::ostringstream out;
+      out << child;
+      stream << "\n";
+      if (--size != 0) {
+        stream << " |" << strings::replace(out.str(), "\n", "\n |");
+      } else {
+        stream << " \\" << strings::replace(out.str(), "\n", "\n  ");
+      }
+    }
+  }
+  return stream;
+}
+
+} // namespace os {
+
+
+// An overload of stringify for printing a list of process trees
+// (since printing a process tree is rather particular).
+inline std::string stringify(const std::list<os::ProcessTree>& list)
+{
+  std::ostringstream out;
+  out << "[ " << std::endl;
+  std::list<os::ProcessTree>::const_iterator iterator = list.begin();
+  while (iterator != list.end()) {
+    out << stringify(*iterator);
+    if (++iterator != list.end()) {
+      out << std::endl << std::endl;
+    }
+  }
+  out << std::endl << "]";
+  return out.str();
+}
+
+#endif // __STOUT_OS_POSIX_PROCESS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/5aa050bf/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/pstree.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/pstree.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/pstree.hpp
new file mode 100644
index 0000000..fd0192c
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/pstree.hpp
@@ -0,0 +1,132 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __STOUT_OS_POSIX_PSTREE_HPP__
+#define __STOUT_OS_POSIX_PSTREE_HPP__
+
+#include <list>
+#include <set>
+
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+#include <stout/os/process.hpp>
+
+
+namespace os {
+
+// Forward declaration.
+inline Try<std::list<Process>> processes();
+
+
+// Returns a process tree rooted at the specified pid using the
+// specified list of processes (or an error if one occurs).
+inline Try<ProcessTree> pstree(
+    pid_t pid,
+    const std::list<Process>& processes)
+{
+  std::list<ProcessTree> children;
+  foreach (const Process& process, processes) {
+    if (process.parent == pid) {
+      Try<ProcessTree> tree = pstree(process.pid, processes);
+      if (tree.isError()) {
+        return Error(tree.error());
+      }
+      children.push_back(tree.get());
+    }
+  }
+
+  foreach (const Process& process, processes) {
+    if (process.pid == pid) {
+      return ProcessTree(process, children);
+    }
+  }
+
+  return Error("No process found at " + stringify(pid));
+}
+
+
+// Returns a process tree for the specified pid (or all processes if
+// pid is none or the current process if pid is 0).
+inline Try<ProcessTree> pstree(Option<pid_t> pid = None())
+{
+  if (pid.isNone()) {
+    pid = 1;
+  } else if (pid.get() == 0) {
+    pid = getpid();
+  }
+
+  const Try<std::list<Process>> processes = os::processes();
+
+  if (processes.isError()) {
+    return Error(processes.error());
+  }
+
+  return pstree(pid.get(), processes.get());
+}
+
+
+// Returns the minimum list of process trees that include all of the
+// specified pids using the specified list of processes.
+inline Try<std::list<ProcessTree>> pstrees(
+    const std::set<pid_t>& pids,
+    const std::list<Process>& processes)
+{
+  std::list<ProcessTree> trees;
+
+  foreach (pid_t pid, pids) {
+    // First, check if the pid is already connected to one of the
+    // process trees we've constructed.
+    bool disconnected = true;
+    foreach (const ProcessTree& tree, trees) {
+      if (tree.contains(pid)) {
+        disconnected = false;
+        break;
+      }
+    }
+
+    if (disconnected) {
+      Try<ProcessTree> tree = pstree(pid, processes);
+      if (tree.isError()) {
+        return Error(tree.error());
+      }
+
+      // Now see if any of the existing process trees are actually
+      // contained within the process tree we just created and only
+      // include the disjoint process trees.
+      // C++11:
+      // trees = trees.filter([](const ProcessTree& t) {
+      //   return tree.get().contains(t);
+      // });
+      std::list<ProcessTree> trees_ = trees;
+      trees.clear();
+      foreach (const ProcessTree& t, trees_) {
+        if (tree.get().contains(t.process.pid)) {
+          continue;
+        }
+        trees.push_back(t);
+      }
+      trees.push_back(tree.get());
+    }
+  }
+
+  return trees;
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_PSTREE_HPP__