proxygen
EnvUtil.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <folly/String.h>
22 
23 using namespace folly;
24 using namespace folly::experimental;
25 
27  std::unordered_map<std::string, std::string> data;
28  for (auto it = environ; it && *it; ++it) {
29  std::string key, value;
30  folly::StringPiece entry(*it);
31  auto equalsPosition = entry.find('=');
32  if (equalsPosition == entry.npos) {
33  throw MalformedEnvironment{to<std::string>(
34  "Environment contains an non key-value-pair string \"", entry, "\"")};
35  }
36  key = entry.subpiece(0, equalsPosition).toString();
37  value = entry.subpiece(equalsPosition + 1).toString();
38  if (data.count(key)) {
39  throw MalformedEnvironment{to<std::string>(
40  "Environment contains duplicate value for \"", key, "\"")};
41  }
42  data.emplace(std::move(key), std::move(value));
43  }
44  return EnvironmentState{std::move(data)};
45 }
46 
48  PCHECK(0 == clearenv());
49  for (const auto& kvp : env_) {
50  PCHECK(0 == setenv(kvp.first.c_str(), kvp.second.c_str(), (int)true));
51  }
52 }
53 
54 std::vector<std::string> EnvironmentState::toVector() const {
55  std::vector<std::string> result;
56  for (auto const& pair : env_) {
57  result.emplace_back(to<std::string>(pair.first, "=", pair.second));
58  }
59  return result;
60 }
61 
62 std::unique_ptr<char*, void (*)(char**)> EnvironmentState::toPointerArray()
63  const {
64  size_t totalStringLength{};
65  for (auto const& pair : env_) {
66  totalStringLength += pair.first.size() + pair.second.size() +
67  2 /* intermediate '=' and the terminating NUL */;
68  }
69  size_t allocationRequired =
70  (totalStringLength / sizeof(char*) + 1) + env_.size() + 1;
71  char** raw = new char*[allocationRequired];
72  char** ptrBase = raw;
73  char* stringBase = reinterpret_cast<char*>(&raw[env_.size() + 1]);
74  char* const stringEnd = reinterpret_cast<char*>(&raw[allocationRequired]);
75  for (auto const& pair : env_) {
76  std::string const& key = pair.first;
77  std::string const& value = pair.second;
78  *ptrBase = stringBase;
79  size_t lengthIncludingNullTerminator = key.size() + 1 + value.size() + 1;
80  CHECK_GT(stringEnd - lengthIncludingNullTerminator, stringBase);
81  memcpy(stringBase, key.c_str(), key.size());
82  stringBase += key.size();
83  *stringBase++ = '=';
84  memcpy(stringBase, value.c_str(), value.size() + 1);
85  stringBase += value.size() + 1;
86  ++ptrBase;
87  }
88  *ptrBase = nullptr;
89  CHECK_EQ(env_.size(), ptrBase - raw);
90  return {raw, [](char** ptr) { delete[] ptr; }};
91 }
void * ptr
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
size_type find(const_range_type str) const
Definition: Range.h:721
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::vector< std::string > toVector() const
Definition: EnvUtil.cpp:54
static EnvironmentState fromCurrentEnvironment()
Definition: EnvUtil.cpp:26
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
Range subpiece(size_type first, size_type length=npos) const
Definition: Range.h:686
std::unique_ptr< char *, void(*)(char **)> toPointerArray() const
Definition: EnvUtil.cpp:62
std::string toString() const
Definition: Range.h:594
static const size_type npos
Definition: Range.h:197
const char * string
Definition: Conv.cpp:212
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
int clearenv()
Definition: Stdlib.cpp:150