@@ -37,7 +37,7 @@ internal static string GetPipePath(string serverName, string pipeName)
37
37
}
38
38
39
39
// Return the pipe path
40
- return Path . Combine ( GetPipeDirectoryPath ( ) , pipeName ) ;
40
+ return Path . Combine ( EnsurePipeDirectoryPath ( ) , pipeName ) ;
41
41
}
42
42
43
43
/// <summary>Throws an exception if the supplied handle does not represent a valid pipe.</summary>
@@ -228,31 +228,57 @@ public virtual PipeTransmissionMode ReadMode
228
228
229
229
private static string s_pipeDirectoryPath ;
230
230
231
- private static string GetPipeDirectoryPath ( )
231
+ private static string EnsurePipeDirectoryPath ( )
232
232
{
233
- string path = s_pipeDirectoryPath ;
234
- if ( path == null )
233
+ const string PipesFeatureName = "pipes" ;
234
+
235
+ // Ideally this would simply use PersistedFiles.GetTempFeatureDirectory(PipesFeatureName) and then
236
+ // Directory.CreateDirectory to ensure it exists. But this assembly doesn't reference System.IO.FileSystem.
237
+ // As such, we'd be calling GetTempFeatureDirectory, only to then need to parse it in order
238
+ // to create each of the individual directories as part of the path. We instead access the named portions
239
+ // of the path directly and do the building of the path and directory structure manually.
240
+
241
+ // First ensure we know what the full path should be, e.g. /tmp/.dotnet/corefx/pipes/
242
+ string fullPath = s_pipeDirectoryPath ;
243
+ string tempPath = null ;
244
+ if ( fullPath == null )
235
245
{
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 ( ) ;
246
+ tempPath = Path . GetTempPath ( ) ;
247
+ fullPath = Path . Combine ( tempPath , PersistedFiles . TopLevelHiddenDirectory , PersistedFiles . SecondLevelDirectory , PipesFeatureName ) ;
248
+ s_pipeDirectoryPath = fullPath ;
249
+ }
242
250
243
- path = Path . Combine ( path , PersistedFiles . TopLevelHiddenDirectory ) ;
244
- CreateDirectory ( path ) ;
251
+ // Then create the directory if it doesn't already exist. If we get any error back from stat,
252
+ // just proceed to build up the directory, failing in the CreateDirectory calls if there's some
253
+ // problem. Similarly, it's possible stat succeeds but the path is a file rather than directory; we'll
254
+ // call that success for now and let this fail later when the code tries to create a file in this "directory"
255
+ // (we don't want to overwrite/delete whatever that unknown file may be, and this is similar to other cases
256
+ // we can't control where the file system is manipulated concurrently with and separately from this code).
257
+ Interop . Sys . FileStatus ignored ;
258
+ bool pathExists = Interop . Sys . Stat ( fullPath , out ignored ) == 0 ;
259
+ if ( ! pathExists )
260
+ {
261
+ // We need to build up the directory manually. Ensure we have the temp directory in which
262
+ // we'll create the structure, e.g. /tmp/
263
+ if ( tempPath == null )
264
+ {
265
+ tempPath = Path . GetTempPath ( ) ;
266
+ }
267
+ Debug . Assert ( Interop . Sys . Stat ( tempPath , out ignored ) == 0 , "Path.GetTempPath() directory could not be accessed" ) ;
245
268
246
- path = Path . Combine ( path , PersistedFiles . SecondLevelDirectory ) ;
247
- CreateDirectory ( path ) ;
269
+ // Create /tmp/.dotnet/ if it doesn't exist.
270
+ string partialPath = Path . Combine ( tempPath , PersistedFiles . TopLevelHiddenDirectory ) ;
271
+ CreateDirectory ( partialPath ) ;
248
272
249
- const string PipesFeatureName = "pipes" ;
250
- path = Path . Combine ( path , PipesFeatureName ) ;
251
- CreateDirectory ( path ) ;
273
+ // Create /tmp/.dotnet/corefx/ if it doesn't exist
274
+ partialPath = Path . Combine ( partialPath , PersistedFiles . SecondLevelDirectory ) ;
275
+ CreateDirectory ( partialPath ) ;
252
276
253
- s_pipeDirectoryPath = path ;
277
+ // Create /tmp/.dotnet/corefx/pipes/ if it doesn't exist
278
+ CreateDirectory ( fullPath ) ;
254
279
}
255
- return path ;
280
+
281
+ return fullPath ;
256
282
}
257
283
258
284
private static void CreateDirectory ( string directoryPath )
0 commit comments