import Prelude
#ifdef __GLASGOW_HASKELL__
-import System.Exit
+import Foreign
import Foreign.C
+import System.Exit
import GHC.IOBase
#endif
because there is no interpretation of shell metasyntax.
-}
-rawSystem :: String -> IO ExitCode
-rawSystem "" = ioException (IOError Nothing InvalidArgument "rawSystem" "null command" Nothing)
-rawSystem cmd =
- withCString cmd $ \s -> do
- status <- throwErrnoIfMinus1 "rawSystem" (primRawSystem s)
+rawSystem :: FilePath -> [String] -> IO ExitCode
+
+#ifndef mingw32_TARGET_OS
+
+rawSystem cmd args =
+ withCString cmd $ \pcmd ->
+ withMany withCString (cmd:args) $ \cstrs ->
+ withArray0 nullPtr cstrs $ \arr -> do
+ status <- throwErrnoIfMinus1 "rawSystem" (c_rawSystem pcmd arr)
+ case status of
+ 0 -> return ExitSuccess
+ n -> return (ExitFailure n)
+
+foreign import ccall unsafe "rawSystem"
+ c_rawSystem :: CString -> Ptr CString -> IO Int
+
+#else
+
+-- On Windows, the command line is passed to the operating system as
+-- a single string. Command-line parsing is done by the executable
+-- itself.
+rawSystem cmd args = do
+ let cmdline = translate cmd ++ concat (map ((' ':) . translate) args)
+ withCString cmdline $ \pcmdline -> do
+ status <- throwErrnoIfMinus1 "rawSystem" (c_rawSystem pcmdline)
case status of
- 0 -> return ExitSuccess
- n -> return (ExitFailure n)
+ 0 -> return ExitSuccess
+ n -> return (ExitFailure n)
-foreign import ccall unsafe "rawSystemCmd" primRawSystem :: CString -> IO Int
+translate :: String -> String
+translate str = '"' : foldr escape "\"" str
+ where escape '"' str = '\\' : '"' : str
+ escape '\\' str = '\\' : '\\' : str
+ escape c str = c : str
+
+foreign import ccall unsafe "rawSystem"
+ c_rawSystem :: CString -> IO Int
+
+#endif
#endif /* __GLASGOW_HASKELL__ */
/*
- * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
+ * (c) The University of Glasgow 1994-2003
*
- * $Id: rawSystem.c,v 1.1 2002/08/28 13:59:19 simonmar Exp $
- *
- * shell-less system Runtime Support
+ * shell-less system Runtime Support (see System.Cmd.rawSystem).
*/
/* The itimer stuff in this module is non-posix */
#include <windows.h>
#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+
+#ifdef HAVE_VFORK
+#define fork vfork
+#endif
+
+#if defined(mingw32_TARGET_OS)
+/* -------------------- WINDOWS VERSION --------------------- */
+
HsInt
-rawSystemCmd(HsAddr cmd)
+rawSystem(HsAddr cmd)
{
- /* -------------------- WINDOWS VERSION --------------------- */
-#if defined(mingw32_TARGET_OS)
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
DWORD retCode;
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
return retCode;
+}
#else
- /* -------------------- UNIX VERSION --------------------- */
+/* -------------------- UNIX VERSION --------------------- */
+
+HsInt
+rawSystem(HsAddr cmd, HsAddr args)
+{
int pid;
int wstat;
#endif
/* the child */
- execl(cmd, NULL);
+ execvp(cmd, args);
_exit(127);
}
}
/* This should never happen */
}
return -1;
-#endif
}
+#endif
/* -----------------------------------------------------------------------------
- * $Id: HsBase.h,v 1.21 2003/05/08 16:06:41 ross Exp $
+ * $Id: HsBase.h,v 1.22 2003/06/12 16:06:07 simonmar Exp $
*
* (c) The University of Glasgow 2001-2002
*
HsInt systemCmd(HsAddr cmd);
/* in rawSystem.c */
-HsInt rawSystemCmd(HsAddr cmd);
+#if defined(mingw32_TARGET_OS)
+HsInt rawSystem(HsAddr cmd);
+#else
+HsInt rawSystem(HsAddr cmd, HsAddr args);
+#endif
/* in inputReady.c */
int inputReady(int fd, int msecs, int isSock);