-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract platform-specifics from ENV to Crystal::System::Env and imple…
…ment for win32 (#6333) * Extract Crystal::System::Env interface * Implement Crystal::System::Env for win32 * Fix use correct bytesize of UTF-16 strings * fixup! Implement Crystal::System::Env for win32 Remove LPCWSTR * fixup! Extract Crystal::System::Env interface Refactor String#check_no_null_byte * fixup! Implement Crystal::System::Env for win32 Use String#check_no_null_byte * fixup! Fix use correct bytesize of UTF-16 strings * fixup! Implement Crystal::System::Env for win32 Add spec for empty environment variable. This fails on win32 because `GetEnvironmentVariableW` doesnt differentiate between unset variable and empty string. In contrast, `GetEnvironmentStringsW` contains empty variables. * fixup! fixup! Implement Crystal::System::Env for win32 Fix implementation for empty string on win32 using `SetLastError`. * Uncomment specs depending on ENV in file_specs * fixup! Uncomment specs depending on ENV in file_specs
- 1.15.1
- 1.15.0
- 1.14.1
- 1.14.0
- 1.13.3
- 1.13.2
- 1.13.1
- 1.13.0
- 1.12.2
- 1.12.1
- 1.12.0
- 1.11.2
- 1.11.1
- 1.11.0
- 1.10.1
- 1.10.0
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.1
- 1.5.0
- 1.4.1
- 1.4.0
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
- 0.36.1
- 0.36.0
- 0.35.1
- 0.35.0
- 0.34.0
- 0.33.0
- 0.32.1
- 0.32.0
- 0.31.1
- 0.31.0
- 0.30.1
- 0.30.0
- 0.29.0
- 0.28.0
- 0.27.2
- 0.27.1
- 0.27.0
- 0.26.1
- 0.26.0
1 parent
2aea034
commit 4f720ab
Showing
14 changed files
with
293 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module Crystal::System::Env | ||
# Sets an environment variable or unsets it if *value* is `nil`. | ||
# def self.set(key : String, value : String?) : Nil | ||
|
||
# Gets an environment variable. | ||
# def self.get(key : String) : String? | ||
|
||
# Returns `true` if environment variable is set. | ||
# def self.has_key?(key : String) : Bool | ||
|
||
# Iterates all environment variables. | ||
# def self.each(&block : String, String ->) | ||
end | ||
|
||
{% if flag?(:win32) %} | ||
require "./win32/env" | ||
{% else %} | ||
require "./unix/env" | ||
{% end %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
require "c/stdlib" | ||
|
||
module Crystal::System::Env | ||
# Sets an environment variable. | ||
def self.set(key : String, value : String) : Nil | ||
key.check_no_null_byte("key") | ||
value.check_no_null_byte("value") | ||
|
||
if LibC.setenv(key, value, 1) != 0 | ||
raise Errno.new("setenv") | ||
end | ||
end | ||
|
||
# Unsets an environment variable. | ||
def self.set(key : String, value : Nil) : Nil | ||
key.check_no_null_byte("key") | ||
|
||
if LibC.unsetenv(key) != 0 | ||
raise Errno.new("unsetenv") | ||
end | ||
end | ||
|
||
# Gets an environment variable. | ||
def self.get(key : String) : String? | ||
key.check_no_null_byte("key") | ||
|
||
if value = LibC.getenv(key) | ||
String.new(value) | ||
end | ||
end | ||
|
||
# Returns `true` if environment variable is set. | ||
def self.has_key?(key : String) : Bool | ||
key.check_no_null_byte("key") | ||
|
||
!!LibC.getenv(key) | ||
end | ||
|
||
# Iterates all environment variables. | ||
def self.each(&block : String, String ->) | ||
environ_ptr = LibC.environ | ||
while environ_ptr | ||
environ_value = environ_ptr.value | ||
if environ_value | ||
key_value = String.new(environ_value).split('=', 2) | ||
key = key_value[0] | ||
value = key_value[1]? || "" | ||
yield key, value | ||
environ_ptr += 1 | ||
else | ||
break | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
require "crystal/system/windows" | ||
require "c/winbase" | ||
|
||
module Crystal::System::Env | ||
# Sets an environment variable or unsets it if *value* is `nil`. | ||
def self.set(key : String, value : String) : Nil | ||
key.check_no_null_byte("key") | ||
value.check_no_null_byte("value") | ||
|
||
if LibC.SetEnvironmentVariableW(key.to_utf16, value.to_utf16) == 0 | ||
raise WinError.new("SetEnvironmentVariableW") | ||
end | ||
end | ||
|
||
# Unsets an environment variable. | ||
def self.set(key : String, value : Nil) : Nil | ||
key.check_no_null_byte("key") | ||
|
||
if LibC.SetEnvironmentVariableW(key.to_utf16, nil) == 0 | ||
raise WinError.new("SetEnvironmentVariableW") | ||
end | ||
end | ||
|
||
# Gets an environment variable. | ||
def self.get(key : String) : String? | ||
key.check_no_null_byte("key") | ||
|
||
System.retry_wstr_buffer do |buffer, small_buf| | ||
# `GetEnvironmentVariableW` doesn't set last error on success but we need | ||
# a success message in order to identify if length == 0 means not found or | ||
# the value is an empty string. | ||
LibC.SetLastError(WinError::ERROR_SUCCESS) | ||
length = LibC.GetEnvironmentVariableW(key.to_utf16, buffer, buffer.size) | ||
|
||
if 0 < length < buffer.size | ||
return String.from_utf16(buffer[0, length]) | ||
elsif small_buf && length > 0 | ||
next length | ||
else | ||
case last_error = LibC.GetLastError | ||
when WinError::ERROR_SUCCESS | ||
return "" | ||
when WinError::ERROR_ENVVAR_NOT_FOUND | ||
return | ||
else | ||
raise WinError.new("GetEnvironmentVariableW", last_error) | ||
end | ||
end | ||
end | ||
end | ||
|
||
# Returns `true` if environment variable is set. | ||
def self.has_key?(key : String) : Bool | ||
key.check_no_null_byte("key") | ||
|
||
buffer = uninitialized UInt16[1] | ||
LibC.GetEnvironmentVariableW(key.to_utf16, buffer, buffer.size) != 0 | ||
end | ||
|
||
# Iterates all environment variables. | ||
def self.each(&block : String, String ->) | ||
orig_pointer = pointer = LibC.GetEnvironmentStringsW | ||
raise WinError.new("GetEnvironmentStringsW") if pointer.null? | ||
|
||
begin | ||
while !pointer.value.zero? | ||
string, pointer = String.from_utf16(pointer) | ||
key_value = string.split('=', 2) | ||
key = key_value[0] | ||
value = key_value[1]? || "" | ||
yield key, value | ||
end | ||
ensure | ||
LibC.FreeEnvironmentStringsW(orig_pointer) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.