Commit c7b4aca6 authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot

Move the Environment portability header to the stdlib header

Summary: This completely kills the environment portability header, which was among the earliest, and was created before the general convention of splitting based on the header they are in, in the standard library, existed. The functions that were defined in it are expected to be in stdlib, so move them there.

Reviewed By: mzlee

Differential Revision: D4462502

fbshipit-source-id: c4549b9d1ea623644223db4365b81507f443ad5e
parent fa172175
......@@ -286,7 +286,6 @@ nobase_follyinclude_HEADERS = \
portability/Config.h \
portability/Constexpr.h \
portability/Dirent.h \
portability/Environment.h \
portability/Event.h \
portability/Fcntl.h \
portability/GFlags.h \
......@@ -475,7 +474,6 @@ libfolly_la_SOURCES = \
MacAddress.cpp \
MemoryMapping.cpp \
portability/Dirent.cpp \
portability/Environment.cpp \
portability/Fcntl.cpp \
portability/Libgen.cpp \
portability/Malloc.cpp \
......
......@@ -41,8 +41,8 @@
#include <folly/Shell.h>
#include <folly/String.h>
#include <folly/io/Cursor.h>
#include <folly/portability/Environment.h>
#include <folly/portability/Sockets.h>
#include <folly/portability/Stdlib.h>
#include <folly/portability/Unistd.h>
constexpr int kExecFailure = 127;
......
......@@ -26,8 +26,8 @@
#include <folly/FileUtil.h>
#include <folly/Memory.h>
#include <folly/String.h>
#include <folly/portability/Environment.h>
#include <folly/portability/Fcntl.h>
#include <folly/portability/Stdlib.h>
#include <folly/portability/Unistd.h>
#ifdef _WIN32
......
......@@ -22,9 +22,9 @@
#include <glog/logging.h>
#include <folly/Memory.h>
#include <folly/portability/Environment.h>
#include <folly/portability/Fcntl.h>
#include <folly/portability/GTest.h>
#include <folly/portability/Stdlib.h>
using namespace folly;
using namespace folly::test;
......
/*
* Copyright 2017 Facebook, Inc.
*
* 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.
*/
#include <folly/portability/Environment.h>
#ifdef _WIN32
#include <Windows.h>
extern "C" {
int setenv(const char* name, const char* value, int overwrite) {
if (overwrite == 0 && getenv(name) != nullptr) {
return 0;
}
if (*value != '\0') {
auto e = _putenv_s(name, value);
if (e != 0) {
errno = e;
return -1;
}
return 0;
}
// We are trying to set the value to an empty string, but
// _putenv_s deletes entries if the value is an empty string,
// and just calling SetEnvironmentVariableA doesn't update
// _environ, so we have to do these terrible things.
if (_putenv_s(name, " ") != 0) {
errno = EINVAL;
return -1;
}
// Here lies the documentation we blatently ignore to make
// this work >_>...
*getenv(name) = '\0';
// This would result in a double null termination, which
// normally signifies the end of the environment variable
// list, so we stick a completely empty environment variable
// into the list instead.
*(getenv(name) + 1) = '=';
// If _wenviron is null, the wide environment has not been initialized
// yet, and we don't need to try to update it.
// We have to do this otherwise we'd be forcing the initialization and
// maintenance of the wide environment even though it's never actually
// used in most programs.
if (_wenviron != nullptr) {
wchar_t buf[_MAX_ENV + 1];
size_t len;
if (mbstowcs_s(&len, buf, _MAX_ENV + 1, name, _MAX_ENV) != 0) {
errno = EINVAL;
return -1;
}
*_wgetenv(buf) = u'\0';
*(_wgetenv(buf) + 1) = u'=';
}
// And now, we have to update the outer environment to have
// a proper empty value.
if (!SetEnvironmentVariableA(name, value)) {
errno = EINVAL;
return -1;
}
return 0;
}
int unsetenv(const char* name) {
if (_putenv_s(name, "") != 0) {
return -1;
}
return 0;
}
}
#endif
/*
* Copyright 2017 Facebook, Inc.
*
* 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.
*/
#pragma once
#include <stdlib.h>
extern "C" {
#ifndef _WIN32
extern char** environ;
#else
int setenv(const char* name, const char* value, int overwrite);
int unsetenv(const char* name);
#endif
}
......@@ -70,5 +70,69 @@ char* realpath(const char* path, char* resolved_path) {
// I sure hope the caller gave us _MAX_PATH space in the buffer....
return _fullpath(resolved_path, path, _MAX_PATH);
}
int setenv(const char* name, const char* value, int overwrite) {
if (overwrite == 0 && getenv(name) != nullptr) {
return 0;
}
if (*value != '\0') {
auto e = _putenv_s(name, value);
if (e != 0) {
errno = e;
return -1;
}
return 0;
}
// We are trying to set the value to an empty string, but
// _putenv_s deletes entries if the value is an empty string,
// and just calling SetEnvironmentVariableA doesn't update
// _environ, so we have to do these terrible things.
if (_putenv_s(name, " ") != 0) {
errno = EINVAL;
return -1;
}
// Here lies the documentation we blatently ignore to make
// this work >_>...
*getenv(name) = '\0';
// This would result in a double null termination, which
// normally signifies the end of the environment variable
// list, so we stick a completely empty environment variable
// into the list instead.
*(getenv(name) + 1) = '=';
// If _wenviron is null, the wide environment has not been initialized
// yet, and we don't need to try to update it.
// We have to do this otherwise we'd be forcing the initialization and
// maintenance of the wide environment even though it's never actually
// used in most programs.
if (_wenviron != nullptr) {
wchar_t buf[_MAX_ENV + 1];
size_t len;
if (mbstowcs_s(&len, buf, _MAX_ENV + 1, name, _MAX_ENV) != 0) {
errno = EINVAL;
return -1;
}
*_wgetenv(buf) = u'\0';
*(_wgetenv(buf) + 1) = u'=';
}
// And now, we have to update the outer environment to have
// a proper empty value.
if (!SetEnvironmentVariableA(name, value)) {
errno = EINVAL;
return -1;
}
return 0;
}
int unsetenv(const char* name) {
if (_putenv_s(name, "") != 0) {
return -1;
}
return 0;
}
}
#endif
......@@ -18,6 +18,7 @@
#include <cstdlib>
extern "C" {
#ifdef _WIN32
// These are technically supposed to be defined linux/limits.h and
// sys/param.h respectively, but Windows defines _MAX_PATH in stdlib.h,
......@@ -27,10 +28,13 @@
#define PATH_MAX _MAX_PATH
#define MAXPATHLEN _MAX_PATH
extern "C" {
char* mktemp(char* tn);
char* mkdtemp(char* tn);
int mkstemp(char* tn);
char* realpath(const char* path, char* resolved_path);
}
int setenv(const char* name, const char* value, int overwrite);
int unsetenv(const char* name);
#else
extern char** environ;
#endif
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment