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__