-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix SIGINT handling during swift run
#4224
Conversation
Sources/Commands/SwiftRunTool.swift
Outdated
@@ -158,6 +166,9 @@ public struct SwiftRunTool: SwiftCommand { | |||
try ProcessEnv.chdir(swiftTool.originalWorkingDirectory) | |||
} | |||
|
|||
// SwiftTool can't handle signals anymore, so reset the signal handler to SIG_DFL before call exec() | |||
signal(SIGINT, SIG_DFL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the fix @kkk669 makes sense. could we maybe create a wrapper for exec
in this file that reset the signal handler first then delegates to the "real" exec? this way we can keep it DRYer. wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you. Should I create a wrapper just for SwiftRunTool
? Or should I create it so that it can be used from other commands? If there is a possibility of using exec
for other commands in the future, I feel that a wrapper should be created for the entire Commands
target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. lets add to SwiftTool and then we can call that from any other tool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the direction. I will try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a wrapper function in bff14cc 72d8c92.
With this change, not only SwiftRunTool
but also WatchmanHelper
and SnippetCard
now call the wrapper.
I wasn't sure whether to create SwiftTool.exec
or global exec
, but in the end I went with the latter. Because I believe that it will prevent mistakes like using TSCBasic.exec
in the future.
Sources/Commands/SwiftRunTool.swift
Outdated
import Darwin | ||
#else | ||
import Glibc | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#if canImport(WinSDK)
import WinSDK
#elseif canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#endif
more idiomatic / correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I also think so. I'll change it to that form.
SwiftTool.swift has the same problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@swift-ci smoke test |
Sources/Commands/SwiftTool.swift
Outdated
@@ -286,6 +286,14 @@ extension SwiftCommand { | |||
public static var _errorLabel: String { "error" } | |||
} | |||
|
|||
/// A safe wrapper of TSCBasic.exec. | |||
static func exec(path: String, args: [String]) throws -> Never { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove static, or make into a static func of SwiftTool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the Commands module, this wrapper function is called by default if you write `try exec(path: ..., args: ...)`.
bff14cc
to
72d8c92
Compare
@swift-ci smoke test |
thanks again @kkk669 could you also crate a cherry-pick PR against the |
* Fix SIGINT handling during `swift run` * Create a safe wrapper of TSCBasic.exec * In the Commands module, this wrapper function is called by default if you write `try exec(path: ..., args: ...)`. Co-authored-by: Kenta Kubo <kkk669@users.noreply.github.com>
This broke the windows build: https://ci-external.swift.org/job/oss-swift-windows-toolchain-x86_64-vs2019/1178/console |
@compnerd Thank you for mentioning it. I'll investigate it. Currently, I'm preparing a Windows VM. |
Perhaps I found the cause. On Windows, |
I fixed SIGINT handling during
swift run
.Motivation:
Since Swift 5.6, Ctrl-C no longer works during
swift run
.The issue was introduced in #3815. That PR added
signal(SIGINT, SIG_IGN)
for handlingSIGINT
byDispatchSourceSignal
. That's no problem, butexec(...)
replaces the process, so onceexec(...)
is called,DispatchSourceSignal
can't handleSIGINT
anymore and no one can handle it. Therefore, it is necessary to cancelsignal(SIGINT, SIG_IGN)
before callingexec(...)
.Modifications:
I created a wrapper function of
exec(...)
that callssignal(SIGINT, SIG_DFL)
just beforeexec(...)
in order to cancelsignal(SIGINT, SIG_IGN)
, and use it fromSwiftRunTool
(2 methods),WatchmanHelper
, andSnippetCard
.Result:
Ctrl-C will work again during
swift run
.