RE: Again: Runtime system doesn't notice changed file descriptor status
On 20 January 2005 00:49, Volker Wysk wrote: > However, I'd still expect "hClose stdin" to actually close the file > descriptor. I've taken a look at the hClose implementation. It's > problematic not to actually close any standard file descriptors. For > instance, some process might be reading the standard output of a > Haskell program. When that program calls "hClose stdout", the > process' read will block, rather than succeed with zero bytes read > (EOF). The process won't notice that the program has finished > outputting, until the program terminates. Imagine a case where a > program outputs some status messages and then forks into demon mode, > closing its standard file descriptors in order to detach itself from > the terminal. I'm wondering if there's any particular reason for not > actually closing the standard file descriptors. I see your point. I don't know why hClose doesn't actually close the std file descriptors - that bit of code was inherited from the previous incarnation of the IO library. Unless anyone can think of a good reason why not, I'll remove that restriction and make hClose work on stdin, stdout, and stderr. Be careful not to do this under GHCi, though! Cheers, Simon ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Re: Again: Runtime system doesn't notice changed file descriptor status
Hello. I've had the misconception that a file descriptor can be in a closed state. So the bug report was rather misguided - sorry for that. Yes, what I actually want is to reset the stdin handle. Thanks for the hint to hDuplicateTo. This should be exactly what I need. I see that the thing which the file descriptor is connected to can be in an EOF state (end of file, other side of pipe closed...), whereas the file descriptor is still valid. This means that the Haskell Library Report actually demands for a closedness state to be maintained in the file handle, since EOF and closed handle are two different things (result in different exceptions etc). However, I'd still expect "hClose stdin" to actually close the file descriptor. I've taken a look at the hClose implementation. It's problematic not to actually close any standard file descriptors. For instance, some process might be reading the standard output of a Haskell program. When that program calls "hClose stdout", the process' read will block, rather than succeed with zero bytes read (EOF). The process won't notice that the program has finished outputting, until the program terminates. Imagine a case where a program outputs some status messages and then forks into demon mode, closing its standard file descriptors in order to detach itself from the terminal. I'm wondering if there's any particular reason for not actually closing the standard file descriptors. Greetings, Volker -- http://www.volker-wysk.de ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
RE: Again: Runtime system doesn't notice changed file descriptor status
Hi Volker, On 02 January 2005 16:35, Volker Wysk wrote: > I made an error when simplifying the program for the bug report. > Here's the message again. > > I'm building a program which converts file names from ISO8859-1 to > UTF-8. It calls the recode program to do the actual conversion. This > part does the work: > >pfade <- fmap lines (contents "-") > >pipe_to (unlines pfade) >(execp "recode" ["-f", "latin1..utf8"] >-|= (do pfade_utf8 <- fmap lines (contents "-") --XX >error here mapM_ (\(pfad, pfad_utf8) -> do > ... > ) > (zip pfade pfade_utf8) >) >) > > ... > > lazy_contents :: String -> IO (String, Handle) > lazy_contents pfad = do > h <- if pfad == "-" then return stdin else openFile pfad > ReadMode txt <- hGetContents h > return (txt, h) > > contents :: String -> IO String > contents pfad = do > (txt, h) <- lazy_contents pfad > seq (length txt) (return ()) > hClose h > return txt > > > pipe_to and (-|=) fork two processes, connected through a pipe. I get > this error at the marked point: > > In child process, part of a pipe: > IO-Error >Error type: illegal operation >Location: hGetContents >Description: handle is closed >File name:"" > > The problem is, the call of contents "-" at the beginning closes the > main process' standard input (mere getContents would semi-close it, > same problem). It is replaced in the child with the pipe from recode, > but the runtime system doesn't notice that stdin is open again. The > openness state seems to be duplicated in the file handle. So, in the child process you actually want to reset the stdin Handle, right? There is hDuplicateTo, which might be enough for your needs. Use it like this: h <- fdToHandle pipe_read_fd hDuplicateTo h stdin hDuplicateTo is only available from GHC.Handle at the moment. > It works when replacing the marked line with the following. > >h <- fdToHandle 0 >pfade_utf8 <- fmap lines (hGetContents h) > > I'm using only functions from the System.Posix library (e.g. dupTo), > so I think the runtime system should notice. I'm not sure if what you're asking could/should be done automatically by the RTS. If I understand correctly, you'd like System.Posix.dupTo to automatically update Handles that refer to the destination file descriptor, right? We don't keep around a table mapping file descriptors to Handles, so that would be quite hard. > Apart from that, is there any way to notify the runtime system that > the file descriptor 0 has changed? > > But in the first place, it should be avoided to duplicate the file > descriptor's state in the handle, if possible. Which state are you referring to here? The "closed" state? If so, that's only Haskell-side state, we don't actually close the real file descriptor. Cheers, Simon ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Runtime system doesn't notice changed file descriptor status
Hi I'm building a program which converts file names from ISO8859-1 to UTF-8. It calls the recode program to do the actual conversion. This part does the work: pfade <- fmap lines getContents pipe_to (unlines pfade) (execp "recode" ["-f", "latin1..utf8"] -|= (do pfade_utf8 <- fmap lines getContents --XX error here mapM_ (\(pfad, pfad_utf8) -> do ... ) (zip pfade pfade_utf8) ) ) pipe_to and (-|=) fork two processes, connected through a pipe. I get this error at the marked point: In child process, part of a pipe: IO-Error Error type: illegal operation Location: hGetContents Description: handle is closed File name:"" The problem is, the call of getContents at the beginning closes the main process' standard input. It is replaced in the child with the pipe from recode, but the runtime system doesn't notice that stdin is open again. The openness state seems to be duplicated in stdin's file handle. It works when replacing the marked line with the following. h <- fdToHandle 0 -- from hslibs pfade_utf8 <- fmap lines (hGetContents h) I'm using only functions from the System.Posix library (e.g. dupTo), so I think the runtime system should notice. Apart from that, is there any way to notify the runtime system that the file descriptor 0 has changed? But in the first place, it should be avoided to duplicate the file descriptor's state in the handle, if possible. I'm running Linux and GHC 6.2.2. Greetings, V.W. -- http://www.volker-wysk.de ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs
Again: Runtime system doesn't notice changed file descriptor status
Hello I made an error when simplifying the program for the bug report. Here's the message again. I'm building a program which converts file names from ISO8859-1 to UTF-8. It calls the recode program to do the actual conversion. This part does the work: pfade <- fmap lines (contents "-") pipe_to (unlines pfade) (execp "recode" ["-f", "latin1..utf8"] -|= (do pfade_utf8 <- fmap lines (contents "-") --XX error here mapM_ (\(pfad, pfad_utf8) -> do ... ) (zip pfade pfade_utf8) ) ) ... lazy_contents :: String -> IO (String, Handle) lazy_contents pfad = do h <- if pfad == "-" then return stdin else openFile pfad ReadMode txt <- hGetContents h return (txt, h) contents :: String -> IO String contents pfad = do (txt, h) <- lazy_contents pfad seq (length txt) (return ()) hClose h return txt pipe_to and (-|=) fork two processes, connected through a pipe. I get this error at the marked point: In child process, part of a pipe: IO-Error Error type: illegal operation Location: hGetContents Description: handle is closed File name:"" The problem is, the call of contents "-" at the beginning closes the main process' standard input (mere getContents would semi-close it, same problem). It is replaced in the child with the pipe from recode, but the runtime system doesn't notice that stdin is open again. The openness state seems to be duplicated in the file handle. It works when replacing the marked line with the following. h <- fdToHandle 0 pfade_utf8 <- fmap lines (hGetContents h) I'm using only functions from the System.Posix library (e.g. dupTo), so I think the runtime system should notice. Apart from that, is there any way to notify the runtime system that the file descriptor 0 has changed? But in the first place, it should be avoided to duplicate the file descriptor's state in the handle, if possible. I'm running Linux and GHC 6.2.2. Greetings, V.W. -- http://www.volker-wysk.de ___ Glasgow-haskell-bugs mailing list Glasgow-haskell-bugs@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs