Estructura sigaction
La estructura sigaction
en C es una estructura que se utiliza para especificar el manejo de una señal en un programa. Esta estructura se utiliza en la función sigaction
para registrar un manejador de señal personalizado.
Es importante destacar que el uso de la estructura sigaction
es opcional, ya que también se pueden manejar señales usando funciones simples, como signal()
, que solo requieren un puntero a función y un número de señal. Sin embargo, la estructura sigaction
ofrece un mayor control y flexibil
La estructura sigaction
tiene la siguiente forma:
sa_handler
:
sa_handler
:sa_handler
es una variable de la estructura struct sigaction
que se utiliza para especificar una función que será llamada cuando se reciba una señal determinada. Esta función se conoce como manejador de señales y su objetivo es realizar una acción específica en respuesta a la recepción de una señal.
La cabecera de la función que se especifica como manejador de señales es la siguiente:
Donde signum
es el número de la señal que se ha recibido.
Ejemplo:
En este ejemplo, se define una función manejador_SIGINT
que se utilizará como manejador de señales para la señal SIGINT
. Luego, se establece la acción para SIGINT
usando sigaction
y especificando manejador_SIGINT
como sa_handler
.
sa_sigaction
sa_sigaction
sa_sigaction
es un puntero a una función que actúa como manejador de señales. Es una variable en la estructura sigaction
que describe la acción a tomar cuando se reciba una señal específica.
La cabecera de la función apunta a una función con el siguiente prototipo:
sa_sigaction
toma tres argumentos:
signum
: es el número de señal que ha sido recibida.info
: es un puntero a una estructurasiginfo_t
que proporciona información adicional sobre la señal.context
: es un puntero a una estructura que contiene información sobre el contexto en el momento en quese recibió la señal.
Aquí hay un ejemplo de código que muestra cómo utilizar sa_sigaction
para manejar la señal SIGINT
:
En este ejemplo, la función sigint_handler
se establece como el manejador de señales para la señal SIGINT
usando la estructura sigaction
sa
. La bandera sa_flags
se establece en SA_SIGINFO
para que la función sa_sigaction
reciba información adicional sobre la señal. Finalmente, se establece la acción para SIGINT
utilizando la función sigaction
. Si se presiona Ctrl + C mientras el programa está en ejecución, se generará la señal SIGINT, que será manejada por sigint_handler
y un mensaje "Recibí la señal 2" será impreso.
sa_mask
sa_mask
La máscara de señales sa_mask
en la estructura sigaction
se utiliza para especificar qué señales deben bloquearse durante la ejecución del manejador de señales. Es decir, cuando se recibe una señal y se activa el manejador de señales, se pueden bloquear otras señales específicas para evitar que se manejen simultáneamente.
El manejo de sa_mask
se realiza mediante las funciones sigemptyset
, sigfillset
, sigaddset
, sigdelset
y sigismember
. Estas funciones se utilizan para manipular la máscara de señales en la estructura sigaction
.
sigemptyset
se utiliza para inicializar una máscara de señales como un conjunto vacío.sigfillset
se utiliza para inicializar una máscara de señales como un conjunto lleno, lo que significa que todas las señales están incluidas en la máscara.sigaddset
se utiliza para agregar una señal a una máscara de señales existente.sigdelset
se utiliza para eliminar una señal de una máscara de señales existente.sigismember
se utiliza para determinar si una señal está incluida en una máscara de señales.
Aquí hay un ejemplo de código en C que ilustra el uso de la máscara de señales:
En este ejemplo, se establece un manejador de señal para la señal SIGUSR1
mediante la función sigaction
. La estructura sigaction
incluye el manejador de señal en el campo sa_handler
, y una máscara de señales que incluye la señal SIGINT
en el campo sa_mask
.
El código ejecuta un bucle infinito que solo imprime "Esperando..." y luego se bloquea por un segundo usando la función sleep
. Si se presiona Ctrl+Z
mientras el código está en el bucle, se enviará la señal SIGUSR1
al proceso, interrumpiendo la función sleep
y activando el manejador de señales.
El manejador de señales imprime un mensaje y luego se bloquea por tres segundos usando la función sleep
. Durante este tiempo, la señal SIGINT
está bloqueada, por lo que si se presiona Ctrl+C
, no se enviará la señal al proceso.
Este ejemplo ilustra cómo la máscara de señales sa_mask
se puede usar para controlar qué señales deben bl
sa_flags
sa_flags
Este es un conjunto de banderas que controlan el comportamiento del manejador de señal. Algunas banderas comunes incluyen:
SA_NOCLDSTOP
: Esta bandera indica que no se debe enviar una señalSIGCHLD
cuando un proceso hijo se detiene o termina.SA_SIGINFO
: Esta bandera indica que se debe utilizarsa_sigaction
en lugar desa_handler
para manejar la señal.SA_RESTART
: Esta bandera indica que las operaciones bloqueadas por la señal deben ser automáticamente restauradas después de que el manejador de señal haya finalizado.
Aquí hay un ejemplo simple de código en C que demuestra el uso de la bandera SA_RESTART
:
En este ejemplo, se establece un manejador de señal para la señal SIGINT
(la señal generada por Ctrl+C
) mediante la función sigaction
. La estructura sigaction
incluye el manejador de señal en el campo sa_handler
, la máscara de señales vacía en el campo sa_mask
, y la bandera SA_RESTART
en el campo sa_flags
.
El código ejecuta un bucle infinito que solo imprime "Esperando..." y luego se bloquea por un segundo usando la función sleep
. Si se presiona Ctrl+C
mientras el código está en el bucle, se enviará la señal SIGINT
al proceso, interrumpiendo la función sleep
.
Sin la bandera SA_RESTART
, la función sleep
no sería reanudada después de manejar la señal, y el proceso simplemente volvería al inicio del bucle. Sin embargo, con la bandera SA_RESTART
, la función sleep
será automáticamente reanudada después de manejar la señal, permitiendo que el proceso continúe su ejecución sin interrupciones.
Este ejemplo muestra cómo la bandera SA_RESTART
puede simplificar el código y asegurar un comportamiento más consistente en el proceso.
Last updated