Caracteres de control especial

Los caracteres de control especial, son una colección de caracteres, como CTRL-C, que actúan de un modo en particular cuando el usuario lo escribe. El miembro c_cc de la estructura termios contiene los caracteres relacionados con cada una de las funciones aceptadas. La posición de cada carácter (su índice de cada matriz) lo define una macro, pero no hay limitación que diga que deban ser caracteres de control.

La matriz c_cc se usa de dos maneras muy diferentes, dependiendo de si la terminal está configurada con modo canónico (es decir, la configuración del indicador ICANON en el miembro  c_iflag de termios).

Hay que tener en cuenta cierta coincidencia en el modo de empleo de los valores de índice de las matrices para los modos diferentes. Por ello, no debería mezclarse nunca los valores de estos dos modos.

MATRICES_CANONICOS_NO_CANONICOS

Caracteres

Como los caracteres especiales y los valores no canónicos son tan importantes para el procesamiento de caracteres de entrada más avanzado, en la siguiente tabla se explica con más detalle:

caracteres especialesLos valores TIME y MIN

Los valores TIME y MIN se usan, con los modos no canónicos y actúan conjuntamente para controlar la lectura de las entradas.Juntos, controlan lo que ocurre cuando un programa intenta leer un descriptor de archivo asociado a una terminal.

Existen cuatro:

  • MIN = 0 y TIME = 0.- En este caso, un read se enviará de inmediato. Si están disponibles algunos caracteres, serán retornados, si no está disponible ninguno, read enviará cero y no se habrá leído ningún carácter.
  • MIN = 0 y TIME > 0.- En este caso, read aparecerá cuando esté disponible para la lectura cualquier carácter o cuando haya pasado una décima de segundo de TIME. Si no leyó ningún carácter porque se pasó el tiempo, read enviará cero. Sino, enviará el número de caracteres leídos.
  • MIN > 0 y TIME = 0.- En este caso. read esperará hasta que se puedan leer caracteres MIN y después enviará el número de caracteres leídos. Al final del archivo se envía cero.
  • MIN > 0 y TIME > 0.- Éste es el caso más complejo. Cuando se llama a read, éste espera a que se reciba un carácter. Cuando se recibe el primer carácter, y siempre que se reciba un carácter, se inicia un contador de caracteres interno (o se vuelve a iniciar si ya estaba funcionando). read se enviará cuando se puedan leer caracteres MIN o cuando se pase el tiempo de caracteres internos de una décima de segundo de TIME. Puede resultar útil para indicar la diferencia entre presionar una sola vez la tecla Escape e iniciar una secuencia de función de teclas de escape. Tenga presente, sin embargo, que la comunicación en red o las cargas de procesadores superiores eliminan con ingenio dicha información de sincronización.

nota_time_minAcceso a los modos de terminal desde la shell

Si desea ver la configuración de termios empleada mientras esté usando la shell, puede obtener una lista usando el comando:

stty_aEn mi sistema Linux, la salida es:

stty_salidaVemos que el carácter EOF es CTRL-D y permiten los ecos. Si estamos experimentando con el control del terminal, es muy fácil dejar a la terminal en un estado no estándar, lo cual dificultara mucho su uso. Tenemos varios modos de solucionarlo:

  • El primer método, si su versión de stty lo acepta, es usar el comando stty sane.
  • Si ha perdido el mapa de las teclas de retorno de carro para el carácter nueva línea (que finaliza la línea), es posible que tenga que introducir stty sane, pero en vez de presionar Intro, tendrá que presionar CTRL-J (que es el carácter de nueva línea).
  • El segundo método es usar el comando stty -g para escribir la configuración stty actual en un formulario listo para volver a leerlo. En la línea de comandos podemos usar:stty_1
  • Podemos usar la misma técnica en un script shell:stty_script
  • Otro método, si nos quedamos atascados, es ir a un terminal diferente, usar el comando ps para encontrar la shell que había inutilizado, y después usar kill HUP <id proceso> para que la shell finalice. Como los parámetros stty se reinician siempre antes de proporcionar un incitador de registro, debería ser capaz de registrarse con toda normalidad.

Configuración de los modos de terminal desde el incitador de comandos

Podemos configurar los modos de terminal directamente desde el incitador de comandos. Para establecer un modo en el cual su script shell pudiese ejecutar lecturas de caracteres únicos, tendría que desactivar el modo canónico y configurarlo en 1 y en 0. El comando sería:

icanon_sttyCon el terminal configurado para leer los caracteres inmediatamente, podemos intentar ejecutar el primer programa que creamos, menu1, de nuevo. Debería funcionar tal como se pensó desde el primer momento.

También podría mejorar su intento de comprobación de contraseña (Capítulo 2) desactivando los ecos antes de solicitar la contraseña.

password_1El comando que lo hace es:

password_stty1password_stty2

VELOCIDAD DE TERMINAL

