blob: b1660a13b78c457803d48c852700c5cadf1ebb4c [file] [log] [blame]
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <grp.h>
#include <stdlib.h>
/**
* This is taken from R. W. Stevens book.
* Alain Magloire.
*/
int ptym_open (char *pts_name);
int ptys_open (int fdm, char * pts_name);
int
openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp)
{
char line[20];
line[0]=0;
*amaster = ptym_open(line);
if (*amaster < 0)
return -1;
*aslave = ptys_open(*amaster, line);
if (*aslave < 0) {
close(*amaster);
return -1;
}
if (name)
strcpy(name, line);
#ifndef TCSAFLUSH
#define TCSAFLUSH TCSETAF
#endif
if (termp)
(void) tcsetattr(*aslave, TCSAFLUSH, termp);
#ifdef TIOCSWINSZ
if (winp)
(void) ioctl(*aslave, TIOCSWINSZ, (char *)winp);
#endif
return 0;
}
int
ptym_open(char * pts_name)
{
char *ptr1, *ptr2;
int fdm;
strcpy(pts_name, "/dev/ptyXY");
/* array index: 012345689 (for references in following code) */
for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
pts_name[8] = *ptr1;
for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
pts_name[9] = *ptr2;
/* try to open master */
fdm = open(pts_name, O_RDWR);
if (fdm < 0) {
if (errno == ENOENT) {/* different from EIO */
return -1; /* out of pty devices */
} else {
continue; /* try next pty device */
}
}
pts_name[5] = 't'; /* chage "pty" to "tty" */
return fdm; /* got it, return fd of master */
}
}
return -1; /* out of pty devices */
}
int
ptys_open(int fdm, char * pts_name)
{
int gid, fds;
struct group *grptr;
grptr = getgrnam("tty");
if (grptr != NULL) {
gid = grptr->gr_gid;
} else {
gid = -1; /* group tty is not in the group file */
}
/* following two functions don't work unless we're root */
chown(pts_name, getuid(), gid);
chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP);
fds = open(pts_name, O_RDWR);
if (fds < 0) {
close(fdm);
return -1;
}
return fds;
}