La interfaz del terminal POSIX es la abstracción generalizada, que comprende tanto una interfaz de programación de aplicaciones para programas como un conjunto de expectativas de comportamiento para los usuarios de un terminal , según lo definido por el estándar POSIX y la Especificación Única de Unix . Es un desarrollo histórico de las interfaces de terminal de BSD versión 4 y Seventh Edition Unix .
Conceptos subyacentes generales
Hardware
Una multiplicidad de dispositivos de E / S se consideran "terminales" en los sistemas Unix. [1] [2] Estos incluyen:
- dispositivos en serie conectados por un puerto en serie , como impresoras / teletipos , teletipos , módems que admiten terminales remotos mediante acceso telefónico y terminales locales conectados directamente [1] [3] [4] [5]
- Adaptador de pantalla y hardware de teclado incorporados directamente en la unidad del sistema, tomados juntos para formar una "consola" local, que puede presentarse a los usuarios y a los programas como un solo terminal CRT o como múltiples terminales virtuales [1]
- emuladores de terminal de software , como los programas xterm , Konsole , GNOME Terminal y Terminal , y servidores de red como el demonio rlogin y el demonio SSH , que utilizan pseudoterminales
Inteligencia y capacidades de terminal
Inteligencia: los terminales son tontos, no inteligentes
A diferencia de sus contemporáneos de mainframe y miniordenador [ cita requerida ] , el sistema Unix original se desarrolló únicamente para terminales tontos , y ese sigue siendo el caso en la actualidad. [6] Un terminal es un dispositivo orientado a caracteres, que comprende flujos de caracteres recibidos y enviados al dispositivo. [6] [7] A pesar de que los flujos de caracteres se estructuran, la incorporación de caracteres de control , códigos de escape y caracteres especiales, el protocolo de E / S no está estructurado como sería el protocolo de E / S de inteligentes , o inteligentes terminales,. No hay especificaciones de formato de campo. No hay transmisión en bloque de pantallas completas (formularios de entrada) de datos de entrada.
Por el contrario, los mainframes y los miniordenadores de arquitecturas cerradas suelen utilizar terminales orientados a bloques .
Capacidades: terminfo, termcap, curses, et al.
Las "capacidades" de un terminal comprenden varias características de terminal tontas que están más allá de lo que está disponible en un teletipo puro, que los programas pueden utilizar. Comprenden (principalmente) códigos de escape que se pueden enviar o recibir desde el terminal. Los códigos de escape enviados al terminal realizan varias funciones que un terminal CRT (o un emulador de terminal de software) es capaz de hacer y que un teletipo no lo es, como mover el cursor del terminal a posiciones en la pantalla, borrar y desplazar toda o parte de la pantalla. , encender y apagar los dispositivos de impresión conectados, las teclas de función programables, cambiar los colores y atributos de la pantalla (como el video inverso ) y configurar las cadenas de título de la pantalla. Los códigos de escape recibidos de las cosas representan a los terminales, tales como teclas de función , tecla de flecha y otros especiales pulsaciones de teclado ( clave casa , clave final , clave ayuda , claves RePág , clave AvPág , inserto clave , clave de eliminación , y así sucesivamente). [8] [9]
Estas capacidades están codificadas en bases de datos configuradas por un administrador del sistema y a las que se accede desde programas a través de la biblioteca terminfo (que reemplaza a la biblioteca termcap anterior ), sobre la cual, a su vez, se construyen bibliotecas como las bibliotecas curses y ncurses . Los programas de aplicación utilizan las capacidades del terminal para proporcionar interfaces de usuario textuales con ventanas, cuadros de diálogo, botones, etiquetas, campos de entrada, menús, etc. [10] [11]
Control de variables ambientales: TERM
et al.
El conjunto particular de capacidades para el terminal que utiliza la entrada y salida de un programa (consciente de terminal) se obtiene de la base de datos en lugar de conectarse en programas y bibliotecas, y está controlado por la TERM
variable de entorno (y, opcionalmente, para las bibliotecas termcap y terminfo , las variables de entorno TERMCAP
y TERMINFO
, respectivamente). [10] Esta variable es establecida por cualquier programa de monitor de terminal que genere los programas que luego usan ese terminal para su entrada y salida, o algunas veces explícitamente. Por ejemplo:
- El programa getty (o equivalente) establece la
TERM
variable de entorno de acuerdo con una base de datos del sistema (varios inittab o los archivos de configuración para los programas ttymon o launchd ) definiendo qué terminales locales están conectados a qué puertos seriales y qué tipos de terminales son proporcionados por los terminales virtuales locales. o la consola del sistema local. - Un usuario de acceso telefónico en un terminal remoto no está utilizando el tipo de terminal que el sistema normalmente espera en esa línea de acceso telefónico, por lo que establece manualmente la
TERM
variable de entorno inmediatamente después de iniciar sesión en el tipo correcto. (Más generalmente, el tipo de terminal establecido por el programa getty para la línea de acceso telefónico, que el administrador del sistema ha determinado que será utilizado con mayor frecuencia por los usuarios de acceso telefónico con terminales remotos, coincide con el utilizado por el usuario de acceso telefónico y ese usuario no tiene necesidad de anular el tipo de terminal). - El demonio del servidor SSH (o equivalente, como el demonio rlogin ) establece la
TERM
variable de entorno en el mismo tipo de terminal que el cliente SSH. [12] - El emulador de terminal de software, utilizando un pseudoterminal, establece la
TERM
variable de entorno para especificar el tipo de terminal que está emulando. Los terminales emulados a menudo no coinciden exactamente con el hardware de terminal real, y los emuladores de terminal tienen nombres de tipo dedicados para su uso. El programa xterm (por defecto) se establecexterm
como el tipo de terminal, por ejemplo. [13] El programa de pantalla GNU se establecescreen
como el tipo de terminal.
Control de trabajos
Las terminales proporcionan facilidades de control de trabajos. De forma interactiva, el usuario en la terminal puede enviar caracteres de control que suspenden el trabajo que se está ejecutando actualmente, volviendo al shell de control de trabajo interactivo que generó el trabajo, y puede ejecutar comandos que colocan trabajos en "segundo plano" o que cambian otro trabajo en segundo plano. en primer plano (anular la suspensión si es necesario). [14] [15]
Disciplinas de línea
Estrictamente hablando, en Unices, un dispositivo terminal comprende el controlador de dispositivo tty subyacente , responsable del control físico del hardware del dispositivo a través de instrucciones de E / S y el manejo de las solicitudes de interrupción del dispositivo para la entrada y salida de caracteres, y la disciplina de línea . Una disciplina de línea es independiente del hardware del dispositivo real, y la misma disciplina de línea se puede utilizar para un dispositivo concentrador de terminal responsable de múltiples terminales de control que para un pseudoterminal. De hecho, la disciplina de línea (o, en el caso de BSD, AIX y otros sistemas, las disciplinas de línea ) son las mismas en todos los dispositivos terminales. Es la disciplina de línea responsable del eco local, edición de línea, procesamiento de modos de entrada, procesamiento de modos de salida y mapeo de caracteres. Todas estas cosas son independientes del hardware real, y se ocupan de las abstracciones simples proporcionadas por los controladores de dispositivos tty: transmitir un carácter, recibir un carácter, establecer varios estados de hardware. [16] [17]
En la séptima edición de Unix , sistemas BSD y derivados, incluidos macOS y Linux , cada dispositivo terminal se puede cambiar entre múltiples disciplinas de línea. [18] En el sistema AT&T STREAMS , las disciplinas de línea son módulos STREAMS que pueden insertarse y extraerse de una pila de E / S STREAMS. [19]
Historia
La interfaz de terminal POSIX se deriva de las interfaces de terminal de varios sistemas Unix.
Early Unices: séptima edición Unix
La interfaz de terminal proporcionada por Unix 32V y Unix de séptima edición, y también presentada por BSD versión 4 como el controlador de terminal antiguo , era simple, en gran parte orientada a los teletipos como terminales. La entrada se ingresó una línea a la vez, con el controlador de terminal en el sistema operativo (y no los terminales en sí) proporcionando capacidades de edición de línea simple. El núcleo mantenía un búfer en el que se realizaba la edición. Las aplicaciones que leen la entrada del terminal recibirán el contenido del búfer solo cuando returnse presione la tecla en el terminal para finalizar la edición de la línea. La @clave enviada desde la terminal al sistema borraría ("mataría") todo el contenido actual del búfer de edición, y normalmente se mostraría como un símbolo ' @ ' seguido de una secuencia de nueva línea para mover la posición de impresión a un nuevo espacio en blanco. línea. La #clave enviada desde el terminal al sistema borraría el último carácter del final del búfer de edición y normalmente se mostraría como un ' El símbolo # ', que los usuarios tendrían que reconocer como un "borrado" del carácter anterior (los teletipos no son físicamente capaces de borrar caracteres una vez impresos en el papel). [20] [21] [22] [23] [18]
Desde el punto de vista de la programación, un dispositivo terminal tenía velocidades de transmisión y recepción en baudios , "borrar" y "matar" caracteres (que realizaban la edición de línea, como se explicó), "interrumpir" y "salir" de caracteres (generando señales a todos los procesos para los que el terminal era un terminal de control), caracteres "iniciar" y "detener" (utilizados para el control de flujo del módem ), un carácter de "fin de archivo" (que actúa como un retorno de carro, excepto que la read()
llamada al sistema lo descarta del búfer y por lo tanto, puede causar que se devuelva un resultado de longitud cero) y varios indicadores de modo básico que determinan si el controlador de terminal del kernel emuló el eco local , si el control de flujo del módem estaba habilitado, las longitudes de varios retrasos de salida, el mapeo para el carácter de retorno de carro, y los tres modos de entrada. [24]
Los tres modos de entrada fueron:
- modo de línea (también llamado modo "cocinado")
En el modo de línea, la disciplina de línea realiza todas las funciones de edición de línea y reconoce los caracteres de control "interrumpir" y "salir" y los transforma en señales enviadas a los procesos. Los programas de aplicaciones que se leen desde el terminal reciben líneas completas, después de que el usuario haya completado la edición de línea presionando regresar. [21] [25]
- modo cbreak
El modo cbreak es uno de los dos modos de carácter a la vez. ( Stephen R. Bourne se refirió en broma ( Bourne 1983 , p. 288) como un modo "medio cocido" y por lo tanto "raro".) La disciplina de línea no realiza edición de línea, y las secuencias de control para las funciones de edición de línea se tratan como entrada normal de caracteres. Los programas de aplicaciones que leen desde el terminal reciben caracteres inmediatamente, tan pronto como están disponibles en la cola de entrada para ser leídos. Sin embargo, los caracteres de control "interrumpir" y "salir", así como los caracteres de control de flujo del módem, todavía se manejan de manera especial y se eliminan del flujo de entrada. [26] [27]
- modo crudo
- el modo sin formato es el otro de los dos modos de carácter a la vez. La disciplina de línea no realiza edición de línea, y las secuencias de control para ambas funciones de edición de línea y los diversos caracteres especiales ("interrumpir", "salir" y control de flujo) se tratan como entrada de caracteres normal. Los programas de aplicaciones que leen desde el terminal reciben caracteres inmediatamente y reciben todo el flujo de caracteres sin alteraciones, tal como provienen del propio dispositivo terminal. [28] [26] [27]
La interfaz programática para consultar y modificar todos estos modos y caracteres de control fue la ioctl()llamada al sistema . (Esto reemplazó las llamadas al sistema stty()
y gtty()
de Sixth Edition Unix.) [29] [30] Aunque los caracteres "borrar" y "matar" eran modificables a partir de sus valores predeterminados de #y @, durante muchos años fueron los valores predeterminados preestablecidos en la terminal. controladores de dispositivos, y en muchos sistemas Unix, que solo alteraron la configuración del dispositivo terminal como parte del proceso de inicio de sesión, en los scripts de inicio de sesión del sistema que se ejecutaron después de que el usuario ingresó el nombre de usuario y la contraseña, cualquier error en las solicitudes de inicio de sesión y contraseña tuvo que corregirse usando los personajes clave de edición histórica heredados de los terminales de teletipo. [23]
BSD: el advenimiento del control del trabajo
Con BSD Unices llegó el control de trabajos y un nuevo controlador de terminal con capacidades ampliadas. [18] Estas extensiones comprendían caracteres especiales adicionales (de nuevo modificables mediante programación):
- Los caracteres "suspender" y "suspender retrasado" (por defecto Control+ Zy Control+ Y- ASCII SUBy EM) provocaron la generación de una nueva
SIGTSTP
señal a los procesos en el grupo de procesos de control de la terminal. [27] - El "literal siguiente", y los caracteres "reimpresión" "borrado la palabra", (por defecto Control+ W, Control+ Vy Control+ R- ASCII ETB, SYNy DC2) lleva a cabo las funciones adicionales de edición de línea. "borrado de palabras" borró la última palabra al final del búfer de edición de línea. "literal siguiente" permitía ingresar cualquier carácter especial en el búfer de edición de línea (una función disponible, algo inconveniente, en la séptima edición de Unix a través del carácter de barra invertida). "reimprimir" hizo que la disciplina de línea reimprimiera el contenido actual del búfer de edición de línea en una nueva línea (útil para cuando otro proceso de fondo había generado una salida que se había entremezclado con la edición de línea). [27]
La interfaz programática para consultar y modificar todos estos modos adicionales y caracteres de control seguía siendo la ioctl()
llamada al sistema, que sus creadores ( Leffler et al. 1989 , p. 262) describieron como una "interfaz bastante desordenada". Se retuvo toda la funcionalidad Unix de la Séptima Edición original, y la nueva funcionalidad se agregó a través de ioctl()
códigos de operación adicionales , lo que resultó en una interfaz programática que claramente había crecido y que presentaba cierta duplicación de funcionalidad. [31]
Sistema III y Sistema V
System III introdujo una nueva interfaz de programación que combinó las ioctl()
operaciones separadas de la Séptima Edición para obtener y establecer indicadores y para obtener y establecer caracteres de control en llamadas que usaban una termio
estructura para contener indicadores y caracteres de control y que podía obtenerlos en una sola operación y establecerlos. en otra sola operación. También dividió algunos de los indicadores de la interfaz de la Séptima Edición en varios indicadores separados y agregó algunas capacidades adicionales, aunque no admitía el control de trabajos o las mejoras del modo cocinado de 4BSD. [32] Por ejemplo, reemplazó los modos "cocido", "cbreak" y "crudo" de la Séptima Edición con diferentes abstracciones. El reconocimiento de caracteres generadores de señales es independiente del modo de entrada y solo existen dos modos de entrada: canónico y no canónico. (Esto permite un modo de entrada de terminal que no está presente en la séptima edición y BSD: modo canónico con la generación de señal desactivada).
Los sucesores de System III, incluido System V , utilizaron la misma interfaz.
POSIX: Consolidación y abstracción
Uno de los principales problemas que abordó el estándar POSIX con su definición de una interfaz de terminal general fue la gran cantidad de interfaces programáticas. Aunque en el momento del estándar el comportamiento de los terminales era bastante uniforme de un sistema a otro, la mayoría de los Unices habían adoptado las nociones de disciplinas de línea y las capacidades de control de trabajos BSD, la interfaz programática a los terminales a través de la ioctl()
llamada al sistema era un desastre. Diferentes Unices suministraron diferentes ioctl()
operaciones, con diferentes nombres (simbólicos) y diferentes banderas. El código fuente portátil tenía que contener una cantidad significativa de compilación condicional para adaptarse a las diferencias entre las plataformas de software, a pesar de que todas eran teóricamente Unix. [33]
El estándar POSIX reemplaza el ioctl()
sistema por completo, con un conjunto de funciones de biblioteca (que, por supuesto, pueden implementarse bajo las cubiertas mediante ioctl()
operaciones específicas de la plataforma ) con nombres y parámetros estandarizados. La termio
estructura de datos de System V Unix se usó como plantilla para la termios
estructura de datos POSIX , cuyos campos se mantuvieron prácticamente sin cambios, excepto que ahora usaban tipos de datos de alias para especificar los campos, lo que les permitía ser portados fácilmente a través de múltiples arquitecturas de procesador por parte de los implementadores, en lugar de que requerir explícitamente los tipos de datos unsigned short
y char
de los lenguajes de programación C y C ++ (que pueden ser tamaños inconvenientes en algunas arquitecturas de procesador). [33] [34]
POSIX también introdujo soporte para el control de trabajos, con la termios
estructura que contiene los caracteres de suspensión y suspensión retardada además de los caracteres de control compatibles con System III y System V. No agregó ninguna de las extensiones de modo cocinado de BSD, aunque SunOS 4. x, System V Release 4 , Solaris , HP-UX , AIX , BSD más nuevos, macOS y Linux los han implementado como extensiones de termios
.
Lo que define el estándar
Control de terminales y grupos de procesos
Cada proceso del sistema tiene una única terminal de control o ninguna terminal de control. Un proceso hereda su terminal de control de su padre, y las únicas operaciones sobre un proceso son adquirir una terminal de control, mediante un proceso que no tiene una terminal de control, y renunciar a ella, mediante un proceso que tiene una terminal de control. [33]
No se define ninguna forma portátil de adquirir un terminal de control, siendo el método definido la implementación. El estándar define la O_NOCTTY
bandera para la open()llamada al sistema , que es la forma de prevenir lo que de otro modo sería la forma convencional de adquirir una terminal de control (un proceso sin terminal de control open()
un archivo de dispositivo de terminal que ya no es la terminal de control para algún otro proceso). , sin especificar la O_NOCTTY
bandera [35] ) pero deja su semántica convencional opcional.
Cada proceso también es miembro de un grupo de procesos. Cada dispositivo terminal registra un grupo de procesos que se denomina grupo de procesos en primer plano . Los grupos de procesos controlan el acceso al terminal y la entrega de señales. Las señales generadas en el terminal se envían a todos los procesos que son miembros del grupo de procesos en primer plano del terminal. read()y las write()operaciones de E / S en un terminal mediante un proceso que no es miembro del grupo de procesos en primer plano del terminal harán y pueden opcionalmente (respectivamente) hacer que se envíen señales ( SIGTTIN
y SIGTTOU
respectivamente) al proceso de invocación. Varias funciones de biblioteca que alteran el modo de terminal tienen el mismo comportamiento que write()
, excepto que siempre generan las señales, incluso si esa funcionalidad está desactivada por write()
sí misma. [36] [37]
La termios
estructura de datos
La estructura de datos utilizada por todas las llamadas a la biblioteca de terminales es la termios
estructura, [38] cuya definición del lenguaje de programación C y C ++ es la siguiente: [34]
struct termios { tcflag_t c_iflag ; // Modos de entrada tcflag_t c_oflag ; // Modos de salida tcflag_t c_cflag ; // Modos de control tcflag_t c_lflag ; // Modos locales cc_t c_cc [ NCCS ] ; // Caracteres de control } ;
El orden de los campos dentro de la termios
estructura no está definido y las implementaciones pueden agregar campos no estándar. [34] De hecho, las implementaciones deben agregar campos no estándar para registrar velocidades de transmisión de entrada y salida. Estos se registran en la estructura, en una forma definida por la implementación, y se accede a ellos a través de funciones de acceso, en lugar de mediante la manipulación directa de los valores de campo, como es el caso de los campos de estructura estandarizados. [39]
Los alias de los tipos de datos tcflag_t
y cc_t
, así como la constante simbólica NCCS
y las constantes simbólicas para los distintos indicadores de modo, los nombres de los caracteres de control y las velocidades en baudios, se definen en un encabezado estándar termios.h
. (Esto no debe confundirse con el encabezado de nombre similar termio.h
de System III y System V, que define una termio
estructura similar y muchas constantes simbólicas de nombre similar. Esta interfaz es específica de System III y System V, y el código que la usa no necesariamente ser portátil a otros sistemas.) [40]
Los campos de la estructura son (en resumen, para obtener más detalles, consulte el artículo principal [ aclaración necesaria ] ):
c_iflag
- indicadores de modo de entrada para controlar la paridad de entrada, la traducción de la nueva línea de entrada, el control de flujo del módem , la limpieza de 8 bits y la respuesta a una condición de "interrupción" (del puerto serie) [34]
c_oflag
- indicadores de modo de salida para controlar el posprocesamiento de salida definido por la implementación, la traducción de la nueva línea de salida y los retrasos de salida después de que se hayan enviado varios caracteres de control [41] [27]
c_cflag
- banderas de control de hardware del terminal para controlar el dispositivo terminal real en lugar de la disciplina de línea: el número de bits en un carácter, tipo de paridad, control de bloqueo y control de flujo de línea serial [42]
c_lflag
- banderas de control local para controlar la disciplina de línea en lugar del hardware del terminal: modo canónico, modos de eco, reconocimiento y manejo de caracteres de generación de señales, y habilitación de la generación de la
SIGTTOU
señal mediante lawrite()
llamada al sistema [39]
Las funciones de la biblioteca son (en resumen, para obtener más detalles, consulte el artículo principal [se necesita aclaración ] ):
tcgetattr()
- consultar la configuración actual de los atributos de un dispositivo terminal en una
termios
estructura [43] tcsetattr()
- establecer la configuración de atributos actuales de un dispositivo terminal desde una
termios
estructura, opcionalmente esperando a que se drene la salida en cola y vaciando la entrada en cola [43] cfgetispeed()
- consultar la velocidad en baudios de entrada de los campos definidos por la implementación en una
termios
estructura [44] cfgetospeed()
- consultar la velocidad en baudios de salida de los campos definidos por la implementación en una
termios
estructura [44] cfsetispeed()
- establecer la velocidad en baudios de entrada en los campos definidos por la implementación en una
termios
estructura [44] cfsetospeed()
- establecer la velocidad en baudios de salida en los campos definidos por la implementación en una
termios
estructura [44] tcsendbreak()
- enviar una señal de "interrupción" del módem en un terminal de dispositivo serie [45]
tcdrain()
- esperar a que se agote la salida en cola [45]
tcflush()
- descartar entrada en cola [45]
tcflow()
- cambiar el control de flujo [45]
tcgetpgrp()
- consultar el grupo de procesos en primer plano de la terminal [46]
tcsetpgrp()
- establecer el grupo de procesos en primer plano de la terminal [46]
Caracteres especiales
Campo | significado | Recuperado por read() | Notas |
---|---|---|---|
c_cc[VEOF] | fin del documento | No | Solo procesado por edición de línea en modo canónico |
c_cc[VEOL] | fin de la línea | sí | Solo procesado por edición de línea en modo canónico |
c_cc[VERASE] | "borrar" | No | Solo procesado por edición de línea en modo canónico |
c_cc[VKILL] | "matar" | No | Solo procesado por edición de línea en modo canónico |
c_cc[VINTR] | "interrumpir" | No | Carácter de generación de señal independiente del modo de entrada |
c_cc[VQUIT] | "dejar" | No | Carácter de generación de señal independiente del modo de entrada |
c_cc[VSUSP] | "suspender" | No | Carácter de generación de señal independiente del modo de entrada |
c_cc[VSTOP] | "detener" | No | Carácter de control de flujo del módem independiente del modo de entrada |
c_cc[VSTART] | "comienzo" | No | Carácter de control de flujo del módem independiente del modo de entrada |
El c_cc[]
miembro de matriz de la termios
estructura de datos especifica todos los caracteres especiales (modificables mediante programación). Los índices de la matriz son constantes simbólicas, una para cada tipo de carácter especial, como en la tabla de la derecha. (Dos entradas más en la matriz son relevantes para el procesamiento de entrada en modo no canónico y se analizan a continuación). [43]
Los caracteres especiales que no se pueden modificar mediante programación son el salto de línea (ASCII LF
) y el retorno de carro (ASCII CR
). [47]
Procesamiento de entrada
El procesamiento de entrada determina el comportamiento de la read()
llamada al sistema en un dispositivo terminal y las características de edición de línea y generación de señal de la disciplina de línea. A diferencia del caso de Seventh Edition Unix y BSD versión 4, y al igual que el caso de System III y System V, la edición de línea opera en uno de solo dos modos: modo canónico y modo no canónico. La diferencia básica entre ellos es cuando, desde el punto de vista de los requisitos de bloqueo / no bloqueo de la read()
llamada al sistema (especificados con la O_NONBLOCK
bandera en el descriptor de archivo a través de open()
o fcntl()
), los datos "están disponibles para leer". [48]
Procesamiento en modo canónico
En el modo canónico, los datos se acumulan en un búfer de edición de línea y no quedan "disponibles para lectura" hasta que el usuario (en el terminal) haya terminado la edición de línea enviando un carácter delimitador de línea . Los caracteres delimitadores de línea son caracteres especiales y son el final del archivo , el final de la línea y el salto de línea (ASCII LF
). Los dos primeros se pueden configurar mediante programación, mientras que el último es fijo. Los dos últimos están incluidos en el búfer de edición de línea, mientras que el primero no lo está. [49]
Más estrictamente, se acumulan cero o más líneas en el búfer de edición de línea, separadas por delimitadores de línea (que pueden o no descartarse una vez que se read()
comienza a leerlos), y la edición de línea opera en la parte del búfer de edición de línea que sigue a la último (si lo hay) delimitador de línea en el búfer. Entonces, por ejemplo, el carácter "borrar" (lo que sea que haya sido programado) borrará el último carácter en el búfer de línea solo hasta (pero sin incluir) un delimitador de línea anterior. [49]
Procesamiento en modo no canónico
En el modo no canónico, los datos se acumulan en un búfer (que puede ser o no el búfer de edición de línea; algunas implementaciones tienen colas de "entrada procesada" y "entrada sin procesar" separadas) y quedan "disponibles para lectura" de acuerdo con los valores. de dos parámetros de control de entrada, los miembros c_cc[MIN]
y c_cc[TIME]
de la termios
estructura de datos. Ambas son cantidades sin firmar (porque cc_t
se requiere que sea un alias para un tipo sin firmar). El primero especifica un número mínimo de caracteres y el segundo especifica un tiempo de espera en décimas de segundo. [50] Hay cuatro posibilidades:
c_cc[TIME]
yc_cc[MIN]
ambos son cero- En este caso, los datos en el búfer están "disponibles para lectura" inmediatamente y
read()
regresan inmediatamente con cualquier dato que esté en el búfer (potencialmente devolviendo cero si hay cero datos disponibles). [51] c_cc[TIME]
es distinto de cero yc_cc[MIN]
es cero- En este caso, los datos en el búfer están "disponibles para lectura" después de que haya transcurrido el tiempo de espera especificado, el temporizador se activa al iniciar la
read()
llamada al sistema o si se recibe un solo carácter. En otras palabras,read()
espera un tiempo total máximo especificado y puede devolver cero datos, y devuelve cualquier dato tan pronto como se reciben. [51] c_cc[TIME]
es cero yc_cc[MIN]
no es cero- En este caso, los datos en el búfer están "disponibles para leer" después de que se haya recibido el número especificado de caracteres en el búfer. En otras palabras,
read()
espera una cantidad mínima de datos (que puede ser mayor de lo que la persona que llama está preparada para leer en la llamada al sistema), no devolverá cero datos y puede esperar indefinidamente. [51] c_cc[TIME]
yc_cc[MIN]
ambos son distintos de cero- En este caso, los datos en el búfer están "disponibles para lectura" después de que se haya recibido el número especificado de caracteres en el búfer o haya expirado el tiempo de espera desde que se ingresó el último carácter. No hay tiempo de espera para el primer carácter. En otras palabras,
read()
espera una cantidad mínima de datos (que puede ser mayor de lo que la persona que llama está preparada para leer en la llamada al sistema), no devolverá cero datos, puede esperar indefinidamente, pero no esperará más que el tiempo de espera especificado. si hay al menos un carácter en el búfer para ser leído. [51]
Procesamiento de salida
El procesamiento de salida se mantiene prácticamente sin cambios desde sus raíces System III / System V. Las banderas de control del modo de salida determinan varias opciones:
- Se pueden insertar retornos de carro antes de cada carácter de salto de línea, para traducir la semántica de nueva línea de Unix a la semántica ASCII que esperan muchos terminales. [27] [22]
- Se puede dar tiempo a las terminales para que ejerzan varios códigos de control que (en un teletipo o similar) resultarían en movimientos físicos del carro que pueden tomar cantidades de tiempo significativas (desde el punto de vista de la computadora), como retrocesos, pestañas horizontales, carro devoluciones, avances de formulario y avances de línea. [27] [52]
Notas
- ↑ a b c Christian , 1988 , pág. 11.
- ^ Bourne 1983 , p. 6.
- ^ Ataúd 1991 , p. 820.
- ^ Ataúd 1991 , p. 23-24.
- ^ Leffler y col. 1989 , pág. 259.
- ↑ a b Ataúd , 1991 , p. 24.
- ^ Leffler y col. 1989 , pág. 37–38.
- ^ Afzal , 2008 , p. 419.
- ^ Frisch 2002 , p. 770.
- ↑ a b Ataúd , 1991 , p. 115.
- ^ Ataúd 1991 , p. 372.
- ^ Ataúd 1991 , p. 779.
- ^ Ataúd 1991 , p. 751–752.
- ^ Leffler y col. 1989 , pág. 265.
- ^ Leffler y col. 1989 , pág. 103.
- ^ Leffler y col. 1989 , pág. 38.
- ^ Leffler y col. 1989 , pág. 260–261.
- ^ a b c Leffler y col. 1989 , pág. 262.
- ^ Christian 1988 , p. 395.
- ^ Bourne 1983 , p. 8.
- ↑ a b Bourne , 1983 , p. 130-131.
- ↑ a b Bourne , 1983 , p. 287.
- ↑ a b Christian , 1988 , pág. 26.
- ^ Bourne 1983 , p. 132-133.
- ^ Leffler y col. 1989 , pág. 259–260.
- ↑ a b Bourne , 1983 , p. 288.
- ^ a b c d e f g Leffler et al. 1989 , pág. 260.
- ^ Bourne 1983 , p. 132.
- ^ Bourne 1983 , p. 133.
- ^ Christian 1988 , p. 393.
- ^ Leffler y col. 1989 , pág. 262–263.
- ^ "Fuente de la página de manual de System III tty (4)" . Consultado el 5 de octubre de 2012 .
- ↑ a b c Zlotnick , 1991 , p. 157.
- ↑ a b c d Zlotnick , 1991 , p. 163.
- ^ Bourne 1983 , p. 130.
- ^ Zlotnick 1991 , p. 158.
- ^ Zlotnick 1991 , p. 173-174.
- ^ Zlotnick 1991 , p. 162.
- ↑ a b Zlotnick , 1991 , p. 166.
- ^ Zlotnick 1991 , p. 162-163.
- ^ Zlotnick 1991 , p. 164.
- ^ Zlotnick 1991 , p. 165.
- ↑ a b c Zlotnick , 1991 , p. 167.
- ↑ a b c d e Zlotnick , 1991 , p. 169.
- ↑ a b c d Zlotnick , 1991 , p. 172.
- ↑ a b Zlotnick , 1991 , p. 174.
- ↑ a b Zlotnick , 1991 , p. 159.
- ^ Zlotnick 1991 , p. 160.
- ↑ a b Zlotnick , 1991 , p. 160-161.
- ^ Zlotnick 1991 , p. 161.
- ↑ a b c d Zlotnick , 1991 , p. 161-162.
- ^ Bourne 1983 , p. 287–288.
Fuentes
- Afzal, Amir (2008). UNIX ilimitado: un enfoque inicial (5ª ed.). Prentice Hall. ISBN 978-0-13-119449-6.
- Bourne, Stephen R. (1983). El sistema UNIX . Serie internacional de informática. Addison-Wesley. ISBN 978-0-201-13791-0.
- Christian, Kaare (1988). El sistema operativo UNIX (2ª ed.). John Wiley e hijos. ISBN 978-0-471-84781-6.
- Ataúd, Stephen (1991). Versión 4 del sistema UNIX V: la referencia completa . Osborne McGraw-Hill. ISBN 978-0-07-881653-6.
- Frisch, Æleen (2002). Administración del sistema esencial . Manual resumido (3ª ed.). O'Reilly Media, Inc. ISBN 978-0-596-00343-2.
- Leffler, Samuel J .; McKusick, Marshall Kirk ; Karels, Michael J .; Quarterman, John S. (1989). "Manejo terminal". El diseño e implementación del sistema operativo 4.3BSD UNIX . Serie Addison-Wesley en informática. Addison-Wesley. ISBN 978-0-201-06196-3.
- Zlotnick, Fred (1991). "Control de dispositivos terminales". El estándar POSIX.1: una guía del programador . Benjamin / Cummings Pub. Co. ISBN 978-0-8053-9605-8.
Otras lecturas
- "11. Interfaz de terminal general" . Especificaciones de la base de grupo abierto . 6. El Grupo Abierto . 2004.
- Lewine, Donald A. (1991). "Terminal I / O". Guía del programador POSIX: escribir programas UNIX portátiles con el estándar POSIX.1 . Serie de Ciencias de la Computación. O'Reilly Media, Inc. ISBN 978-0-937175-73-6.