summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--bootstraptest/test_io.rb6
-rw-r--r--configure.in3
-rw-r--r--io.c16
4 files changed, 30 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 76e7be2257..50c6ce694d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sun Jan 6 18:43:48 2013 Yuki Yugui Sonoda <yugui@yugui.jp>
+
+ * bootstraptest/test_io.c: add a test for [ruby-dev:46834].
+
+ * io.c (rb_cloexec_fcntl_dupfd) Use an emulation with dup(2) when
+ fcntl(2) and/or F_DUPFD is unavailable.
+ Suggested by akr.
+
+ * configure.in (HAVE_FCNTL): NativeClient does not provide fcntl(2).
+
Sun Jan 6 11:11:26 2013 Eric Hodel <drbrain@segment7.net>
* doc/syntax/modules_and_classes.rdoc: Fixed typo.
diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb
index ff858b67fb..f7360f34b3 100644
--- a/bootstraptest/test_io.rb
+++ b/bootstraptest/test_io.rb
@@ -74,6 +74,12 @@ assert_equal 'ok', %q{
:ok
}
+assert_equal 'ok', %q{
+ dup = STDIN.dup
+ dupfd = dup.fileno
+ dupfd == STDIN.dup.fileno ? :ng : :ok
+}, '[ruby-dev:46834]'
+
assert_normal_exit %q{
ARGF.set_encoding "foo"
}
diff --git a/configure.in b/configure.in
index 5475abc278..b87b325248 100644
--- a/configure.in
+++ b/configure.in
@@ -1302,6 +1302,7 @@ $POSTLINK"
RUBY_APPEND_OPTION(XCFLAGS, -fPIC)
fi
ac_cv_func_shutdown=no
+ ac_cv_func_fcntl=no
],
[ LIBS="-lm $LIBS"])
AC_CHECK_LIB(crypt, crypt)
@@ -1576,7 +1577,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall __syscall chroot ge
setuid setgid daemon select_large_fdset setenv unsetenv\
mktime timegm gmtime_r clock_gettime gettimeofday poll ppoll\
pread sendfile shutdown sigaltstack dl_iterate_phdr\
- dup3 pipe2 posix_memalign memalign ioctl)
+ dup dup3 pipe2 posix_memalign memalign ioctl)
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
[AC_TRY_COMPILE([
diff --git a/io.c b/io.c
index ea52db0a35..bd21de0102 100644
--- a/io.c
+++ b/io.c
@@ -168,7 +168,7 @@ void
rb_maygvl_fd_fix_cloexec(int fd)
{
/* MinGW don't have F_GETFD and FD_CLOEXEC. [ruby-core:40281] */
-#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC) && !defined(__native_client__)
+#if defined(HAVE_FCNTL) && defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
int flags, flags2, ret;
flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
if (flags == -1) {
@@ -298,7 +298,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
{
int ret;
-#if defined(HAVE_FCNTL) && defined(F_DUPFD_CLOEXEC) && defined(F_DUPFD) && !defined(__native_client__)
+#if defined(HAVE_FCNTL) && defined(F_DUPFD_CLOEXEC) && defined(F_DUPFD)
static int try_dupfd_cloexec = 1;
if (try_dupfd_cloexec) {
ret = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
@@ -318,10 +318,18 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd)
else {
ret = fcntl(fd, F_DUPFD, minfd);
}
-#elif defined(HAVE_FCNTL) && defined(F_DUPFD) && !defined(__native_client__)
+#elif defined(HAVE_FCNTL) && defined(F_DUPFD)
ret = fcntl(fd, F_DUPFD, minfd);
+#elif defined(HAVE_DUP)
+ ret = dup(fd);
+ if (ret != -1 && ret < minfd) {
+ const int prev_fd = ret;
+ ret = rb_cloexec_fcntl_dupfd(fd, minfd);
+ close(prev_fd);
+ }
+ return ret;
#else
- ret = dup2(fd, minfd);
+# error "dup() or fcntl(F_DUPFD) must be supported."
#endif
if (ret == -1) return -1;
rb_maygvl_fd_fix_cloexec(ret);