GNU/Linux >> Tutoriels Linux >  >> Linux

Comment fonctionnent les pseudo-terminaux *nix ? Quel est le canal maître/esclave ?

En ce qui concerne la partie maître/esclave de votre question, à partir de la page de manuel pty(4) (qui est référencée à partir de la page de manuel openpty(3) sur mon système) :

Un pseudo-terminal est une paire de dispositifs de caractères, un dispositif maître et un dispositif esclave. Le périphérique esclave fournit à un processus une interface identique à celle décrite dans tty (4). Cependant, alors que tous les autres périphériques qui fournissent l'interface décrite dans tty (4) ont un périphérique matériel d'une certaine sorte derrière eux, le périphérique esclave a, à la place, un autre processus le manipulant via la moitié maîtresse du pseudo terminal. C'est-à-dire que tout ce qui est écrit sur l'appareil maître est transmis à l'appareil esclave comme entrée et tout ce qui est écrit sur l'appareil esclave est présenté comme entrée sur l'appareil maître.

Les pages de manuel sont vos amis.


Je viens d'essayer les exemples trouvés sur ce tutoriel, ils fonctionnent très bien pour moi et je pense qu'ils sont un point de départ intéressant pour le problème.

EDIT :Le tutoriel explique brièvement la fonction des pseudo-terminaux. L'explication se fait étape par étape et est suivie d'exemples.

L'exemple suivant montre comment créer un nouveau pseudo-terminal et fork le processus en deux parties, une écrivant sur le maître côté du pseudo-terminal, l'autre lecture depuis l'esclave côté du 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'est-ce que NGINX ? Comment ça marche?

  2. Comment fonctionne le Sticky Bit ?

  3. Comment fonctionnent les composants internes de Sudo ?

  4. Qu'est-ce que le DNS et comment ça marche ?

  5. Comment savoir ce que signifie 'errno' ?

Comment configurer la réplication maître-esclave MySQL

Comment fonctionnent les composants internes du démon Cron ?

Comment signaler la fin de l'entrée Stdin ?

Comment fonctionne un équilibreur de charge ? Qu'est-ce que l'équilibrage de charge ?

Comment fonctionnent les macros probables/improbables du noyau Linux et quel est leur avantage ?

Comment fonctionnent les options '-s', '-t' et '-c' de la commande tr sous Unix ?