Files
fluxer/fluxer_desktop/src/main/LinuxLaunchPath.ts
T

58 lines
1.8 KiB
TypeScript

// SPDX-License-Identifier: AGPL-3.0-or-later
import {spawn} from 'node:child_process';
import {existsSync} from 'node:fs';
import {homedir} from 'node:os';
import {createChildLogger} from '@electron/common/Logger';
import {app} from 'electron';
const logger = createChildLogger('LinuxLaunchPath');
const PREFERRED_RELAUNCH_SHELL = '/bin/bash';
const FALLBACK_RELAUNCH_SHELL = '/bin/sh';
const RELAUNCH_AFTER_EXIT =
'pid="$1"; app="$2"; home="$3"; shift 3; cd /proc/self/fd && for n in *; do case "$n" in 0|1|2) ;; [0-9]) eval "exec $n>&-";; *) [ -n "$BASH_VERSION" ] && eval "exec $n>&-";; esac; done; cd "$home" || cd /; attempt=0; while [ "$attempt" -lt 300 ] && kill -0 "$pid"; do sleep 0.1; attempt=$((attempt + 1)); done; kill -0 "$pid" || exec "$app" "$@"';
function getAppImagePath(): string | null {
if (process.platform !== 'linux') return null;
const appImage = process.env.APPIMAGE;
return appImage && appImage.length > 0 ? appImage : null;
}
export function getStableLinuxLaunchPath(): string {
return getAppImagePath() ?? process.execPath;
}
export function relaunchStableLaunchPath(): void {
const appImagePath = getAppImagePath();
if (appImagePath == null) {
app.relaunch();
return;
}
try {
const child = spawn(
existsSync(PREFERRED_RELAUNCH_SHELL) ? PREFERRED_RELAUNCH_SHELL : FALLBACK_RELAUNCH_SHELL,
[
'-c',
RELAUNCH_AFTER_EXIT,
'fluxer-relaunch',
String(process.pid),
appImagePath,
homedir(),
...process.argv.slice(1),
],
{
cwd: homedir(),
detached: true,
stdio: 'ignore',
},
);
child.unref();
logger.info('Relaunching the AppImage once this process exits', {path: appImagePath, pid: child.pid});
} catch (error) {
logger.error('Failed to start the AppImage replacement process', {error});
app.relaunch({execPath: appImagePath});
}
}