Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 8abcb39

Browse files
committed
Consolidate temp files in Unix implementations
System.IO.Pipes and System.IO.MemoryMappedFiles both create temporary files, and end up doing so in inconsistent locations. This commit changes them to use a consistently named location under the temporary path, e.g. /tmp/.dotnet/corefx/pipes/* and /tmp/.dotnet/corefx/maps/*
1 parent 89d9448 commit 8abcb39

File tree

9 files changed

+91
-49
lines changed

9 files changed

+91
-49
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
namespace System.IO
5+
{
6+
internal static partial class PersistedFiles
7+
{
8+
// Temporary data, /tmp/.dotnet/corefx
9+
// User-persisted data, ~/.dotnet/corefx/
10+
// System-persisted data, /etc/dotnet/corefx/
11+
12+
internal const string TopLevelDirectory = "dotnet";
13+
internal const string TopLevelHiddenDirectory = "." + TopLevelDirectory;
14+
internal const string SecondLevelDirectory = "corefx";
15+
}
16+
}

src/Common/src/System/IO/PersistedFiles.Unix.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,8 @@
55

66
namespace System.IO
77
{
8-
internal static class PersistedFiles
8+
internal static partial class PersistedFiles
99
{
10-
// If we ever need system persisted data, /etc/dotnet/corefx/
11-
private const string TopLevelDirectory = "dotnet";
12-
// User persisted data, ~/.dotnet/corefx/
13-
private const string TopLevelUserDirectory = "." + TopLevelDirectory;
14-
private const string SecondLevelDirectory = "corefx";
15-
1610
private static string s_userProductDirectory;
1711

1812
/// <summary>
@@ -79,7 +73,7 @@ private static void EnsureUserDirectories()
7973

8074
s_userProductDirectory = Path.Combine(
8175
userHomeDirectory,
82-
TopLevelUserDirectory,
76+
TopLevelHiddenDirectory,
8377
SecondLevelDirectory);
8478
}
8579
}

src/System.IO.MemoryMappedFiles/src/System.IO.MemoryMappedFiles.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@
198198
<Compile Include="$(CommonPath)\Interop\OSX\libc\Interop.SysConfNames.cs">
199199
<Link>Common\Interop\OSX\Interop.SysConfNames.cs</Link>
200200
</Compile>
201+
<Compile Include="$(CommonPath)\System\IO\PersistedFiles.Names.Unix.cs">
202+
<Link>Common\System\IO\PersistedFiles.Names.Unix.cs</Link>
203+
</Compile>
201204
</ItemGroup>
202205
<!-- Resource files -->
203206
<ItemGroup>

src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.Unix.BackingObject_File.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ public partial class MemoryMappedFile
99
{
1010
private static FileStream CreateSharedBackingObject(Interop.libc.MemoryMappedProtections protections, long capacity)
1111
{
12-
string path = TmpPathPrefix + Guid.NewGuid().ToString("N") + ".tmp";
13-
12+
Directory.CreateDirectory(s_tempMapsDirectory);
13+
string path = Path.Combine(s_tempMapsDirectory, Guid.NewGuid().ToString("N"));
14+
1415
FileAccess access =
1516
(protections & (Interop.libc.MemoryMappedProtections.PROT_READ | Interop.libc.MemoryMappedProtections.PROT_WRITE)) != 0 ? FileAccess.ReadWrite :
1617
(protections & (Interop.libc.MemoryMappedProtections.PROT_WRITE)) != 0 ? FileAccess.Write :
@@ -37,6 +38,10 @@ private static FileStream CreateSharedBackingObject(Interop.libc.MemoryMappedPro
3738
// ---- PAL layer ends here ----
3839
// -----------------------------
3940

40-
private static readonly string TmpPathPrefix = Path.Combine(Path.GetTempPath(), MemoryMapObjectFilePrefix);
41+
private static readonly string s_tempMapsDirectory = Path.Combine(
42+
Path.GetTempPath(),
43+
PersistedFiles.TopLevelHiddenDirectory,
44+
PersistedFiles.SecondLevelDirectory,
45+
"maps");
4146
}
4247
}

src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.Unix.BackingObject_Memory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ private static FileStream CreateSharedBackingObject(
1111
Interop.libc.MemoryMappedProtections protections, long capacity)
1212
{
1313
// The POSIX shared memory object name must begin with '/'. After that we just want something short and unique.
14-
string mapName = "/" + MemoryMapObjectFilePrefix + Guid.NewGuid().ToString("N");
14+
string mapName = "/corefx_map_" + Guid.NewGuid().ToString("N");
1515

1616
// Determine the flags to use when creating the shared memory object
1717
Interop.libc.OpenFlags flags = (protections & Interop.libc.MemoryMappedProtections.PROT_WRITE) != 0 ?

src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.Unix.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ private static Exception CreateNamedMapsNotSupportedException()
122122
{
123123
return new PlatformNotSupportedException(SR.PlatformNotSupported_NamedMaps);
124124
}
125-
126-
private const string MemoryMapObjectFilePrefix = "corefx_mmf_";
127-
125+
128126
private static FileAccess TranslateProtectionsToFileAccess(Interop.libc.MemoryMappedProtections protections)
129127
{
130128
return

src/System.IO.Pipes/src/System.IO.Pipes.csproj

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,6 @@
139139
<Compile Include="System\IO\Pipes\PipeStreamAsyncResult.cs" />
140140
</ItemGroup>
141141
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' ">
142-
<Compile Include="$(CommonPath)\System\NotImplemented.cs">
143-
<!-- TODO: Remove once implemented -->
144-
<Link>Common\System\NotImplemented.cs</Link>
145-
</Compile>
146142
<Compile Include="Microsoft\Win32\SafeHandles\SafePipeHandle.Unix.cs" />
147143
<Compile Include="System\IO\Pipes\AnonymousPipeServerStream.Unix.cs" />
148144
<Compile Include="System\IO\Pipes\NamedPipeClientStream.Unix.cs" />
@@ -199,6 +195,9 @@
199195
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.Stat.cs">
200196
<Link>Common\Interop\Unix\Interop.Stat.cs</Link>
201197
</Compile>
198+
<Compile Include="$(CommonPath)\System\IO\PersistedFiles.Names.Unix.cs">
199+
<Link>Common\System\IO\PersistedFiles.Names.Unix.cs</Link>
200+
</Compile>
202201
</ItemGroup>
203202
<!-- Linux -->
204203
<ItemGroup Condition="'$(TargetsLinux)' == 'true'">

src/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ public abstract partial class PipeStream : Stream
2020
// Windows, but can't assume a valid handle on Unix.
2121
internal const bool CheckOperationsRequiresSetHandle = false;
2222

23-
private static readonly string PipeDirectoryPath = Path.Combine(Path.GetTempPath(), "corefxnamedpipes");
24-
2523
internal static string GetPipePath(string serverName, string pipeName)
2624
{
2725
if (serverName != "." && serverName != Interop.libc.gethostname())
@@ -38,35 +36,8 @@ internal static string GetPipePath(string serverName, string pipeName)
3836
throw new PlatformNotSupportedException();
3937
}
4038

41-
// Make sure we have the directory in which to put the pipe paths
42-
while (true)
43-
{
44-
int result = Interop.libc.mkdir(PipeDirectoryPath, (int)Interop.libc.Permissions.S_IRWXU);
45-
if (result >= 0)
46-
{
47-
// directory created
48-
break;
49-
}
50-
51-
Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
52-
if (errorInfo.Error == Interop.Error.EINTR)
53-
{
54-
// I/O was interrupted, try again
55-
continue;
56-
}
57-
else if (errorInfo.Error == Interop.Error.EEXIST)
58-
{
59-
// directory already exists
60-
break;
61-
}
62-
else
63-
{
64-
throw Interop.GetExceptionForIoErrno(errorInfo, PipeDirectoryPath, isDirectory: true);
65-
}
66-
}
67-
6839
// Return the pipe path
69-
return Path.Combine(PipeDirectoryPath, pipeName);
40+
return Path.Combine(GetPipeDirectoryPath(), pipeName);
7041
}
7142

7243
/// <summary>Throws an exception if the supplied handle does not represent a valid pipe.</summary>
@@ -255,6 +226,59 @@ public virtual PipeTransmissionMode ReadMode
255226
// ---- PAL layer ends here ----
256227
// -----------------------------
257228

229+
private static string s_pipeDirectoryPath;
230+
231+
private static string GetPipeDirectoryPath()
232+
{
233+
string path = s_pipeDirectoryPath;
234+
if (path == null)
235+
{
236+
// Create the pipes temporary directory, e.g. "/tmp/.dotnet/corefx/pipes".
237+
// We don't have access to Directory.CreateDirectory (which handles creating
238+
// all levels of the directory full path specified), so we create each nested
239+
// level individually (though we assume that the temp path already exists).
240+
241+
path = Path.GetTempPath();
242+
243+
path = Path.Combine(path, PersistedFiles.TopLevelHiddenDirectory);
244+
CreateDirectory(path);
245+
246+
path = Path.Combine(path, PersistedFiles.SecondLevelDirectory);
247+
CreateDirectory(path);
248+
249+
const string PipesFeatureName = "pipes";
250+
path = Path.Combine(path, PipesFeatureName);
251+
CreateDirectory(path);
252+
253+
s_pipeDirectoryPath = path;
254+
}
255+
return path;
256+
}
257+
258+
private static void CreateDirectory(string directoryPath)
259+
{
260+
while (true)
261+
{
262+
int result = Interop.libc.mkdir(directoryPath, (int)Interop.libc.Permissions.S_IRWXU);
263+
264+
// If successful created, we're done.
265+
if (result >= 0)
266+
return;
267+
268+
// If the directory already exists, consider it a success.
269+
Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
270+
if (errorInfo.Error == Interop.Error.EEXIST)
271+
return;
272+
273+
// If the I/O was interrupted, try again.
274+
if (errorInfo.Error == Interop.Error.EINTR)
275+
continue;
276+
277+
// Otherwise, fail.
278+
throw Interop.GetExceptionForIoErrno(errorInfo, directoryPath, isDirectory: true);
279+
}
280+
}
281+
258282
internal static Interop.libc.OpenFlags TranslateFlags(PipeDirection direction, PipeOptions options, HandleInheritability inheritability)
259283
{
260284
// Translate direction

src/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@
219219
<Compile Include="$(CommonPath)\System\IO\PersistedFiles.Unix.cs">
220220
<Link>Common\System\IO\PersistedFiles.Unix.cs</Link>
221221
</Compile>
222+
<Compile Include="$(CommonPath)\System\IO\PersistedFiles.Names.Unix.cs">
223+
<Link>Common\System\IO\PersistedFiles.Names.Unix.cs</Link>
224+
</Compile>
222225
</ItemGroup>
223226
<ItemGroup>
224227
<None Include="project.json" />

0 commit comments

Comments
 (0)