summaryrefslogtreecommitdiff
path: root/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs')
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs b/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs
new file mode 100644
index 0000000000..bea2df93b9
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace System.IO
+{
+ /// <summary>Contains internal path helpers that are shared between many projects.</summary>
+ internal static partial class PathInternal
+ {
+ private enum Tristate : byte
+ {
+ NotInitialized,
+ True,
+ False,
+ }
+
+ private static Tristate s_isCaseSensitive = Tristate.NotInitialized;
+
+ /// <summary>Returns a comparison that can be used to compare file and directory names for equality.</summary>
+ internal static StringComparison StringComparison
+ {
+ get
+ {
+ return IsCaseSensitive ?
+ StringComparison.Ordinal :
+ StringComparison.OrdinalIgnoreCase;
+ }
+ }
+
+ /// <summary>Gets whether the system is case-sensitive.</summary>
+ internal static bool IsCaseSensitive
+ {
+ get
+ {
+ // This must be lazily initialized as there are dependencies on PathInternal's static constructor
+ // being fully initialized. (GetIsCaseSensitive() calls GetFullPath() which needs to use PathInternal)
+ if (s_isCaseSensitive == Tristate.NotInitialized)
+ s_isCaseSensitive = GetIsCaseSensitive() ? Tristate.True : Tristate.False;
+
+ return s_isCaseSensitive == Tristate.True;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the file system is case sensitive.
+ /// </summary>
+ /// <remarks>
+ /// Ideally we'd use something like pathconf with _PC_CASE_SENSITIVE, but that is non-portable,
+ /// not supported on Windows or Linux, etc. For now, this function creates a tmp file with capital letters
+ /// and then tests for its existence with lower-case letters. This could return invalid results in corner
+ /// cases where, for example, different file systems are mounted with differing sensitivities.
+ /// </remarks>
+ private static bool GetIsCaseSensitive()
+ {
+ try
+ {
+ string pathWithUpperCase = Path.Combine(Path.GetTempPath(), "CASESENSITIVETEST" + Guid.NewGuid().ToString("N"));
+ using (new FileStream(pathWithUpperCase, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, 0x1000, FileOptions.DeleteOnClose))
+ {
+ string lowerCased = pathWithUpperCase.ToLowerInvariant();
+ return !File.Exists(lowerCased);
+ }
+ }
+ catch (Exception exc)
+ {
+ // In case something goes terribly wrong, we don't want to fail just because
+ // of a casing test, so we assume case-insensitive-but-preserving.
+ Debug.Fail("Casing test failed: " + exc);
+ return false;
+ }
+ }
+ }
+}