diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,9 @@
 	cabal haddock
 	cabal install
 
-dist/build/libHShsshellscript-3.0.0.a :: 
+build :: dist/build/libHShsshellscript-3.2.0.a
+
+dist/build/libHShsshellscript-3.2.0.a :: 
 	cabal build
 
 dist ::
@@ -22,3 +24,6 @@
 uninstall-manual ::
 	rm -rf /usr/local/share/hsshellscript/manual
 	rmdir --ignore-fail-on-non-empty /usr/local/share/hsshellscript 
+
+doc ::
+	cabal haddock
diff --git a/hsshellscript.cabal b/hsshellscript.cabal
--- a/hsshellscript.cabal
+++ b/hsshellscript.cabal
@@ -1,5 +1,5 @@
 Name:                hsshellscript
-Version:             3.1.0
+Version:             3.2.0
 Synopsis:            Haskell for Unix shell scripting tasks
 Description:         A Haskell-library for tasks which are usually done in
                      shell scripts. This includes parsing command line
@@ -15,7 +15,7 @@
 Copyright:           (c)2004-2011 by Volker Wysk
 Category:            System
 Build-type:          Simple
-Extra-source-files:  README, manual/*.html, manual/LICENSE, Makefile
+Extra-source-files:  README, manual/*.html, manual/LICENSE, Makefile, test/*.hs
 
 cabal-version:       >= 1.6
 
@@ -44,5 +44,3 @@
 
   -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
   Build-tools:       c2hs >= 0.15.1
-
-
diff --git a/manual/index.html b/manual/index.html
--- a/manual/index.html
+++ b/manual/index.html
@@ -8,7 +8,7 @@
 <H1>HsShellScript User Manual</H1>
 
 <P>This is the user manual for the <A HREF="http://www.volker-wysk.de/hsshellscript">HsShellScript</A>
-Haskell shell scripting library, version 3.1.0. It has been released 2012-04-02. The API
+Haskell shell scripting library, version 3.2.0. It has been released 2012-08-28. The API
 documentation is in a separate document.</P>
 <P>HsShellScript is a library which makes things easy to program in
 Haskell, which are typically done by shell scripts on Unix-like
@@ -23,6 +23,6 @@
 <BR><A HREF="LICENSE">License</A></P>
 
 <P STYLE="border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.05cm; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm">
-<small>Last changed 2012-04-02</small></P>
+<small>Last changed 2012-08-28</small></P>
 </BODY>
 </HTML>
diff --git a/manual/install.html b/manual/install.html
--- a/manual/install.html
+++ b/manual/install.html
@@ -17,7 +17,7 @@
 <p>In order to install, unpack the source distribution somewhere. Go to the
   directory, and call <tt>make</tt>. This will compile and install the library,
   locally, as a user package. The location of the API documentation
-  is <tt>~/.cabal/share/doc/hsshellscript-3.1.0/html/index.html</tt>.
+  is <tt>~/.cabal/share/doc/hsshellscript-3.2.0/html/index.html</tt>.
 
 <p>Cabal's Simple Build Infrastructure doesn't provide any means to add extra
   documenation to a project. Therefore the user manual isn't installed by default.
diff --git a/src/HsShellScript.hs b/src/HsShellScript.hs
--- a/src/HsShellScript.hs
+++ b/src/HsShellScript.hs
@@ -126,7 +126,7 @@
                       putStrLn $ "\n" ++ (argerror_usageinfo argerror)
                       exitFailure
               , Handler $ \(processstatus :: ProcessStatus) ->
-                   do errm $ "Process error. process status = " ++ show ( processstatus :: ProcessStatus )
+                   do errm $ "Process error. Process status = " ++ show ( processstatus :: ProcessStatus )
                       exitFailure
               , Handler $ \(runerror :: RunError) ->
                    do errm (show_runerror runerror)
@@ -232,7 +232,7 @@
    duplicated. When the child process uses that handle, that data gets written
    twice.
 
-   The functions which fork a child process ('call', 'spawn', 'silently',
+   The functions which fork a child process ('subproc', 'spawn', 'silently',
    'pipe_to' etc.) flush @stdout@ and @stderr@ (should be unbuffered) before the
    fork. So the child process can use them. The pipe functions also take care of
    @stdin@, which is used to read from the pipe. But they don't know about any
@@ -282,8 +282,8 @@
    might have changed, see "HsShellScript#exec"). They are also reset to
    blocking mode. All others are closed when the exec succeeds.
 
-   /You can't use/ @executeFile@ /directly, unless you take care of the things
-   outlined at/ "HsShellScript#exec" /and/ 'execute_file' /by yourself./
+   /You can't use/ @executeFile@ /directly, unless you take care of the things/
+   /outlined at/ "HsShellScript#exec" /and/ 'execute_file' /by yourself./
 
    If replacing the process fails (for instance, because the program wasn't
    found), then everything is restored to original state, and an @IOError@ is
diff --git a/src/HsShellScript/ProcErr.chs b/src/HsShellScript/ProcErr.chs
--- a/src/HsShellScript/ProcErr.chs
+++ b/src/HsShellScript/ProcErr.chs
@@ -1,4 +1,3 @@
--- Ausnahme in child, Exception
 -- #hide
 module HsShellScript.ProcErr where
 
@@ -65,26 +64,42 @@
 -- Execute an IO action as a separate process, and wait for it to finish.
 -- Report errors as exceptions.
 --
--- The program forks a child process and performs the specified action.
--- Then it waits for the child process to finish. If it exits in any way
--- which indicates an error, the @ProcessStatus@ is thrown as an
--- exception.
+-- This forks a child process, which performs the specified IO action.
+-- In
+-- case the child process has been stopped by a signal, the parent blocks.
 --
--- When the action throws an @IOError@, it is transmitted to the parent.
+-- If the action throws an @IOError@, it is transmitted to the parent.
 -- It is then raised there, as if it happened locally. The child then aborts
 -- quietly with an exit code of 0.
 --
+-- Exceptions in
+-- the child process, other than @IOError@s, result in an error message on @stderr@, and a
+-- @ProcessStatus@ exception in the parent, with the value of @Exited
+-- (ExitFailure 1)@. The following exceptions are understood by @subproc@, and
+-- result in corresponding messages: @ArgError@, @ProcessStatus@, @RunError@,
+-- @IOError@ and @ExitCode@. Other exceptions result in the generic message, as
+-- produced by @show@.
+--
+-- If the child process exits with an exit code other than zero, or it is
+-- terminated by a signal, the corresponding @ProcessStatus@ is raised as an
+-- exception in the parent program. Only @IOError@s are transmitted to the parent.
+--
 -- When used in conjunction with an @exec@ variant, this means that the parent
 -- process can tell the difference between failure of the @exec@ call itself,
--- and failure of the program being executed. You get the @IOError@, which
--- happened in the child when calling @executeFile@ (GHC hierarchical
--- libraries). Of course, the action can prevent this form happening, by
--- itself catching @IOError@s.
+-- and failure of the child program being executed after a successful call of
+-- the @exec@ variant. In case of failure of the @exec@
+-- call, You get the @IOError@, which
+-- happened in the child when calling @executeFile@ (from the GHC hierarchical
+-- libraries). In case of the called program failing, you get the @ProcessStatus@.
 --
--- The parent process waits for the child process, if it has been stopped by a
--- signal.
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally (unless it throws an
+-- @IOError@). The child process is then properly terminated by @subproc@, such
+-- that no resources, which have been duplicated by the fork, cause problems.
+-- See "HsShellScript#subr" for details.
 --
--- See "HsShellScript#subr" for further details.
+-- If you want to run an external program, by calling one of the @exec@
+-- variants in the child action, you might want to call @runprog@ instead of @subproc@.
 --
 --
 -- Examples:
@@ -233,7 +248,7 @@
 
 
 
-{- | An error which occured when calling an external program via 'runprog'.
+{- | An error which occured when calling an external program.
    The fields specifiy the details of the call.
 
    See 'show_runerror', 'to_ioe', 'as_ioe', @System.Posix.ProcessStatus@.
@@ -333,7 +348,8 @@
 
 -- |
 -- Run an external program, and report errors as exceptions. The executable is
--- searched via the @PATH@.
+-- searched via the @PATH@. In case the child process has been stopped by a
+-- signal, the parent blocks.
 --
 -- In case the program exits in an way which indicates an error, or is
 -- terminated by a signal, a @RunError@ is thrown. It
@@ -343,7 +359,9 @@
 --
 -- In case of starting the program itself failed, an @IOError@ is thrown.
 --
--- @runprog prog par@ is essentially @subproc (execp prog par)@.
+-- @runprog prog par@ is a simple front end to @subproc@. It is essentially
+-- @subproc (execp prog par)@, apart from building a @RunError@ from a
+-- @ProcessStatus@.
 --
 -- Example 1:
 --
@@ -379,8 +397,7 @@
                              , re_env   = env
                              , re_wd    = wd
                              , re_ps    = ps
-                             , re_errno = if c_errno /= (0::CInt) then Just c_errno
-                                                                  else Nothing
+                             , re_errno = if c_errno /= (0::CInt) then Just c_errno else Nothing
                              }))
 
 
@@ -883,13 +900,51 @@
             return (Just h)
 
 
--- | Run an IO action as a separate process, and pipe some text to its @stdin@.
--- Then close the pipe and wait for the child process to finish. If it
--- exits in a way which indicates an error, the @ProcessStatus@ is thrown.
+-- |
+-- Run an IO action as a separate process, and pipe some text to its @stdin@.
+-- Then close the pipe and wait for the child process to finish.
 --
--- Example: @pipe_to \"blah\" $ exec \"\/usr\/bin\/foo\" [\"bar\"]@
+-- This forks a child process, which executes the specified action. The specified
+-- text is sent to the action's @stdin@ through a pipe. Then the pipe is closed.
+-- In case the action replaces the process by calling an @exec@ variant, it is
+-- made sure that the process gets the text on it's file descriptor 0.
 --
--- See 'subproc', 'runprog', '-<-', 'h_pipe_to'. See "HsShellScript#fdpipes" for more details.
+-- In case the action fails (exits with an exit status other than 0, or is
+-- terminated by a signal), the @ProcessStatus@ is thrown, such as reported by
+-- 'System.Posix.getProcessStatus'. No attempt is made to create more meaningful
+-- exceptions, like it is done by @runprog@/@subproc@.
+--
+-- Exceptions in the action result in an error message on @stderr@, and the
+-- termination of the child. The parent gets a @ProcessStatus@ exception, with
+-- the value of @Exited (ExitFailure 1)@. The following exceptions are
+-- understood, and result in corresponding messages: @ArgError@,
+-- @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other exceptions
+-- result in the generic message, as produced by @show@.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally.
+-- The child process is then properly terminated, such
+-- that no resources, which have been duplicated by the fork, cause problems.
+-- See "HsShellScript#subr" for details.
+--
+-- Example:
+--
+-- >pipe_to "blah" (exec "/usr/bin/foo" ["bar"])
+--
+-- Example: Access both @stdin@ and @stdout@ of an external program.
+--
+-- >import HsShellScript
+-- >
+-- >main = mainwrapper $ do
+-- >
+-- >   res <- pipe_from $
+-- >      pipe_to "2\n3\n1" $
+-- >         exec "/usr/bin/sort" []
+-- >
+-- >   putStrLn res
+--
+--
+-- See 'subproc', 'runprog', '-<-', 'h_pipe_to'.
 pipe_to :: String       -- ^ Text to pipe
         -> IO a         -- ^ Action to run as a separate process, and to pipe to
         -> IO ()
@@ -903,11 +958,46 @@
        else throw ps
 
 
--- | Run an IO action as a separate process, and connect to its @stdin@
--- with a pipe.
+-- |
+-- Run an IO action as a separate process, and get a connection (a pipe) to
+-- its @stdin@ as a file handle.
 --
--- Example: @h \<- h_pipe_to $ exec \"\/usr\/bin\/foo\" [\"bar\"]@
+-- This forks a subprocess, which executes the specified action. A file handle,
+-- which is connected to its @stdin@, is returned. The child's @ProcessID@
+-- is returned as well. If the action replaces the child process, by calling an
+-- @exec@ variant, it is made sure that its file descriptor 0 is connected to
+-- the returned file handle.
 --
+-- This gives you full control of the pipe, and of the forked process. But you
+-- must cope with the child process by yourself. 
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally.
+-- The child process is then properly terminated, such
+-- that no resources, which have been duplicated by the fork, cause problems.
+-- See "HsShellScript#subr" for details.
+--
+-- Errors can only be detected by examining the child's process status (using
+-- 'System.Posix.Process.getProcessStatus'). If the child action throws an
+-- exception, an error message is printed on @stderr@, and the child process
+-- exits with a @ProcessStatus@ of @Exited
+-- (ExitFailure 1)@. The following exceptions are understood, and
+-- result in corresponding messages: @ArgError@, @ProcessStatus@, @RunError@,
+-- @IOError@ and @ExitCode@. Other exceptions result in the generic message, as
+-- produced by @show@.
+--
+-- If the child process exits in a way which signals an error, the
+-- corresponding @ProcessStatus@ is returned by @getProcessStatus@. See
+-- 'System.Posix.Process.getProcessStatus' for details.
+--
+-- Example:
+--
+-- >(handle, pid) <- h_pipe_to $ exec "/usr/bin/foo" ["bar"]
+-- >hPutStrLn handle "Some text to go through the pipe"
+-- >(Just ps) <- getProcessStatus True False pid
+-- >when (ps /= Exited ExitSuccess) $
+-- >   throw ps
+--
 -- See '-<-', 'pipe_to', 'pipe_from', 'pipe_from2'. See "HsShellScript#fdpipes" for more details.
 h_pipe_to :: IO a                       -- ^ Action to run as a separate process, and to pipe to
           -> IO (Handle, ProcessID)     -- ^ Returns handle connected to the standard input of the child process, and the child's process ID
@@ -916,70 +1006,181 @@
    return (h, pid)
 
 
--- | Run an IO action as a separate process, and read its @stdout@
--- strictly. Then wait for the child process to finish. This is like the
--- backquote feature of shells.
+-- | Run an IO action as a separate process, and read its @stdout@ strictly.
+-- Then wait for the child process to finish. This is like the backquote feature
+-- of shells.
 --
--- If the child process exits with a non-zero exit code, the
--- @ProcessStatus@ is thrown.
+-- This forks a child process, which executes the specified action. The output
+-- of the child is read from its standard output. In case it replaces the
+-- process by calling an @exec@ variant, it is make sure that the output is
+-- read from the new process' file descriptor 1.
 --
--- The whole output is returned, no trailing newline character is removed, like the shell does with backquotes. You may want to apply @chomp@
--- to the result.
+-- The end of the child's output is reached when either the standard output is
+-- closed, or the child process exits. The program blocks until the action
+-- exits, even if the child closes its standard output earlier. So the parent
+-- process always notices a failure of the action (when it exits in a way which
+-- indicates an error).
 --
+-- When the child action exits in a way which indicates an error, the
+-- corresponding @ProcessStatus@ is thrown. See
+-- 'System.Posix.Process.getProcessStatus'. No attempt is made to create more
+-- meaningful exceptions, like it is done by @runprog@/@subproc@.
+--
+-- Exceptions in the action result in an error message on @stderr@, and the
+-- proper termination of the child. The parent gets a @ProcessStatus@ exception, with
+-- the value of @Exited (ExitFailure 1)@. The following exceptions are
+-- understood, and result in corresponding messages: @ArgError@,
+-- @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other exceptions
+-- result in the generic message, as produced by @show@.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally. The child process is
+-- then properly terminated, such that no resources, which have been duplicated
+-- by the fork, cause problems. See "HsShellScript#subr" for details.
+--
+-- Unlike shells\' backquote feature, @pipe_from@ does not remove any trailing
+-- newline characters. The entire output of the action is returned. You might want
+-- to apply @chomp@ to the result.
+--
 -- Example:
 --
--- >output <- pipe_from $ exec "/bin/foo" ["bar"]
+-- >output <- pipe_from $ exec "/bin/mount" []
 --
--- See 'exec', 'pipe_to', 'pipe_from2', 'h_pipe_from', 'lazy_pipe_from', 'chomp', 'silently'. See "HsShellScript#fdpipes" for more details.
-pipe_from :: IO a               -- ^ Action to run as a separate process
-          -> IO String          -- ^ The called program's standard output
+-- Example: Access both @stdin@ and @stdout@ of an external program.
+--
+-- >import HsShellScript
+-- >
+-- >main = mainwrapper $ do
+-- >
+-- >   res <- pipe_from $
+-- >      pipe_to "2\n3\n1" $
+-- >         exec "/usr/bin/sort" []
+-- >
+-- >   putStrLn res
+--
+-- See 'exec', 'pipe_to', 'pipe_from2', 'h_pipe_from', 'lazy_pipe_from', 'chomp', 'silently'.
+pipe_from :: IO a               -- ^ Action to run as a separate process. Its
+                                -- return value is ignored.
+          -> IO String          -- ^ The action's standard output
 pipe_from io = do
    (h, pid) <- h_pipe_from io
    txt <- hGetContents h
    seq (length txt) (hClose h)
-   (Just ps) <- getProcessStatus True False pid
+   (Just ps) <- System.Posix.getProcessStatus True False pid
    if ps == Exited ExitSuccess
        then return txt
        else throw ps
 
 
--- | Run an IO action as a separate process, and read its @stderr@
--- strictly. Then wait for the child process to finish, and return the text
--- along with its exit code.
+-- | Run an IO action as a separate process, and read its standard error output
+-- strictly. Then wait for the child process to finish. This is like the
+-- backquote feature of shells. This function is exactly the same as
+-- @pipe_from@, except that the standard error output is read, instead of the
+-- standard output.
 --
+-- This forks a child process, which executes the specified action. The error output
+-- of the child is read from its standard error output. In case it replaces the
+-- process by calling an @exec@ variant, it is made sure that the output is
+-- read from the new process' file descriptor 2.
+--
+-- The end of the child's error output is reached when either the standard error
+-- output is closed, or the child process exits. The program blocks until the
+-- action exits, even if the child closes its standard error output earlier. So
+-- the parent process always notices a failure of the action (which means it
+-- exits in a way which indicates an error).
+--
+-- When the child action exits in a way which indicates an error, the
+-- corresponding @ProcessStatus@ is thrown. See
+-- 'System.Posix.Process.getProcessStatus'.
+-- No attempt is made to create
+-- more meaningful exceptions, like it is done by @runprog@/@subproc@.
+--
+--
+-- Exceptions in the action result in an error message on @stderr@, and the
+-- proper termination of the child. This means that the error message is sent
+-- through the pipe, to the parent process. The message can be found in the text
+-- which has been read from the child process. It doesn't appear on the console.
+--
+-- The parent gets a @ProcessStatus@ exception, with
+-- the value of @Exited (ExitFailure 1)@. The following exceptions are
+-- understood, and result in corresponding messages: @ArgError@,
+-- @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other exceptions
+-- result in the generic message, as produced by @show@.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally. The child process is
+-- then properly terminated, such that no resources, which have been duplicated
+-- by the fork, cause problems. See "HsShellScript#subr" for details.
+--
+-- Unlike shells\' backquote feature, @pipe_from2@ does not remove any trailing
+-- newline characters. The entire error output of the action is returned. You might want
+-- to apply @chomp@ to the result.
+--
 -- Example:
 --
--- >(errmsg, ec) <- pipe_from2 $ exec "/bin/foo" ["bar"] ->- "/dev/null"
+-- >output <- pipe_from $ exec "/bin/mount" []
+--
+-- Example: Access both @stdin@ and @stdout@ of an external program.
+--
+-- >import HsShellScript
 -- >
--- >when (ec /= Exited ExitSuccess) $ do
--- >   errm errmsg
--- >   ...
+-- >main = mainwrapper $ do
+-- >
+-- >   res <- pipe_from $
+-- >      pipe_to "2\n3\n1" $
+-- >         exec "/usr/bin/sort" []
+-- >
+-- >   putStrLn res
 --
 -- See 'exec', 'pipe_to', 'pipe_from', 'h_pipe_from2', 'lazy_pipe_from2', 'silently'. See "HsShellScript#fdpipes" for more details.
-pipe_from2 :: IO a                              -- ^ Action to run as a separate process
-           -> IO (String, ProcessStatus)        -- ^ The called program's standard output
+pipe_from2 :: IO a              -- ^ Action to run as a separate process
+           -> IO String         -- ^ The action's standard error output
 pipe_from2 io = do
    (h, pid) <- h_pipe_from2 io
    txt <- hGetContents h
    seq (length txt) (hClose h)
-   (Just ps) <- getProcessStatus True False pid
-   return (txt, ps)
+   (Just ps) <- System.Posix.getProcessStatus True False pid
+   if ps == Exited ExitSuccess
+       then return txt
+       else throw ps
 
 
 -- | Run an IO action as a separate process, and connect to its @stdout@
--- with a pipe.
+-- with a file handle.
+-- This is like the backquote feature of shells.
 --
--- A handle connected to the child process, and the process ID
--- of the child are returned. The process ID can be used with
--- @System.Posix.getProcessStatus@ to get the child's exit code. You must either
--- ensure that all data has been read, or close the handle, before calling
--- @getProcessStatus@ blockingly. Otherwise you'll get a deadlock. When you
--- close the handle before all data has been read, then the child gets a
--- @SIGPIPE@ signal.
+-- This forks a subprocess, which executes the specified action. A file handle,
+-- which is connected to its @stdout@, is returned. The child's @ProcessID@
+-- is returned as well. If the action replaces the child process, by calling an
+-- @exec@ variant, it is made sure that its file descriptor 1 is connected to
+-- the returned file handle.
 --
+-- This gives you full control of the pipe, and of the forked process. But you
+-- must cope with the child process by yourself. 
+--
+-- When you call @getProcessStatus@ blockingly, you must first ensure that all
+-- data has been read, or close the handle. Otherwise you'll get a deadlock.
+-- When you close the handle before all data has been read, then the child gets
+-- a @SIGPIPE@ signal.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally.
+-- The child process is then properly terminated, such
+-- that no resources, which have been duplicated by the fork, cause problems.
+-- See "HsShellScript#subr" for details.
+--
+-- Errors can only be detected by examining the child's process status (using
+-- 'System.Posix.Process.getProcessStatus'). No attempt is made to create more
+-- meaningful exceptions, like it is done by @runprog@/@subproc@. If the child
+-- action throws an exception, an error message is printed on @stderr@, and the
+-- child process exits with a @ProcessStatus@ of @Exited (ExitFailure 1)@. The
+-- following exceptions are understood, and result in corresponding messages:
+-- @ArgError@, @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other
+-- exceptions result in the generic message, as produced by @show@.
+--
 -- Example:
 --
--- >h <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
+-- >(h,pid) <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
 --
 -- See 'exec', 'pipe_to', 'h_pipe_from2', 'pipe_from', 'lazy_pipe_from', 'chomp', 'silently'. See "HsShellScript#fdpipes" for more details.
 h_pipe_from :: IO a                             -- ^ Action to run as a separate process, and to pipe from
@@ -990,22 +1191,43 @@
 
 
 -- | Run an IO action as a separate process, and connect to its @stderr@
--- with a pipe.
+-- with a file handle.
 --
--- A handle connected to the child process' standard error output, and the process ID
--- of the child are returned. The process ID can be used with
--- @System.Posix.getProcessStatus@ to get the child's exit code. You must either
--- ensure that all data has been read, or close the handle, before calling
--- @getProcessStatus@ blockingly. Otherwise you'll get a deadlock. When you
--- close the handle before all data has been read, then the child gets a
--- @SIGPIPE@ signal. Of course, you can also use the process ID to kill the
--- child process.
+-- This forks a subprocess, which executes the specified action. A file handle,
+-- which is connected to its @stderr@, is returned. The child's @ProcessID@
+-- is returned as well. If the action replaces the child process, by calling an
+-- @exec@ variant, it is made sure that its file descriptor 2 is connected to
+-- the returned file handle.
 --
+-- This gives you full control of the pipe, and of the forked process. But you
+-- must cope with the child process by yourself. 
+--
+-- When you call @getProcessStatus@ blockingly, you must first ensure that all
+-- data has been read, or close the handle. Otherwise you'll get a deadlock.
+-- When you close the handle before all data has been read, then the child gets
+-- a @SIGPIPE@ signal.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally. The child process is
+-- then properly terminated, such that no resources, which have been duplicated
+-- by the fork, cause problems. See "HsShellScript#subr" for details.
+--
+-- Errors can only be detected by examining the child's process status (using
+-- 'System.Posix.Process.getProcessStatus'). No attempt is made to create more
+-- meaningful exceptions, like it is done by @runprog@/@subproc@. If the child
+-- action throws an exception, an error message is printed on @stderr@. This
+-- means that the message goes through the pipe to the parent process. Then the
+-- child process exits with a @ProcessStatus@ of @Exited (ExitFailure 1)@. The
+-- following exceptions are understood, and result in corresponding messages:
+-- @ArgError@, @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other
+-- exceptions result in the generic message, as produced by @show@.
+--
 -- Example:
 --
--- >h <- h_pipe_from2 $ exec "/usr/bin/foo" ["bar"]
+-- >(h,pid) <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
 --
--- See 'exec', 'pipe_to', 'h_pipe_from', 'pipe_from2', 'lazy_pipe_from2', 'chomp', 'silently'. See "HsShellScript#fdpipes" for more details.
+-- See 'exec', 'pipe_from', 'pipe_from2', 'h_pipe_from', 'pipe_to',
+-- 'lazy_pipe_from', 'chomp', 'silently'.
 h_pipe_from2 :: IO a                             -- ^ Action to run as a separate process, and to pipe from
              -> IO (Handle, ProcessID)           -- ^ Returns handle connected to the standard output of the child process, and the child's process ID
 h_pipe_from2 io = do
@@ -1013,28 +1235,90 @@
    return (h, pid)
 
 
--- | Run an IO action as a separate process, and read its @stdout@,
--- This is like the backquote feature of shells. The output is read
--- lazily, as the returned string is evaluated.
+
+
+-- | Run an IO action in a separate process, and read its standard output, The output
+-- is read lazily, as the returned string is evaluated. The child's output along
+-- with its process ID are returned.
+-- 
+-- This forks a child process, which executes the specified action. The output
+-- of the child is read lazily through a pipe, which connncts to its standard
+-- output. In case the child replaces the process by calling an @exec@ variant,
+-- it is make sure that the output is read from the new process' file descriptor
+-- 1.
 --
--- The child's output along with its process ID are returned. The process ID can
--- be used with @System.Posix.getProcessStatus@ to get the child process' exit
--- code. Be aware that you must evaluate the whole string, before calling
--- @getProcessStatus@ blockingly, or you'll get a deadlock.
+-- @lazy_pipe_from@ calls 'System.IO.hGetContents', in order to read the pipe
+-- lazily. This means that the file handle goes to semi-closed state. The handle
+-- holds a file descriptor, and as long as the string isn't fully evaluated,
+-- this file descriptor won't be closed. For the file descriptor to be closed,
+-- first its standard output needs to be closed on the child side. This happens
+-- when the child explicitly closes it, or the child process exits. When
+-- afterwards the string on the parent side is completely evaluated, the handle,
+-- along with the file descritor it holds, are closed and freed.
 --
--- The whole output is returned, no trailing newline character is removed, like
--- the shell does with backquotes. You'll possibly want to apply 'chomp' to the
--- result.
+-- If you use the string in such a way that you only access the beginning of the
+-- string, the handle will remain in semi-closed state, holding a file
+-- descriptor, even when the pipe is closed on the child side. When you do that
+-- repeatedly, you may run out of file descriptors.
 --
--- Example:
+-- Unless you're sure that your program will reach the string's end, you should 
+-- take care for it explicitly, by doing something like this:
 --
--- >(txt, pid) <- lazy_pipe_from $ exec "/usr/bin/foo" ["bar"]
+-- >(output, pid) <- lazy_pipe_from (exec "\/usr\/bin\/foobar" [])
 -- >...
--- >-- Done, but must read the rest of the output
--- >seq (length txt) (return ())
--- >(Just ps) <- getProcessStatus True False pid
+-- >seq (length output) (return ())   
 --
--- See 'exec', 'pipe_to', 'pipe_from', 'h_pipe_from', 'lazy_pipe_from2', 'silently'. See "HsShellScript#fdpipes" for more details.
+-- This will read the entire standard output of the child, even if it isn't
+-- needed. You can't cut the child process' output short, when you use
+-- @lazy_pipe_from@. If you need to do this, you should use @h_pipe_from@, which 
+-- gives you the handle, which can then be closed by 'System.IO.hClose', even 
+-- if the child's output isn't completed:
+--
+-- >(h, pid) <- h_pipe_from io
+-- >
+-- >-- Lazily read io's output
+-- >output <- hGetContents h
+-- >...
+-- >-- Not eveyting read yet, but cut io short.
+-- >hClose h   
+-- >
+-- >-- Wait for io to finish, and detect errors
+-- >(Just ps) <- System.Posix.getProcessStatus True False pid
+-- >when (ps /= Exited ExitSuccess) $
+-- >   throw ps
+--   
+-- When you close the handle before all data has been read, then the child gets
+-- a @SIGPIPE@ signal.
+-- 
+-- After all the output has been read, you should call @getProcessStatus@ on the
+-- child's process ID, in order to detect errors. Be aware that you must
+-- evaluate the whole string, before calling @getProcessStatus@ blockingly, or
+-- you'll get a deadlock.
+--   
+-- You won't get an exception, if the child action exits in a way which 
+-- indicates an error. Errors occur asynchronously, when the output string is 
+-- evaluated. You must detect errors by yourself, by calling 
+-- 'System.Posix.Process.getProcessStatus'.
+--
+-- In case the action doesn't replace the child process with an external
+-- program, an exception may be thrown out of the action. This results in an error
+-- message on @stderr@, and the proper termination of the child. The
+-- @ProcessStatus@, which can be accessed in the parent process by
+-- @getProcessStatus@, is @Exited (ExitFailure 1)@. The following exceptions are
+-- understood, and result in corresponding messages: @ArgError@,
+-- @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other exceptions
+-- result in the generic message, as produced by @show@.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally. The child process is
+-- then properly terminated, such that no resources, which have been duplicated
+-- by the fork, cause problems. See "HsShellScript#subr" for details.
+--
+-- Unlike shells\' backquote feature, @lazy_pipe_from@ does not remove any trailing
+-- newline characters. The entire output of the action is returned. You might want
+-- to apply @chomp@ to the result.
+--   
+-- See 'exec', 'pipe_to', 'pipe_from', 'h_pipe_from', 'lazy_pipe_from2', 'silently'.
 lazy_pipe_from :: IO a                          -- ^ Action to run as a separate process
                -> IO (String, ProcessID)        -- ^ The action's lazy output and the process ID of the child process
 lazy_pipe_from io = do
@@ -1043,31 +1327,97 @@
    return (txt, pid)
 
 
--- | Run an IO action as a separate process, and read its @stderr@. The output
--- is read lazily, as the returned string is evaluated.
+
+-- | Run an IO action in a separate process, and read its standard error output, The output
+-- is read lazily, as the returned string is evaluated. The child's error output along
+-- with its process ID are returned.
+-- 
+-- This forks a child process, which executes the specified action. The error output
+-- of the child is read lazily through a pipe, which connncts to its standard error
+-- output. In case the child replaces the process by calling an @exec@ variant,
+-- it is make sure that the output is read from the new process' file descriptor
+-- 1.
 --
--- The child's error output along with its process ID are returned. The process
--- ID can be used with @System.Posix.getProcessStatus@ to get the child process'
--- exit code. Be aware that you must evaluate the whole string, before calling
--- @getProcessStatus@ blockingly, or you'll get a deadlock.
+-- @lazy_pipe_from@ calls 'System.IO.hGetContents', in order to read the pipe
+-- lazily. This means that the file handle goes to semi-closed state. The handle
+-- holds a file descriptor, and as long as the string isn't fully evaluated,
+-- this file descriptor won't be closed. For the file descriptor to be closed,
+-- first its standard error output needs to be closed on the child side. This happens
+-- when the child explicitly closes it, or the child process exits. When
+-- afterwards the string on the parent side is completely evaluated, the handle,
+-- along with the file descritor it holds, are closed and freed.
 --
--- Example:
+-- If you use the string in such a way that you only access the beginning of the
+-- string, the handle will remain in semi-closed state, holding a file
+-- descriptor, even when the pipe is closed on the child side. When you do that
+-- repeatedly, you may run out of file descriptors.
 --
--- >(errmsg, pid) <- lazy_pipe_from2 $ exec "/usr/bin/foo" ["bar"] ->- "/dev/null"
+-- Unless you're sure that your program will reach the string's end, you should 
+-- take care for it explicitly, by doing something like this:
+--
+-- >(errmsg, pid) <- lazy_pipe_from2 (exec "/usr/bin/foobar" [])
 -- >...
--- >-- Read enough error messages, terminate the child.
--- >signalProcess killProcess pid
+-- >seq (length errmsg) (return ())   
+--
+-- This will read the entire standard error output of the child, even if it isn't
+-- needed. You can't cut the child process' output short, when you use
+-- @lazy_pipe_from@. If you need to do this, you should use @h_pipe_from@, which 
+-- gives you the handle, which can then be closed by 'System.IO.hClose', even 
+-- if the child's output isn't completed:
+--
+-- >(h, pid) <- h_pipe_from io
 -- >
--- >-- Make sure the file descriptor gets closed, or you may run out of file descriptors.
--- >seq (length errmsg) (return ())
+-- >-- Lazily read io's output
+-- >output <- hGetContents h
+-- >...
+-- >-- Not eveyting read yet, but cut io short.
+-- >hClose h   
+-- >
+-- >-- Wait for io to finish, and detect errors
+-- >(Just ps) <- System.Posix.getProcessStatus True False pid
+-- >when (ps /= Exited ExitSuccess) $
+-- >   throw ps
+--   
+-- When you close the handle before all data has been read, then the child gets
+-- a @SIGPIPE@ signal.
+-- 
+-- After all the output has been read, you should call @getProcessStatus@ on the
+-- child's process ID, in order to detect errors. Be aware that you must
+-- evaluate the whole string, before calling @getProcessStatus@ blockingly, or
+-- you'll get a deadlock.
+--   
+-- You won't get an exception, if the child action exits in a way which 
+-- indicates an error. Errors occur asynchronously, when the output string is 
+-- evaluated. You must detect errors by yourself, by calling 
+-- 'System.Posix.Process.getProcessStatus'.
 --
--- See 'exec', 'pipe_to', 'pipe_from2', 'h_pipe_from2', 'lazy_pipe_from', 'silently'. See "HsShellScript#fdpipes" for more details.
+-- In case the action doesn't replace the child process with an external
+-- program, an exception may be thrown out of the action. This results in an
+-- error message on @stderr@. This means that the message is sent through the
+-- pipe, to the parent process. Then the child process is properly terminated.
+-- The @ProcessStatus@, which can be accessed in the parent process by
+-- @getProcessStatus@, is @Exited (ExitFailure 1)@. The following exceptions are
+-- understood, and result in corresponding messages: @ArgError@,
+-- @ProcessStatus@, @RunError@, @IOError@ and @ExitCode@. Other exceptions
+-- result in the generic message, as produced by @show@.
+--
+-- Unless you replace the child process, calling an @exec@ variant, the child
+-- should let the control flow leave the action normally. The child process is
+-- then properly terminated, such that no resources, which have been duplicated
+-- by the fork, cause problems. See "HsShellScript#subr" for details.
+--
+-- Unlike shells\' backquote feature, @lazy_pipe_from@ does not remove any trailing
+-- newline characters. The entire output of the action is returned. You might want
+-- to apply @chomp@ to the result.
+--   
+-- See 'exec', 'pipe_to', 'pipe_from2', 'h_pipe_from2', 'lazy_pipe_from', 'silently'.
 lazy_pipe_from2 :: IO a                          -- ^ Action to run as a separate process
                 -> IO (String, ProcessID)        -- ^ The action's lazy output and the process ID of the child process
 lazy_pipe_from2 io = do
-   (_, Just h, _, pid) <- pipe_fork_dup io False True False
+   (_, _, Just h, pid) <- pipe_fork_dup io False False True
    txt <- hGetContents h
    return (txt, pid)
+   
 
 
 -- | Run an IO action as a separate process, and optionally connect to its
@@ -1335,7 +1685,7 @@
       -> IO b           -- Never returns
 child io = do
    (io `finally` flush_outerr)
-      `catches` 
+      `catches`
       [ Handler $ (\argerror -> do
                       errm $ "In child process:\n" ++ argerror_message argerror
                       _exit 1
@@ -1344,11 +1694,15 @@
                       errm $ "Process error in child process. Process status = " ++ show ( processstatus :: ProcessStatus )
                       _exit 1
                   )
+      , Handler $ (\(runerror::RunError) -> do
+                      errm $ (show_runerror runerror)
+                      _exit 1
+                  )
       , Handler $ (\(ioe::IOError) -> do
                       errm ("In child process:\n   " ++ show_ioerror ioe)
                       _exit 1
                   )
-      , Handler $ (\(e::ExitCode) -> do 
+      , Handler $ (\(e::ExitCode) -> do
                       -- Child process is a subroutine that has terminated normally.
                       errm "Warning! Child process tries to shut down normally. This is a bug. It should\n\
                            \terminate with _exit (or catch the ExitException yourself). See section\n\"\
@@ -1777,7 +2131,7 @@
    typeOf = const tyCon_ProcessStatus
 
 -- GHC 6.4
-tyCon_ProcessStatus = mkTyConApp (mkTyCon3 "hsshellscript"              
+tyCon_ProcessStatus = mkTyConApp (mkTyCon3 "hsshellscript"
                                            "HsShellScript.ProcErr"
                                            "Posix.ProcessStatus") []
 
diff --git a/src/cbits/hsshellscript.c b/src/cbits/hsshellscript.c
--- a/src/cbits/hsshellscript.c
+++ b/src/cbits/hsshellscript.c
@@ -48,8 +48,6 @@
   int ret;
   buf->gl_pathv = 0;
 
-  printf("pattern = >%s<\n", pattern);  /***/
-
   ret = glob(pattern, GLOB_ERR, 0, buf);
 
   switch (ret) {
diff --git a/test/IOError.hs b/test/IOError.hs
new file mode 100644
--- /dev/null
+++ b/test/IOError.hs
@@ -0,0 +1,36 @@
+to_ioe :: RunError -> IOError
+to_ioe re =
+   GHC.IO.Exception.IOError { ioe_handle      = Nothing,
+                              ioe_type        = GHC.IO.Exception.SystemError,
+                              ioe_location    = "runprog",
+                              ioe_description = show_runerror re,
+                              ioe_filename    = Just (shell_command (re_prog re) (re_pars re)),
+                              ioe_errno       = re_errno re
+                            }
+      
+{-
+ FilePath -> IOErrorSource
+                                
+   GHC.IO.Exception.IOError { 
+                              
+                              
+                              ioe_description = show_runerror re,
+                              ioe_filename    = 
+                              ioe_errno       = re_errno re
+                            }
+-}
+{-
+to_ioe re =
+   System.IO.Error.ioeSetErrorString 
+      ( System.IO.Error.mkIOError GHC.IO.Exception.SystemError       -- Type
+                                  "runprog"                          -- Location
+                                  Nothing                            -- handle 
+                                  (Just (shell_command (re_prog re) (re_pars re)))   -- file name
+      )
+      (show_runerror re)
+      { 
+-}
+
+
+
+-- In ProcErr.hs:317
diff --git a/test/as_ioe.hs b/test/as_ioe.hs
new file mode 100644
--- /dev/null
+++ b/test/as_ioe.hs
@@ -0,0 +1,16 @@
+import Control.Exception
+import Prelude hiding (catch)
+import HsShellScript
+
+main = mainwrapper $ do
+   outm "RunError:"
+   runprog "/bin/false" []
+     `catch` (\(re::RunError) -> 
+                 outm (show re))
+   
+   outm "\n\nIOError:" 
+   (as_ioe $ runprog "/bin/false" [])
+     `catch` (\(ioe::IOError) -> 
+                 outm (show ioe))
+
+   outm "\n\nEnd."
diff --git a/test/bug.hs b/test/bug.hs
new file mode 100644
--- /dev/null
+++ b/test/bug.hs
@@ -0,0 +1,16 @@
+import Foreign.C
+import Foreign.Ptr
+
+
+main = 
+  aufruf "äöü"
+
+
+aufruf :: String -> IO ()
+aufruf str =
+  withCString str $ \ptr -> c_aufruf ptr
+
+
+foreign import ccall safe "test/glob.chs.h c_aufruf"
+  c_aufruf :: ((Ptr CChar) -> (IO ()))
+
diff --git a/test/child.hs b/test/child.hs
new file mode 100644
--- /dev/null
+++ b/test/child.hs
@@ -0,0 +1,5 @@
+import HsShellScript
+
+
+main = mainwrapper $ do
+   pipe_to "bla" (exec "/bin/false" [])
diff --git a/test/glob.hs b/test/glob.hs
new file mode 100644
--- /dev/null
+++ b/test/glob.hs
@@ -0,0 +1,6 @@
+import HsShellScript
+
+main = do
+   l <- glob "*"
+   mapM_ outm l
+   
diff --git a/test/h_pipe_to.hs b/test/h_pipe_to.hs
new file mode 100644
--- /dev/null
+++ b/test/h_pipe_to.hs
@@ -0,0 +1,14 @@
+import System.Posix
+import HsShellScript
+
+
+main = mainwrapper $ do
+  (h,pid) <- h_pipe_to (exec "/fooble" [])
+  (Just ps) <- getProcessStatus True False pid
+  print (ps::ProcessStatus)
+  
+  
+{- 
+     getProcessStatus block stopped pid
+                      - Ob getProcessStatus blockieren soll
+-}
diff --git a/test/path_exists'.hs b/test/path_exists'.hs
new file mode 100644
--- /dev/null
+++ b/test/path_exists'.hs
@@ -0,0 +1,16 @@
+import HsShellScript
+import System.Posix.Files
+
+main = do 
+  createSymbolicLink "/frooble" "symlink"
+  
+  outm_ "Symlink exists: "
+  ex <- path_exists' "symlink"
+  outm (show ex)
+  
+  outm_ "Path exists: "
+  ex <- path_exists "symlink"
+  outm (show ex)
+
+  removeLink "symlink"
+  
diff --git a/test/pipe.hs b/test/pipe.hs
new file mode 100644
--- /dev/null
+++ b/test/pipe.hs
@@ -0,0 +1,9 @@
+import HsShellScript
+
+main = mainwrapper $ do
+
+   erg <- pipe_from $
+      pipe_to "2\n3\n1" $
+         exec "/usr/bin/sort" []
+
+   putStrLn erg
diff --git a/test/run.hs b/test/run.hs
new file mode 100644
--- /dev/null
+++ b/test/run.hs
@@ -0,0 +1,12 @@
+import HsShellScript
+import Control.Exception
+import Prelude hiding (catch)
+
+main = do
+   outm "run:"
+   (mainwrapper $ run "/frooble" [])
+      `catch` (\(e::SomeException) -> print e)
+
+   outm "\n\nrunprog:"
+   (mainwrapper $ runprog "/frooble" [])
+      `catch` (\(e::SomeException) -> print e)
diff --git a/test/subproc.hs b/test/subproc.hs
new file mode 100644
--- /dev/null
+++ b/test/subproc.hs
@@ -0,0 +1,12 @@
+import HsShellScript
+import Control.Exception
+import Data.Typeable
+
+data Ausnahme = Ausnahme
+   deriving (Show, Typeable)
+
+instance Exception Ausnahme
+
+
+main = mainwrapper $ do
+   subproc (throw Ausnahme)
diff --git a/test/test.hs b/test/test.hs
new file mode 100644
--- /dev/null
+++ b/test/test.hs
@@ -0,0 +1,11 @@
+
+import HsShellScript
+
+main = do
+  outm "-1-"
+  subproc (outm "Durch die Röhre" -|- exec "/bin/cat" [])
+  outm "-2-"
+
+  mount <- pipe_from (exec "/bin/mount" [])
+  outm "Mount:"
+  outm mount
