github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/old/linux_backend/src/wsh/pty.c (about)

     1  #include <fcntl.h>
     2  #include <stdio.h>
     3  #include <string.h>
     4  #include <sys/ioctl.h>
     5  #include <sys/stat.h>
     6  #include <sys/types.h>
     7  #include <pty.h>
     8  
     9  #include "pty.h"
    10  
    11  /* Instead of using openpty from glibc, the following custom version is used
    12   * because we need to bypass dynamically loading the nsswitch libraries.
    13   * Executing glibc's openpty calls grantpt, which in turn depends on nsswitch
    14   * being loaded. The version of glibc inside a container may be different than
    15   * the version that wshd is compiled for, leading to undefined behavior. */
    16  int openpty(int *master, int *slave, char *slave_name) {
    17    int rv;
    18    int lock;
    19    int pty;
    20    char buf[32];
    21  
    22    /* Open master */
    23    rv = open("/dev/ptmx", O_RDWR | O_NOCTTY);
    24    if (rv == -1) {
    25      return -1;
    26    }
    27  
    28    *master = rv;
    29  
    30    /* Figure out PTY number */
    31    pty = 0;
    32    rv = ioctl(*master, TIOCGPTN, &pty);
    33    if (rv == -1) {
    34      return -1;
    35    }
    36  
    37    rv = snprintf(buf, sizeof(buf), "/dev/pts/%d", pty);
    38    if (rv >= sizeof(buf)) {
    39      return -1;
    40    }
    41  
    42    /* Unlock slave before opening it */
    43    lock = 0;
    44    rv = ioctl(*master, TIOCSPTLCK, &lock);
    45    if (rv == -1) {
    46      return -1;
    47    }
    48  
    49    /* Open slave */
    50    rv = open(buf, O_RDWR | O_NOCTTY);
    51    if (rv == -1) {
    52      return -1;
    53    }
    54  
    55    *slave = rv;
    56    if (slave_name != NULL) {
    57      strcpy(slave_name, buf);
    58    }
    59  
    60    return 0;
    61  }