aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkitsunyan2018-04-20 00:08:22 +0000
committerkitsunyan2018-04-20 00:08:22 +0000
commit15a78acfc45556cf73264e1a20af1e0894d5aaf1 (patch)
tree62298e9123a2a25a226185387f936b0ec3897c43 /src
parentedd51c66aa5667135bdb9b82b9ab9f4a6fe5ba6a (diff)
Catch SIGINT and ask to remove build dependencies
Diffstat (limited to 'src')
-rw-r--r--src/feature/syncinstall.nim49
-rw-r--r--src/main.nim4
-rw-r--r--src/utils.nim21
3 files changed, 48 insertions, 26 deletions
diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim
index 03d1342..9d22574 100644
--- a/src/feature/syncinstall.nim
+++ b/src/feature/syncinstall.nim
@@ -299,7 +299,7 @@ proc editLoop(config: Config, base: string, repoPath: string, gitPath: Option[st
editFileLoopAll(0)
proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
- noextract: bool): (Option[BuildResult], int) =
+ noextract: bool): (Option[BuildResult], int, bool) =
let base = pkgInfos[0].base
let repoPath = repoPath(config.tmpRoot, base)
let gitPath = pkgInfos[0].gitPath
@@ -333,7 +333,7 @@ proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
if not workConfFileCopySuccess:
printError(config.color, tr"failed to copy config file '$#'" % [confFile])
- (none(BuildResult), 1)
+ (none(BuildResult), 1, false)
else:
let envExt = getEnv("PKGEXT")
let confExt = if envExt.len == 0:
@@ -346,29 +346,32 @@ proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
else:
envExt
- let buildCode = forkWait(proc: int =
- if chdir(buildPath) == 0:
- discard cunsetenv("MAKEPKG_CONF")
- dropPrivileges()
+ let (buildCode, interrupted) = catchInterrupt():
+ forkWait(proc: int =
+ if chdir(buildPath) == 0:
+ discard cunsetenv("MAKEPKG_CONF")
+ dropPrivileges()
- if not noextract:
- removeDirQuiet(buildPath & "src")
+ if not noextract:
+ removeDirQuiet(buildPath & "src")
- let optional: seq[tuple[arg: string, cond: bool]] = @[
- ("-e", noextract),
- ("-m", not config.color)
- ]
+ let optional: seq[tuple[arg: string, cond: bool]] = @[
+ ("-e", noextract),
+ ("-m", not config.color)
+ ]
- execResult(@[makepkgCmd, "--config", workConfFile, "-f"] &
- optional.filter(o => o.cond).map(o => o.arg))
- else:
- quit(1))
+ execResult(@[makepkgCmd, "--config", workConfFile, "-f"] &
+ optional.filter(o => o.cond).map(o => o.arg))
+ else:
+ quit(1))
discard unlink(workConfFile)
- if buildCode != 0:
+ if interrupted:
+ (none(BuildResult), buildCode, interrupted)
+ elif buildCode != 0:
printError(config.color, tr"failed to build '$#'" % [base])
- (none(BuildResult), buildCode)
+ (none(BuildResult), buildCode, false)
else:
let resultPkgInfos = reloadPkgInfos(config, buildPath, pkgInfos)
@@ -392,7 +395,7 @@ proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
if failedNames.len > 0:
for name in failedNames:
printError(config.color, tr"$#: failed to extract package info" % [name])
- (none(BuildResult), 1)
+ (none(BuildResult), 1, false)
else:
let targetPkgInfos: seq[ReplacePkgInfo] = resultByIndices
.map(i => (some(i.name), i.pkgInfo.get))
@@ -400,7 +403,7 @@ proc buildLoop(config: Config, pkgInfos: seq[PackageInfo], noconfirm: bool,
let additionalPkgInfos: seq[ReplacePkgInfo] = resultPkgInfos
.filter(i => not (i.name in filterNames))
.map(i => (none(string), i))
- (some(($confExt, targetPkgInfos & additionalPkgInfos)), 0)
+ (some(($confExt, targetPkgInfos & additionalPkgInfos)), 0, false)
proc buildFromSources(config: Config, commonArgs: seq[Argument],
pkgInfos: seq[PackageInfo], noconfirm: bool): (Option[BuildResult], int) =
@@ -423,10 +426,12 @@ proc buildFromSources(config: Config, commonArgs: seq[Argument],
if res == 'a':
(none(BuildResult), 1)
else:
- let (buildResult, code) = buildLoop(config, pkgInfos,
+ let (buildResult, code, interrupted) = buildLoop(config, pkgInfos,
noconfirm, noextract)
- if code != 0:
+ if interrupted:
+ (buildResult, 1)
+ elif code != 0:
proc ask(): char =
let res = printColonUserChoice(config.color,
tr"Build failed, retry?", ['y', 'e', 'n', '?'], 'n', '?',
diff --git a/src/main.nim b/src/main.nim
index 685b9d3..045b44e 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -193,11 +193,7 @@ proc handleVersion(): int =
echo(' '.repeat(23), "Copyright (C) ", copyright)
pacmanExec(false, false, ("V", none(string), ArgumentType.short))
-proc signal(sign: cint, handler: pointer): pointer
- {.importc, header: "<signal.h>".}
-
discard setlocale(LC_ALL, "")
-discard signal(SIGINT, cast[pointer](SIG_DFL))
template withErrorHandler(propColor: Option[bool], T: typedesc, body: untyped):
tuple[success: Option[T], code: int] =
diff --git a/src/utils.nim b/src/utils.nim
index e67274f..7cbf184 100644
--- a/src/utils.nim
+++ b/src/utils.nim
@@ -277,6 +277,27 @@ proc dropPrivileges*() =
discard cunsetenv("SUDO_GID")
discard cunsetenv("PKEXEC_UID")
+var intSigact: SigAction
+intSigact.sa_handler = SIG_DFL
+discard sigaction(SIGINT, intSigact)
+
+var wasInterrupted = false
+
+proc interruptHandler(signal: cint): void {.noconv.} =
+ wasInterrupted = true
+
+template catchInterrupt*(body: untyped): untyped =
+ block:
+ var intSigact: SigAction
+ var oldIntSigact: SigAction
+ intSigact.sa_handler = interruptHandler
+ discard sigaction(SIGINT, intSigact, oldIntSigact)
+ let data = body
+ let interrupted = wasInterrupted
+ wasInterrupted = false
+ discard sigaction(SIGINT, oldIntSigact)
+ (data, interrupted)
+
proc toString*[T](arr: array[T, char], length: Option[int]): string =
var workLength = length.get(T.high + 1)
var str = newStringOfCap(workLength)