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

Commit 35f6a21

Browse files
committed
Merge pull request #2283 from Priya91/addlib
Fix bugs in OSX on process type implementations.
2 parents eb71264 + 84b08b7 commit 35f6a21

File tree

4 files changed

+126
-30
lines changed

4 files changed

+126
-30
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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+
using System.Runtime.InteropServices;
5+
6+
using pid_t = System.Int32;
7+
8+
internal static partial class Interop
9+
{
10+
internal static partial class libc
11+
{
12+
[DllImport(Libraries.Libc)]
13+
internal static extern pid_t getsid(pid_t pid);
14+
}
15+
}

src/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@
261261
<Compile Include="$(CommonPath)\Interop\Unix\libcoreclr\Interop.ForkAndExecProcess.cs">
262262
<Link>Common\Interop\Unix\Interop.ForkAndExecProcess.cs</Link>
263263
</Compile>
264+
<Compile Include="$(CommonPath)\Interop\Unix\libc\Interop.getsid.cs">
265+
<Link>Common\Interop\Unix\Interop.getsid.cs</Link>
266+
</Compile>
264267
<Compile Include="$(CommonPath)\Interop\Unix\libc\Interop.ResourceLimits.cs">
265268
<Link>Common\Interop\Unix\Interop.ResourceLimits.cs</Link>
266269
</Compile>
@@ -312,4 +315,4 @@
312315
<None Include="project.json" />
313316
</ItemGroup>
314317
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
315-
</Project>
318+
</Project>

src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.OSX.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ private static ProcessInfo CreateProcessInfo(int pid)
3939
// Set the values we have; all the other values don't have meaning or don't exist on OSX
4040
Interop.libproc.proc_taskallinfo temp = info.Value;
4141
unsafe { procInfo.ProcessName = Marshal.PtrToStringAnsi(new IntPtr(temp.pbsd.pbi_comm)); }
42-
procInfo.BasePriority = temp.ptinfo.pti_priority;
42+
procInfo.BasePriority = temp.pbsd.pbi_nice;
4343
procInfo.HandleCount = Interop.libproc.GetFileDescriptorCountForPid(pid);
4444
procInfo.VirtualBytes = (long)temp.ptinfo.pti_virtual_size;
4545
procInfo.WorkingSet = (long)temp.ptinfo.pti_resident_size;
4646
}
4747

48+
// Get the sessionId for the given pid, getsid returns -1 on error
49+
int sessionId = Interop.libc.getsid(pid);
50+
if (sessionId != -1)
51+
procInfo.SessionId = sessionId;
52+
4853
// Create a threadinfo for each thread in the process
4954
List<KeyValuePair<ulong, Interop.libproc.proc_threadinfo?>> lstThreads = Interop.libproc.GetAllThreadsInProcess(pid);
5055
foreach (KeyValuePair<ulong, Interop.libproc.proc_threadinfo?> t in lstThreads)

src/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests/ProcessTest.cs

