summaryrefslogtreecommitdiff
path: root/ext/pty
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-07-26 09:15:31 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2006-07-26 09:15:31 +0000
commite0ba1de2b1e57d92248d8cd8878e838e25aadb86 (patch)
tree8cdb083e5cba69bf6a2890d5dbb4a7a01b11b698 /ext/pty
parent1bc1c9f103c60fed79a1aac57da3323ad5e18ba4 (diff)
* ext/pty/pty.c (getDevice): retry once after GC on failure.
[ruby-core:08282] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@10607 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/pty')
-rw-r--r--ext/pty/pty.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index db072744d6..626898ae76 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -304,40 +304,36 @@ pty_finalize_syswait(info)
return Qnil;
}
-#ifdef HAVE_OPENPTY
+static int
+get_device_once(master, slave, fail)
+ int *master, *slave, fail;
+{
+#if defined HAVE_OPENPTY
/*
* Use openpty(3) of 4.3BSD Reno and later,
* or the same interface function.
*/
-static void
-getDevice(master,slave)
- int *master,*slave;
-{
if (openpty(master, slave, SlaveName,
(struct termios *)0, (struct winsize *)0) == -1) {
+ if (!fail) return -1;
rb_raise(rb_eRuntimeError, "openpty() failed");
}
-}
-#else /* HAVE_OPENPTY */
-#ifdef HAVE__GETPTY
-static void
-getDevice(master,slave)
- int *master,*slave;
-{
+
+ return 0;
+#elif defined HAVE__GETPTY
char *name;
if (!(name = _getpty(master, O_RDWR, 0622, 0))) {
+ if (!fail) return -1;
rb_raise(rb_eRuntimeError, "_getpty() failed");
}
*slave = open(name, O_RDWR);
strcpy(SlaveName, name);
+
+ return 0;
}
#else /* HAVE__GETPTY */
-static void
-getDevice(master,slave)
- int *master,*slave;
-{
int i,j;
#ifdef HAVE_PTSNAME
@@ -362,7 +358,7 @@ getDevice(master,slave)
*master = i;
*slave = j;
strcpy(SlaveName, pn);
- return;
+ return 0;
#if defined I_PUSH && !defined linux
}
}
@@ -373,7 +369,8 @@ getDevice(master,slave)
}
close(i);
}
- rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
+ if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
+ return -1;
#else
char **p;
char MasterName[DEVICELEN];
@@ -387,16 +384,26 @@ getDevice(master,slave)
*slave = j;
chown(SlaveName, getuid(), getgid());
chmod(SlaveName, 0622);
- return;
+ return 0;
}
close(i);
}
}
- rb_raise(rb_eRuntimeError, "can't get %s", SlaveName);
+ if (fail) rb_raise(rb_eRuntimeError, "can't get %s", SlaveName);
+ return -1;
#endif
+#endif
+}
+
+static void
+getDevice(master, slave)
+ int *master, *slave;
+{
+ if (get_device_once(master, slave, 0)) {
+ rb_gc();
+ get_device_once(master, slave, 1);
+ }
}
-#endif /* HAVE__GETPTY */
-#endif /* HAVE_OPENPTY */
static void
freeDevice()