Back to index

glibc  2.9
Defines | Functions | Variables
ptsname.c File Reference
#include <errno.h>
#include <paths.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <termios.h>
#include <unistd.h>
#include <stdio-common/_itoa.h>

Go to the source code of this file.

Defines

#define MASTER_P(Dev)
#define SLAVE_P(Dev)
#define _PATH_DEVPTS   "/dev/pts/"

Functions

char * ptsname (int fd)
int __ptsname_r (int fd, char *buf, size_t buflen)

Variables

const char __libc_ptyname1[] attribute_hidden
static char buffer [sizeof(_PATH_DEVPTS)+20]

Define Documentation

#define _PATH_DEVPTS   "/dev/pts/"

Definition at line 50 of file ptsname.c.

#define MASTER_P (   Dev)
Value:
(major ((Dev)) == 2                                                         \
   || (major ((Dev)) == 4 && minor ((Dev)) >= 128 && minor ((Dev)) < 192)     \
   || (major ((Dev)) >= 128 && major ((Dev)) < 136))

Definition at line 33 of file ptsname.c.

#define SLAVE_P (   Dev)
Value:
(major ((Dev)) == 3                                                         \
   || (major ((Dev)) == 4 && minor ((Dev)) >= 192 && minor ((Dev)) < 256)     \
   || (major ((Dev)) >= 136 && major ((Dev)) < 144))

Definition at line 39 of file ptsname.c.


Function Documentation

int __ptsname_r ( int  fd,
char *  buf,
size_t  buflen 
)

Definition at line 74 of file ptsname.c.

{
  int save_errno = errno;
  struct stat64 st;
  unsigned int ptyno;

  if (buf == NULL)
    {
      __set_errno (EINVAL);
      return EINVAL;
    }

  if (!__isatty (fd))
    {
      __set_errno (ENOTTY);
      return ENOTTY;
    }

#ifdef TIOCGPTN
  if (__ioctl (fd, TIOCGPTN, &ptyno) == 0)
    {
      /* Buffer we use to print the number in.  For a maximum size for
         `int' of 8 bytes we never need more than 20 digits.  */
      char numbuf[21];
      const char *devpts = _PATH_DEVPTS;
      const size_t devptslen = strlen (_PATH_DEVPTS);
      char *p;

      numbuf[sizeof (numbuf) - 1] = '\0';
      p = _itoa_word (ptyno, &numbuf[sizeof (numbuf) - 1], 10, 0);

      if (buflen < devptslen + (&numbuf[sizeof (numbuf)] - p))
       {
         __set_errno (ERANGE);
         return ERANGE;
       }

      memcpy (__stpcpy (buf, devpts), p, &numbuf[sizeof (numbuf)] - p);
    }
  else if (errno == EINVAL)
#endif
    {
      char *p;

      if (buflen < strlen (_PATH_TTY) + 3)
       {
         __set_errno (ERANGE);
         return ERANGE;
       }

      if (__fxstat64 (_STAT_VER, fd, &st) < 0)
       return errno;

      /* Check if FD really is a master pseudo terminal.  */
      if (! MASTER_P (st.st_rdev))
       {
         __set_errno (ENOTTY);
         return ENOTTY;
       }

      ptyno = minor (st.st_rdev);
      /* This is for the old BSD pseudo terminals.  As of Linux
         2.1.115 these are no longer supported.  */
      if (major (st.st_rdev) == 4)
       ptyno -= 128;

      if (ptyno / 16 >= strlen (__libc_ptyname1))
       {
         __set_errno (ENOTTY);
         return ENOTTY;
       }

      p = __stpcpy (buf, _PATH_TTY);
      p[0] = __libc_ptyname1[ptyno / 16];
      p[1] = __libc_ptyname2[ptyno % 16];
      p[2] = '\0';
    }

  if (__xstat64 (_STAT_VER, buf, &st) < 0)
    return errno;

  /* Check if the name we're about to return really corresponds to a
     slave pseudo terminal.  */
  if (! S_ISCHR (st.st_mode) || ! SLAVE_P (st.st_rdev))
    {
      /* This really is a configuration problem.  */
      __set_errno (ENOTTY);
      return ENOTTY;
    }

  __set_errno (save_errno);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* ptsname ( int  fd)

Definition at line 64 of file ptsname.c.

{
  return __ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer;
}

Here is the call graph for this function:


Variable Documentation

const char __libc_ptyname2 [] attribute_hidden

Definition at line 54 of file ptsname.c.

char buffer[sizeof(_PATH_DEVPTS)+20] [static]

Definition at line 57 of file ptsname.c.