Skip to content

Commit

Permalink
Bazel client: depend less on <unistd.h>
Browse files Browse the repository at this point in the history
We moved most of the functionality (e.g. _exit,
SetupStreams) into blaze_util_<platform> or
changed to alternative functions (fwrite + stderr
instead of write + STDERR_HANDLE).

This change brings us closer to compiling blaze.cc
with MSVC. We still have to move signal handlers
out of blaze.cc as well as code dealing with the
server PID.

See #2107

--
MOS_MIGRATED_REVID=140123945
  • Loading branch information
laszlocsomor authored and dslomov committed Nov 24, 2016
1 parent b7bc525 commit 74ffaf7
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 25 deletions.
34 changes: 11 additions & 23 deletions src/main/cpp/blaze.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ static void handler(int signum) {
if (globals->server_pid != -1) {
KillServerProcess(globals->server_pid);
}
_exit(1);
blaze::ExitImmediately(1);
}
sigprintf("\n%s caught interrupt signal; shutting down.\n\n",
globals->options->product_name.c_str());
Expand Down Expand Up @@ -1321,19 +1321,6 @@ static void CheckEnvironment() {
blaze::SetEnv("LC_CTYPE", "en_US.ISO-8859-1");
}

static void SetupStreams() {
// Line-buffer stderr, since we always flush at the end of a server
// message. This saves lots of single-char calls to write(2).
// This doesn't work if any writes to stderr have already occurred!
setlinebuf(stderr);

// Ensure we have three open fds. Otherwise we can end up with
// bizarre things like stdout going to the lock file, etc.
if (fcntl(STDIN_FILENO, F_GETFL) == -1) open("/dev/null", O_RDONLY);
if (fcntl(STDOUT_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
if (fcntl(STDERR_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
}

static void CheckBinaryPath(const string& argv0) {
if (argv0[0] == '/') {
globals->binary_path = argv0;
Expand All @@ -1360,7 +1347,7 @@ int Main(int argc, const char *argv[], OptionProcessor *option_processor,
// Logging must be set first to assure no log statements are missed.
blaze_util::SetLogHandler(std::move(log_handler));
globals = new GlobalVariables(option_processor);
SetupStreams();
blaze::SetupStdStreams();

// Must be done before command line parsing.
ComputeWorkspace();
Expand Down Expand Up @@ -1640,18 +1627,19 @@ unsigned int GrpcBlazeServer::Communicate() {
}

bool pipe_broken_now = false;
if (response.standard_output().size() > 0) {
int result = write(STDOUT_FILENO, response.standard_output().c_str(),
response.standard_output().size());
if (result < 0 && errno == EPIPE) {

if (!response.standard_output().empty()) {
size_t size = response.standard_output().size();
size_t r = fwrite(response.standard_output().c_str(), 1, size, stdout);
if (r < size && errno == EPIPE) {
pipe_broken_now = true;
}
}

if (response.standard_error().size() > 0) {
int result = write(STDERR_FILENO, response.standard_error().c_str(),
response.standard_error().size());
if (result < 0 && errno == EPIPE) {
if (!response.standard_error().empty()) {
size_t size = response.standard_error().size();
size_t r = fwrite(response.standard_error().c_str(), 1, size, stderr);
if (r < size && errno == EPIPE) {
pipe_broken_now = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/cpp/blaze_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ bool CheckJavaVersionIsAtLeast(const std::string &jvm_version,
// Returns true iff arg is a valid command line argument for bazel.
bool IsArg(const std::string& arg);

// Converts a project identifier to string.
// Returns the string representation of `value`.
// Workaround for mingw where std::to_string is not implemented.
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52015.
template <typename T>
Expand Down
9 changes: 9 additions & 0 deletions src/main/cpp/blaze_util_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <string>

#include "src/main/cpp/util/port.h"

namespace blaze {

std::string GetProcessIdAsString();
Expand Down Expand Up @@ -159,6 +161,13 @@ void SetEnv(const std::string& name, const std::string& value);

void UnsetEnv(const std::string& name);

// Terminate the process immediately.
// This is a wrapper around POSIX's _exit(2).
ATTRIBUTE_NORETURN void ExitImmediately(int exit_code);

// Ensure we have open file descriptors for stdin/stdout/stderr.
void SetupStdStreams();

} // namespace blaze

#endif // BAZEL_SRC_MAIN_CPP_BLAZE_UTIL_PLATFORM_H_
22 changes: 22 additions & 0 deletions src/main/cpp/blaze_util_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <fcntl.h>
#include <limits.h> // PATH_MAX
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
Expand Down Expand Up @@ -375,4 +376,25 @@ void UnsetEnv(const string& name) {
unsetenv(name.c_str());
}

ATTRIBUTE_NORETURN void ExitImmediately(int exit_code) {
_exit(exit_code);
}

void SetupStdStreams() {
// Set non-buffered output mode for stderr/stdout. The server already
// line-buffers messages where it makes sense, so there's no need to do set
// line-buffering here. On the other hand the server sometimes sends binary
// output (when for example a query returns results as proto), in which case
// we must not perform line buffering on the client side. So turn off
// buffering here completely.
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);

// Ensure we have three open fds. Otherwise we can end up with
// bizarre things like stdout going to the lock file, etc.
if (fcntl(STDIN_FILENO, F_GETFL) == -1) open("/dev/null", O_RDONLY);
if (fcntl(STDOUT_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
if (fcntl(STDERR_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
}

} // namespace blaze.
31 changes: 31 additions & 0 deletions src/main/cpp/blaze_util_windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,37 @@ void UnsetEnv(const string& name) {
#endif // COMPILER_MSVC
}

ATTRIBUTE_NORETURN void ExitImmediately(int exit_code) {
#ifdef COMPILER_MSVC
// TODO(bazel-team): implement this.
pdie(255, "blaze::ExitImmediately is not implemented on Windows");
#else // not COMPILER_MSVC
_exit(exit_code);
#endif // COMPILER_MSVC
}

void SetupStdStreams() {
#ifdef COMPILER_MSVC
// TODO(bazel-team): implement this.
pdie(255, "blaze::SetupStdStreams is not implemented on Windows");
#else // not COMPILER_MSVC
// Set non-buffered output mode for stderr/stdout. The server already
// line-buffers messages where it makes sense, so there's no need to do set
// line-buffering here. On the other hand the server sometimes sends binary
// output (when for example a query returns results as proto), in which case
// we must not perform line buffering on the client side. So turn off
// buffering here completely.
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);

// Ensure we have three open fds. Otherwise we can end up with
// bizarre things like stdout going to the lock file, etc.
if (fcntl(STDIN_FILENO, F_GETFL) == -1) open("/dev/null", O_RDONLY);
if (fcntl(STDOUT_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
if (fcntl(STDERR_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
#endif // COMPILER_MSVC
}

LARGE_INTEGER WindowsClock::GetFrequency() {
LARGE_INTEGER result;
if (!QueryPerformanceFrequency(&result)) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/cpp/workspace_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class WorkspaceLayout {
static bool WorkspaceRelativizeRcFilePath(const std::string& workspace,
std::string* path_fragment);

static constexpr char WorkspacePrefix[] = "%workspace%/";
static constexpr const char WorkspacePrefix[] = "%workspace%/";
static const int WorkspacePrefixLength = sizeof WorkspacePrefix - 1;
};

Expand Down

0 comments on commit 74ffaf7

Please sign in to comment.