packages feed

setenv (empty) → 0.1.0

raw patch · 5 files changed

+155/−0 lines, 5 filesdep +QuickCheckdep +basedep +hspecsetup-changed

Dependencies added: QuickCheck, base, hspec, setenv, unix

Files

+ LICENSE view
@@ -0,0 +1,19 @@+Copyright (c) 2012 Simon Hengel <sol@typeful.net>++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ setenv.cabal view
@@ -0,0 +1,43 @@+name:             setenv+version:          0.1.0+license:          MIT+license-file:     LICENSE+copyright:        (c) 2012 Simon Hengel+author:           Simon Hengel <sol@typeful.net>+maintainer:       Simon Hengel <sol@typeful.net>+category:         System+synopsis:         A cross-platform library for setting environment variables+description:      A cross-platform library for setting environment variables+build-type:       Simple+cabal-version:    >= 1.8++source-repository head+  type: git+  location: https://github.com/sol/setenv++library+  ghc-options:+      -Wall+  hs-source-dirs:+      src+  exposed-modules:+      System.SetEnv+  build-depends:+      base == 4.*+  if !os(windows)+    build-depends: unix++test-suite spec+  type:+      exitcode-stdio-1.0+  ghc-options:+      -Wall -Werror+  hs-source-dirs:+      test+  main-is:+      Spec.hs+  build-depends:+      base+    , setenv+    , hspec >= 1.3+    , QuickCheck
+ src/System/SetEnv.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE CPP, ForeignFunctionInterface #-}+module System.SetEnv (+  setEnv+, unsetEnv+) where++#ifdef mingw32_HOST_OS+import GHC.Windows+import Foreign.Safe+import Foreign.C+import Control.Monad+#else+import qualified System.Posix.Env as Posix+#endif++#ifdef mingw32_HOST_OS+# if defined(i386_HOST_ARCH)+#  define WINDOWS_CCONV stdcall+# elif defined(x86_64_HOST_ARCH)+#  define WINDOWS_CCONV ccall+# else+#  error Unknown mingw32 arch+# endif++foreign import WINDOWS_CCONV unsafe "windows.h GetLastError"+  c_GetLastError:: IO DWORD++eRROR_ENVVAR_NOT_FOUND :: DWORD+eRROR_ENVVAR_NOT_FOUND = 203++#endif++-- | @setEnv name value@ sets the specified environment variable to @value@.+--+-- If @value@ is the empty string, the specified environment variable is+-- removed from the environment.+--+-- Throws `Control.Exception.IOException` if @name@ is the empty string or+-- contains an equals character.+setEnv :: String -> String -> IO ()+setEnv key value_+  | null value = unsetEnv key+  | otherwise  = setEnv_ key value+  where+    -- NOTE: Anything that follows NUL is ignored on both POSIX and Windows.+    -- We still strip it manually so that the null check above succeds if a+    -- value starts with NUL, and `unsetEnv` is called.  This is important for+    -- two reasons.+    --+    --  * On POSIX setting an environment variable to the empty string does not+    --    remove it.+    --+    --  * On Windows setting an environment variable to the empty string+    --    removes that environment variable.  A subsequent call to+    --    GetEnvironmentVariable will then return 0, but GetLastError will not+    --    be updates, and hence may not return ERROR_ENVVAR_NOT_FOUND.  This is+    --    at least true for observed this behavior with Windows XP SP 3.+    value = takeWhile (/= '\NUL') value_++setEnv_ :: String -> String -> IO ()+#ifdef mingw32_HOST_OS+setEnv_ key value = withCWString key $ \k -> withCWString value $ \v -> do+  success <- c_SetEnvironmentVariable k v+  unless success (throwGetLastError "setEnv")++foreign import WINDOWS_CCONV unsafe "windows.h SetEnvironmentVariableW"+  c_SetEnvironmentVariable :: LPTSTR -> LPTSTR -> IO Bool+#else+setEnv_ k v = Posix.setEnv k v True+#endif++-- | @unSet name@ removes the specified environment variable from the+-- environment of the current process.+--+-- Throws `Control.Exception.IOException` if @name@ is the empty string or+-- contains an equals character.+unsetEnv :: String -> IO ()+#ifdef mingw32_HOST_OS+unsetEnv key = withCWString key $ \k -> do+  success <- c_SetEnvironmentVariable k nullPtr+  unless success $ do+    -- We consider unsetting an environment variable that does not exist not as+    -- an error, hence we ignore eRROR_ENVVAR_NOT_FOUND.+    err <- c_GetLastError+    unless (err == eRROR_ENVVAR_NOT_FOUND) $ do+      throwGetLastError "unsetEnv"+#else+unsetEnv = Posix.unsetEnv+#endif
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}