Re: [Haskell] Win32 process spawning, POpen and Hugs, revisited

On Tue, Mar 16, 2004 at 05:26:14PM +0000, Graham Klyne wrote:
Further to my previous messages: http://www.haskell.org//pipermail/haskell/2004-February/013522.html http://www.haskell.org//pipermail/haskell/2004-February/013679.html
I've come back to my stripped-down test case, and recreated the C test program SpawnEchoShiftLetters.c [1] in Haskell SpawnEchoShiftLetters.hs [2]. I've also added some diagnostic code. To recap: the C code demonstrates that that the Win32 API used by spawnProc.c [4] is working as expected, so the problem appears to be in the Haskell interface to it.
My problem seems to be occurring about here: [[ spawn cmd = withCString cmd $ \ p_cmd -> withObject 0 $ \ p_wIn -> withObject 0 $ \ p_rOut -> withObject 0 $ \ p_rErr -> do rc <- spawnProc p_cmd p_wIn p_rOut p_rErr when (rc /= 0) (ioError (userError ("runProc: unable to spawn " ++ show cmd))) wIn <- peek p_wIn (-1-} trace ("wIn "++show wIn) $ return () {- : -} (-2-} hIn <- openFd (fromIntegral wIn) False WriteMode False (-3-} trace ("hIn "++show hIn) $ return () ]] -- http://www.ninebynine.org/Software/HaskellUtils/Win32/POpen.hs
Specifically: + the trace at {-1-} displays the expected value (i.e. the same as a similar trace in the C version of the code [1], namely the value 3), + the trace at {-3-} is not displayed, indicating... + failure of the openFd call at {-2-}, also indicated by a Hugs error message, thus: [[ SpawnEchoShiftLetters> runTest wIn 3
Program error: openFd: does not exist (file does not exist)
SpawnEchoShiftLetters> ]]
Thus, it would appear that I'm misunderstanding how to use the openFd function that is part of the Hugs-supplied library code, declared as a primitive: [[ -- Creating a handle from a file descriptor/socket. -- primitive openFd :: Int -- file descriptor -> Bool -- True => it's a socket. -> IOMode -- what mode to open the handle in. -> Bool -- binary? -> IO Handle ]] -- http://cvs.haskell.org/cgi-bin/cvsweb.cgi/hugs98/libraries/Hugs/IO.hs?rev=1.9&content-type=text/x-cvsweb-markup
Can anyone help me out here?
It could well be Hugs. In this situation it calls fdopen(fd, "w+"), but I think it should be fdopen(fd, "w").

At 18:14 16/03/04 +0000, Ross Paterson wrote:
It could well be Hugs. In this situation it calls fdopen(fd, "w+"), but I think it should be fdopen(fd, "w").
Ah... in "iomonad.c", I see: [[ static String local modeString(hmode,binary) /* return mode string for f(d)open */ Int hmode; Bool binary; { if (binary) { return (hmode&HAPPEND) ? "ab+" : (hmode&HWRITE) ? "wb+" : (hmode&HREADWRITE) ? "wb+" : (hmode&HREAD) ? "rb" : (String)0; } else { return (hmode&HAPPEND) ? "a+" : (hmode&HWRITE) ? "w+" : (hmode&HREADWRITE) ? "w+" : (hmode&HREAD) ? "r" : (String)0; } } ]] I tried changing w+ to w, and wb+ to wb for the write-only modes, thus: [[ static String local modeString(hmode,binary) /* return mode string for f(d)open */ Int hmode; Bool binary; { // printf("Access mode %i,%i\n",hmode,binary) ; // [[[GK]]] if (binary) { return (hmode&HAPPEND) ? "ab+" : (hmode&HWRITE) ? "wb" : // [[[GK]]] (hmode&HREADWRITE) ? "wb+" : (hmode&HREAD) ? "rb" : (String)0; } else { return (hmode&HAPPEND) ? "a+" : (hmode&HWRITE) ? "w" : // [[[GK]]] (hmode&HREADWRITE) ? "w+" : (hmode&HREAD) ? "r" : (String)0; } } ]] But the result is the same: [[ SpawnEchoShiftLetters> runTest wIn 3 Access mode 4,0 Program error: openFd: does not exist (file does not exist) SpawnEchoShiftLetters> ]] (The access mode trace was mainly to prove to myself that my changes were indeed being picked up. The value 4 is equal to HWRITE.) So this (alone) is not enough. I did also try using "a" and "ab", but no joy there, either. This starts to point to some interaction between the I/O library and Windows anonymous pipe. My C code (which works as expected) uses the _write function (equiv. Unix "write") directly on the returned file descriptor. #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact

On Wed, Mar 17, 2004 at 10:47:59AM +0000, Graham Klyne wrote:
So this (alone) is not enough. I did also try using "a" and "ab", but no joy there, either. This starts to point to some interaction between the I/O library and Windows anonymous pipe. My C code (which works as expected) uses the _write function (equiv. Unix "write") directly on the returned file descriptor.
Can you try fdopen+fwrite in your C code?

At 11:43 17/03/04 +0000, Ross Paterson wrote:
On Wed, Mar 17, 2004 at 10:47:59AM +0000, Graham Klyne wrote:
So this (alone) is not enough. I did also try using "a" and "ab", but no joy there, either. This starts to point to some interaction between the I/O library and Windows anonymous pipe. My C code (which works as expected) uses the _write function (equiv. Unix "write") directly on the returned file descriptor.
Can you try fdopen+fwrite in your C code?
Ah, yes.... All relevant source code is here: http://www.ninebynine.org/Software/HaskellUtils/Win32/ The revised calling program is here: http://www.ninebynine.org/Software/HaskellUtils/Win32/FdSpawnEchoShiftLetter... The result from running the revised code is this: [[ D:\Dev\HaskellUtils\Win32>FdSpawnEchoShiftLetters Characters written: 26 Characters read from sout: 26 Data: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' Characters read from serr: 43 Data: 'EchoShiftLetters: 26 characters processed. ' FdSpawnEchoShiftLetters: finished. D:\Dev\HaskellUtils\Win32> ]] That is, it works fine. I tried this using "w" and "w+" access modes. Both worked OK. #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact
participants (2)
-
Graham Klyne
-
Ross Paterson