|
From: Bernd H. <ber...@ic...> - 2008-11-05 12:57:16
|
Hi Mads, thanks a lot for your reply. I wasn't subscribed to wxhaskell-develop yet so I only today realized you answered my posting. I applied your supposal on my Windows machine with the following results: wxExecProcess now indeed yields output on stderr, but output on both stdout and stderr are somewhat incomplete (with no change when setting output buffering in processtest.exe to NoBuffering): display on stdout frame: Stdout: 100: Info 98: Info 96: Info 94: Info 92: Info 90: Info 88: Info 86: Info 84: Info 82: Info Stdout: 80: Info 78: Info ... and on stderr frame: Stderr: 99: Error 97: Error 95: Error 93: Error 91: Error 89: Error 87: Error 85: ErroStderr: r 83: Error ... That is, the first 8 bytes (Stdout: / Stderr: ) are most of the time vanished. Whereas processExecAsyncTimed yields the correct output (of course only on stdout): Stdout: 100: Info Stdout: 98: Info Stdout: 96: Info Stdout: 94: Info ... Do you have any idea? (Before starting to delve deep into the process management myself...) Thanks again, Bernd > Hi Bernd > > Bernd Holzmüller wrote: >> Hi all, >> >> I am developing a test management GUI where processes are started and >> their output (on stdout and stderr) are shown on corresponding console >> windows. The process management worked quite OK with version 0.9.4 but >> does no longer work in version 0.10.3 (using ghc 6.8.3 on Windows XP). >> >> The attached small example application shows what happens: with >> processExecAsync only garbage is shown on both the stdout and the stderr >> console window, with processExecAsyncTimed the stdout console works >> fine, but the stderr console shows nothing. Main.hs is the wxHaskell GUI >> with two buttons, both calling the application compiled from >> Testproc.hs, one using processExecAsync, one using the Timed variant. >> The attached makefile builds everything. >> >> If someone with understanding of the internals of wxHaskell could have a >> look on this topic, I would be very grateful. Perhaps the (soon?) coming >> new wxHaskell version 0.11 will do correctly? >> >> Thanks, >> Bernd >> > > Your processExecAsyncTimed example works on Linux. But of cause that do > not help you much. The processExecAsync example do not work on Linux > either. > > A while ago I got tired of the hard-to-get-to-work nature of > processExecAsyncTimed and therefore wrote my own process executor. I > have attached my own process executor and an adapted version of your > code, which works for me (on Linux). You will have to adapt it a little > bit to work on windows (properly just changing "./testproc.exe" to > "testproc" should do). > > I would love to hear if it works on your machine. > > > Greetings, > > Mads Lindstrøm |
|
From: Mads L. <mad...@ya...> - 2008-11-05 20:46:39
|
Hi, > Hi Mads, > > thanks a lot for your reply. I wasn't subscribed to wxhaskell-develop > yet so I only today realized you answered my posting. > > I applied your supposal on my Windows machine with the following > results: wxExecProcess now indeed yields output on stderr, but output on > both stdout and stderr are somewhat incomplete (with no change when > setting output buffering in processtest.exe to NoBuffering): > > display on stdout frame: > > Stdout: 100: Info > 98: Info > 96: Info > 94: Info > 92: Info > 90: Info > 88: Info > 86: Info > 84: Info > 82: Info > Stdout: > 80: Info > 78: Info > ... > > and on stderr frame: > > Stderr: 99: Error > 97: Error > 95: Error > 93: Error > 91: Error > 89: Error > 87: Error > 85: ErroStderr: r > 83: Error > ... > > That is, the first 8 bytes (Stdout: / Stderr: ) are most of the time > vanished. Whereas processExecAsyncTimed yields the correct output (of > course only on stdout): > > Stdout: 100: Info > Stdout: 98: Info > Stdout: 96: Info > Stdout: 94: Info > ... > > Do you have any idea? (Before starting to delve deep into the process > management myself...) Nope, I have no idea why it do not work for you - sorry :( /Mads Lindstrøm > > Thanks again, > Bernd > > > Hi Bernd > > > > Bernd Holzmüller wrote: > >> Hi all, > >> > >> I am developing a test management GUI where processes are started and > >> their output (on stdout and stderr) are shown on corresponding console > >> windows. The process management worked quite OK with version 0.9.4 but > >> does no longer work in version 0.10.3 (using ghc 6.8.3 on Windows XP). > >> > >> The attached small example application shows what happens: with > >> processExecAsync only garbage is shown on both the stdout and the stderr > >> console window, with processExecAsyncTimed the stdout console works > >> fine, but the stderr console shows nothing. Main.hs is the wxHaskell GUI > >> with two buttons, both calling the application compiled from > >> Testproc.hs, one using processExecAsync, one using the Timed variant. > >> The attached makefile builds everything. > >> > >> If someone with understanding of the internals of wxHaskell could have a > >> look on this topic, I would be very grateful. Perhaps the (soon?) coming > >> new wxHaskell version 0.11 will do correctly? > >> > >> Thanks, > >> Bernd > >> > > > > Your processExecAsyncTimed example works on Linux. But of cause that do > > not help you much. The processExecAsync example do not work on Linux > > either. > > > > A while ago I got tired of the hard-to-get-to-work nature of > > processExecAsyncTimed and therefore wrote my own process executor. I > > have attached my own process executor and an adapted version of your > > code, which works for me (on Linux). You will have to adapt it a little > > bit to work on windows (properly just changing "./testproc.exe" to > > "testproc" should do). > > > > I would love to hear if it works on your machine. > > > > > > Greetings, > > > > Mads Lindstrøm > > > > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > wxhaskell-devel mailing list > wxh...@li... > https://lists.sourceforge.net/lists/listinfo/wxhaskell-devel |
|
From: shelarcy <she...@gm...> - 2008-11-12 16:22:12
|
Hi,
On Wed, 05 Nov 2008 21:57:07 +0900, Bernd Holzmüller <ber...@ic...> wrote:
>>> The attached small example application shows what happens: with
>>> processExecAsync only garbage is shown on both the stdout and the stderr
>>> console window, with processExecAsyncTimed the stdout console works
>>> fine, but the stderr console shows nothing. Main.hs is the wxHaskell GUI
>>> with two buttons, both calling the application compiled from
>>> Testproc.hs, one using processExecAsync, one using the Timed variant.
>>> The attached makefile builds everything.
I tested Mads' program on Mac OS X platform.
[1]. processExecAsync example crashes this program.
[2]. processExecAsyncTimed example doesn't work correctory. stdout console works
fine, but the stderr console *almost* shows nothing. We must care about this
fact. stderr console *sometimes* works fine.
(I also saw this fact on Windows. stderr console *sometimes* works fine, too.)
[3]. wxExecProcess example works fine.
>>> I am developing a test management GUI where processes are started and
>>> their output (on stdout and stderr) are shown on corresponding console
>>> windows. The process management worked quite OK with version 0.9.4 but
>>> does no longer work in version 0.10.3 (using ghc 6.8.3 on Windows XP).
> I applied your supposal on my Windows machine with the following
> results: wxExecProcess now indeed yields output on stderr, but output on
> both stdout and stderr are somewhat incomplete (with no change when
> setting output buffering in processtest.exe to NoBuffering):
>
> (snip)
Do you test program with same version's GHC? GHC's IO functions has some bugs
on Windows platform. So, I want to know that this is wxHaskell's bug or GHC's
bug.
http://hackage.haskell.org/trac/ghc/ticket/806
http://hackage.haskell.org/trac/ghc/ticket/2189
etc...
I tried to fix the problem in this week. But I can't find where causes this
problem by undoing Graphics.UI.WXCore.Process related changes.
Best Regards,
> display on stdout frame:
>
> Stdout: 100: Info
> 98: Info
> 96: Info
> 94: Info
> 92: Info
> 90: Info
> 88: Info
> 86: Info
> 84: Info
> 82: Info
> Stdout:
> 80: Info
> 78: Info
> ...
>
> and on stderr frame:
>
> Stderr: 99: Error
> 97: Error
> 95: Error
> 93: Error
> 91: Error
> 89: Error
> 87: Error
> 85: ErroStderr: r
> 83: Error
> ...
>
> That is, the first 8 bytes (Stdout: / Stderr: ) are most of the time
> vanished. Whereas processExecAsyncTimed yields the correct output (of
> course only on stdout):
>
> Stdout: 100: Info
> Stdout: 98: Info
> Stdout: 96: Info
> Stdout: 94: Info
> ...
--
shelarcy <shelarcy hotmail.co.jp>
http://page.freett.com/shelarcy/
|
|
From: Bernd H. <ber...@ic...> - 2008-11-13 10:08:13
|
{-# LANGUAGE PatternSignatures #-}
module WxProcess
( wxExecProcess
, ExitCode(..)
)
where
import Control.Concurrent -- forkIO, MVars
import System.Exit (ExitCode(..))
import System.Process (runInteractiveCommand, waitForProcess, ProcessHandle)
import System.IO
import Foreign.Marshal.Array
import Foreign.Marshal.Alloc
import Data.Word
import Data.IORef
-- import qualified Graphics.UI.WX as WX
import Graphics.UI.WX
import Graphics.UI.WX (Prop(..), on)
type OnReceive = String -> IO()
wxExecProcess :: Window a -> String -> Int -> IORef Bool -> (ExitCode -> IO()) -> OnReceive -> OnReceive
-> IO ProcessHandle
-- if the user needs to give input to the created process, we could return IO (String -> IO StreamStatus) in stead
wxExecProcess parent cmd bufferSize killedByUser onEndProcess onOutput onErrOutput =
do (inh,outh,errh,pid) <- runInteractiveCommand cmd
mapM_ (\hdl -> hSetBuffering hdl NoBuffering) [inh, outh, errh]
-- fork off two threads to start consuming the stdout and stderr output
stdOutMVar <- newEmptyMVar
stdErrMVar <- newEmptyMVar
stdOutIsFinished <- newEmptyMVar
stdErrIsFinished <- newEmptyMVar
processFinished <- newEmptyMVar
let consume handle isFinished outputMVar =
do buf <- mallocArray bufferSize
consume' handle isFinished outputMVar buf
free buf
consume' handle isFinished outputMVar buf =
do outIsEOF <- hIsEOF handle
if outIsEOF
then putMVar isFinished ()
else do hWaitForInput handle 1000 -- 1000 = one second
count <- hGetBufNonBlocking handle buf bufferSize
(x :: [Word8]) <- peekArray count buf
putMVar outputMVar (map (toEnum . fromIntegral) x)
consume' handle isFinished outputMVar buf
forkIO $ consume outh stdOutIsFinished stdOutMVar
forkIO $ consume errh stdErrIsFinished stdErrMVar
let handleAnyInput mvar withOutput =
do val <- tryTakeMVar mvar
maybe (return ()) withOutput val
let handleAllInput = do handleAnyInput stdOutMVar onOutput
handleAnyInput stdErrMVar onErrOutput
checkOutput <- timer parent [ interval := 100 ] -- 10 times a second
set checkOutput [ on command := do
exitCode <- tryTakeMVar processFinished
handleAllInput
case exitCode of
Nothing -> return ()
Just code -> do onEndProcess code
set checkOutput [enabled := False]
]
forkIO $ do exitCode <- waitForProcess pid -- compile with -threaded to allow other threads to be active concurrently!
wasKilled <- varGet killedByUser
let waitForOutputs = mapM_ takeMVar [stdOutIsFinished, stdErrIsFinished]
signalFinished = putMVar processFinished exitCode
if wasKilled
then do signalFinished; waitForOutputs
else do waitForOutputs; signalFinished
hClose outh
hClose errh
return pid |