From 3f167fd6ddb074b008efa240f5d5cca329990eea Mon Sep 17 00:00:00 2001
From: Evan Laforge <qdunkan@gmail.com>
Date: Sun, 11 Mar 2012 19:38:42 -0700
Subject: [PATCH 2/2] Add System.Environment.lookupEnv, as per trac #5930

---
 System/Environment.hs |   42 +++++++++++++++++++++++++++++-------------
 1 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/System/Environment.hs b/System/Environment.hs
index 72d7eba..3dd9502 100644
--- a/System/Environment.hs
+++ b/System/Environment.hs
@@ -190,18 +190,15 @@ basename f = go f f
 
 getEnv :: String -> IO String
 #ifdef mingw32_HOST_OS
-getEnv name = withCWString name $ \s -> try_size s 256
-  where
-    try_size s size = allocaArray (fromIntegral size) $ \p_value -> do
-      res <- c_GetEnvironmentVariable s p_value size
-      case res of
-        0 -> do
-                  err <- c_GetLastError
-                  if err == eRROR_ENVVAR_NOT_FOUND
-                   then ioe_missingEnvVar name
-                   else throwGetLastError "getEnv"
-        _ | res > size -> try_size s res -- Rare: size increased between calls to GetEnvironmentVariable
-          | otherwise  -> peekCWString p_value
+getEnv name = do
+    mbVal <- lookupEnv name
+    case mbVal of
+        Nothing -> do
+            err <- c_GetLastError
+            if err == eRROR_ENVVAR_NOT_FOUND
+                then ioe_missingEnvVar name
+                else throwGetLastError "getEnv"
+        Just val -> return val
 
 eRROR_ENVVAR_NOT_FOUND :: DWORD
 eRROR_ENVVAR_NOT_FOUND = 203
@@ -209,10 +206,29 @@ eRROR_ENVVAR_NOT_FOUND = 203
 foreign import stdcall unsafe "windows.h GetLastError"
   c_GetLastError:: IO DWORD
 
+#else
+getEnv name = maybe (ioe_missingEnvVar name) return =<< lookupEnv name
+#endif
+
+-- | Return the value of the environment variable @var@, or @Nothing@ if
+-- there is no such value.
+--
+-- For POSIX users, this is equivalent to 'System.Posix.Environ.Env.getEnv'.
+lookupEnv :: String -> IO (Maybe String)
+#ifdef mingw32_HOST_OS
+lookupEnv name = withCWString name $ \s -> try_size s 256
+  where
+    try_size s size = allocaArray (fromIntegral size) $ \p_value -> do
+      res <- c_GetEnvironmentVariable s p_value size
+      case res of
+        0 -> return Nothing
+        _ | res > size -> try_size s res -- Rare: size increased between calls to GetEnvironmentVariable
+          | otherwise  -> peekCWString p_value
+
 foreign import stdcall unsafe "windows.h GetEnvironmentVariableW"
   c_GetEnvironmentVariable :: LPTSTR -> LPTSTR -> DWORD -> IO DWORD
 #else
-getEnv name =
+lookupEnv name =
     withCString name $ \s -> do
       litstring <- c_getenv s
       if litstring /= nullPtr
-- 
1.7.5

