programando en linux gestión de procesos y señales realizado por: kepa bengoetxea...

63
Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea [email protected]

Upload: pedro-palma-medina

Post on 31-Jan-2016

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Programando en LinuxGestión de Procesos y

Señales

Realizado por: Kepa Bengoetxea

[email protected]

Page 2: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Referencias

Programación en Linux con ejemplos.-Kurt WallDescripción Funcional de los Sistemas Operativos.-Iñaki AlegriaUNIX.Programación Avanzada.-Manuel Márquez

Page 3: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Antes de empezar

Antes de empezar a programar en c, instalar: sudo apt-get install build-essential

Se instalarán los siguientes paquetes extras: dpkg-dev g++ g+

+-4.2 libc6-dev libstdc++6-4.2-dev libtimedate-perl linux-libc-

dev patch

Paquetes sugeridos: debian-keyring g++-multilib g++-4.2-

multilib gcc-4.2-doc libstdc++6-4.2-dbg glibc-doc manpages-

dev libstdc++6-4.2-doc diff-doc

Para instalar el man de los comandos de usuario del sistema POSIX: sudo apt-get install manpages-posix

Page 4: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Creación de procesos

Entorno de un proceso consiste en un conjunto de variables que se le pasan al proceso en el momento de su creación. El entorno esta formado por una tabla NOMBRE-VALOR que se incluye en la pila del proceso. Ejm:

PATH=/usr/bin/:/home/pepe/bin

HOME=/home/pepe

Servicios o llamadas a sistema que brinda UNIX para manipular y gestionar procesos.

Page 5: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Llamadas a Sistema Podemos agrupar los servicios en las siguientes categorías:

gestión de procesos:

Crear: fork Cambiar: familia exec (execl, execv, execle, execve,

execlp, execvp) Terminar: exit Esperar: wait,waitpid

identificación de proceso: getpid, getppid, getuid, geteuid, getgid, getegid

entorno de un proceso: las variables de entorno que se pasan a un proceso son accesibles a través de la variable externa environ y las funciones getenv y setenv

Page 6: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

Las llamadas a exec, son una familia de funciones con interfaz diferente pero funcionan de forma igual.

La funciones de tipo exec cargan un programa en la zona de memoria del proceso que las ejecuta, sobreescribiendo los segmentos del programa antiguo con los del nuevo.

El programa viejo es sustituido y nunca retornaremos a él.

Si exec devuelve el control al programa que la invoca, es porque no se ha ejecutado correctamente. Devolviendo -1.

Page 7: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

La declaración de la familia de funciones exec es la siguiente:

//l:lista de argumentos

int execl(char * path, char * arg0, ...,char * argn, (char *)0);

//v:vector de argumentos

int execv(char * path, char *argv[]);

//e:enviroment (variables de entorno)

int execle(char * path, char * arg0, .,char * argn, (char*)0, char * envp[]);

int execve(char * path, char * argv[], char * envp[]);

Page 8: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

La declaración de la familia de funciones exec es la siguiente:

//p:busca un fichero ejecutable si el nombre de fichero especificado no contiene un carácter de barra inclinada

int execlp (char * file, char * arg0, ..., char * argn,(char*)0);

int execvp (char * file, char * argv[])

char * file es un puntero que apunta a la ruta del programa que queremos ejecutar

char * argv[] es un array de punteros a char que contiene los parámetros que queremos pasar a dicho programa (como si lo hiciéramos desde la linea de comandos), siendo el primer parámetro el nombre del mismo programa, y el último NULL, con lo que decimos que no quedan más parámetros .

Page 9: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

Si el programa esta escrito en C: copy.c

int main(int argc, char * argv[])

Llamada: copy fic1 fic2

argc argv

3

f \01ci

f \02ci

c \0ypo

argv[0]=”copy”argv[1]=”fic1”argv[2]=”fic2”

Page 10: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

La declaración de la familia de funciones exec es la siguiente:

char * path es un puntero que apunta al path name (absoluto o relativo) de un fichero ejecutable

char * arg0, ...*argn son punteros a cadenas de caracteres y constituyen la lista de argumentos que se le pasa al nuevo programa.

(char *)0 es un puntero a NULL, indica final de argumentos.

