Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ public ProcessModuleCollection(System.Diagnostics.ProcessModule[] processModules
public void CopyTo(System.Diagnostics.ProcessModule[] array, int index) { }
public int IndexOf(System.Diagnostics.ProcessModule module) { throw null; }
}
public sealed partial class ProcessExitStatus
{
public ProcessExitStatus(int exitCode, bool canceled, System.Runtime.InteropServices.PosixSignal? signal = null) { throw null; }
public bool Canceled { get { throw null; } }
public int ExitCode { get { throw null; } }
public System.Runtime.InteropServices.PosixSignal? Signal { get { throw null; } }
}
public enum ProcessPriorityClass
{
Normal = 32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<Compile Include="System\Diagnostics\AsyncStreamReader.cs" />
<Compile Include="System\Diagnostics\DataReceivedEventArgs.cs" />
<Compile Include="System\Diagnostics\Process.cs" />
<Compile Include="System\Diagnostics\ProcessExitStatus.cs" />
<Compile Include="System\Diagnostics\ProcessInfo.cs" />
<Compile Include="System\Diagnostics\ProcessManager.cs" />
<Compile Include="System\Diagnostics\ProcessModule.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

namespace System.Diagnostics
{
/// <summary>
/// Represents the exit status of a process.
/// </summary>
public sealed class ProcessExitStatus
{
/// <summary>
/// Initializes a new instance of the <see cref="ProcessExitStatus"/> class.
/// </summary>
/// <param name="exitCode">The exit code of the process.</param>
/// <param name="canceled">A value indicating whether the process has been terminated due to timeout or cancellation.</param>
/// <param name="signal">On Unix, the POSIX signal that terminated the process, or null if the process exited normally.</param>
public ProcessExitStatus(int exitCode, bool canceled, PosixSignal? signal = null)
{
ExitCode = exitCode;
Canceled = canceled;
Signal = signal;
}

/// <summary>
/// Gets the exit code of the process.
/// </summary>
/// <remarks>
/// <para>
/// If the process was terminated by a signal on Unix, this is 128 + the signal number.
/// Use <see cref="Signal"/> to get the actual signal.
/// </para>
/// </remarks>
public int ExitCode { get; }

/// <summary>
/// Gets the POSIX signal that terminated the process on Unix, or <see langword="null" /> if the process was not terminated by a signal.
/// </summary>
/// <remarks>
/// <para>
/// On Unix, a process can be terminated by a signal (e.g., SIGKILL, SIGTERM). When this happens,
/// the kernel reports "terminated by signal X" rather than an exit code. This property captures
/// that signal. When the process exits normally on Unix, or on Windows where signals do not exist,
/// this property is <see langword="null" />.
/// </para>
/// </remarks>
public PosixSignal? Signal { get; }

/// <summary>
/// Gets a value indicating whether the process has been terminated due to timeout or cancellation.
/// </summary>
public bool Canceled { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using Xunit;

namespace System.Diagnostics.Tests
{
public class ProcessExitStatusTests
{
[Fact]
public void Constructor_WithExitCodeOnly_SetsPropertiesCorrectly()
{
ProcessExitStatus status = new ProcessExitStatus(0, false);

Assert.Equal(0, status.ExitCode);
Assert.False(status.Canceled);
Assert.Null(status.Signal);
}

[Fact]
public void Constructor_WithNonZeroExitCode_SetsPropertiesCorrectly()
{
ProcessExitStatus status = new ProcessExitStatus(42, false);

Assert.Equal(42, status.ExitCode);
Assert.False(status.Canceled);
Assert.Null(status.Signal);
}

[Fact]
public void Constructor_WithCanceled_SetsPropertiesCorrectly()
{
ProcessExitStatus status = new ProcessExitStatus(1, true);

Assert.Equal(1, status.ExitCode);
Assert.True(status.Canceled);
Assert.Null(status.Signal);
}

[Fact]
public void Constructor_WithSignal_SetsPropertiesCorrectly()
{
ProcessExitStatus status = new ProcessExitStatus(137, false, PosixSignal.SIGTERM);

Assert.Equal(137, status.ExitCode);
Assert.False(status.Canceled);
Assert.Equal(PosixSignal.SIGTERM, status.Signal);
}

[Fact]
public void Constructor_WithAllParameters_SetsPropertiesCorrectly()
{
ProcessExitStatus status = new ProcessExitStatus(130, true, PosixSignal.SIGINT);

Assert.Equal(130, status.ExitCode);
Assert.True(status.Canceled);
Assert.Equal(PosixSignal.SIGINT, status.Signal);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<Compile Include="Helpers.cs" />
<Compile Include="Interop.cs" />
<Compile Include="ProcessCollectionTests.cs" />
<Compile Include="ProcessExitStatusTests.cs" />
<Compile Include="ProcessModuleTests.cs" />
<Compile Include="ProcessStandardConsoleTests.cs" />
<Compile Include="ProcessStartInfoTests.cs" />
Expand Down