rewrite getpty to make use openpty when its found, save the slave fd

so that cleanopen can use it if its available


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@14848 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-04-19 13:36:20 +00:00
parent 7adcb73bb8
commit 0ffd30a6e4

View File

@@ -358,6 +358,8 @@ getnpty()
* Returns the file descriptor of the opened pty. * Returns the file descriptor of the opened pty.
*/ */
static int ptyslavefd = -1;
static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; static char Xline[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
char *line = Xline; char *line = Xline;
@@ -378,150 +380,150 @@ static char *ptsname(int fd)
int getpty(int *ptynum) int getpty(int *ptynum)
{ {
#ifdef __osf__ /* XXX */ #if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__) /* XXX */
int master; {
int slave; int master;
if(openpty(&master, &slave, line, 0, 0) == 0){ int slave;
close(slave); if(openpty(&master, &slave, line, 0, 0) == 0){
return master; ptyslavefd = slave;
return master;
}
} }
return -1; #endif /* HAVE_OPENPTY .... */
#else
#ifdef HAVE__GETPTY #ifdef HAVE__GETPTY
int master, slave; {
char *p; int master;
p = _getpty(&master, O_RDWR, 0600, 1); char *p;
if(p == NULL) p = _getpty(&master, O_RDWR, 0600, 1);
return -1; if(p == NULL)
strlcpy(line, p, sizeof(Xline)); return -1;
return master; strlcpy(line, p, sizeof(Xline));
#else
int p;
char *cp, *p1, *p2;
int i;
#if SunOS == 40
int dummy;
#endif
#if __linux
int master;
int slave;
if(openpty(&master, &slave, line, 0, 0) == 0){
close(slave);
return master; return master;
} }
#else #endif
#ifdef STREAMSPTY
char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm",
"/dev/ptym/clone", 0 };
char **q; #ifdef STREAMSPTY
for(q=clone; *q; q++){ {
p=open(*q, O_RDWR); char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm",
if(p >= 0){ "/dev/ptym/clone", 0 };
char **q;
for(q=clone; *q; q++){
p=open(*q, O_RDWR);
if(p >= 0){
#ifdef HAVE_GRANTPT #ifdef HAVE_GRANTPT
grantpt(p); grantpt(p);
#endif #endif
#ifdef HAVE_UNLOCKPT #ifdef HAVE_UNLOCKPT
unlockpt(p); unlockpt(p);
#endif #endif
strlcpy(line, ptsname(p), sizeof(Xline)); strlcpy(line, ptsname(p), sizeof(Xline));
really_stream = 1; really_stream = 1;
return p; return p;
}
} }
} }
#endif /* STREAMSPTY */ #endif /* STREAMSPTY */
#ifndef _CRAY #ifndef _CRAY
{
int p;
char *cp, *p1, *p2;
int i;
#ifndef __hpux #ifndef __hpux
snprintf(line, sizeof(Xline), "/dev/ptyXX"); snprintf(line, sizeof(Xline), "/dev/ptyXX");
p1 = &line[8]; p1 = &line[8];
p2 = &line[9]; p2 = &line[9];
#else #else
snprintf(line, sizeof(Xline), "/dev/ptym/ptyXX"); snprintf(line, sizeof(Xline), "/dev/ptym/ptyXX");
p1 = &line[13]; p1 = &line[13];
p2 = &line[14]; p2 = &line[14];
#endif #endif
for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) { for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {
struct stat stb; struct stat stb;
*p1 = *cp; *p1 = *cp;
*p2 = '0'; *p2 = '0';
/* /*
* This stat() check is just to keep us from * This stat() check is just to keep us from
* looping through all 256 combinations if there * looping through all 256 combinations if there
* aren't that many ptys available. * aren't that many ptys available.
*/ */
if (stat(line, &stb) < 0) if (stat(line, &stb) < 0)
break; break;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
*p2 = "0123456789abcdef"[i]; *p2 = "0123456789abcdef"[i];
p = open(line, O_RDWR); p = open(line, O_RDWR);
if (p > 0) { if (p > 0) {
#ifndef __hpux
line[5] = 't';
#else
for (p1 = &line[8]; *p1; p1++)
*p1 = *(p1+1);
line[9] = 't';
#endif
chown(line, 0, 0);
chmod(line, 0600);
#if SunOS == 40 #if SunOS == 40
if (ioctl(p, TIOCGPGRP, &dummy) == 0 int dummy;
|| errno != EIO) { #endif
chmod(line, 0666);
close(p); #ifndef __hpux
line[5] = 'p'; line[5] = 't';
} else #else
for (p1 = &line[8]; *p1; p1++)
*p1 = *(p1+1);
line[9] = 't';
#endif
chown(line, 0, 0);
chmod(line, 0600);
#if SunOS == 40
if (ioctl(p, TIOCGPGRP, &dummy) == 0
|| errno != EIO) {
chmod(line, 0666);
close(p);
line[5] = 'p';
} else
#endif /* SunOS == 40 */ #endif /* SunOS == 40 */
return(p); return(p);
}
} }
} }
} }
#else /* CRAY */ #else /* CRAY */
extern lowpty, highpty; {
struct stat sb; extern lowpty, highpty;
struct stat sb;
int p;
for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) { for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) {
snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum); snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum);
p = open(myline, 2);
if (p < 0)
continue;
snprintf(line, sizeof(Xline), "/dev/ttyp%03d", *ptynum);
/*
* Here are some shenanigans to make sure that there
* are no listeners lurking on the line.
*/
if(stat(line, &sb) < 0) {
close(p);
continue;
}
if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
chown(line, 0, 0);
chmod(line, 0600);
close(p);
p = open(myline, 2); p = open(myline, 2);
if (p < 0) if (p < 0)
continue; continue;
} snprintf(line, sizeof(Xline), "/dev/ttyp%03d", *ptynum);
/* /*
* Now it should be safe...check for accessability. * Here are some shenanigans to make sure that there
*/ * are no listeners lurking on the line.
if (access(line, 6) == 0) */
return(p); if(stat(line, &sb) < 0) {
else { close(p);
/* no tty side to pty so skip it */ continue;
close(p); }
if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
chown(line, 0, 0);
chmod(line, 0600);
close(p);
p = open(myline, 2);
if (p < 0)
continue;
}
/*
* Now it should be safe...check for accessability.
*/
if (access(line, 6) == 0)
return(p);
else {
/* no tty side to pty so skip it */
close(p);
}
} }
} }
#endif /* CRAY */ #endif /* CRAY */
#endif /* STREAMSPTY */
#endif /* OPENPTY */
return(-1); return(-1);
#endif
} }
@@ -966,6 +968,9 @@ int cleanopen(char *line)
{ {
int t; int t;
if (ptyslavefd != -1)
return ptyslavefd;
#ifdef STREAMSPTY #ifdef STREAMSPTY
if (!really_stream) if (!really_stream)
#endif #endif