es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está en el delegado sa_restorer en la estructura sigaction. Este delegado no tiene equivalente en .NET y no se puede marshalear, lo que está causando la ArgumentException que estás viendo.

    Una posible solución es eliminar el campo sa_restorer de la estructura sigaction y establecer sa_flags en SA_SIGINFO en su lugar. Esto te permitirá usar el delegado sa_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;
    }


    Y la implementación modificada para ignorar SIGTERM: ```C# var act = new sigaction(); act.sa_flags = SA_SIGINFO; act.sa_handler = HandleSignal; IntPtr actPtr = Marshal.AllocHGlobal(Marshal.SizeOf<sigaction>()); Marshal.StructureToPtr(act, actPtr, false); var returnCode = sigaction(15, actPtr, IntPtr.Zero); Console.WriteLine($"sigaction retornó [{returnCode}]"); private static void HandleSignal(int signal, siginfo_t siginfo, IntPtr context) { Console.WriteLine($"Ignorando la señal [{signal}]"); }

    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 y context 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étodo sigaction utilizando DllImport con los parámetros adecuados.

Comments are closed.