Merge pull request #95 from neonichu/swift-3.1-branch
Cherry pick of "Don't fail `executeProcess()` if SIGINT or SIGKILL" to Swift 3.1 branch
diff --git a/examples/c-api/buildsystem/main.c b/examples/c-api/buildsystem/main.c
index b3754f8..8019cfd 100644
--- a/examples/c-api/buildsystem/main.c
+++ b/examples/c-api/buildsystem/main.c
@@ -178,6 +178,7 @@
static void command_process_finished(void* context,
llb_buildsystem_command_t* command,
llb_buildsystem_process_t* process,
+ llb_buildsystem_command_result_t result,
int exit_status) {
}
diff --git a/include/llbuild/BuildSystem/BuildExecutionQueue.h b/include/llbuild/BuildSystem/BuildExecutionQueue.h
index 93cbef2..b969137 100644
--- a/include/llbuild/BuildSystem/BuildExecutionQueue.h
+++ b/include/llbuild/BuildSystem/BuildExecutionQueue.h
@@ -26,6 +26,7 @@
class BuildExecutionQueueDelegate;
class Command;
+enum class CommandResult;
/// Opaque type which allows the queue implementation to maintain additional
/// state and associate subsequent requests (e.g., \see executeProcess()) with
@@ -221,12 +222,14 @@
/// \param handle - The handle used to identify the process. This handle will
/// become invalid as soon as the client returns from this API call.
///
- /// \param exitStatus - The exit status of the process, or -1 if an error was
+ /// \param result - Whether the process suceeded, failed or was cancelled.
+ /// \param exitStatus - The raw exit status of the process, or -1 if an error was
/// encountered.
//
// FIXME: Need to include additional information on the status here, e.g., the
// signal status, and the process output (if buffering).
virtual void commandProcessFinished(Command*, ProcessHandle handle,
+ CommandResult result,
int exitStatus) = 0;
};
diff --git a/include/llbuild/BuildSystem/BuildSystemFrontend.h b/include/llbuild/BuildSystem/BuildSystemFrontend.h
index a78af12..8c90b23 100644
--- a/include/llbuild/BuildSystem/BuildSystemFrontend.h
+++ b/include/llbuild/BuildSystem/BuildSystemFrontend.h
@@ -40,6 +40,7 @@
class BuildSystemFrontendDelegate;
class BuildSystemInvocation;
+enum class CommandResult;
/// This provides a standard "frontend" to the build system features, for use in
/// building bespoke build systems that can still take advantage of desirable
@@ -239,11 +240,13 @@
/// \param handle - The handle used to identify the process. This handle will
/// become invalid as soon as the client returns from this API call.
///
- /// \param exitStatus - The exit status of the process.
+ /// \param result - Whether the process suceeded, failed or was cancelled.
+ /// \param exitStatus - The raw exit status of the process.
//
// FIXME: Need to include additional information on the status here, e.g., the
// signal status, and the process output (if buffering).
virtual void commandProcessFinished(Command*, ProcessHandle handle,
+ CommandResult result,
int exitStatus);
/// @}
diff --git a/include/llbuild/BuildSystem/CommandResult.h b/include/llbuild/BuildSystem/CommandResult.h
new file mode 100644
index 0000000..283ccaf
--- /dev/null
+++ b/include/llbuild/BuildSystem/CommandResult.h
@@ -0,0 +1,34 @@
+//===- CommandResult.h -----------------------------------------------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// Compiler support and compatibility macros. Liberally taken from LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLBUILD_BUILDSYSTEM_COMMAND_RESULT_H
+#define LLBUILD_BUILDSYSTEM_COMMAND_RESULT_H
+
+namespace llbuild {
+namespace buildsystem {
+
+/// Result of a command execution
+enum class CommandResult {
+ Succeeded = 0,
+ Failed = 1,
+ Cancelled = 2,
+};
+
+}
+}
+
+#endif
diff --git a/lib/BuildSystem/BuildSystemFrontend.cpp b/lib/BuildSystem/BuildSystemFrontend.cpp
index 510209b..8547c42 100644
--- a/lib/BuildSystem/BuildSystemFrontend.cpp
+++ b/lib/BuildSystem/BuildSystemFrontend.cpp
@@ -179,11 +179,12 @@
}
virtual void commandProcessFinished(Command* command, ProcessHandle handle,
+ CommandResult result,
int exitStatus) override {
static_cast<BuildSystemFrontendDelegate*>(&getSystem().getDelegate())->
commandProcessFinished(
command, BuildSystemFrontendDelegate::ProcessHandle { handle.id },
- exitStatus);
+ result, exitStatus);
}
};
@@ -424,6 +425,7 @@
void BuildSystemFrontendDelegate::
commandProcessFinished(Command*, ProcessHandle handle,
+ CommandResult result,
int exitStatus) {
}
diff --git a/lib/BuildSystem/LaneBasedExecutionQueue.cpp b/lib/BuildSystem/LaneBasedExecutionQueue.cpp
index 429436c..c497462 100644
--- a/lib/BuildSystem/LaneBasedExecutionQueue.cpp
+++ b/lib/BuildSystem/LaneBasedExecutionQueue.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llbuild/BuildSystem/BuildExecutionQueue.h"
+#include "llbuild/BuildSystem/CommandResult.h"
#include "llbuild/Basic/LLVM.h"
@@ -277,7 +278,7 @@
context.job.getForCommand(), handle,
Twine("unable to open output pipe (") + strerror(errno) + ")");
getDelegate().commandProcessFinished(context.job.getForCommand(),
- handle, -1);
+ handle, CommandResult::Failed, -1);
return false;
}
@@ -350,7 +351,7 @@
context.job.getForCommand(), handle,
Twine("unable to spawn process (") + strerror(errno) + ")");
getDelegate().commandProcessFinished(context.job.getForCommand(), handle,
- -1);
+ CommandResult::Failed, -1);
return false;
}
@@ -403,7 +404,7 @@
context.job.getForCommand(), handle,
Twine("unable to wait for process (") + strerror(errno) + ")");
getDelegate().commandProcessFinished(context.job.getForCommand(), handle,
- -1);
+ CommandResult::Failed, -1);
return false;
}
@@ -414,11 +415,11 @@
}
// Notify of the process completion.
- //
- // FIXME: Need to communicate more information on the process exit status.
+ bool cancelled = WIFSIGNALED(status) && (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGKILL);
+ CommandResult commandResult = cancelled ? CommandResult::Cancelled : (status == 0) ? CommandResult::Succeeded : CommandResult::Failed;
getDelegate().commandProcessFinished(context.job.getForCommand(), handle,
- status);
- return (status == 0);
+ commandResult, status);
+ return (status == 0) || cancelled;
}
};
diff --git a/llbuild.xcodeproj/project.pbxproj b/llbuild.xcodeproj/project.pbxproj
index de8435f..51d0afb 100644
--- a/llbuild.xcodeproj/project.pbxproj
+++ b/llbuild.xcodeproj/project.pbxproj
@@ -695,6 +695,8 @@
54E187B81CD296EA00F7EC89 /* SwiftTools.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftTools.h; sourceTree = "<group>"; };
9D0A6D7F1E1FFEA800BE636F /* TempDir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TempDir.cpp; sourceTree = "<group>"; };
9D0A6D801E1FFEA800BE636F /* TempDir.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TempDir.hpp; sourceTree = "<group>"; };
+ 9D2589301E3820E3006C76F4 /* PlatformUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformUtility.h; sourceTree = "<group>"; };
+ 9D2589311E38221D006C76F4 /* CommandResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommandResult.h; sourceTree = "<group>"; };
9DADBBAC1E256C52005B4869 /* PlatformUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformUtility.cpp; sourceTree = "<group>"; };
9DB0478B1DF9D3E2006CDF52 /* LaneBasedExecutionQueueTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LaneBasedExecutionQueueTest.cpp; sourceTree = "<group>"; };
9DB047A81DF9D43D006CDF52 /* BuildSystemTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BuildSystemTests; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1379,6 +1381,7 @@
E138129C1C536CFC000092C0 /* FileSystem.h */,
E147DEFD1BA81D0E0032D08E /* Hashing.h */,
E1066C091BC5BCE700B892CE /* LLVM.h */,
+ 9D2589301E3820E3006C76F4 /* PlatformUtility.h */,
E147DEFC1BA81D0E0032D08E /* SerialQueue.h */,
E17440C11CE192E30070A30C /* ShellUtility.h */,
E1A2245119F997D40059043E /* Version.h */,
@@ -1793,6 +1796,7 @@
isa = PBXGroup;
children = (
54E187B61CD296EA00F7EC89 /* BuildNode.h */,
+ 9D2589311E38221D006C76F4 /* CommandResult.h */,
54E187B71CD296EA00F7EC89 /* ExternalCommand.h */,
54E187B81CD296EA00F7EC89 /* SwiftTools.h */,
E10FE0D51B6FF2000059D086 /* BuildExecutionQueue.h */,
diff --git a/products/libllbuild/BuildSystem-C-API.cpp b/products/libllbuild/BuildSystem-C-API.cpp
index 7d5a628..ce7d411 100644
--- a/products/libllbuild/BuildSystem-C-API.cpp
+++ b/products/libllbuild/BuildSystem-C-API.cpp
@@ -17,6 +17,7 @@
#include "llbuild/BuildSystem/BuildFile.h"
#include "llbuild/BuildSystem/BuildSystemCommandInterface.h"
#include "llbuild/BuildSystem/BuildSystemFrontend.h"
+#include "llbuild/BuildSystem/CommandResult.h"
#include "llbuild/BuildSystem/ExternalCommand.h"
#include "llbuild/Core/BuildEngine.h"
@@ -250,12 +251,30 @@
}
virtual void commandProcessFinished(Command* command, ProcessHandle handle,
+ CommandResult commandResult,
int exitStatus) override {
if (cAPIDelegate.command_process_finished) {
+ llb_buildsystem_command_result_t result = llb_buildsystem_command_result_failed;
+ switch (commandResult) {
+ case CommandResult::Succeeded:
+ result = llb_buildsystem_command_result_succeeded;
+ break;
+ case CommandResult::Cancelled:
+ result = llb_buildsystem_command_result_cancelled;
+ break;
+ case CommandResult::Failed:
+ result = llb_buildsystem_command_result_failed;
+ break;
+ default:
+ assert(0 && "unknown command result");
+ break;
+ }
+
cAPIDelegate.command_process_finished(
cAPIDelegate.context,
(llb_buildsystem_command_t*) command,
(llb_buildsystem_process_t*) handle.id,
+ result,
exitStatus);
}
}
diff --git a/products/libllbuild/public-api/llbuild/buildsystem.h b/products/libllbuild/public-api/llbuild/buildsystem.h
index 78acacb..61b16b2 100644
--- a/products/libllbuild/public-api/llbuild/buildsystem.h
+++ b/products/libllbuild/public-api/llbuild/buildsystem.h
@@ -87,6 +87,13 @@
/// Opaque handle to a build system command's launched process.
typedef struct llb_buildsystem_process_t_ llb_buildsystem_process_t;
+/// Result of a command execution
+typedef enum {
+ llb_buildsystem_command_result_succeeded = 0,
+ llb_buildsystem_command_result_failed = 1,
+ llb_buildsystem_command_result_cancelled = 2,
+} llb_buildsystem_command_result_t;
+
/// Status change event kinds.
typedef enum {
/// Indicates the command is being scanned to determine if it needs to run.
@@ -288,10 +295,12 @@
/// Xparam process The handle used to identify the process. This handle
/// will become invalid as soon as the client returns from this API call.
///
- /// Xparam exitStatus The exit status of the process.
+ /// Xparam result Whether the process suceeded, failed or was cancelled.
+ /// Xparam exitStatus The raw exit status of the process.
void (*command_process_finished)(void* context,
llb_buildsystem_command_t* command,
llb_buildsystem_process_t* process,
+ llb_buildsystem_command_result_t result,
int exit_status);
/// @}
diff --git a/unittests/BuildSystem/BuildSystemFrontendTest.cpp b/unittests/BuildSystem/BuildSystemFrontendTest.cpp
index fe39665..510e996 100644
--- a/unittests/BuildSystem/BuildSystemFrontendTest.cpp
+++ b/unittests/BuildSystem/BuildSystemFrontendTest.cpp
@@ -177,13 +177,13 @@
super::commandProcessHadError(command, handle, message);
}
- virtual void commandProcessFinished(Command* command, ProcessHandle handle,
+ virtual void commandProcessFinished(Command* command, ProcessHandle handle, CommandResult result,
int exitStatus) override {
{
std::lock_guard<std::mutex> lock(traceMutex);
traceStream << __FUNCTION__ << ": " << command->getName() << ": " << exitStatus << "\n";
}
- super::commandProcessFinished(command, handle, exitStatus);
+ super::commandProcessFinished(command, handle, result, exitStatus);
}
virtual FileSystem& getFileSystem() override {
diff --git a/unittests/BuildSystem/LaneBasedExecutionQueueTest.cpp b/unittests/BuildSystem/LaneBasedExecutionQueueTest.cpp
index 9ccbbd1..ce61841 100644
--- a/unittests/BuildSystem/LaneBasedExecutionQueueTest.cpp
+++ b/unittests/BuildSystem/LaneBasedExecutionQueueTest.cpp
@@ -37,7 +37,7 @@
virtual void commandProcessStarted(Command* command, ProcessHandle handle) override {}
virtual void commandProcessHadError(Command* command, ProcessHandle handle, const Twine& message) override {}
virtual void commandProcessHadOutput(Command* command, ProcessHandle handle, StringRef data) override {}
- virtual void commandProcessFinished(Command* command, ProcessHandle handle, int exitStatus) override {}
+ virtual void commandProcessFinished(Command* command, ProcessHandle handle, CommandResult result, int exitStatus) override {}
};
TEST(LaneBasedExecutionQueueTest, basic) {