Lines changed: 101 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using Microsoft.Win32.SafeHandles;
45
using System.Collections.Generic;
56
using System.IO;
67
using System.IO.Pipes;
@@ -13,7 +14,7 @@ namespace System.Diagnostics.ProcessTests
1314
{
1415
public partial class ProcessTest : IDisposable
1516
{
16-
private const int WaitInMS = 100 * 1000;
17+
private const int WaitInMS = 100 * 1000;
1718
private const string CoreRunName = "corerun";
1819
private const string TestExeName = "System.Diagnostics.Process.TestConsoleApp.exe";
1920
private const int SuccessExitCode = 100;
@@ -51,8 +52,8 @@ Process CreateProcess(string optionalArgument = ""/*String.Empty is not a consta
5152
_processes.Add(p);
5253

5354
p.StartInfo.FileName = CoreRunName;
54-
p.StartInfo.Arguments = string.IsNullOrWhiteSpace(optionalArgument) ?
55-
TestExeName :
55+
p.StartInfo.Arguments = string.IsNullOrWhiteSpace(optionalArgument) ?
56+
TestExeName :
5657
TestExeName + " " + optionalArgument;
5758

5859
// Profilers / code coverage tools doing coverage of the test process set environment
@@ -79,25 +80,45 @@ public void SetAndCheckBasePriority(ProcessPriorityClass exPriorityClass, int pr
7980
Assert.Equal(priority, _process.BasePriority);
8081
}
8182

82-
[Fact]
83-
public void Process_BasePriority()
83+
[Fact, PlatformSpecific(PlatformID.Windows)]
84+
public void Process_BasePriorityWindows()
8485
{
8586
ProcessPriorityClass originalPriority = _process.PriorityClass;
8687
Assert.Equal(ProcessPriorityClass.Normal, originalPriority);
8788

88-
if (global::Interop.IsWindows)
89+
try
8990
{
90-
try
91-
{
92-
//SetAndCheckBasePriority(ProcessPriorityClass.RealTime, 24);
93-
SetAndCheckBasePriority(ProcessPriorityClass.High, 13);
94-
SetAndCheckBasePriority(ProcessPriorityClass.Idle, 4);
95-
SetAndCheckBasePriority(ProcessPriorityClass.Normal, 8);
96-
}
97-
finally
98-
{
99-
_process.PriorityClass = originalPriority;
100-
}
91+
// We are not checking for RealTime case here, as RealTime priority process can
92+
// preempt the threads of all other processes, including operating system processes
93+
// performing important tasks, which may cause the machine to be unresponsive.
94+
95+
//SetAndCheckBasePriority(ProcessPriorityClass.RealTime, 24);
96+
97+
SetAndCheckBasePriority(ProcessPriorityClass.High, 13);
98+
SetAndCheckBasePriority(ProcessPriorityClass.Idle, 4);
99+
SetAndCheckBasePriority(ProcessPriorityClass.Normal, 8);
100+
}
101+
finally
102+
{
103+
_process.PriorityClass = originalPriority;
104+
}
105+
}
106+
107+
[Fact, PlatformSpecific(PlatformID.AnyUnix), OuterLoop] // This test requires admin elevation on Unix
108+
public void Process_BasePriorityUnix()
109+
{
110+
ProcessPriorityClass originalPriority = _process.PriorityClass;
111+
Assert.Equal(ProcessPriorityClass.Normal, originalPriority);
112+
113+
try
114+
{
115+
SetAndCheckBasePriority(ProcessPriorityClass.High, -11);
116+
SetAndCheckBasePriority(ProcessPriorityClass.Idle, 19);
117+
SetAndCheckBasePriority(ProcessPriorityClass.Normal, 0);
118+
}
119+
finally
120+
{
121+
_process.PriorityClass = originalPriority;
101122
}
102123
}
103124

@@ -184,10 +205,17 @@ public void Process_ExitTime()
184205

185206

186207
[Fact]
187-
[PlatformSpecific(PlatformID.Windows)]
188-
public void Process_GetHandle()
208+
public void Process_Id()
189209
{
190-
Assert.Equal(_process.Id, Interop.GetProcessId(_process.SafeHandle));
210+
if (global::Interop.IsWindows)
211+
{
212+
Assert.Equal(_process.Id, Interop.GetProcessId(_process.SafeHandle));
213+
}
214+
else
215+
{
216+
IEnumerable<int> testProcessIds = Process.GetProcessesByName(CoreRunName).Select(p => p.Id);
217+
Assert.Contains(_process.Id, testProcessIds);
218+
}
191219
}
192220

193221
[Fact]
@@ -225,7 +253,6 @@ public void Process_MachineName()
225253
}
226254

227255
[Fact]
228-
[ActiveIssue(1896, PlatformID.Windows)]
229256
public void Process_MainModule()
230257
{
231258
// Get MainModule property from a Process object
@@ -246,7 +273,7 @@ public void Process_MainModule()
246273
{
247274
foreach (ProcessModule pModule in _process.Modules)
248275
{
249-
if (String.Equals(Path.GetFileNameWithoutExtension(mainModule.ModuleName), CoreRunName, StringComparison.OrdinalIgnoreCase))
276+
if (String.Equals(Path.GetFileNameWithoutExtension(pModule.ModuleName), CoreRunName, StringComparison.OrdinalIgnoreCase))
250277
{
251278
foundMainModule = true;
252279
break;
@@ -443,7 +470,26 @@ public void Process_PriorityBoostEnabled()
443470
}
444471
}
445472

446-
public void Process_PriorityClass()
473+
[Fact, PlatformSpecific(PlatformID.AnyUnix), OuterLoop] // This test requires admin elevation on Unix
474+
public void Process_PriorityClassUnix()
475+
{
476+
ProcessPriorityClass priorityClass = _process.PriorityClass;
477+
try
478+
{
479+
_process.PriorityClass = ProcessPriorityClass.High;
480+
Assert.Equal(_process.PriorityClass, ProcessPriorityClass.High);
481+
482+
_process.PriorityClass = ProcessPriorityClass.Normal;
483+
Assert.Equal(_process.PriorityClass, ProcessPriorityClass.Normal);
484+
}
485+
finally
486+
{
487+
_process.PriorityClass = priorityClass;
488+
}
489+
}
490+
491+
[Fact, PlatformSpecific(PlatformID.Windows)]
492+
public void Process_PriorityClassWindows()
447493
{
448494
ProcessPriorityClass priorityClass = _process.PriorityClass;
449495
try
@@ -473,13 +519,40 @@ public void ProcessProcessName()
473519
Assert.Equal(_process.ProcessName, CoreRunName, StringComparer.OrdinalIgnoreCase);
474520
}
475521

522+
[Fact]
523+
public void Process_SafeHandle()
524+
{
525+
Assert.False(_process.SafeHandle.IsInvalid);
526+
}
527+
528+
[Fact]
529+
public void Process_SessionId()
530+
{
531+
uint sessionId;
532+
if (global::Interop.IsWindows)
533+
{
534+
ProcessIdToSessionId((uint)_process.Id, out sessionId);
535+
}
536+
else
537+
{
538+
sessionId = (uint)getsid(_process.Id);
539+
}
540+
541+
Assert.Equal(sessionId, (uint)_process.SessionId);
542+
}
476543

477544
[DllImport("api-ms-win-core-processthreads-l1-1-0.dll")]
478545
internal static extern int GetCurrentProcessId();
479546

480547
[DllImport("libc")]
481548
internal static extern int getpid();
482549

550+
[DllImport("libc")]
551+
internal static extern int getsid(int pid);
552+
553+
[DllImport("api-ms-win-core-processthreads-l1-1-2.dll")]
554+
internal static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId);
555+
483556
[Fact]
484557
public void Process_GetCurrentProcess()
485558
{
@@ -501,14 +574,14 @@ public void Process_GetProcesses()
501574
Process currentProcess = Process.GetCurrentProcess();
502575

503576
var foundCurrentProcess = (from p in Process.GetProcesses()
504-
where (p.Id == currentProcess.Id) && (p.ProcessName.Equals(currentProcess.ProcessName))
505-
select p).Any();
577+
where (p.Id == currentProcess.Id) && (p.ProcessName.Equals(currentProcess.ProcessName))
578+
select p).Any();
506579

507580
Assert.True(foundCurrentProcess, "Process_GetProcesses001 failed");
508581

509582
foundCurrentProcess = (from p in Process.GetProcesses(currentProcess.MachineName)
510-
where (p.Id == currentProcess.Id) && (p.ProcessName.Equals(currentProcess.ProcessName))
511-
select p).Any();
583+
where (p.Id == currentProcess.Id) && (p.ProcessName.Equals(currentProcess.ProcessName))
584+
select p).Any();
512585
Assert.True(foundCurrentProcess, "Process_GetProcesses002 failed");
513586
}
514587

@@ -765,7 +838,7 @@ public void Process_IPC()
765838
p.Start();
766839
outbound.DisposeLocalCopyOfClientHandle();
767840
inbound.DisposeLocalCopyOfClientHandle();
768-
841+
769842
for (byte i = 0; i < 10; i++)
770843
{
771844
outbound.WriteByte(i);

0 commit comments

Comments
 (0)