diff --git a/uni/ulsp/udap/communicator.icn b/uni/ulsp/udap/communicator.icn index 471e20cb4..e06eb7c47 100644 --- a/uni/ulsp/udap/communicator.icn +++ b/uni/ulsp/udap/communicator.icn @@ -3,32 +3,30 @@ package udap link findre import json -class Communicator(udb, udbSock, filePath, progArgs, debuggerActive) +class Communicator(udb, udbSock, progSock, progComSock, filePath, progArgs) # Attempt to start udb if not already active and connect to it. # Returns "success" if successful and an appropriate error string if otherwise. method start_debugger(port) local udbPath, dir, result - if debuggerActive == "n" then { - udbPath := find_debugger() - if /udbPath then return "udap could not find udb" + udbPath := find_debugger() + if /udbPath then return "udap could not find udb" - udb := system(udbPath || " -adapter " || port, &null, &null, &null, "nowait") - } + udb := system(udbPath || " -adapter " || port, &null, &null, &null, "nowait") + + udbSock := open_sock(port) + if /udbSock then return "udap failed to open udbSock: " || port - result := connect_udbsock(port) - if result ~== "success" then { - return result - } + progSock := open_sock(port + 10) + if /progSock then return "udap failed to open progSock: " || port + 10 return "success" end # Send a termination signal to udb. method end_debugger() - kill(\udb, "SIGTERM") - debuggerActive := "n" + kill(\udb, 9) end # Returns udb's absolute path. @@ -155,23 +153,22 @@ class Communicator(udb, udbSock, filePath, progArgs, debuggerActive) filePath := fpath end - # Attempts to connect to udb on a specified port. - # Returns "success" if successful and an appropriate error string if otherwise. - method connect_udbsock(port) + # Attempts to open a specified port. Returns communication source if successful. + method open_sock(port) + local sock if /port then return "udb communication port not declared" - if \udbSock then return "success" - every 1 to 5 do { - if udbSock := open(":" || port, "n") then { - return "success" + if sock := open(":" || port, "na") then { + return sock } else { + write("Attempting to open sock on port " || port || " again.") delay(1000) } } - return "udap failed to connect to udb on port: " || port + write("udap failed to open port: " || port) end # Disconnects from udb. @@ -289,7 +286,4 @@ class Communicator(udb, udbSock, filePath, progArgs, debuggerActive) else breakpoints[bp]["verified"] := "__false__" } end - - initially() - debuggerActive := "n" end diff --git a/uni/ulsp/udap/progcom.icn b/uni/ulsp/udap/progcom.icn index d95647568..b81c23782 100644 --- a/uni/ulsp/udap/progcom.icn +++ b/uni/ulsp/udap/progcom.icn @@ -4,20 +4,22 @@ procedure main(argv) port := pop(argv) trap("SIGINT", progcomExit) - trap("SIGTERM", progcomExit) + trap("SIGHUP", progcomExit) + trap("SIGPIPE", progcomExit) every 1 to 5 do { if sock := open(":" || port, "n") then { break } else { + write("progcom open(",port,") ERROR: ", &errortext) delay(1000) } } if /sock then stop("failed to connect to ",port) repeat { - resList := select([sock, &input], 0) + resList := select([sock, &input]) every res := !resList do { if res === sock then writes(ready(sock)) if res === &input then writes(sock, ready()) diff --git a/uni/ulsp/udap/server.icn b/uni/ulsp/udap/server.icn index fcda00682..b72418f04 100644 --- a/uni/ulsp/udap/server.icn +++ b/uni/ulsp/udap/server.icn @@ -78,7 +78,7 @@ class Server(port, sock, communicator, shellProcessId, clientDetails, currentReq while /request_body | request_body == "" do { # Even while waiting for request, listen to udb - if \communicator.udbSock & \communicator.debuggerActive == "y" then { + if \communicator.udbSock then { select([sock, communicator.udbSock]) udb_listen() } @@ -237,13 +237,20 @@ class Server(port, sock, communicator, shellProcessId, clientDetails, currentReq progPort := tab(0) } progPort := integer(progPort) - progPort +:= 20 + progPort +:= 30 args := ["progcom " || progPort] event := build_request("runInTerminal", table("kind", "integrated", "cwd", "", "title", "udbTerminal", "args", args, "argsCanBeInterpretedByShell", "__true__")) writes(sock, event) waitingForTerminal := 1 + communicator.progComSock := communicator.open_sock(progPort) + if /communicator.progComSock then { + res := build_response(request_seq, "__false__", request_command, &null, "udap failed to open progComSock: " || port + 10) + writes(sock, res) + return + } + res := build_response(request_seq, "__true__", request_command) writes(sock, res) end @@ -500,6 +507,22 @@ class Server(port, sock, communicator, shellProcessId, clientDetails, currentReq writes(sock, event) end + # Enable communication between progcom and debugee. + method debuggee_progcom_communication() + local resList, res + repeat { + if \communicator then { + if \communicator.progSock & \communicator.progComSock then { + resList := select([communicator.progSock, communicator.progComSock]) + every res := !resList do { + if res === communicator.progSock then writes(communicator.progComSock, ready(communicator.progSock)) + if res === communicator.progComSock then writes(communicator.progSock, ready(communicator.progComSock)) + } + } + } + } + end + ######################################################## # disconnect # ######################################################## @@ -507,9 +530,10 @@ class Server(port, sock, communicator, shellProcessId, clientDetails, currentReq # Disconnect from client and udb and startup as a fresh session. method disconnect() communicator.disconnect_udbsock() + communicator.end_debugger() communicator.udb_input(&null, &null, 1) - kill(shellProcessId, "SIGKILL") - close(sock) + kill(\shellProcessId, 9) + close(\sock) startup() end @@ -526,7 +550,7 @@ class Server(port, sock, communicator, shellProcessId, clientDetails, currentReq if /sock then stop("failed to connect to ",port) - communicator := Communicator(self) + communicator := Communicator() seq := 1 udbError := &null @@ -535,5 +559,6 @@ class Server(port, sock, communicator, shellProcessId, clientDetails, currentReq end initially + thread debuggee_progcom_communication() startup() end \ No newline at end of file