char * envp[] es un puntero a un array de punteros a cadenas de caracteres que constituyen el entorno en el que se va ejecutar el nuevo programa. Termina con NULL.

Page 11: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

Exec en detalle:

Función de si aceptan rutas/nombre de fichero:

execl,execv,exele y execve: “/bin/ls” execlp,execvp:”ls” busca PATH sino tiene “/” en el nombre

Reciben los parámetros como:

una lista de argumentos separados por comas:

“/bin/cat”,”/etc/passwd”,”/etc/group”,NULL un vector: char *

argv[]={“/bin/cat”,”/etc/passwd”,”/etc/group”};

Page 12: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

Exec en detalle:

Entorno:

Execve y execle permiten crear un entorno especializado para el programa:

char *envp[]={”PATH=/bin:/usr/bin”,”USUARIO=Juan Perez”}

El resto recibe sus entornos de manera implícita a través de la variable environ, esta se puede manipular con las funciones que estan en <stdlib.h>:

int putenv(const char *string);

char *getenv(const char *name);

Page 13: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

Ejemplos:

execl(“/bin/cat”,“/bin/cat”,”/etc/passwd”,”/etc/group”,NULL);

char * argv[]={“/bin/cat”,”/etc/passwd”,”/etc/group”,NULL};

execv(“/bin/cat”,argv);

char *argv[] = { "ls", "-l", NULL };

char *envp[] = { "HOME=/home/euiti", "LOGNAME=euiti", NULL};

execve ("/bin/ls", argv, envp);

Page 14: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

#include <stdio.h>

#include <unistd.h> /*man fork,exec */

#include <sys/types.h> /*man 2 wait */

#include <sys/wait.h> /*man 2 wait */

int main() {

int pid,status;

pid=fork();

Page 15: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

if (pid == 0) { /* Proceso Hijo */

if (execl("esclavo","esclavo", "nombre", "-a", NULL) == -1) {

printf("Error al ejecutar execl\n");

exit(1);} }

else { /* Proceso Padre */

wait(&status);

printf("\nEl proceso hijo finalizo con el estado %d\n", status);

exit(0);}

}

Page 16: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

esclavo.c:

#include <stdio.h>

int main(int argc, char *argv[]) {

int i = 0;

for (i = 0; i < argc; i++) printf("\nArgumento [%d]: %s", i, argv[i]);

exit(0);}

gcc -o miexec.exe miexec.c

gcc -o esclavo esclavo.c

./miexec.exe

Page 17: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: exec

./miexec.exe

Argumento [0]: esclavo

Argumento [1]: nombre

Argumento [2]: -a

El proceso hijo finalizo con el estado 0

Page 18: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: fork

La uńica forma de crear un proceso en el sistema UNIX es mediante la llamada fork

El proceso que invoca se le llama proceso padre y el proceso creado es el hijo

fork crea un proceso hijo. El proceso hijo creado es una copia exacta del padre, excepto que recibe un valor diferente de la llamada fork. Devuelve 0 al proceso hijo y el PID del hijo al proceso padre y un valor -1 en caso de no poder crearse el proceso hijo.

Page 19: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: fork

Cuando llamamos a fork, el kernel realiza las siguientes operaciones:

Busca una entrada libre en la tabla de procesos y la reserva para el proceso hijo

Asigna un identificador de proceso para el proceso hijo, es invariante mientras viva, es la clave para controlarlo.

Se crea un nuevo proceso hijo con sus propias copias del texto del programa,datos y segmentos de pila del padre, incluyendo UIDs y GIDs reales y efectivos, archivos abiertos y segmentos de memoria compartida (no hereda las alarmas programadas por alarm, ni las señales pendientes)

Retorna al proceso padre el PID del proceso hijo, y al proceso hijo le devuelve el valor de 0.

Page 20: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: fork

El proceso padre, antes de finalizar se suspende hasta que el hijo

acaba, para evitar que éste se quede zombie. Para ello, utiliza la llamada al sistema wait(), que recibe en la variable status el estado en que el proceso hijo finalizó.

#include <stdio.h>

#include <unistd.h> /*man 2 fork */

#include <sys/types.h> /*man 2 wait */

#include <sys/wait.h>

