Commit 4b43c554 authored by Michael Hanus 's avatar Michael Hanus
Browse files

Add implementation of external operations

parent 113d5a86
......@@ -2,7 +2,7 @@
--- Library with some useful extensions to the IO monad.
---
--- @author Michael Hanus
--- @version March 2021
--- @version April 2021
------------------------------------------------------------------------------
{-# LANGUAGE CPP #-}
......@@ -25,7 +25,7 @@ import System.Process
--- Executes a command with a new default shell process.
--- The standard I/O streams of the new process (stdin,stdout,stderr)
--- are returned as handles so that they can be explicitly manipulated.
--- They should be closed with <code>IO.hClose</code> since they are not
--- They should be closed with `IO.hClose` since they are not
--- closed automatically when the process terminates.
--- @param cmd - the shell command to be executed
--- @return the handles of the input/output/error streams of the new process
......@@ -57,8 +57,8 @@ evalCmd cmd args input = do
" ; (echo $? > "++tmpfile++")")
unless (null input) (hPutStrLn hi input)
hClose hi
outs <- hGetEOF ho
errs <- hGetEOF he
outs <- hGetContents ho
errs <- hGetContents he
ecodes <- readCompleteFile tmpfile
removeFile tmpfile
return (read ecodes, outs, errs)
......@@ -74,16 +74,6 @@ evalCmd cmd args input = do
| c == '\'' = "'\\''" ++ s
| otherwise = c : s
goodChar c = isAlphaNum c || c `elem` "-_.,/"
--- Reads from an input handle until EOF and returns the input.
hGetEOF :: Handle -> IO String
hGetEOF h = do
eof <- hIsEOF h
if eof
then hClose h >> return ""
else do c <- hGetChar h
cs <- hGetEOF h
return (c:cs)
#endif
......@@ -92,7 +82,7 @@ evalCmd cmd args input = do
--- as one handle which is both readable and writable.
--- Thus, writing to the handle produces input to the process and
--- output from the process can be retrieved by reading from this handle.
--- The handle should be closed with <code>IO.hClose</code> since they are not
--- The handle should be closed with `IO.hClose` since they are not
--- closed automatically when the process terminates.
--- @param cmd - the shell command to be executed
--- @return the handle connected to the input/output streams
......@@ -105,7 +95,7 @@ prim_connectToCmd external
--- An action that reads the complete contents of a file and returns it.
--- This action can be used instead of the (lazy) <code>readFile</code>
--- This action can be used instead of the (lazy) `readFile`
--- action if the contents of the file might be changed.
--- @param file - the name of the file
--- @return the complete contents of the file
......
package SystemIOExts
import "gocurry"
import "../IO"
import "../../Prelude"
import "os/exec"
func ExternalSystem_IOExts_prim_execCmd(task *gocurry.Task){
panic("System.IOExts.execCmd: not yet implemented")
root := task.GetControl()
commandNode := root.GetChild(0)
command := gocurry.ReadString(commandNode)
// create command
cmd := exec.Command(command)
// get pipes from command
stdinPipe, err := cmd.StdinPipe()
if(err != nil){
panic("System.IOExts.execCmd: " + err.Error())
}
stdoutPipe, err := cmd.StdoutPipe()
if(err != nil){
panic("System.IOExts.execCmd: " + err.Error())
}
stderrPipe, err := cmd.StderrPipe()
if(err != nil){
panic("System.IOExts.execCmd: " + err.Error())
}
// create handles for pipes
stdinHandle := SystemIO.HandleCreate(root.NewNode(), nil, &stdinPipe, 1, true)
stdoutHandle := SystemIO.HandleCreate(root.NewNode(), &stdoutPipe, nil, 0, true)
stderrHandle := SystemIO.HandleCreate(root.NewNode(), &stderrPipe, nil, 0, true)
// start command
cmd.Start()
// return
tupel := Prelude.Prelude__CREATE_LbCommaCommaCommaRb(root.NewNode(), stdinHandle, stdoutHandle, stderrHandle)
gocurry.IOCreate(root, tupel)
}
func ExternalSystem_IOExts_prim_connectToCmd(task *gocurry.Task){
panic("System.IOExts.connectToCmd: not yet implemented")
root := task.GetControl()
commandNode := root.GetChild(0)
command := gocurry.ReadString(commandNode)
// create command
cmd := exec.Command(command)
// get pipes from command
stdinPipe, err := cmd.StdinPipe()
if(err != nil){
panic("System.IOExts.execCmd: " + err.Error())
}
stdoutPipe, err := cmd.StdoutPipe()
if(err != nil){
panic("System.IOExts.execCmd: " + err.Error())
}
// create handles for pipes
handle := SystemIO.HandleCreate(root.NewNode(), &stdoutPipe, &stdinPipe, 1, true)
// start command
cmd.Start()
// return
gocurry.IOCreate(root, handle)
}
......@@ -5,10 +5,12 @@ import System.IOExts
import Test.Prop
-- Execute shell command show the first output line of its execution:
getExec :: String -> IO String
getExec cmd = do
hdl <- connectToCommand cmd
s <- hGetLine hdl
hClose hdl
return s
testConnectToCommand :: PropIO
testConnectToCommand = (getExec "echo abcde") `returns` "abcde"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment