setenv-0.1.0/0000755000000000000000000000000012033070120011166 5ustar0000000000000000setenv-0.1.0/LICENSE0000644000000000000000000000206212033070120012173 0ustar0000000000000000Copyright (c) 2012 Simon Hengel 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. setenv-0.1.0/setenv.cabal0000644000000000000000000000165212033070120013462 0ustar0000000000000000name: setenv version: 0.1.0 license: MIT license-file: LICENSE copyright: (c) 2012 Simon Hengel author: Simon Hengel maintainer: Simon Hengel 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 setenv-0.1.0/Setup.lhs0000644000000000000000000000011412033070120012772 0ustar0000000000000000#!/usr/bin/env runhaskell > import Distribution.Simple > main = defaultMain setenv-0.1.0/test/0000755000000000000000000000000012033070120012145 5ustar0000000000000000setenv-0.1.0/test/Spec.hs0000644000000000000000000000005412033070120013372 0ustar0000000000000000{-# OPTIONS_GHC -F -pgmF hspec-discover #-} setenv-0.1.0/src/0000755000000000000000000000000012033070120011755 5ustar0000000000000000setenv-0.1.0/src/System/0000755000000000000000000000000012033070120013241 5ustar0000000000000000setenv-0.1.0/src/System/SetEnv.hs0000644000000000000000000000550712033070120015010 0ustar0000000000000000{-# 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