ioctl , la enciclopedia libre

ioctl es una llamada de sistema en Unix que permite a una aplicación controlar o comunicarse con un driver de dispositivo, fuera de los usuales read/write de datos. Esta llamada se originó en la versión 7 del AT&T Unix. Su nombre abrevia la frase input/output control.

Descripción

[editar]

Una llamada ioctl toma como parámetros:

  1. un descriptor de archivos abierto
  2. un número de código de requerimiento
  3. también un valor entero, posiblemente sin signo (va al driver), o un puntero a datos (también va al driver y vuelve de él)

El kernel generalmente envía un ioctl directamente al driver, el cual puede interpretar el número de requerimiento y datos en cualquier forma requerida. Los escritores del driver documentan cada número de requerimiento del driver para ese driver particular, y los proveen de constantes en el archivo de cabeceras (*.h)

Algunos sistemas tienen convenciones en su codificación, dentro del número de codificación, el tamaño de los datos a ser transferidos desde o hacia el driver del dispositivo, la dirección de la transferencia de datos y la identidad del driver implementando el requerimiento.

Independientemente de que esa convención se cumpla o no, el kernel y el driver colaboran para entregar un código de error uniforme (señalados por la constante simbólica ENOTTY) a una aplicación que haga un requerimiento al driver que no reconozca.

El nemónico ENOTTY (tradicionalmente asociado con el mensaje textual "Not a typerwriter") viene del hecho de que en los sistemas iniciales que incorporaba una llamada ioctl, solo el dispositivo teletipo (tty) planteaba este error. A través del nemónico simbólico es ajustado por los requerimientos de compatibilidad; algunos sistemas modernos muy útilmente prestan un mensaje más general, como: "Inappropriate device control operation", o la localización del mismo.

TCSETS ejemplifica un ioctl en un puerto serial. Las llamadas de lectura y escritura normales en un puerto serial reciben y envían paquetes de datos. Una llamada ioctl(fd, TCSETS, data), independiente de las llamadas normales I/O, controla varias opciones del controlador, como la manipulación de caracteres especiales, o las señales de salida en el puerto (por ejemplo, la señal DTR).

Ejemplo de uso

[editar]

Un ejemplo de uso para ioctl es el manejo de los leds del teclado, KDGKLED, KDSKBLED son las macros definidas para poder acceder a los leds que la mayoría de los teclados tienen.

#include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/kd.h> #include <time.h> #include <unistd.h>    /*Encabezado para la función sleep() and close() */   int get_state(int fd,int *estado) {     if (-1 == ioctl(fd, KDGKBLED, estado)){           /*Si la función ioctl devuelve -1, hubo un error, que será especificado en la función perror(), si es cero significa que finalizo exitosamente*/         perror("ioctl");         close(fd);         return -1;     }    return 0;     }  void print_caps_lock_state(int estado) {     printf("Estado Caps Lock: %s (%d)\n",            (estado & K_CAPSLOCK) == K_CAPSLOCK ? "on" : "off", estado); }  int apaga(int fd,int *estado) {     get_state(fd,estado);     if (-1 == ioctl(fd, KDSKBLED, *estado ^ K_CAPSLOCK)){         perror("ioctl set");         close(fd);         return -1;     }     return 0; }  int prende(int fd,int *estado) {     if (-1 == ioctl(fd, KDSKBLED, K_CAPSLOCK)){         perror("ioctl set");         close(fd);         return -1;     }     get_state(fd,estado);     return 0; }  int main() {     int fd = open("/dev/tty0", O_NOCTTY);      if (fd == -1){         perror("open");         return -1;     }      int estado = 0;       prende(fd,&estado);         sleep(1);     apaga(fd,&estado);     sleep(2);     prende(fd,&estado);     sleep(1);     apaga(fd,&estado);     close(fd);     return 0; } 

Enlaces externos

[editar]