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:26 UTC

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

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__