- master_fd = -1;
- for (i = 0; i < 64; ++i) {
- slprintf(loop_name, sizeof(loop_name), "/dev/pty%c%x",
- 'p' + i / 16, i % 16);
- master_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
- if (master_fd >= 0)
- break;
+#ifdef TIOCGPTN
+ /*
+ * Try the unix98 way first.
+ */
+ mfd = open("/dev/ptmx", O_RDWR);
+ if (mfd >= 0) {
+ int ptn;
+ if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
+ slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
+ chmod(pty_name, S_IRUSR | S_IWUSR);
+#ifdef TIOCSPTLCK
+ ptn = 0;
+ if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
+ warn("Couldn't unlock pty slave %s: %m", pty_name);
+#endif
+ if ((sfd = open(pty_name, O_RDWR)) < 0)
+ warn("Couldn't open pty slave %s: %m", pty_name);
+ }
+ }
+#endif /* TIOCGPTN */
+
+ if (sfd < 0) {
+ /* the old way - scan through the pty name space */
+ for (i = 0; i < 64; ++i) {
+ slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
+ 'p' + i / 16, i % 16);
+ mfd = open(pty_name, O_RDWR, 0);
+ if (mfd >= 0) {
+ pty_name[5] = 't';
+ sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
+ if (sfd >= 0) {
+ fchown(sfd, uid, -1);
+ fchmod(sfd, S_IRUSR | S_IWUSR);
+ break;
+ }
+ close(mfd);
+ }
+ }