-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
OpenHandle.cs
99 lines (89 loc) · 3.9 KB
/
OpenHandle.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Win32.SafeHandles;
using Xunit;
namespace System.IO.Tests
{
// to avoid a lot of code duplication, we reuse FileStream tests
public class File_OpenHandle : FileStream_ctor_options
{
protected override string GetExpectedParamName(string paramName) => paramName;
protected override FileStream CreateFileStream(string path, FileMode mode) =>
CreateFileStream(path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite);
protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access)
{
SafeFileHandle handle = File.OpenHandle(path, mode, access);
try
{
return new FileStream(handle, access);
}
catch
{
handle.Dispose();
throw;
}
}
protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
{
SafeFileHandle handle = File.OpenHandle(path, mode, access, share, options);
try
{
return new FileStream(handle, access, bufferSize, (options & FileOptions.Asynchronous) != 0);
}
catch
{
handle.Dispose();
throw;
}
}
protected override FileStream CreateFileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, long preallocationSize)
{
SafeFileHandle handle = File.OpenHandle(path, mode, access, share, options, preallocationSize);
try
{
return new FileStream(handle, access, bufferSize, (options & FileOptions.Asynchronous) != 0);
}
catch
{
handle.Dispose();
throw;
}
}
[ActiveIssue("https://github.com/dotnet/runtime/issues/53432")]
[Theory, MemberData(nameof(StreamSpecifiers))]
public override void FileModeAppendExisting(string streamSpecifier)
{
_ = streamSpecifier; // to keep the xUnit analyser happy
}
[Theory]
[InlineData(FileOptions.None)]
[InlineData(FileOptions.Asynchronous)]
public void SafeFileHandle_IsAsync_ReturnsCorrectInformation(FileOptions options)
{
using (var handle = File.OpenHandle(GetTestFilePath(), FileMode.Create, FileAccess.Write, options: options))
{
Assert.Equal((options & FileOptions.Asynchronous) != 0, handle.IsAsync);
// the following code exercises the code path where we don't know FileOptions used for opening the handle
// and instead we ask the OS about it
if (OperatingSystem.IsWindows()) // async file handles are a Windows concept
{
SafeFileHandle createdFromIntPtr = new SafeFileHandle(handle.DangerousGetHandle(), ownsHandle: false);
Assert.Equal((options & FileOptions.Asynchronous) != 0, createdFromIntPtr.IsAsync);
}
}
}
[Theory]
[InlineData(FileOptions.DeleteOnClose)]
[InlineData(FileOptions.DeleteOnClose | FileOptions.Asynchronous)]
public void DeleteOnClose_FileDeletedAfterSafeHandleDispose(FileOptions options)
{
string path = GetTestFilePath();
Assert.False(File.Exists(path));
using (SafeFileHandle sfh = File.OpenHandle(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, options))
{
Assert.True(File.Exists(path));
}
Assert.False(File.Exists(path));
}
}
}