diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 CFLAGS = -XScopedTypeVariables
-VERSION = 3.3.0
+VERSION = 3.3.1
 
 default :: lib
 
diff --git a/hsshellscript.cabal b/hsshellscript.cabal
--- a/hsshellscript.cabal
+++ b/hsshellscript.cabal
@@ -1,5 +1,5 @@
 Name:                hsshellscript
-Version:             3.3.0
+Version:             3.3.1
 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, test/*.hs, test/Makefile
+Extra-source-files:  README, manual/*.html, manual/LICENSE, Makefile, test/Makefile, test/*.hs, test/*.c, test/*.chs
 
 cabal-version:       >= 1.6
 
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.2.0. It has been released 2012-08-28. The API
+Haskell shell scripting library, version 3.3.1. It has been released 2012-09-30. 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-08-28</small></P>
+<small>Last changed 2012-09-30</small></P>
 </BODY>
 </HTML>
diff --git a/manual/install.html b/manual/install.html
--- a/manual/install.html
+++ b/manual/install.html
@@ -23,9 +23,9 @@
   calls <tt>sudo cabal install --global</tt>.
 
 <p>If installed as a user package, then the location of the API documentation
-  is <tt>~/.cabal/share/doc/hsshellscript-3.3.0/html/index.html</tt>. If it is
+  is <tt>~/.cabal/share/doc/hsshellscript-3.3.1/html/index.html</tt>. If it is
   installed globaly, it
-  is <tt>/usr/local/share/doc/hsshellscript-3.3.0/html/index.html</tt>. 
+  is <tt>/usr/local/share/doc/hsshellscript-3.3.1/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/ProcErr.chs b/src/HsShellScript/ProcErr.chs
--- a/src/HsShellScript/ProcErr.chs
+++ b/src/HsShellScript/ProcErr.chs
@@ -916,14 +916,13 @@
   where
      -- Make a pipe, if applicable.
      pipe_if False = return Nothing
-     --pipe_if True  = fmap Just $ createPipe  -- Just (read,write)
      pipe_if True  = do
         (read, write) <- createPipe
         return (Just (read,write))
 
      -- Child work after fork: connect a fd of the new process to the pipe.
      dup_close :: Maybe (Fd, Fd)        -- maybe the pipe
-               -> Handle                -- which handle descriptor to connect to the pipe
+               -> Handle                -- which handle to connect to the pipe
                -> Bool                  -- whether the child reads from this pipe
                -> IO ()
      dup_close Nothing _ _ =
@@ -932,11 +931,14 @@
          do
             h <- System.Posix.fdToHandle readend
             hDuplicateTo h dest
+            hSetBinaryMode dest False -- Use Text mode for the new handle by default. 
             hClose h
             closeFd writeend
      dup_close m@(Just (readend,writeend)) dest False =
-         do h <- System.Posix.fdToHandle writeend
+         do 
+            h <- System.Posix.fdToHandle writeend
             hDuplicateTo h dest
+            hSetBinaryMode dest False -- Use Text mode for the new handle by default. 
             hClose h
             closeFd readend
 
diff --git a/test/Makefile b/test/Makefile
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,18 +1,37 @@
+VERSION=3.3.1
 CFLAGS=-XDeriveDataTypeable
 
-% : %.o cteile.o ../dist/build/libHShsshellscript-3.3.0.a
+PROG_HS  = $(notdir $(basename $(wildcard [_abcdefghijklmnopqrstuvwxyzäöü]*.hs)))
+PROG_CHS = $(notdir $(basename $(wildcard [_abcdefghijklmnopqrstuvwxyzäöü]*.chs)))
+
+# Löscht Doppelgänger
+PROGS    = $(sort $(PROG_HS) $(PROG_CHS))
+
+
+% : %.o cteile.o ../dist/build/libHShsshellscript-$(VERSION).a
 	ghc -o $@ $^ -package haskell2010 -package unix
 
 %.o : %.hs
-	ghc $(CFLAGS) -c $^
+	ghc -c $(CFLAGS) $^
 
 %.o : %.c
-	ghc $(CFLAGS) -c $^
+	gcc -c -o $@ $<
 
 %.hs : %.chs
 	-chmod u+w $@
-	c2hs  -o $@ $<
+	c2hs -o $@ $<
 	chmod u-w $@
 
-clean ::
-	rm *.hi *.o *~ 
+clean :: depend
+	rm -f *.hi *.o *~ *.bak $(PROGS) *.chi *.chs.h \
+	      $(foreach m, $(PROG_CHS), "$(m).hs")
+
+depend :: $(foreach m, $(PROGS), $(m).hs)
+	ghc -M $(CFLAGS) -dep-makefile -optdepdepend \
+	       $(foreach m, $(PROGS), "$(m).hs")
+	make cteile.o
+
+z : z.c
+	gcc -o $@ $<
+
+-include depend
diff --git a/test/cteile.c b/test/cteile.c
new file mode 100644
--- /dev/null
+++ b/test/cteile.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+
+void c_aufruf(const char* ptr)
+{
+  printf("ptr = >%s<\nlength = %d\n", ptr, strlen(ptr));
+}
+
+
+//--------------------------------------------------------------------------------
+// #include <stdio.h>
+int puts(const char *txt);
+
+
+// Debug
+void print_utf8_c(char* puf)
+{
+  int idx = 0;
+  int len = strlen(puf);
+
+  do {
+    if (puf[idx] & 0x80) 
+      printf("!");
+    printf("%02x ", puf[idx] & 0xFF);
+    idx++;
+  } while (idx < len);
+
+  printf("\nC-Seite ausgegeben; \"");
+  for (idx = 0; idx < len; idx++)
+    printf("%c", puf[idx]);
+  printf("\", Länge = %d\n",len);
+}
+
diff --git a/test/path_exists'.hs b/test/path_exists'.hs
deleted file mode 100644
--- a/test/path_exists'.hs
+++ /dev/null
@@ -1,16 +0,0 @@
-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/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/textmode.chs b/test/textmode.chs
new file mode 100644
--- /dev/null
+++ b/test/textmode.chs
@@ -0,0 +1,120 @@
+{-
+   * withCString konvertiert von Haskell (d.h. Unicode) nach UTF-8 (je nach Locale)
+   * puts aus der C-Bibliothek fügt einen Zeilenumbruch am Ende ein.
+-}
+
+import HsShellScript
+import System.IO
+import System.Posix.Process
+import System.Posix.Types
+import Foreign.C
+import Foreign.Ptr
+
+main = mainwrapper $ do
+   
+
+   h <- openFile "/home/v/src/hsskripte/tmp/txt" ReadMode
+   hSetBinaryMode h True
+   c <- hGetContents h
+   seq (length c) (return ())
+   hClose h
+   putStr ("Datei im Binär-Modus: " ++ c)
+
+   h <- openFile "/home/v/src/hsskripte/tmp/txt" ReadMode
+   hSetBinaryMode h False
+   c <- hGetContents h
+   seq (length c) (return ())
+   hClose h
+   putStr ("Datei im Text-Modus: " ++ c)
+
+   h <- openFile "/home/v/src/hsskripte/tmp/txt" ReadMode
+   c <- hGetContents h
+   seq (length c) (return ())
+   hClose h
+   putStr ("Datei im voreingestellten Modus: " ++ c)
+
+  
+   
+   let str = "-äöü-"
+   putStrLn ("Haskell-Seite\n-------------");
+   putStrLn ("str = \"" ++ str ++ "\"\nLänge = " ++ show (length str))
+
+
+   putStrLn "\n1. withCString\n--------------"
+   putStr ("Per withCString an die C-Seite übergeben = ")
+   hFlush stdout
+   print_utf8 str
+
+   putStrLn "\n2. pipe_to zu einer IO-Aktion\n-----------------------------"
+   pipe_to str lies_stdin
+
+   putStrLn "\n2a. pipe_to zu einer IO-Aktion, im Binärmodus\n---------------------------------------------\n"
+   pipe_to str lies_stdin_binary
+
+   putStrLn "\n3. h_pipe_to' zu einer IO-Aktion\n-------------------------------"
+   (h, pid) <- h_pipe_to' lies_stdin
+   hPutStr h str
+   hClose h
+   getProcessStatus True False pid
+   putStrLn ""
+
+
+   putStrLn "\n4. h_pipe_to' zu /bin/cat\n------------------------\n"
+   (h, pid) <- h_pipe_to'
+                  (do exec "/bin/cat" [])
+   hPutStr h str
+   hClose h
+   getProcessStatus True False pid
+   putStrLn ""
+
+
+   putStrLn "\n5. pipes zu tmp/z\n--------------------\n"
+   (Just h, _, _, pid) <- pipes (do exec "./z" [])
+                                True False False
+   hSetBinaryMode h False
+   hPutStr h str
+   hClose h
+   getProcessStatus True False pid
+   putStrLn ""
+
+
+
+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
+h_pipe_to' io = do
+   (Just h, _, _, pid) <- pipes io True False False
+   return (h, pid)
+
+
+
+lies_stdin = do
+   hSetBinaryMode stdin False --XX
+   daten <- hGetContents stdin
+   putStrLn ("Angekommen: \"" ++ daten ++ "\", Länge = " ++ show (length daten))
+   hFlush stdout
+
+lies_stdin_binary = do
+   hSetBinaryMode stdin True
+   daten <- hGetContents stdin
+   putStrLn ("Angekommen: \"" ++ daten ++ "\", Länge = " ++ show (length daten))
+   hFlush stdout
+
+
+puts_hs :: String -> IO ()
+puts_hs str = do
+   i <- withCString str $ \str -> {#call puts#} str
+   return ()
+
+print_utf8 :: String -> IO ()
+print_utf8 str = do
+   i <- withCString str $ \str -> {#call print_utf8_c#} str
+   return ()
+
+
+#c
+
+#include <stdio.h>
+
+void print_utf8_c(char* puf);
+
+#endc
diff --git a/test/textmode.hs b/test/textmode.hs
new file mode 100644
--- /dev/null
+++ b/test/textmode.hs
@@ -0,0 +1,124 @@
+-- GENERATED by C->Haskell Compiler, version 0.16.2 Crystal Seed, 24 Jan 2009 (Haskell)
+-- Edit the ORIGNAL .chs file instead!
+
+
+{-# LINE 1 "textmode.chs" #-}{-
+   * withCString konvertiert von Haskell (d.h. Unicode) nach UTF-8 (je nach Locale)
+   * puts aus der C-Bibliothek fügt einen Zeilenumbruch am Ende ein.
+-}
+
+import HsShellScript
+import System.IO
+import System.Posix.Process
+import System.Posix.Types
+import Foreign.C
+import Foreign.Ptr
+
+main = mainwrapper $ do
+   
+
+   h <- openFile "/home/v/src/hsskripte/tmp/txt" ReadMode
+   hSetBinaryMode h True
+   c <- hGetContents h
+   seq (length c) (return ())
+   hClose h
+   putStr ("Datei im Binär-Modus: " ++ c)
+
+   h <- openFile "/home/v/src/hsskripte/tmp/txt" ReadMode
+   hSetBinaryMode h False
+   c <- hGetContents h
+   seq (length c) (return ())
+   hClose h
+   putStr ("Datei im Text-Modus: " ++ c)
+
+   h <- openFile "/home/v/src/hsskripte/tmp/txt" ReadMode
+   c <- hGetContents h
+   seq (length c) (return ())
+   hClose h
+   putStr ("Datei im voreingestellten Modus: " ++ c)
+
+  
+   
+   let str = "-äöü-"
+   putStrLn ("Haskell-Seite\n-------------");
+   putStrLn ("str = \"" ++ str ++ "\"\nLänge = " ++ show (length str))
+
+
+   putStrLn "\n1. withCString\n--------------"
+   putStr ("Per withCString an die C-Seite übergeben = ")
+   hFlush stdout
+   print_utf8 str
+
+   putStrLn "\n2. pipe_to zu einer IO-Aktion\n-----------------------------"
+   pipe_to str lies_stdin
+
+   putStrLn "\n2a. pipe_to zu einer IO-Aktion, im Binärmodus\n---------------------------------------------\n"
+   pipe_to str lies_stdin_binary
+
+   putStrLn "\n3. h_pipe_to' zu einer IO-Aktion\n-------------------------------"
+   (h, pid) <- h_pipe_to' lies_stdin
+   hPutStr h str
+   hClose h
+   getProcessStatus True False pid
+   putStrLn ""
+
+
+   putStrLn "\n4. h_pipe_to' zu /bin/cat\n------------------------\n"
+   (h, pid) <- h_pipe_to'
+                  (do exec "/bin/cat" [])
+   hPutStr h str
+   hClose h
+   getProcessStatus True False pid
+   putStrLn ""
+
+
+   putStrLn "\n5. pipes zu tmp/z\n--------------------\n"
+   (Just h, _, _, pid) <- pipes (do exec "./z" [])
+                                True False False
+   hSetBinaryMode h False
+   hPutStr h str
+   hClose h
+   getProcessStatus True False pid
+   putStrLn ""
+
+
+
+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
+h_pipe_to' io = do
+   (Just h, _, _, pid) <- pipes io True False False
+   return (h, pid)
+
+
+
+lies_stdin = do
+   hSetBinaryMode stdin False --XX
+   daten <- hGetContents stdin
+   putStrLn ("Angekommen: \"" ++ daten ++ "\", Länge = " ++ show (length daten))
+   hFlush stdout
+
+lies_stdin_binary = do
+   hSetBinaryMode stdin True
+   daten <- hGetContents stdin
+   putStrLn ("Angekommen: \"" ++ daten ++ "\", Länge = " ++ show (length daten))
+   hFlush stdout
+
+
+puts_hs :: String -> IO ()
+puts_hs str = do
+   i <- withCString str $ \str -> puts str
+   return ()
+
+print_utf8 :: String -> IO ()
+print_utf8 str = do
+   i <- withCString str $ \str -> print_utf8_c str
+   return ()
+
+
+
+
+foreign import ccall safe "textmode.chs.h puts"
+  puts :: ((Ptr CChar) -> (IO CInt))
+
+foreign import ccall safe "textmode.chs.h print_utf8_c"
+  print_utf8_c :: ((Ptr CChar) -> (IO ()))
diff --git a/test/z.c b/test/z.c
new file mode 100644
--- /dev/null
+++ b/test/z.c
@@ -0,0 +1,33 @@
+#include <unistd.h>
+#include <stdio.h>
+
+void print_utf8(char puf[], int len);
+
+
+main()
+{
+  char puf[1024];
+  int  len;
+
+  len = read(0, puf, 1024);
+  print_utf8(puf, len);
+}
+
+
+
+void print_utf8(char puf[], int len) 
+{
+  int idx = 0;
+
+  do {
+    if (puf[idx] & 0x80) 
+      printf("!");
+    printf("%02x ", puf[idx] & 0xFF);
+    idx++;
+  } while (idx < len);
+
+  printf("\n\"");
+  for (idx = 0; idx < len; idx++)
+    printf("%c", puf[idx]);
+  printf("\"\nLänge = %d\n",len);
+}
