From c463278dd0f859c5e247a1b68869fb9adafdb100 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 19 Jul 2023 18:51:17 -0700 Subject: [PATCH] Add more FFI; fix FFI; some uncurried FFI --- CHANGELOG.md | 13 +++++++++ src/Node/ChildProcess.js | 11 ++++++++ src/Node/ChildProcess.purs | 56 ++++++++++++++++++++++++++++++++------ test/Main.purs | 4 +-- 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8e5bd5..7a02af7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,10 +19,22 @@ Breaking changes: BySignal signal -> ... ``` See https://pursuit.purescript.org/packages/purescript-node-event-emitter/3.0.0/docs/Node.EventEmitter for more details. +- Update `pid` type signature to return `Maybe Pid` rather than `Pid` (#44 by @JordanMartinez) +- Update `kill` returned value from `Effect Unit` to `Effect Boolean` (#44 by @JordanMartinez) New features: - Added event handler for `spawn` event (#43 by @JordanMartinez) +- Added missing APIs (#44 by @JordanMartinez) + + - exitCode + - kill (no signal specified) + - kill' (kill with a `String` signal) + - killSignal (kill with an ADT `Signal` arg) + - killed + - signalCode + - spawnArgs + - spawnFile Bugfixes: @@ -30,6 +42,7 @@ Other improvements: - Bumped CI's node version to `lts/*` (#41 by @JordanMartinez) - Updated CI `actions/checkout` and `actions/setup-nodee` to `v3` (#41 by @JordanMartinez) - Format codebase & enforce formatting in CI via purs-tidy (#42 by @JordanMartinez) +- Migrate more FFI to uncurried functions (#44 by @JordanMartinez) ## [v9.0.0](https://github.com/purescript-node/purescript-node-child-process/releases/tag/v9.0.0) - 2022-04-29 diff --git a/src/Node/ChildProcess.js b/src/Node/ChildProcess.js index e5a11ca..d621449 100644 --- a/src/Node/ChildProcess.js +++ b/src/Node/ChildProcess.js @@ -9,6 +9,17 @@ export function unsafeFromNullable(msg) { }; } +export const connectedImpl = (cp) => cp.connected; +export const disconnectImpl = (cp) => cp.disconnect(); +export const exitCodeImpl = (cp) => cp.exitCode; +export const pidImpl = (cp) => cp.pid; +export const killImpl = (cp) => cp.kill(); +export const killStrImpl = (cp, str) => cp.kill(str); +export const killedImpl = (cp) => cp.killed; +export const signalCodeImpl = (cp) => cp.signalCode; +export const spawnArgs = (cp) => cp.spawnArgs; +export const spawnFile = (cp) => cp.spawnFile; + export function spawnImpl(command) { return args => opts => () => spawn(command, args, opts); } diff --git a/src/Node/ChildProcess.purs b/src/Node/ChildProcess.purs index a225ce2..3f9696d 100644 --- a/src/Node/ChildProcess.purs +++ b/src/Node/ChildProcess.purs @@ -26,9 +26,14 @@ module Node.ChildProcess , stderr , pid , connected + , disconnect + , exitCode , kill + , kill' + , killSignal + , killed + , signalCode , send - , disconnect , Error , toStandardError , Exit(..) @@ -61,7 +66,7 @@ import Data.Posix.Signal (Signal) import Data.Posix.Signal as Signal import Effect (Effect) import Effect.Exception as Exception -import Effect.Uncurried (EffectFn2, mkEffectFn1, mkEffectFn2) +import Effect.Uncurried (EffectFn1, EffectFn2, mkEffectFn1, mkEffectFn2, runEffectFn1, runEffectFn2) import Foreign (Foreign) import Foreign.Object (Object) import Node.Buffer (Buffer) @@ -152,13 +157,22 @@ foreign import unsafeFromNullable :: forall a. String -> Nullable a -> a -- | The process ID of a child process. Note that if the process has already -- | exited, another process may have taken the same ID, so be careful! -pid :: ChildProcess -> Pid -pid = _.pid <<< runChildProcess +pid :: ChildProcess -> Effect (Maybe Pid) +pid cp = map toMaybe $ runEffectFn1 pidImpl cp + +foreign import pidImpl :: EffectFn1 (ChildProcess) (Nullable Pid) -- | Indicates whether it is still possible to send and receive -- | messages from the child process. connected :: ChildProcess -> Effect Boolean -connected (ChildProcess cp) = mkEffect \_ -> cp.connected +connected cp = runEffectFn1 connectedImpl cp + +foreign import connectedImpl :: EffectFn1 (ChildProcess) (Boolean) + +exitCode :: ChildProcess -> Effect (Maybe Int) +exitCode cp = map toMaybe $ runEffectFn1 exitCodeImpl cp + +foreign import exitCodeImpl :: EffectFn1 (ChildProcess) (Nullable Int) -- | Send messages to the (`nodejs`) child process. -- | @@ -174,7 +188,19 @@ send msg handle (ChildProcess cp) = mkEffect \_ -> runFn2 cp.send msg handle -- | Closes the IPC channel between parent and child. disconnect :: ChildProcess -> Effect Unit -disconnect = _.disconnect <<< runChildProcess +disconnect cp = runEffectFn1 disconnectImpl cp + +foreign import disconnectImpl :: EffectFn1 (ChildProcess) (Unit) + +kill :: ChildProcess -> Effect Boolean +kill cp = runEffectFn1 killImpl cp + +foreign import killImpl :: EffectFn1 (ChildProcess) (Boolean) + +kill' :: String -> ChildProcess -> Effect Boolean +kill' sig cp = runEffectFn2 killStrImpl cp sig + +foreign import killStrImpl :: EffectFn2 (ChildProcess) (String) (Boolean) -- | Send a signal to a child process. In the same way as the -- | [unix kill(2) system call](https://linux.die.net/man/2/kill), @@ -184,8 +210,22 @@ disconnect = _.disconnect <<< runChildProcess -- | and the signal. They can vary from system to system. -- | The child process might emit an `"error"` event if the signal -- | could not be delivered. -kill :: Signal -> ChildProcess -> Effect Unit -kill sig (ChildProcess cp) = mkEffect \_ -> cp.kill (Signal.toString sig) +killSignal :: Signal -> ChildProcess -> Effect Boolean +killSignal sig cp = kill' (Signal.toString sig) cp + +killed :: ChildProcess -> Effect Boolean +killed cp = runEffectFn1 killedImpl cp + +signalCode :: ChildProcess -> Effect (Maybe String) +signalCode cp = map toMaybe $ runEffectFn1 signalCodeImpl cp + +foreign import signalCodeImpl :: EffectFn1 (ChildProcess) (Nullable String) + +foreign import killedImpl :: EffectFn1 (ChildProcess) (Boolean) + +foreign import spawnArgs :: ChildProcess -> Array String + +foreign import spawnFile :: ChildProcess -> String mkEffect :: forall a. (Unit -> a) -> Effect a mkEffect = unsafeCoerce diff --git a/test/Main.purs b/test/Main.purs index a07337b..23ee033 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -24,7 +24,7 @@ main = do log "doesn't perform effects too early" spawn "ls" [ "-la" ] defaultSpawnOptions >>= \ls -> do - let _ = kill SIGTERM ls + let _ = kill ls ls # on_ exitH \exit -> case exit of Normally 0 -> @@ -34,7 +34,7 @@ main = do log "kills processes" spawn "ls" [ "-la" ] defaultSpawnOptions >>= \ls -> do - _ <- kill SIGTERM ls + _ <- kill ls ls # on_ exitH \exit -> case exit of BySignal SIGTERM ->