aboutsummaryrefslogtreecommitdiff
path: root/Utility/Shell.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-09-05 12:09:23 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-09-05 12:09:23 -0400
commitd0d0d07b9e88992f8beedce33a78918e27b41a6a (patch)
treee6d8404473a702a662a0d32299cc992e4fafeeb7 /Utility/Shell.hs
parent362a9d87c473e0bc9b50757cd58567f3cd37d40c (diff)
Windows: Handle shebang in external special remote program.
Diffstat (limited to 'Utility/Shell.hs')
-rw-r--r--Utility/Shell.hs42
1 files changed, 42 insertions, 0 deletions
diff --git a/Utility/Shell.hs b/Utility/Shell.hs
index e71ca53aa..860ee11dd 100644
--- a/Utility/Shell.hs
+++ b/Utility/Shell.hs
@@ -9,6 +9,19 @@
module Utility.Shell where
+import Utility.SafeCommand
+#ifdef mingw32_HOST_OS
+import Utility.Path
+import Utility.FileSystemEncoding
+import Utility.Exception
+import Utility.PartialPrelude
+#endif
+
+#ifdef mingw32_HOST_OS
+import System.IO
+import System.FilePath
+#endif
+
shellPath_portable :: FilePath
shellPath_portable = "/bin/sh"
@@ -24,3 +37,32 @@ shebang_portable = "#!" ++ shellPath_portable
shebang_local :: String
shebang_local = "#!" ++ shellPath_local
+
+-- | On Windows, shebang is not handled by the kernel, so to support
+-- shell scripts etc, have to look at the program being run and
+-- parse it for shebang.
+--
+-- This has no effect on Unix.
+findShellCommand :: FilePath -> IO (FilePath, [CommandParam])
+findShellCommand f = do
+#ifndef mingw32_HOST_OS
+ defcmd
+#else
+ l <- catchDefaultIO Nothing $ withFile f ReadMode $ \h -> do
+ fileEncoding h
+ headMaybe . lines <$> hGetContents h
+ case l of
+ Just ('#':'!':rest) -> case words rest of
+ [] -> defcmd
+ (c:ps) -> do
+ let ps' = map Param ps ++ [File f]
+ -- If the command is not inPath,
+ -- take the base of it, and run eg "sh"
+ -- which in some cases on windows will work
+ -- despite it not being inPath.
+ ok <- inPath c
+ return (if ok then c else takeFileName c, ps')
+ _ -> defcmd
+#endif
+ where
+ defcmd = return (f, [])