int main() {

Page 21: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: fork

Int pid = 0, status = 0;

if ((pid = fork()) == -1)

{ printf(''Error al crear proceso hijo\n'');exit(1); }

if (pid == 0)

{ printf(''El PID de mi padre es %d\n'',getppid()); exit(0); }

else

{ printf(''Mi PID es %d y el PID de mi hijo es %d\n'', getpid(), pid);

wait(&status);

printf(''\nEl proceso hijo finalizo con el estado %d\n'', status);

exit(0);}

Page 22: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Crear un proceso: fork

$gcc -o mifork.exe fork.c

$./mifork.exe

El PID de mi proceso padre es 4693

Mi PID es el 4693 y he creado un proceso hijo cuyo pid es 4694

El proceso hijo finalizo con el estado 0

ó

Mi PID es el 4693 y he creado un proceso hijo cuyo pid es 4694

El PID de mi proceso padre es 4693

El proceso hijo finalizo con el estado 0

Page 23: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

Un proceso zombie es un proceso que ha completado su ejecución y a liberado todos los recursos, pero aún tiene una entrada en la tabla de procesos, permitiendo al proceso que le ha creado lea el estado de su salida. Al padre se le envía una señal SIGCHLD indicando que el proceso ha muerto; el manejador para esta señal será típicamente ejecutar la llamada al sistema wait, que lee el estado de salida y borra al zombie. El ID del proceso zombie y la entrada en la tabla de procesos pueden volver a usarse. Los zombies pueden ser identificados con ps por la presencia de una Z en la columna de estado.

Page 24: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

En UNIX el kernel asigna a "init" cualquier proceso cuyo padre muera antes que hacer un wait, automáticamente. "init" simplemente hace "wait" esperando que alguno de sus hijos (heredados) muera. No tiene que preocuparse de saber cuales son. "init" simplemente hace un "wait", descarta la notificación y hace otro, en un bucle. Su única misión es "limpiar" los procesos zombie (zombie: proceso muerto a la espera de que su padre haga un wait)). A estos procesos se le llaman procesos huérfanos.

Page 25: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

wait: La función wait suspende la ejecución del proceso actual hasta que un proceso hijo ha terminado, o hasta que se produce una señal cuya acción es terminar el proceso actual. Todos los recursos del sistema reservados por el hijo son liberados.

waitpid:Función que espera hasta que termine el proceso con pid

#include <sys/types.h> y #include <sys/wait.h>

pid_t wait(int *status)

pid_t waitpid(pid_t pid, int *status, int options);

Page 26: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

Parámetros:

pid_t pid

Si -1: lo que significa que espera por cualquier proceso hijo; este es el mismo comportamiento que tiene wait.

Si 0: lo que significa que espera por cualquier proceso hijo cuyo ID es igual al del proceso llamante.

Si > 0: lo que significa que espera por el proceso hijo cuyo ID es igual al valor de pid.

Page 27: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

Parámetros:

options:

WNOHANG (wait if no hang): que significa que vuelve inmediatamente si ningún hijo ha terminado.

WUNTRACED (wait if no traced) : que significa que también vuelve si hay hijos parados, y de cuyo estado no ha recibido notificación.

Ambas conductas: WNOHANG||WUNTRACED

Nínguna:0 (No vuelve, permanece a la espera)

variable entera ''status'' :el estado de salida del hijo (si el hijo ha acabado su ejecución sin error, lo normal es que devuelva cero)

Page 28: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

Ejm:waitpid

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

int main() { int pid = 0, status = 0;

if ((pid = fork()) == -1){ printf("Error al crear proceso hijo\n");exit(1); }

if (pid == 0) { sleep(30);printf("El PID de mi padre es %d\n",getppid()); exit(0); }

Page 29: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

Ejm:waitpid

else { waitpid(pid,&status,WNOHANG);

printf("Mi PID es %d y el PID de mi hijo es %d\n", getpid(), pid);

printf("\nEl proceso hijo finalizo con el estado %d\n", status);exit(0);}}

Al Ejecutar:

Mi PID es 17101 y el PID de mi hijo es 17102

El proceso hijo finalizo con el estado 0

$ El PID de mi padre es 1

Page 30: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Esperar: wait

Ejm: Si cambiamos por wait

