1  /* Copyright (C) 1998-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <fcntl.h>
      20  #include <string.h>
      21  #include <unistd.h>
      22  #include <stdlib.h>
      23  
      24  /* Prefix for master pseudo terminal nodes.  */
      25  #define _PATH_PTY "/dev/pty"
      26  
      27  
      28  /* Letters indicating a series of pseudo terminals.  */
      29  #ifndef PTYNAME1
      30  #define PTYNAME1 "pqrsPQRS"
      31  #endif
      32  const char __libc_ptyname1[] attribute_hidden = PTYNAME1;
      33  
      34  /* Letters indicating the position within a series.  */
      35  #ifndef PTYNAME2
      36  #define PTYNAME2 "0123456789abcdefghijklmnopqrstuv";
      37  #endif
      38  const char __libc_ptyname2[] attribute_hidden = PTYNAME2;
      39  
      40  
      41  /* Open a master pseudo terminal and return its file descriptor.  */
      42  int
      43  __bsd_openpt (int oflag)
      44  {
      45    char buf[sizeof (_PATH_PTY) + 2];
      46    const char *p, *q;
      47    char *s;
      48  
      49    s = __mempcpy (buf, _PATH_PTY, sizeof (_PATH_PTY) - 1);
      50    /* s[0] and s[1] will be filled in the loop.  */
      51    s[2] = '\0';
      52  
      53    for (p = __libc_ptyname1; *p != '\0'; ++p)
      54      {
      55        s[0] = *p;
      56  
      57        for (q = __libc_ptyname2; *q != '\0'; ++q)
      58  	{
      59  	  int fd;
      60  
      61  	  s[1] = *q;
      62  
      63  	  fd = __open (buf, oflag);
      64  	  if (fd != -1)
      65  	    return fd;
      66  
      67  	  if (errno == ENOENT)
      68  	    return -1;
      69  	}
      70      }
      71  
      72    __set_errno (ENOENT);
      73    return -1;
      74  }
      75  
      76  int
      77  __getpt (void)
      78  {
      79    return __bsd_openpt (O_RDWR);
      80  }
      81  libc_hidden_def (__getpt)
      82  weak_alias (__getpt, getpt)
      83  
      84  int
      85  __posix_openpt (int oflag)
      86  {
      87    return __bsd_openpt (oflag);
      88  }
      89  weak_alias (__posix_openpt, posix_openpt)