@@ -3,6 +3,7 @@ import { initPanels, disposePanels, disposeCommands } from "./initPanels";
33import * as utils from "./utils" ;
44import * as os from "os" ;
55import * as fs from "fs" ;
6+ import { access , lstat } from "fs/promises" ;
67import {
78 DapVsCodeApi ,
89 setupVsCodeExtensionViewsApi ,
@@ -202,9 +203,19 @@ async function toggleCt(context: vscode.ExtensionContext, dapVsCodeApi: DapVsCod
202203let commandDisposables : vscode . Disposable [ ] = [ ] ;
203204let miscDisposables : vscode . Disposable [ ] = [ ] ; // e.g. listeners registered once
204205
205- function isExecutable ( p ?: string ) : boolean {
206- if ( p ?. endsWith ( ".AppImage" ) ) return true ;
207- return false
206+ export async function isExecutable ( p ?: string ) : Promise < boolean > {
207+ if ( ! p ) return false ;
208+ try {
209+ const stat = await lstat ( p ) ;
210+ if ( ! stat . isFile ( ) ) {
211+ return false ;
212+ } else if ( p . endsWith ( ".AppImage" ) ) {
213+ return true ;
214+ }
215+ await access ( p , fs . constants . X_OK ) ;
216+ return true ;
217+ }
218+ catch { return false ; }
208219}
209220
210221function disposeAll ( ) {
@@ -217,7 +228,7 @@ async function reinitCommands(context: vscode.ExtensionContext) {
217228
218229 const cfg = vscode . workspace . getConfiguration ( 'codetracer' ) ;
219230 const codetracerExe = cfg . get < string > ( 'runnablePath' ) ?. trim ( ) ;
220- const valid = isExecutable ( codetracerExe ) ;
231+ const valid = await isExecutable ( codetracerExe ) ;
221232 const dapVsCodeApi = newDapVsCodeApi ( vscode , context ) ;
222233 const viewsApi = setupVsCodeExtensionViewsApi (
223234 "vscode-extension-to-views"
0 commit comments