Fix pragma warning restore (dotnet/coreclr#26389)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / IO / Path.Unix.cs
blob487c880c8e0b79128b9aa24fa2a829319dc0a009
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Diagnostics;
6 using System.Runtime.InteropServices;
7 using System.Text;
9 namespace System.IO
11 public static partial class Path
13 public static char[] GetInvalidFileNameChars() => new char[] { '\0', '/' };
15 public static char[] GetInvalidPathChars() => new char[] { '\0' };
17 // Expands the given path to a fully qualified path.
18 public static string GetFullPath(string path)
20 if (path == null)
21 throw new ArgumentNullException(nameof(path));
23 if (path.Length == 0)
24 throw new ArgumentException(SR.Arg_PathEmpty, nameof(path));
26 if (path.Contains('\0'))
27 throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
29 // Expand with current directory if necessary
30 if (!IsPathRooted(path))
32 path = Combine(Interop.Sys.GetCwd(), path);
35 // We would ideally use realpath to do this, but it resolves symlinks, requires that the file actually exist,
36 // and turns it into a full path, which we only want if fullCheck is true.
37 string collapsedString = PathInternal.RemoveRelativeSegments(path, PathInternal.GetRootLength(path));
39 Debug.Assert(collapsedString.Length < path.Length || collapsedString.ToString() == path,
40 "Either we've removed characters, or the string should be unmodified from the input path.");
42 string result = collapsedString.Length == 0 ? PathInternal.DirectorySeparatorCharAsString : collapsedString;
44 return result;
47 public static string GetFullPath(string path, string basePath)
49 if (path == null)
50 throw new ArgumentNullException(nameof(path));
52 if (basePath == null)
53 throw new ArgumentNullException(nameof(basePath));
55 if (!IsPathFullyQualified(basePath))
56 throw new ArgumentException(SR.Arg_BasePathNotFullyQualified, nameof(basePath));
58 if (basePath.Contains('\0') || path.Contains('\0'))
59 throw new ArgumentException(SR.Argument_InvalidPathChars);
61 if (IsPathFullyQualified(path))
62 return GetFullPath(path);
64 return GetFullPath(CombineInternal(basePath, path));
67 private static string RemoveLongPathPrefix(string path)
69 return path; // nop. There's nothing special about "long" paths on Unix.
72 public static string GetTempPath()
74 const string TempEnvVar = "TMPDIR";
75 const string DefaultTempPath = "/tmp/";
77 // Get the temp path from the TMPDIR environment variable.
78 // If it's not set, just return the default path.
79 // If it is, return it, ensuring it ends with a slash.
80 string? path = Environment.GetEnvironmentVariable(TempEnvVar);
81 return
82 string.IsNullOrEmpty(path) ? DefaultTempPath :
83 PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path :
84 path + PathInternal.DirectorySeparatorChar;
87 public static string GetTempFileName()
89 const string Suffix = ".tmp";
90 const int SuffixByteLength = 4;
92 // mkstemps takes a char* and overwrites the XXXXXX with six characters
93 // that'll result in a unique file name.
94 string template = GetTempPath() + "tmpXXXXXX" + Suffix + "\0";
95 byte[] name = Encoding.UTF8.GetBytes(template);
97 // Create, open, and close the temp file.
98 IntPtr fd = Interop.CheckIo(Interop.Sys.MksTemps(name, SuffixByteLength));
99 Interop.Sys.Close(fd); // ignore any errors from close; nothing to do if cleanup isn't possible
101 // 'name' is now the name of the file
102 Debug.Assert(name[name.Length - 1] == '\0');
103 return Encoding.UTF8.GetString(name, 0, name.Length - 1); // trim off the trailing '\0'
106 public static bool IsPathRooted(string? path)
108 if (path == null)
109 return false;
111 return IsPathRooted(path.AsSpan());
114 public static bool IsPathRooted(ReadOnlySpan<char> path)
116 return path.Length > 0 && path[0] == PathInternal.DirectorySeparatorChar;
119 /// <summary>
120 /// Returns the path root or null if path is empty or null.
121 /// </summary>
122 public static string? GetPathRoot(string? path)
124 if (PathInternal.IsEffectivelyEmpty(path)) return null;
126 return IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString : string.Empty;
129 public static ReadOnlySpan<char> GetPathRoot(ReadOnlySpan<char> path)
131 return PathInternal.IsEffectivelyEmpty(path) && IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString.AsSpan() : ReadOnlySpan<char>.Empty;
134 /// <summary>Gets whether the system is case-sensitive.</summary>
135 internal static bool IsCaseSensitive
139 #if PLATFORM_OSX
140 return false;
141 #else
142 return true;
143 #endif