else { wait(&status);

printf("Mi PID es %d y el PID de mi hijo es %d\n", getpid(), pid);

printf("\nEl proceso hijo finalizo con el estado %d\n", status);exit(0);}}

Al Ejecutar:

El PID de mi padre es 17270

Mi PID es 17270 y el PID de mi hijo es 17271

El proceso hijo finalizo con el estado 0

Page 31: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Identificación de proceso

Información del proceso:(Están en unistd.h)

getpid:Función que devuelve el identificador del proceso. Ejm:

pid_t getpid(void);

getppid:Función que devuelve el identificador del proceso padre. Ejm: pid_t getppid(void);

getuid:Función que devuelve el identificador de usuario real.Ejm:

uid_t getuid(void);

geteuid:Función que devuelve el identificador de usuario efectivo. Ejm:uid_t geteuid(void);

Page 32: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Identificación de proceso

getgid:Función que devuelve el identificador de grupo real. Ejm:

gid_t getgid(void);

getegid:Función que devuelve el identificador de grupo efectivo. Ejm:gid_t getegid(void);

Page 33: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Entorno de un proceso

Entorno de un proceso: las variables de entorno que se pasan a un proceso son accesibles a través de la variable externa environ (un array de apuntadores a char)

extern char **environ; ó extern char *environ[ ];

Obtener el valor de una variable de entorno:

#include <stdlib.h>

char * getenv (const char *name); Definir el entorno de un proceso:

#include <stdlib.h>

int putenv (const char *string);

Nota:extern: variable global y que está en otro fichero fuente.

Page 34: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso.Entorno de un proceso:environ

Es un programa que nos muestra el contenido de la variable environ, simula el script $env

#include <stdio.h>

int main(void)

{extern char **environ; /*char * environ[]

while (*environ)

puts(*environ++);

}

Nota:extern: variable global y que está en otro fichero fuente.

Page 35: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso.Entorno de un proceso:environ

$env y ./env.exe

TERM=xterm

SHELL=/bin/bash

HISTSIZE=1000

...

Page 36: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Entorno de un proceso:getenv y

setenv#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

int main(void){

char variable_de_entorno[]={"MI_RUTA=/home/kepa/lana"};

if (putenv(variable_de_entorno))

puts("putenv fallo");

else

puts("putenv tuvo éxito");

Page 37: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Entorno de un proceso:getenv y

setenvif (getenv("MI_RUTA"))

printf("MI_RUTA=%s \n",getenv("MI_RUTA"));

else

puts("MI_RUTA sin asignar");

exit(EXIT_SUCCESS);}

$gcc entorno.c -o entorno.exe

$ ./entorno.exe

putenv tuvo exito

MI_RUTA=/home/kepa/lana

Page 38: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Terminar:

Un proceso puede terminar por:

Su función main llama a return

llama a exit de la librería estándar de C <stdlib.h> uso general

llama a _exit declarada en <unistd.h> llamada del sistema unix

llama a abort

es finalizado por una señal

Page 39: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso.Terminar:return

return:

return expresión;

Fuerza la salida inmediata de una función. Y provoca que se salte al punto en que se hizo la llamada a la función.

Si hay un valor asociado con return, se trata del valor de vuelta de la función.

Si el return es de la función del main() provoca el fin del programa.

Page 40: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso.Terminar:exit

exit: #include <stdlib.h>

void exit(int status);

La función exit produce la terminación normal del programa y la devolución de status al proceso padre. Antes de finalizar se llama a todas las funciones registradas con atexit() en orden inverso a su registro.

status es el valor que se le devuelve al proceso padre como estado de terminación del proceso, y se puede leer mediante una de las funciones de la familia de wait.

Nota: atexit - registra una función para ser llamada al momento de una terminación normal del programa.

Page 41: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso.Terminar:_exit

_exit: #include <unistd.h> void _exit(int status);

Termina inmediatamente la ejecución del proceso invocador

No se ejecutan las funciones que se encuentran registradas con atexit.

Page 42: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Abort

abort

#include <stdlib.h>: void abort(void);

La función abort() causa una terminación anormal y graba una imagen de la memoria. Todos los canales abiertos se cierran y borran. Genera la señal: SIGABRT

Uso: casos extremos Ejm: sin memoria

Page 43: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

abort

vi abortprueba.c

#include <stdio.h>

#include <stdlib.h>

int main(void)

{ abort();

/*el programa no debería llegar aqui*/

exit(EXIT_SUCCESS);}

