Ignore los procesos de señales de Linux, como SIGTERM, utilizando sigaction desde una aplicación .NET.
No estoy realmente familiarizado con la interoperabilidad de .NET. Estoy tratando de implementar la ignorancia de las señales de proceso de Linux en .NET, utilizando una llamada a sigaction
.
Las definiciones de interoperabilidad que he podido encontrar son las siguientes:
public delegate void __sighandler_t(int signal);
public delegate void sa_restorer();
[StructLayout(LayoutKind.Sequential)]
public struct __sigset_t
{
ulong[] __val; // 1024 / (8 * 8)
}
[StructLayout(LayoutKind.Sequential)]
public struct sigaction
{
public __sighandler_t sa_handler;
/* Conjunto adicional de señales que serán bloqueadas. */
public __sigset_t sa_mask;
/* Banderas especiales. */
public int sa_flags;
/* Restaurador de manejador. */
public sa_restorer sa_restorer;
};
Al intentar escribir una implementación de ejemplo para ignorar un SIGTERM, intento lo siguiente:
var returnCode = NetlinkDemo.sigaction(15, IntPtr.Zero, IntPtr.Zero);
System.Console.WriteLine($"sigaction 1 retornó [{returnCode}]");
sigaction act = new sigaction();
act.sa_flags = 0;
act.sa_handler = HandleSignal;
IntPtr actPtr = Marshal.AllocHGlobal(Marshal.SizeOf<sigaction>());
Marshal.StructureToPtr<sigaction>(act, actPtr, true);
returnCode = NetlinkDemo.sigaction(15, actPtr, IntPtr.Zero);
System.Console.WriteLine($"sigaction 2 retornó [{returnCode}]");
private static void HandleSignal(int signal)
{
System.Console.WriteLine($"Manejando señal [{signal}]");
}
Esto genera un error en Marshal.AllocHGlobal
: System.ArgumentException: El tipo 'myProject.sigaction' no se puede convertir en una estructura no administrada; no se puede calcular ningún tamaño u offset significativo
.
¿Mis definiciones de interoperabilidad están equivocadas?
¿Estoy haciendo algo que no tiene sentido?
davy.ai
Parece que el problema está en el delegado
sa_restorer
en la estructurasigaction
. Este delegado no tiene equivalente en .NET y no se puede marshalear, lo que está causando laArgumentException
que estás viendo.Una posible solución es eliminar el campo
sa_restorer
de la estructurasigaction
y establecersa_flags
enSA_SIGINFO
en su lugar. Esto te permitirá usar el delegadosa_handler
para manejar la señal y pasar información adicional a través de sus parámetros.Aquí tienes una versión actualizada de la estructura
sigaction
con los cambios:“`C#
[StructLayout(LayoutKind.Sequential)]
public struct sigaction
{
public __sighandler_t sa_handler;
/* Conjunto adicional de señales para bloquear. /
public __sigset_t sa_mask;
/ Banderas especiales. */
public int sa_flags;
}
Ten en cuenta que el delegado
HandleSignal
ahora toma tres parámetros:signal
para el número de la señal,siginfo
para información adicional pasada al manejador de señales ycontext
para el contexto del proceso cuando se generó la señal. En este caso, estamos ignorando la señal, por lo que no necesitamos utilizar ninguno de estos parámetros.Además, en lugar de utilizar el método
NetlinkDemo.sigaction
, he asumido que ya has definido el métodosigaction
utilizandoDllImport
con los parámetros adecuados.