Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,46 +23,37 @@ internal static partial class Sys
// This is 'raw' sysctl call, only wrapped to allocate memory if needed
// caller always needs to free returned buffer using Marshal.FreeHGlobal()

public static unsafe int Sysctl(Span<int> name, ref byte* value, ref int len)
internal static unsafe void Sysctl(Span<int> name, ref byte* value, ref int len)
{
fixed (int * ptr = &MemoryMarshal.GetReference(name))
fixed (int* ptr = &MemoryMarshal.GetReference(name))
{
return Sysctl(ptr, name.Length, ref value, ref len);
Sysctl(ptr, name.Length, ref value, ref len);
}
}

public static unsafe int Sysctl(int* name, int name_len, ref byte* value, ref int len)
private static unsafe void Sysctl(int* name, int name_len, ref byte* value, ref int len)
{
IntPtr bytesLength = (IntPtr)len;
byte * pBuffer = value;
value = null;
int ret=-1;
int ret = -1;

if (value == null && len == 0)
{
// do one try to see how much data we need
ret = Sysctl(name, name_len, pBuffer, &bytesLength);
ret = Sysctl(name, name_len, value, &bytesLength);
if (ret != 0)
{
throw new InvalidOperationException(SR.Format(SR.InvalidSysctl, *name, Marshal.GetLastWin32Error()));
}
pBuffer = (byte*)Marshal.AllocHGlobal((int)bytesLength);
value = (byte*)Marshal.AllocHGlobal((int)bytesLength);
}
ret = Sysctl(name, name_len, pBuffer, &bytesLength);

ret = Sysctl(name, name_len, value, &bytesLength);
if (ret != 0)
{
if (value == null && len == 0)
{
// This is case we allocated memory for caller
Marshal.FreeHGlobal((IntPtr)pBuffer);
}
throw new InvalidOperationException(SR.Format(SR.InvalidSysctl, *name, Marshal.GetLastWin32Error()));
}

value = pBuffer;
len = (int)bytesLength;

return ret;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal static partial class Process
private const int CTL_KERN = 1;
private const int KERN_PROC = 14;
private const int KERN_PROC_PROC = 8;
private const int KERN_PROC_PID = 1;
private const int KERN_PROC_PID = 1;
private const int KERN_PROC_INC_THREAD = 16;

// From sys/_sigset.h
Expand Down Expand Up @@ -144,13 +144,13 @@ public unsafe struct kinfo_proc
private byte ki_rqindex; /* Run queue index */
private byte ki_oncpu_old; /* Which cpu we are on (legacy) */
private byte ki_lastcpu_old; /* Last cpu we were on (legacy) */
public fixed byte ki_tdname[TDNAMLEN+1]; /* thread name */
private fixed byte ki_wmesg[WMESGLEN+1]; /* wchan message */
private fixed byte ki_login[LOGNAMELEN+1]; /* setlogin name */
private fixed byte ki_lockname[LOCKNAMELEN+1]; /* lock name */
public fixed byte ki_comm[COMMLEN+1]; /* command name */
private fixed byte ki_emul[KI_EMULNAMELEN+1]; /* emulation name */
private fixed byte ki_loginclass[LOGINCLASSLEN+1]; /* login class */
public fixed byte ki_tdname[TDNAMLEN + 1]; /* thread name */
private fixed byte ki_wmesg[WMESGLEN + 1]; /* wchan message */
private fixed byte ki_login[LOGNAMELEN + 1]; /* setlogin name */
private fixed byte ki_lockname[LOCKNAMELEN + 1]; /* lock name */
public fixed byte ki_comm[COMMLEN + 1]; /* command name */
private fixed byte ki_emul[KI_EMULNAMELEN + 1]; /* emulation name */
private fixed byte ki_loginclass[LOGINCLASSLEN + 1]; /* login class */
private fixed byte ki_sparestrings[50]; /* spare string space */
private fixed int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */
private int ki_oncpu; /* Which cpu we are on */
Expand Down Expand Up @@ -189,7 +189,6 @@ public unsafe struct kinfo_proc
int bytesLength = 0;
byte* pBuffer = null;
kinfo_proc* kinfo = null;
int ret;

count = -1;

Expand All @@ -210,11 +209,7 @@ public unsafe struct kinfo_proc

try
{
ret = Interop.Sys.Sysctl(sysctlName, ref pBuffer, ref bytesLength);
if (ret != 0 ) {
throw new ArgumentOutOfRangeException(nameof(pid));
}

Interop.Sys.Sysctl(sysctlName, ref pBuffer, ref bytesLength);
kinfo = (kinfo_proc*)pBuffer;
if (kinfo->ki_structsize != sizeof(kinfo_proc))
{
Expand All @@ -224,10 +219,12 @@ public unsafe struct kinfo_proc

count = (int)bytesLength / sizeof(kinfo_proc);
}
catch
finally
{
Marshal.FreeHGlobal((IntPtr)pBuffer);
throw;
if (pBuffer != null)
{
Marshal.FreeHGlobal((IntPtr)pBuffer);
}
}

return kinfo;
Expand Down
25 changes: 14 additions & 11 deletions src/libraries/Common/src/Interop/FreeBSD/Interop.Process.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal static unsafe int[] ListAllPids()
if (list[i].ki_ppid == 0)
{
// skip kernel threads
numProcesses-=1;
numProcesses -= 1;
}
else
{
Expand All @@ -76,22 +76,25 @@ internal static unsafe int[] ListAllPids()
/// <param name="pid">The PID of the process</param>
public static unsafe string? GetProcPath(int pid)
{
Span<int> sysctlName = stackalloc int[4];
Span<int> sysctlName = stackalloc int[] { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid };
byte* pBuffer = null;
int bytesLength = 0;

sysctlName[0] = CTL_KERN;
sysctlName[1] = KERN_PROC;
sysctlName[2] = KERN_PROC_PATHNAME;
sysctlName[3] = pid;
try
{
Interop.Sys.Sysctl(sysctlName, ref pBuffer, ref bytesLength);
string path = System.Text.Encoding.UTF8.GetString(pBuffer, (int)bytesLength - 1);
Marshal.FreeHGlobal((IntPtr)pBuffer);

if (Interop.Sys.Sysctl(sysctlName, ref pBuffer, ref bytesLength) != 0)
return path;
}
finally
{
return null;
if (pBuffer != null)
{
Marshal.FreeHGlobal((IntPtr)pBuffer);
}
}

// TODO Fix freeing of pBuffer: https://github.com/dotnet/runtime/issues/43418
return System.Text.Encoding.UTF8.GetString(pBuffer, (int)bytesLength-1);
}

/// <summary>
Expand Down