Page 44: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

abort

$gcc -o abortprueba abortprueba.c

$./abortprueba

#permite el volcado de memoria del programa(core dump)

$ulimit -c unlimited

$./abortprueba

$ls -lias

core

Page 45: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

¿En qué situaciones las usaremos?

Programación en Linux:

Cuando uno quiere o necesita utilizar las prestaciones de un programa externo en su própio código.(Ejm: ls)

Resulta vital recoger los código de salida del fork ó exec con wait. Y también que los programas llamen a return o exit antes de salir del programa para poder recoger sus códigos de salida.

En caso de que tengamos problemas de código podremos incluir abort para crear una imagen de un programa en ejecución escribirla en disco, para la depuración del mismo.

Page 46: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

kill:

#include <sys/types.h> y <signal.h>: int kill(pid_t pid, int sig);

Función que envía al proceso pid la señal SIGXXXX

devuelve 0 si ha ido bien y sino -1 si no se ha podido ejecutar.

Ejm:kill(pid,SIGTERM)

Page 47: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

kill: Función que envía al proceso pid la señal SIGXXXX

Su declaración esta en: #include <sys/types.h> y <signal.h>: int kill(pid_t pid, int sig);

Ejm:

#include <sys/types.h> /*kill y wait*/

#include <sys/wait.h> /*wait*/

#include <signal.h>/*kill*/

#include <stdlib.h>/*puts y exit*/

#include <stdio.h>/*printf*/

#include <unistd.h>/*fork*/

int main(void){

Page 48: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

kill:

pid_t hijo;

int condicion,valor_retornado;

if ((hijo=fork())==-1){perror("fork");exit(EXIT_FAILURE);}

if (hijo==0) {sleep(1000);exit(EXIT_SUCCESS);}

else {valor_retornado=kill(hijo,SIGKILL);

if (valor_retornado) {perror("kill");wait(&condicion);}

else {printf("%d eliminado\n",hijo);}

exit(EXIT_SUCCESS); }}

Page 49: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

kill:

$gcc -o killer killer.c

$ ./killer

6680 eliminado

Page 50: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

Señales

Suceso que tiene lugar en cualquier momento durante la ejcución de un proceso (Señal=Interrupción Software)

Cada señal tiene un nombre (kill -l ó man 7 signal) y las funciones que las tratan están en </usr/include/signal.h>

Cuando un proceso recibe una señal, este puede realizar :

Puede ignorar la señal Puede permitir que ocurra una acción predeterminada

normalmente un exit con/sin volcado de un fichero core. Puede capturar la señal, ejecutando una rutina de

tratamiento de señal(handler), y luego exit o volver a un estado anterior o al punto donde se produjo la interrupción.

Page 51: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

man 7 signal

signal - lista de las señales disponibles

Señal Valor Acción Comentario

----------------------------------------------------------------------

SIGHUP 1 A Cuelgue detectado en la terminal de

control o muerte del proceso de control

SIGINT 2 A Interrupción procedente del teclado(Crtl-C)(salida)

SIGQUIT 3 C Terminación procedente del teclado(Ctrl-4)(salida con core)

SIGILL 4 C Instrucción ilegal

Page 52: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

Señal Valor Acción Comentario

----------------------------------------------------------------------

SIGABRT 6 C Señal de aborto procedente de abort(3)

SIGFPE 8 C Excepción de coma flotante

SIGKILL 9 AEF Señal de matar

SIGSEGV 11 C Referencia inválida a memoria

SIGPIPE 13 A Tubería rota: escritura sin lectores

SIGALRM 14 A Señal de alarma de alarm(2)

SIGTERM 15 A Señal de terminación

Page 53: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

Señal Valor Acción Comentario

SIGUSR1 30,10,16 A Señal definida por usuario 1

SIGUSR2 31,12,17 A Señal definida por usuario 2

SIGCHLD 20,17,18 B Proceso hijo terminado o parado

SIGCONT 19,18,25 Continuar si estaba parado

SIGSTOP 17,19,23 DEF Parar proceso