La última función que proporciona la estructura termios es la manipulación de la velocidad de línea. Para la velocidad de la terminal no se define ningún miembro, sino que se configura mediante llamadas a funciones. Las velocidades de entrada y de salida se gestionan por separado.

Los cuatro prototipos son:

velocidad_terminal1Tenga en cuenta que todos actúan en una estructura termios, no directamente en el puerto. Esto significa que para configurar una nueva velocidad, debe leer las configuraciones actuales con tcgetattr, configurar la velocidad usando una de las llamadas anteriores y después volver a escribir la estructura termios usando tcsetattr. Únicamente después de la llamada a tcsetattr se modificará la velocidad de la nueva línea.

 velocidad_terminal3velocidad_terminal_notaFUNCIONES ADICIONALES

Existe un pequeño número de funciones adicionales para el control de terminales. Trabajan directamente con los descriptores de archivos sin tener que obtener y configurar las estructuras termios. Estas definiciones son:

funciones_adicionalesLas funciones tienen las siguientes finalidades:

  • tcdrain ..- Hace que el programa de llamada espere hasta que se envíe una salida que estuviese haciéndola sola.
  • tcflow .- Se usa para suspender o reinicia una salida.
  • tcflush .- Se puede usar para vaciar las salidas, las entradas o ambas.

Ahora que ya hemos profundizado en el tema de la estructura termios, vamos a ver varios ejemplos prácticos. Es posible que lo más sencillo sea deshabilitar el eco para leer una contraseña. Hágalo desactivando el indicador ECHO.

 UN PROGRAMA DE CONTRASEÑA CON TERMIOS

  1. Comience su programa de contraseña, password.c, con las siguientes definiciones:password_1
  2. A continuación, añada una línea para obtener las opciones actuales de la entrada estándar, y cópielos en la estructura termios que creó previamente:password_2
  3. Haga una copia de las opciones originales para reemplazar al final. Desactive el indicador ECHO en newrsettings y pregunte al usuario su contraseña.password_3
  4. A continuación, establezca los atributos de la terminal en newrsettings y lea la contraseña. Por último, reinicie los atributos originales de la terminal y muestre la contraseña para que todos los esfuerzos de seguridad previos sean inútiles.password_4

Cuando ejecute el programa, debería ver:

password_terminalCOMO FUNCIONA

En este ejemplo , escribimos la contraseña 1234567, pero no se envía hasta el incitador Entra la contraseña:. Hasta que el usuario no presiona Intro no se produce ningún dato de salida.

Tenga cuidado y modifique únicamente los indicadores que tenga que modificar, use la estructura X &= ~FlAG (que vacía el bit definido por FLAG en la variable X). Si fuese necesario, podría usar X | = FlAG para configurar un único bit definido por FLAG, a pesar de que no fue necesario para el ejemplo anterior.

Al configurar los atributos usa TCSAFLUSH para desechar cualquier carácter o escritura que el usuario haya introducido antes de que el programa esté listo para leerlos. Es un buen modo que los usuarios no empiecen a escribir sus contraseñas hasta que se hayan desactivado los ecos. También restablecerá la configuración previa, antes de que finalice su programa.

Otro uso común de la estructura termios es introducir a la terminal en un estado en el que pueda leer cada carácter en cuanto se escriba. Para hacerlo, desactive el modo canónico y use las opciones MIN y TIME.

 LEER CADA CARÁCTER

Gracias a los nuevos conocimientos adquiridos, puede realizar cambios en el programa menu. el siguiente programa (que llamaremos menu4.c, se basa en menu3.c y contiene gran parte del código de password.c. Los cambios se explican en los siguientes pasos:

  1. Para empezar, debe incluir un nuevo archivo de cabecera en la parte superior del programa:menu4_1
  2. Después tiene que declarar un par de variables nuevas en la función principal:menu4_2
  3. Tiene que modificar las características de la terminal antes de llamar a la función getchoice. Tiene que colocar las siguientes líneas aquí:menu4_3
  4. También debería retornar las opciones a sus valores originales antes de salir:menu4_4
  5. Ahora que está en el modo no canónico tiene que comprobar los retornos de carro, porque el trazado predeterminado de CR a LF ya no se va a ejecutar.menu4_5

A menos que lo disponga de otra manera, si el usuario escribe ahora CTRL-C en su programa, el programa se finalizará. Puede deshabilitar el procedimiento de estos caracteres especiales vaciando el indicador ISIG en los modos locales. Para hacerlo, se incluye la siguiente línea en main, tal como muestra el paso anterior.

new_settings.c_lflag &= ~ISIG;

Si introduce estos cambios en su programa de menú, obtendrá una respuesta inmediata y los caracteres escritos no se transmitirán mediante echo.

menu4_terminalSi escribe CTRL-C, se transmite directamente al programa y será tratado como una elección.

menu4_terminal_error

atras

 

 

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.