diff --git a/asyncutils.nim b/asyncutils.nim index f00fbe7..1813486 100644 --- a/asyncutils.nim +++ b/asyncutils.nim @@ -23,17 +23,29 @@ from posix import sendmsg, recvmsg -proc asyncExecCmd*(command: string): Future[int] = - let event = newAsyncEvent() - let future = newFuture[int]("asyncExecCmd") - proc execCmdBackground(event: AsyncEvent, command: string): int = - result = execCmd(command) - event.trigger() - let flowVar = spawn execCmdBackground(event, command) - proc callback(fd: AsyncFD): bool = +proc asyncExecCmd*(command: string): Future[string] = + let successEvent = newAsyncEvent() + let failureEvent = newAsyncEvent() + let future = newFuture[result.T]("asyncExecCmd") + proc execCmdBackground(successEvent: AsyncEvent, failureEvent: AsyncEvent, + command: string): string = + var exitCode: int + (result, exitCode) = execCmdEx(command) + if exitCode != 0: + failureEvent.trigger() + successEvent.close() # FIXME: is close the right way to cancel an event? + else: + successEvent.trigger() + failureEvent.close() # FIXME: is close the right way to cancel an event? + let flowVar = spawn execCmdBackground(successEvent, failureEvent, command) + proc successCallback(fd: AsyncFD): bool = future.complete(^flowVar) - true - addEvent(event, callback) + true + proc failureCallback(fd: AsyncFD): bool = + future.fail(newException(OSError, ^flowVar)) + true + addEvent(successEvent, successCallback) + addEvent(failureEvent, failureCallback) return future type ControlMessage* = object diff --git a/tcp_syni.nim b/tcp_syni.nim index 4b58568..5a9804f 100644 --- a/tcp_syni.nim +++ b/tcp_syni.nim @@ -35,8 +35,9 @@ proc addFirewallRule(srcIp: IpAddress, srcPort: Port, --ctorigdst {dstIp} \ --ctorigdstport {dstPort.int} \ -j DROP""" - let exitcode = await asyncExecCmd(firewall_cmd) - if exitcode != 0: + try: + discard await asyncExecCmd(firewall_cmd) + except OSError: raise newException(PunchHoleError, "cannot add firewall rule") proc delFirewallRule(srcIp: IpAddress, srcPort: Port, @@ -53,8 +54,9 @@ proc delFirewallRule(srcIp: IpAddress, srcPort: Port, --ctorigdst {dstIp} \ --ctorigdstport {dstPort.int} \ -j DROP""" - let exitcode = await asyncExecCmd(firewall_cmd) - if exitcode != 0: + try: + discard await asyncExecCmd(firewall_cmd) + except OSError: raise newException(PunchHoleError, "cannot delete firewall rule") proc captureSeqNumbers(puncher: TcpSyniPuncher, rawFd: AsyncFD,