2 * openpty() tries to open a pty; applications won't have to
3 * duplicate this code all the time (or change it if the system
4 * pty interface changes).
6 * First version by Ben Gras <beng@few.vu.nl>,
7 * Initially heavily based on telnetd/pty.c
8 * by Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>.
20 #include <sys/types.h>
22 #include <sys/ioc_tty.h>
24 #define DEV_DIR "/dev"
27 * Allocate a PTY, by trying to open one repeatedly.
29 int openpty(int *amaster
, int *aslave
, char *name
,
30 struct termios
*termp
, struct winsize
*winp
)
32 char buff
[128], temp
[128];
35 static char tty_name
[128];
36 struct group
*ttygroup
;
39 if(!amaster
|| !aslave
) {
44 for(i
= 'p'; i
< 'w'; i
++) {
47 sprintf(buff
, "%s/pty%c%c",
48 DEV_DIR
, i
, (j
< 10) ? j
+ '0' : j
+ 'a' - 10);
50 if((*amaster
= open(buff
, O_RDWR
)) >= 0) {
51 sprintf(tty_name
, "%s/tty%c%c", DEV_DIR
,
52 i
, (j
< 10) ? j
+ '0' : j
+ 'a' - 10);
53 if((*aslave
= open(tty_name
, O_RDWR
)) >= 0)
62 /* Did we find one? */
65 if (*amaster
< 0) { errno
= ENOENT
; return(-1); }
68 ttygroup
= getgrnam("tty");
70 if(ttygroup
) tty_gid
= ttygroup
->gr_gid
;
72 if(name
) strcpy(name
, tty_name
);
74 /* Ignore errors on these. */
75 chown(tty_name
, getuid(), tty_gid
);
76 chmod(tty_name
, 0620); /* -rw--w---- */
77 if(termp
) tcsetattr(*aslave
, TCSAFLUSH
, termp
);
78 if(winp
) ioctl(*aslave
, TIOCSWINSZ
, winp
);