fix: not restarting correctly after an automatic update on linux
Massimo Melina committed
Mar 4, 2026 at 22:22 UTC
05370a98a89aa55bcfc346f4e2b886625827cfa7
1 file changed
+14
-9
src/update.ts
+14
-9
@@ -1,7 +1,7 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
import { apiGithubPaginated, getProjectInfo, getRepoInfo } from './github'
4
-import { ARGS_FILE, HFS_REPO, IS_BINARY, IS_WINDOWS, PREVIOUS_TAG, RUNNING_BETA } from './const'
4
+import { ARGS_FILE, HFS_REPO, IS_BINARY, IS_WINDOWS, IS_MAC, PREVIOUS_TAG, RUNNING_BETA } from './const'
5
import { dirname, join } from 'path'
6
import { spawn, spawnSync } from 'child_process'
7
import { DAY, exists, debounceAsync, unzip, prefix, xlate, HOUR, httpStream, statWithTimeout } from './misc'
@@ -191,20 +191,25 @@ if (argv.updating) { // we were launched with a temporary name, restore original
191
const bin = process.execPath
192
const dest = join(dirname(bin), argv.updating)
193
renameSync(bin, dest)
194
- // have to relaunch with the new name, or otherwise next update will fail with EBUSY on hfs.exe
194
+ // have to relaunch with the new name, or otherwise the next update will fail with EBUSY on hfs.exe
195
console.log(`renamed binary file to "${argv.updating}" and now restarting`)
196
- // be sure to test launching both double-clicking and in a terminal
197
- if (IS_WINDOWS) // this method on Mac works only once, and without console
196
+ // if you change anything, be sure to test launching both double-clicking and in a terminal
197
+ if (IS_WINDOWS) // windows-only; this method on Mac works only once, and without console
198
onProcessExit(() =>
199
launch(dest, ['--updated', '--cwd .']) ) // launch+sync here would cause old process to stay open, locking ports
200
- else {
201
- /* open() is the only consistent way that I could find working on macos preserving console input/output over relaunching,
202
- * but I couldn't find a way to pass parameters, at least on Linux. The workaround I'm using is to write them to a temp file, that's read and deleted at restart.
203
- * For the record, on mac you can: write "./hfs arg1 arg2" to /tmp/tmp.sh with 0o700, and then spawn "open -a Terminal /tmp/tmp.sh"
204
- */
200
+ else if (IS_MAC) {
201
+ // open() is the only consistent way that I could find working on macos preserving console input/output over relaunching,
202
+ // and it doesn't let us pass cli arguments, so we pass them through a temp file consumed at the next startup.
203
+ // For the record, on mac you can: write "./hfs arg1 arg2" to /tmp/tmp.sh with 0o700, and then spawn "open -a Terminal /tmp/tmp.sh"
204
try { writeFileSync(ARGS_FILE, JSON.stringify(['--updated', '--cwd', process.cwd().replaceAll(' ', '\\ ')])) }
205
catch {}
206
void open(dest)
207
}
208
+ else { // linux and other *nix
209
+ if (process.stdin.isTTY && process.stdout.isTTY) // in interactive terminals, block this bridge process on the restarted hfs so the terminal session stays attached
210
+ spawnSync(dest, ['--updated', '--cwd', process.cwd()], { stdio: [0, 1, 2] })
211
+ else
212
+ spawn(dest, ['--updated', '--cwd', process.cwd()], { detached: true, stdio: 'ignore' }).unref()
213
+ }
214
process.exit()
215
}