GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo funcionan los pseudo-terminales *nix? ¿Cuál es el canal maestro/esclavo?

Con respecto a la parte maestro/esclavo de su pregunta, de la página de manual de pty(4) (a la que se hace referencia en la página de manual de openpty(3) en mi sistema):

Un pseudo terminal es un par de dispositivos de carácter, un dispositivo maestro y un dispositivo esclavo. El dispositivo esclavo proporciona a un proceso una interfaz idéntica a la descrita en tty (4). Sin embargo, mientras que todos los demás dispositivos que proporcionan la interfaz descrita en tty (4) tienen un dispositivo de hardware de algún tipo detrás de ellos, el dispositivo esclavo tiene, en cambio, otro proceso que lo manipula a través de la mitad maestra del pseudo terminal. Es decir, cualquier cosa escrita en el dispositivo maestro se entrega al dispositivo esclavo como entrada y cualquier cosa escrita en el dispositivo esclavo se presenta como entrada en el dispositivo maestro.

Las páginas man son tus amigas.


Acabo de probar los ejemplos que se encuentran en este tutorial, funcionan muy bien para mí y creo que son un punto de partida interesante para el problema.

EDITAR:El tutorial explica brevemente la función de pseudo-terminales. La explicación se hace paso a paso y va seguida de ejemplos.

El siguiente ejemplo muestra cómo crear un nuevo pseudo-terminal y fork el proceso en dos partes, una escribiendo en el maestro lado de la pseudo-terminal, la otra lectura del esclavo lado del pseudo-terminal.

#define _XOPEN_SOURCE 600 
#include <stdlib.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <unistd.h> 
#include <stdio.h> 
#define __USE_BSD 
#include <termios.h> 


int main(void) 
{ 
int fdm, fds, rc; 
char input[150]; 

fdm = posix_openpt(O_RDWR); 
if (fdm < 0) 
{ 
fprintf(stderr, "Error %d on posix_openpt()\n", errno); 
return 1; 
} 

rc = grantpt(fdm); 
if (rc != 0) 
{ 
fprintf(stderr, "Error %d on grantpt()\n", errno); 
return 1; 
} 

rc = unlockpt(fdm); 
if (rc != 0) 
{ 
fprintf(stderr, "Error %d on unlockpt()\n", errno); 
return 1; 
} 

// Open the slave PTY
fds = open(ptsname(fdm), O_RDWR); 
printf("Virtual interface configured\n");
printf("The master side is named : %s\n", ptsname(fdm));

// Creation of a child process
if (fork()) 
{ 
  // Father
 
  // Close the slave side of the PTY 
  close(fds); 
  while (1) 
  { 
    // Operator's entry (standard input = terminal) 
    write(1, "Input : ", sizeof("Input : ")); 
    rc = read(0, input, sizeof(input)); 
    if (rc > 0) 
    {
      // Send the input to the child process through the PTY 
      write(fdm, input, rc); 

      // Get the child's answer through the PTY 
      rc = read(fdm, input, sizeof(input) - 1); 
      if (rc > 0) 
      { 
        // Make the answer NUL terminated to display it as a string
        input[rc] = '\0'; 

        fprintf(stderr, "%s", input); 
      } 
      else 
      { 
        break; 
      } 
    } 
    else 
    { 
      break; 
    } 
  } // End while 
} 
else 
{ 
struct termios slave_orig_term_settings; // Saved terminal settings 
struct termios new_term_settings; // Current terminal settings 

  // Child

  // Close the master side of the PTY 
  close(fdm); 

  // Save the default parameters of the slave side of the PTY 
  rc = tcgetattr(fds, &slave_orig_term_settings); 

  // Set raw mode on the slave side of the PTY
  new_term_settings = slave_orig_term_settings; 
  cfmakeraw (&new_term_settings); 
  tcsetattr (fds, TCSANOW, &new_term_settings); 

  // The slave side of the PTY becomes the standard input and outputs of the child process 
  close(0); // Close standard input (current terminal) 
  close(1); // Close standard output (current terminal) 
  close(2); // Close standard error (current terminal) 

  dup(fds); // PTY becomes standard input (0) 
  dup(fds); // PTY becomes standard output (1) 
  dup(fds); // PTY becomes standard error (2) 

  while (1) 
  { 
    rc = read(fds, input, sizeof(input) - 1); 

    if (rc > 0) 
    { 
      // Replace the terminating \n by a NUL to display it as a string
      input[rc - 1] = '\0'; 

      printf("Child received : '%s'\n", input); 
    } 
    else 
    { 
      break; 
    } 
  } // End while 
} 

return 0; 
} // main

Linux
  1. ¿Qué es un servidor web y cómo funciona un servidor web?

  2. ¿Cómo funcionan la entrada de teclado y la salida de texto?

  3. ¿Cuáles son las responsabilidades de cada componente de pseudoterminal (pty) (software, lado maestro, lado esclavo)?

  4. ¿Cómo funcionan las macros probables/improbables en el kernel de Linux y cuál es su beneficio?

  5. ¿Cómo saber qué significa el 'errno'?

Cómo configurar la replicación de esclavo maestro de MySQL

¿Qué es el DNS y cómo funciona?

¿Cómo funciona un balanceador de carga? ¿Qué es el equilibrio de carga?

¿Cuál es el significado de *nix?

¿Cómo funcionan las opciones '-s', '-t' y '-c' del comando tr en Unix?

¿Cómo funciona el comando ps?