Back to index

glibc  2.9
Functions
openpty.c File Reference
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pty.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>

Go to the source code of this file.

Functions

static int pts_name (int fd, char **pts, size_t buf_len)
int openpty (int *amaster, int *aslave, char *name, const struct termios *termp, const struct winsize *winp)

Function Documentation

int openpty ( int amaster,
int aslave,
char *  name,
const struct termios termp,
const struct winsize winp 
)

Definition at line 87 of file openpty.c.

{
#ifdef PATH_MAX
  char _buf[PATH_MAX];
#else
  char _buf[512];
#endif
  char *buf = _buf;
  int master, slave;

  master = getpt ();
  if (master == -1)
    return -1;

  if (grantpt (master))
    goto fail;

  if (unlockpt (master))
    goto fail;

  if (pts_name (master, &buf, sizeof (_buf)))
    goto fail;

  slave = open (buf, O_RDWR | O_NOCTTY);
  if (slave == -1)
    {
      if (buf != _buf)
       free (buf);

      goto fail;
    }

  /* XXX Should we ignore errors here?  */
  if(termp)
    tcsetattr (slave, TCSAFLUSH, termp);
  if (winp)
    ioctl (slave, TIOCSWINSZ, winp);

  *amaster = master;
  *aslave = slave;
  if (name != NULL)
    strcpy (name, buf);

  if (buf != _buf)
    free (buf);
  return 0;

 fail:
  close (master);
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pts_name ( int  fd,
char **  pts,
size_t  buf_len 
) [static]

Definition at line 36 of file openpty.c.

{
  int rv;
  char *buf = *pts;

  for (;;)
    {
      char *new_buf;

      if (buf_len)
       {
         rv = ptsname_r (fd, buf, buf_len);

         if (rv != 0 || memchr (buf, '\0', buf_len))
           /* We either got an error, or we succeeded and the
              returned name fit in the buffer.  */
           break;

         /* Try again with a longer buffer.  */
         buf_len += buf_len;       /* Double it */
       }
      else
       /* No initial buffer; start out by mallocing one.  */
       buf_len = 128;              /* First time guess.  */

      if (buf != *pts)
       /* We've already malloced another buffer at least once.  */
       new_buf = realloc (buf, buf_len);
      else
       new_buf = malloc (buf_len);
      if (! new_buf)
       {
         rv = -1;
         __set_errno (ENOMEM);
         break;
       }
      buf = new_buf;
    }

  if (rv == 0)
    *pts = buf;             /* Return buffer to the user.  */
  else if (buf != *pts)
    free (buf);             /* Free what we malloced when returning an error.  */

  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function: