Programando llamadas al sistema del kernel Linux

Normalmente todo esta implementado en las librerías , sin embargo conocer esta información es útil y seguro le podría encontrar un uso, además cuando implemente sus propias funciones en el kernel de Linux y requiera llamarlas y esas no estarán disponible en la biblioteca standart

Re implementado el comando kill

kill.c

#include <linux/unistd.h>

_syscall2(int,kill,int, pid, int, sig);

int main ()
{
int ppid = 0, argumento = 0;
printf (“Pid: “);
scanf (“%d”,&ppid);
printf (“Argumento: “);
scanf (“%d”,&argumento);
kill (ppid,argumento);
return 0;
}

solo 3 líneas podrían ser nuevas para usted

primero esta la include a Linux/unistd.h que es diferente a solo usar unistd.h pues aquí la funciones las vamos sacar directamente del kernel no de una librería

la segunda línea es la declaración de la llamada y para activarla en el programa busca que este definida en el archivo de kernel /usr/src/kernels/2.6.9-5.EL-i686/include/asm/unistd.h
y lo esta de la siguiente forma

#define __NR_kill 37

Ahora busquemos su prototipo para saber que argumentos y cuantos requiere, en el archivo
/usr/src/kernels/2.6.9-5.EL-smp-i686/include/linux/syscalls.h

aparece de la siguiente forma:
asmlinkage long sys_kill(int pid, int sig);

aquí se ve que kill esta implementado con 2 argumentos el pid del programa a matar y la señal

En el programa muestra hago una llamada a _syscall2(int,kill,int, pid, int, sig)

el _syscall2 significa que quiero llamar una función que tiene 2 argumentos, si llamara a syscall0 seria una función sin argumento “void? o _syscall6 seria una función con 6 argumentos y así.

sin embargo cuanto la implemento vemos que hay mas de 2 argumentos

el primero es un int y es para el resultado de la función por que kill devuelve un valor entero para saber si se ejecuto correctamente o no, el segundo argumento es el nombre de la funciona que estoy llamando, en syscalls.h esta implementada como sys_kill, pero la macro de syscall le retira el sys_

el tercer argumento es el tipo del primer argumento de la función, esta es entera, el siguiente argumento es el nombre de la variable que le pasamos a la función pid, el quinto argumento es nuevamente el tipo de argumento y de nuevo es entero y por ultimo el nombre del segundo argumento que pasamos a la función.

syscall ocupa un argumento para definir solo tipo, otro para definir nombre por eso hay 6 argumentos para llamar a una función que solo debería tener 2

por ultimo en el programa que he puesto pongo por fin la llamada a la función en el kernel

kill (ppid,argumento);

ppid y argumentos son variables declaradas en el mismo programa y capturadas por stdin o séase teclado si la ejecutas en consola.

compilamos y ejecutamos

[root@linux eboot]# gcc kill.c -o kill
[root@linux eboot]# ./kill
Pid: 2296
Argumento: 9
[root@linux eboot]#

esto seria el equivalente a el comando nativo que viene en la distro kill y usado así kill 2296 -9

como ultima practica se hace un programa que obtiene su propio PID uno escrito usando la librerías del sistema y otro que nuevamente hace uso de una llamada al sistema para obtener el pid directamente del kernel, aunque al final el feel and look del programa es el mismo el código que ejecutan es diferente

primero la versión normalmente programada por la mayoria.

normalpid.c

#include <unistd.h>

int main ()
{
printf (“Mi propio PID es: %d”,getpid());
return 0;
}

Ahora el código con la llamada al sistema

kernelpid.c

#include <linux/unistd.h>

_syscall0(int,getpid);

int main ()
{
printf (“Mi propio PID es: %d”,getpid());
return 0;
}

veamos los archivos anteriores para ver su define y su prototipo
#define __NR_getpid 20 // en Linux/unistd.h
asmlinkage long sys_getpid(void); // en syscalls.h

al ejecutar ambos la salida será idéntica

[root@linux eboot]# gcc kernelpid.c -o kernelpid; ./kernelpid
Mi propio PID es: 3421

3 Comments

Add a Comment

Comment spam protected by SpamBam