1 /******************************************************************************* 2 3 Copyright: 4 Copyright (c) 2007 Tango contributors. 5 Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH. 6 All rights reserved. 7 8 License: 9 Tango Dual License: 3-Clause BSD License / Academic Free License v3.0. 10 See LICENSE_TANGO.txt for details. 11 12 Version: Feb 2007: Initial release 13 14 Authors: Deewiant, Maxter, Gregor, Kris 15 16 *******************************************************************************/ 17 18 module ocean.sys.Environment; 19 20 import ocean.transition; 21 22 import ocean.sys.Common; 23 24 import ocean.io.Path; 25 import ocean.io.FilePath; 26 27 import ocean.core.ExceptionDefinitions; 28 29 import ocean.io.model.IFile; 30 31 import Text = ocean.text.Util; 32 33 private 34 { 35 mixin(global("extern (C) extern char** environ")); 36 } 37 38 import core.sys.posix.stdlib; 39 import ocean.stdc.string; 40 41 /******************************************************************************* 42 43 Exposes the system Environment settings, along with some handy 44 utilities 45 46 *******************************************************************************/ 47 48 struct Environment 49 { 50 public alias cwd directory; 51 52 /*********************************************************************** 53 54 Throw an exception 55 56 ***********************************************************************/ 57 58 private static void exception (istring msg) 59 { 60 throw new PlatformException (msg); 61 } 62 63 /*********************************************************************** 64 65 Returns an absolute version of the provided path, where cwd is used 66 as the prefix. 67 68 The provided path is returned as is if already absolute. 69 70 ***********************************************************************/ 71 72 static istring toAbsolute(mstring path) 73 { 74 scope fp = new FilePath(path); 75 if (fp.isAbsolute) 76 return idup(path); 77 78 fp.absolute(cwd); 79 return fp.toString; 80 } 81 82 /*********************************************************************** 83 84 Returns the full path location of the provided executable 85 file, rifling through the PATH as necessary. 86 87 Returns null if the provided filename was not found 88 89 ***********************************************************************/ 90 91 static FilePath exePath (cstring file) 92 { 93 auto bin = new FilePath (file); 94 95 // is this a directory? Potentially make it absolute 96 if (bin.isChild && !bin.isAbsolute) 97 return bin.absolute (cwd); 98 99 // rifle through the path (after converting to standard format) 100 foreach (_pe; Text.patterns (standard(get("PATH").dup), FileConst.SystemPathString)) 101 { 102 auto pe = assumeUnique(_pe); // only acessible via foreach args 103 104 if (bin.path(pe).exists) 105 { 106 stat_t stats; 107 stat(bin.cString.ptr, &stats); 108 if (stats.st_mode & Octal!("100")) 109 return bin; 110 } 111 } 112 return null; 113 } 114 115 /*************************************************************************** 116 117 Returns: 118 the provided 'def' value if the variable does not exist 119 120 ***************************************************************************/ 121 122 static istring get (cstring variable, istring def = null) 123 { 124 char* ptr = getenv ((variable ~ '\0').ptr); 125 126 if (ptr is null) 127 return def; 128 129 return idup(ptr[0 .. strlen(ptr)]); 130 } 131 132 /*************************************************************************** 133 134 Clears the variable, if value is null or empty 135 136 ***************************************************************************/ 137 138 static void set (cstring variable, cstring value = null) 139 { 140 int result; 141 142 if (value.length is 0) 143 unsetenv ((variable ~ '\0').ptr); 144 else 145 result = setenv ((variable ~ '\0').ptr, (value ~ '\0').ptr, 1); 146 147 if (result != 0) 148 exception (SysError.lastMsg); 149 } 150 151 /*************************************************************************** 152 153 Get all set environment variables as an associative array. 154 155 ***************************************************************************/ 156 157 static istring[istring] get () 158 { 159 istring[istring] arr; 160 161 for (char** p = environ; *p; ++p) 162 { 163 size_t k = 0; 164 char* str = *p; 165 166 while (*str++ != '=') 167 ++k; 168 istring key = idup((*p)[0..k]); 169 170 k = 0; 171 char* val = str; 172 while (*str++) 173 ++k; 174 arr[key] = idup(val[0 .. k]); 175 } 176 177 return arr; 178 } 179 180 /*************************************************************************** 181 182 Set the current working directory 183 184 ***************************************************************************/ 185 186 static void cwd (cstring path) 187 { 188 char[512] tmp = void; 189 tmp [path.length] = 0; 190 tmp[0..path.length] = path; 191 192 if (core.sys.posix.unistd.chdir (tmp.ptr)) 193 exception ("Failed to set current directory"); 194 } 195 196 /*************************************************************************** 197 198 Get the current working directory 199 200 ***************************************************************************/ 201 202 static istring cwd () 203 { 204 char[512] tmp = void; 205 206 char *s = core.sys.posix.unistd.getcwd (tmp.ptr, tmp.length); 207 if (s is null) 208 exception ("Failed to get current directory"); 209 210 auto path = s[0 .. strlen(s)+1].dup; 211 if (path[$-2] is '/') // root path has the slash 212 path.length = path.length-1; 213 else 214 path[$-1] = '/'; 215 return assumeUnique(path); 216 } 217 }