Repository: apache/arrow
File: cpp/src/arrow/util/io_util.cc (C++)

Code before:
  ret = errno_actual == 0 ? 0 : -1;
#else
  ret = ftruncate(fd, static_cast<size_t>(size));
  errno_actual = errno;
#endif

  if (ret == -1) {
    return IOErrorFromErrno(errno_actual, "Error writing bytes to file");
  }
  return Status::OK();
}

//
// Environment variables
//

Result<std::string> GetEnvVar(std::string_view name) {
#ifdef _WIN32
  // On Windows, getenv() reads an early copy of the process' environment
  // which doesn't get updated when SetEnvironmentVariable() is called.
  constexpr int32_t bufsize = 2000;
  char c_str[bufsize];
  auto res = GetEnvironmentVariableA(name.data(), c_str, bufsize);
  if (res >= bufsize) {
    return Status::CapacityError("environment variable value too long");
  } else if (res == 0) {
    return Status::KeyError("environment variable '", name, "'undefined");
  }
  return std::string(c_str);
#else
  char* c_str = getenv(name.data());
  if (c_str == nullptr) {
    return Status::KeyError("environment variable '", name, "'undefined");
  }
  return std::string(c_str);
#endif
}

#ifdef _WIN32
Result<NativePathString> GetEnvVarNative(std::string_view name) {
  NativePathString w_name;
  constexpr int32_t bufsize = 2000;
  wchar_t w_str[bufsize];

  ARROW_ASSIGN_OR_RAISE(w_name, StringToNative(name));
  auto res = GetEnvironmentVariableW(w_name.c_str(), w_str, bufsize);
  if (res >= bufsize) {
    return Status::CapacityError("environment variable value too long");
  } else if (res == 0) {
    return Status::KeyError("environment variable '", name, "'undefined");
  }

Review comment (suggestion):
This `>=` comparison was a bit confusing to me at first but this is fine as the `==` case should never happen.

Code after:
  errno_actual = _chsize_s(fd, static_cast<size_t>(size));
  ret = errno_actual == 0 ? 0 : -1;
#else
  ret = ftruncate(fd, static_cast<size_t>(size));
  errno_actual = errno;
#endif

  if (ret == -1) {
    return IOErrorFromErrno(errno_actual, "Error writing bytes to file");
  }
  return Status::OK();
}

//
// Environment variables
//

Result<std::string> GetEnvVar(std::string_view name) {
#ifdef _WIN32
  // On Windows, getenv() reads an early copy of the process' environment
  // which doesn't get updated when SetEnvironmentVariable() is called.
  std::string value(100, '\0');

  uint32_t res = GetEnvironmentVariableA(name.data(), value.data(),
                                         static_cast<uint32_t>(value.size()));
  if (res >= value.size()) {
    // Value buffer too small, need to upsize
    // (`res` includes the null-terminating character in this case)
    value.resize(res);
    res = GetEnvironmentVariableA(name.data(), value.data(),
                                  static_cast<uint32_t>(value.size()));
  }
  if (res == 0) {
    return Status::KeyError("environment variable '", name, "' undefined");
  }
  // On success, `res` does not include the null-terminating character
  DCHECK_EQ(value.data()[res], 0);
  value.resize(res);
  return value;
#else
  char* c_str = getenv(name.data());
  if (c_str == nullptr) {
    return Status::KeyError("environment variable '", name, "' undefined");
  }
  return std::string(c_str);
#endif
}

#ifdef _WIN32
Result<NativePathString> GetEnvVarNative(std::string_view name) {
  ARROW_ASSIGN_OR_RAISE(std::wstring w_name, StringToNative(name));