Skip to content

Commit

Permalink
feat(cpp-client): Move GetHostname and GetEnv to dhcore (#5845)
Browse files Browse the repository at this point in the history
  • Loading branch information
kosak committed Jul 25, 2024
1 parent 8a7329e commit 45bf00b
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cstdio>
#include <iostream>
#include <memory>
#include <optional>
#include <string>
#include <thread>
#include <typeinfo>
Expand Down Expand Up @@ -203,6 +204,19 @@ std::string Basename(std::string_view path);
*/
[[nodiscard]] std::string GetTidAsString();

/**
* Gets the hostname.
* @return The hostname.
*/
[[nodiscard]] std::string GetHostname();

/**
* Gets a value from the environment.
* @param envname the key
* @return If found, an optional set to the value. Otherwise (if not found), an empty optional.
*/
[[nodiscard]] std::optional<std::string> GetEnv(const std::string& envname);

template <class T> [[nodiscard]] std::string
TypeName(const T& t) {
return demangle(typeid(t).name());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,92 @@
/*
* Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
*/
#include <climits>
#include <optional>
#include <string>
#include "deephaven/dhcore/utility/utility.h"

// for GetTidAsString
#if defined(__linux__)
#if defined(__unix__)
#include <netdb.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#elif defined(_WIN32)
#include <windows.h>
#include "winsock.h"
#endif

namespace deephaven::dhcore::utility {
[[nodiscard]] std::string GetTidAsString() {
std::string GetTidAsString() {
#if defined(__linux__)
const pid_t tid = syscall(__NR_gettid); // this is more portable than gettid().
return std::to_string(tid);
#elif defined(_WIN32)
auto tid = GetCurrentThreadId();
return std::to_string(tid);
return std::to_string(tid);
#else
#error "Don't have a way to getting thread id on your platform"
#endif
}

std::string GetHostname() {
#if defined(__unix__)
char hostname[HOST_NAME_MAX];
gethostname(hostname, HOST_NAME_MAX);
const addrinfo hints = { AI_ADDRCONFIG|AI_CANONNAME, AF_UNSPEC, 0, 0 };
addrinfo *info;
const int r = getaddrinfo(hostname, nullptr, &hints, &info);
if (r != 0 || info == nullptr) {
throw std::runtime_error(DEEPHAVEN_LOCATION_STR("getaddrinfo failed: ") + gai_strerror(r));
}
// Of all the alternatives, pick the longest.
std::size_t maxlen = std::strlen(info->ai_canonname);
const addrinfo *maxinfo = info;
for (const addrinfo *p = info->ai_next; p != nullptr; p = p->ai_next) {
if (p->ai_canonname == nullptr) {
continue;
}
const std::size_t len = std::strlen(p->ai_canonname);
if (len > maxlen) {
maxlen = len;
maxinfo = p;
}
}
std::string result(maxinfo->ai_canonname);
freeaddrinfo(info);
return result;
#elif defined(_WIN32)
char hostname[256];
const int r = gethostname(hostname, sizeof(hostname));
if (r != 0) {
int lasterr = WSAGetLastError();
throw std::runtime_error(
DEEPHAVEN_LOCATION_STR("gethostname failed: error code ") +
std::to_string(lasterr));
}
return std::string(hostname);
#else
#error "Unsupported configuration"
#endif
}

std::optional<std::string> GetEnv(const std::string& envname) {
#if defined(__unix__)
const char* ret = getenv(envname.c_str());
if (ret != nullptr) {
return std::string(ret);
}
return {};
#elif defined(_WIN32)
static char ret[1024];
size_t len;
const errno_t err = getenv_s(&len, ret, sizeof(ret), envname.c_str());
if (err == 0) {
return std::string(ret);
}
return {};
#else
#error "Unsupported configuration"
#endif
}
} // namespace deephaven::dhcore::utility
25 changes: 24 additions & 1 deletion cpp-client/deephaven/tests/src/utility_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
using deephaven::dhcore::utility::Base64Encode;
using deephaven::dhcore::utility::Basename;
using deephaven::dhcore::utility::EpochMillisToStr;
using deephaven::dhcore::utility::GetEnv;
using deephaven::dhcore::utility::GetTidAsString;
using deephaven::dhcore::utility::GetHostname;
using deephaven::dhcore::utility::ObjectId;

namespace deephaven::client::tests {
Expand Down Expand Up @@ -45,10 +47,31 @@ TEST_CASE("Basename", "[utility]") {

// This isn't much of a test, but if it can compile on all supported
// platforms (Linux and Windows) then that is at least a sanity check
// (that the entry point exists). For now we just visuallyi spot-check
// (that the entry point exists). For now we just visually spot-check
// that ireturns the right value.
TEST_CASE("ThreadId", "[utility]") {
auto tid = GetTidAsString();
fmt::println("This should be my thread id: {}", tid);
}

// This isn't much of a test, but if it can compile on all supported
// platforms (Linux and Windows) then that is at least a sanity check
// (that the entry point exists). For now we just visually spot-check
// that ireturns the right value.
TEST_CASE("GetHostname", "[utility]") {
auto hostname = GetHostname();
fmt::println("This should be the hostname: {}", hostname);
}

// This isn't much of a test, but if it can compile on all supported
// platforms (Linux and Windows) then that is at least a sanity check
// (that the entry point exists). For now we just visually spot-check
// that ireturns the right value.
TEST_CASE("GetEnv", "[utility]") {
auto path = GetEnv("PATH");
// Very suspect if neither Windows nor Linux has a PATH set in their
// environment.
REQUIRE(path.has_value());
fmt::println("PATH is: {}", *path);
}
} // namespace deephaven::client::tests

0 comments on commit 45bf00b

Please sign in to comment.