SIGTSTP 18,20,24 D Parada escrita en la tty

SIGTTIN 21,21,26 D E. de la tty para un proc. de fondo

SIGTTOU 22,22,27 D S. a la tty para un proc. de fondo

Page 54: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

A-La acción por defecto es terminar el proceso

B-La acción por defecto es ignorar la señal

C-La acción por defecto es terminar el proceso y hace core dump

D-La acción por defecto es parar la ejecución del proceso

E-La señal no puede ser capturada por el programa(manipulada)

F-La señal no puede ser ignorada

*core dump: volcado de memoria del contexto del proceso a la

carpeta del proceso, para poder ver con un programa de

depuración como gdb,sdb o adb

Page 55: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal.Pause

pause

Cuando queramos que un proceso espere a que llegue

una señal. Esta función provoca que el proceso

duerma hasta que llegue la señal.

Declaración: int pause (void)

Devuelve -1 cuando la llamada a la función que

captura la señal ha terminado.

Page 56: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal.Pause

Ejm:vi pausa.c

#include <unistd.h>

#include <stdlib.h>

int main(void){pause();

exit(EXIT_SUCCESS);}

$gcc -o pausa pausa.c

$./pausa

Ctrl-4 ó kill -USR1 <PID>

Salir

Page 57: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal.Signal

signal

man signal

La función signal() recibe dos parámetros, el número de señal que queremos capturar (los números en el sistema en concreto en el que nos encontremos los podemos obtener ejecutando “kill –l”, como ya hemos visto), y un puntero a una función que se encargará de tratar la señal especificada.También puede ser una de las siguientes macros: SIG_IGN (No tener en cuenta la señal) ó SIG_DFL( Dejar la señal con su comportamiento predefinido)

Signal devuelve SIG_ERR si ocurre un error.

Page 58: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

Conceptos básicos: Punteros a funciones.

Cuando una función en C se compila, se crea un punto de entrada en el código objeto.

Cuando se llama a la función se hace una llamada a ese punto de entrada.

El punto de entrada se puede utilizar para llamar a la función.

Declaración de puntero a función: tipo_devuelve_f (*p) ();

La dirección del punto de entrada se obtiene con el nombre de la fución sin paréntesis ni argumentos(Igual que los arrays)

Asignación: p=printf

Llamada: (*p)(“kaixo”)

Page 59: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

ejemplo

#include <stdio.h>

#include <signal.h>

int sig;

void funcion (sig)

{printf("Recibida la señal %d\n",sig);}

int main(){

/*Se habilita la función */

signal(SIGUSR1,funcion);

kill(getpid(),SIGUSR1);

/*Se ignora la señal*/

signal(SIGUSR1,SIG_IGN);

kill(getpid(),SIGUSR1);

/*Tratamiento por defecto*/

signal(SIGUSR1,SIG_DFL);

kill(getpid(),SIGUSR1);

return 0;

}

Page 60: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal

alarm: Función que activa un temporizador en el proceso que efectúa la llamada. Cuando el tiempo asignado al temporizador expira, se envía SIGALRM al proceso que efectuo la llamada. Definida en <unistd.h>: unsigned int alarm(unsigned int seconds);

sleep:Función que hace que el proceso quede inactivo durante x segundos. Ejm: int sleep(unsigned int seconds);

Ejm:sleep(30)

Page 61: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal.Alarm

Ejm:vi alarma.c

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

int main(void)

{ if ((alarm(5))>0) {puts("Ya hay una alarma programada");}

sleep(30);

puts("¿Como fue que el programa llego aqui?");

exit(EXIT_FAILURE);

}

Page 62: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Gestión de Proceso:Enviar señal.Alarm

$gcc -o alarma alarma.c

$ ./alarma

Reloj de alarma

Page 63: Programando en Linux Gestión de Procesos y Señales Realizado por: Kepa Bengoetxea jipbekok@vc.ehu.es

Crear y Manipular señales

Programación en Linux:

El procedimiento general consiste en:

Crear un conjunto de señales Establecer las señales que se quieren interceptar Registrar un handler de señales en el kernel Aguardar a interceptar la señal

Utilizar las siguientes funciones del API que están en /usr/include/signal.h :sigemptyset,sigfillset,sigaddset...