diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-12-16 10:49:12 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-12-16 10:49:12 +0000 |
commit | d057d3a47003d79d846eedbabd55a3b31b688e5e (patch) | |
tree | 3fb0bcebba1366187c66bfa8785e5f954fbf4264 | |
parent | 9f3aabd935759314fc308c4bb7630acf0f7db395 (diff) | |
download | ruby-d057d3a47003d79d846eedbabd55a3b31b688e5e.tar.gz ruby-d057d3a47003d79d846eedbabd55a3b31b688e5e.tar.xz ruby-d057d3a47003d79d846eedbabd55a3b31b688e5e.zip |
* ext/pty/extconf.rb: check posix_openpt.
* ext/pty/pty.c (get_device_once): use posix_openpt if available.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@20793 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | ext/pty/extconf.rb | 3 | ||||
-rw-r--r-- | ext/pty/pty.c | 46 | ||||
-rw-r--r-- | test/test_pty.rb | 19 |
4 files changed, 68 insertions, 6 deletions
@@ -1,3 +1,9 @@ +Tue Dec 16 19:48:18 2008 Tanaka Akira <akr@fsij.org> + + * ext/pty/extconf.rb: check posix_openpt. + + * ext/pty/pty.c (get_device_once): use posix_openpt if available. + Tue Dec 16 19:43:53 2008 Tanaka Akira <akr@fsij.org> * re.c: use strlcpy for error messages. diff --git a/ext/pty/extconf.rb b/ext/pty/extconf.rb index 87fbdc602..b26600ab3 100644 --- a/ext/pty/extconf.rb +++ b/ext/pty/extconf.rb @@ -6,7 +6,8 @@ if /mswin|mingw|bccwin/ !~ RUBY_PLATFORM have_header("libutil.h") have_header("pty.h") have_library("util", "openpty") - if have_func("openpty") or + if have_func("posix_openpt") or + have_func("openpty") or have_func("_getpty") or have_func("ptsname") or have_func("ioctl") diff --git a/ext/pty/pty.c b/ext/pty/pty.c index d190aba94..a8a02d876 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -2,6 +2,7 @@ #ifdef RUBY_EXTCONF_H #include RUBY_EXTCONF_H #endif +#include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -272,7 +273,44 @@ establishShell(int argc, VALUE *argv, struct pty_info *info, static int get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail) { -#if defined HAVE_OPENPTY +#if defined(HAVE_POSIX_OPENPT) + int masterfd,slavefd; + char *slavedevice; + struct sigaction dfl, old; + + dfl.sa_handler = SIG_DFL; + dfl.sa_flags = 0; + sigemptyset(&dfl.sa_mask); + + if((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) != -1) { + sigaction(SIGCHLD, &dfl, &old); + if(grantpt(masterfd) != -1) { + sigaction(SIGCHLD, &old, NULL); + if(unlockpt(masterfd) != -1) { + if((slavedevice = ptsname(masterfd)) != NULL) { + if((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) != -1) { +#if defined I_PUSH && !defined linux + if(ioctl(slavefd, I_PUSH, "ptem") != -1) { + if(ioctl(slavefd, I_PUSH, "ldterm") != -1) { + ioctl(slavefd, I_PUSH, "ttcompat"); +#endif + *master = masterfd; + *slave = slavefd; + strlcpy(SlaveName, slavedevice, DEVICELEN); + return 0; +#if defined I_PUSH && !defined linux + } + } +#endif + } + } + } + } + close(masterfd); + } + if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device"); + return -1; +#elif defined HAVE_OPENPTY /* * Use openpty(3) of 4.3BSD Reno and later, * or the same interface function. @@ -296,10 +334,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail) strlcpy(SlaveName, name, DEVICELEN); return 0; -#else /* HAVE__GETPTY */ +#elif defined(HAVE_PTSNAME) int i,j; - -#ifdef HAVE_PTSNAME char *pn; void (*s)(); @@ -336,6 +372,7 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail) if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device"); return -1; #else + int i,j; const char *const *p; char MasterName[DEVICELEN]; @@ -356,7 +393,6 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail) if (fail) rb_raise(rb_eRuntimeError, "can't get %s", SlaveName); return -1; #endif -#endif } static void diff --git a/test/test_pty.rb b/test/test_pty.rb index 684ab2c01..704861dd3 100644 --- a/test/test_pty.rb +++ b/test/test_pty.rb @@ -98,5 +98,24 @@ class TestPTY < Test::Unit::TestCase } end + def test_stat_slave + # If grantpt is used, the slave device is changed as follows. + # owner: real UID + # group: an unspecified value (e.g. tty) + # mode: 0620 (rw--w----) + # + # The group is not testable because unspecified. + # + # The mode is testable but the condition is relaxed because other + # pty functions (openpty, _getpty, etc.) may not use 0620. + # But no one can read from the tty, I hope (for security reason). + # + PTY.open {|master, slave| + s = File.stat(slave.path) + assert_equal(Process.uid, s.uid) + assert_equal(0600, s.mode & 0755) + } + end + end if defined? PTY |