summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-io
diff options
context:
space:
mode:
authorHiroshi Mimaki <[email protected]>2020-06-05 12:42:56 +0900
committerHiroshi Mimaki <[email protected]>2020-06-05 12:42:56 +0900
commit81d340e0421daf39a8208a0181d6a54e726db134 (patch)
tree18cefdd763a716dbd27c23bfdf98ffa2135f7624 /mrbgems/mruby-io
parentf9d113f7647121f8578742a2a9ac256ece365e3f (diff)
parent4e40169ed6d200918e542aa8d8e64634794e1864 (diff)
downloadmruby-81d340e0421daf39a8208a0181d6a54e726db134.tar.gz
mruby-81d340e0421daf39a8208a0181d6a54e726db134.zip
Merge master.
Diffstat (limited to 'mrbgems/mruby-io')
-rw-r--r--mrbgems/mruby-io/include/mruby/ext/io.h6
-rw-r--r--mrbgems/mruby-io/src/file.c32
-rw-r--r--mrbgems/mruby-io/src/file_test.c18
-rw-r--r--mrbgems/mruby-io/src/io.c105
-rw-r--r--mrbgems/mruby-io/test/file.rb30
-rw-r--r--mrbgems/mruby-io/test/io.rb4
-rw-r--r--mrbgems/mruby-io/test/mruby_io_test.c86
7 files changed, 151 insertions, 130 deletions
diff --git a/mrbgems/mruby-io/include/mruby/ext/io.h b/mrbgems/mruby-io/include/mruby/ext/io.h
index 38ed0f222..dfff8e0e0 100644
--- a/mrbgems/mruby-io/include/mruby/ext/io.h
+++ b/mrbgems/mruby-io/include/mruby/ext/io.h
@@ -18,7 +18,7 @@ extern "C" {
#if defined(MRB_WITHOUT_IO_PREAD_PWRITE)
# undef MRB_WITH_IO_PREAD_PWRITE
#elif !defined(MRB_WITH_IO_PREAD_PWRITE)
-# if defined(__unix__)
+# if defined(__unix__) || defined(__MACH__)
# define MRB_WITH_IO_PREAD_PWRITE
# endif
#endif
@@ -50,8 +50,8 @@ struct mrb_io {
#define MRB_O_SHARE_DELETE 0x1000
#define MRB_O_TMPFILE 0x2000
#define MRB_O_NOATIME 0x4000
-#define MRB_O_DSYNC 0x00008000 /* Ignored with MRB_INT16 and MRB_WITHOUT_FLOAT */
-#define MRB_O_RSYNC 0x00010000 /* Ignored with MRB_INT16 and MRB_WITHOUT_FLOAT */
+#define MRB_O_DSYNC 0x00008000
+#define MRB_O_RSYNC 0x00010000
#define MRB_O_RDONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDONLY))
#define MRB_O_WRONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_WRONLY))
diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c
index e166d82fa..dd65e2da9 100644
--- a/mrbgems/mruby-io/src/file.c
+++ b/mrbgems/mruby-io/src/file.c
@@ -89,7 +89,7 @@ flock(int fd, int operation) {
}
#endif
-mrb_value
+static mrb_value
mrb_file_s_umask(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -265,7 +265,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
return result;
}
-mrb_value
+static mrb_value
mrb_file__getwd(mrb_state *mrb, mrb_value klass)
{
mrb_value path;
@@ -401,7 +401,7 @@ mrb_file_mtime(mrb_state *mrb, mrb_value self)
return mrb_funcall(mrb, obj, "at", 1, mrb_fixnum_value(st.st_mtime));
}
-mrb_value
+static mrb_value
mrb_file_flock(mrb_state *mrb, mrb_value self)
{
#if defined(sun)
@@ -458,7 +458,7 @@ mrb_file_size(mrb_state *mrb, mrb_value self)
}
static int
-mrb_ftruncate(int fd, int64_t length)
+mrb_ftruncate(int fd, mrb_int length)
{
#ifndef _WIN32
return ftruncate(fd, (off_t)length);
@@ -491,32 +491,12 @@ static mrb_value
mrb_file_truncate(mrb_state *mrb, mrb_value self)
{
int fd;
- int64_t length;
+ mrb_int length;
mrb_value lenv;
fd = mrb_io_fileno(mrb, self);
mrb_get_args(mrb, "o", &lenv);
- switch (mrb_type(lenv)) {
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
- {
- mrb_float lenf = mrb_float(lenv);
- if (lenf > INT64_MAX) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "length too large");
- }
- length = (int64_t)lenf;
- }
- break;
-#endif
- case MRB_TT_FIXNUM:
- default:
- {
- mrb_int leni = mrb_int(mrb, lenv);
- length = (int64_t)leni;
- }
- break;
- }
-
+ length = mrb_int(mrb, lenv);
if (mrb_ftruncate(fd, length) != 0) {
mrb_raise(mrb, E_IO_ERROR, "ftruncate failed");
}
diff --git a/mrbgems/mruby-io/src/file_test.c b/mrbgems/mruby-io/src/file_test.c
index d75cbd598..19fd5739b 100644
--- a/mrbgems/mruby-io/src/file_test.c
+++ b/mrbgems/mruby-io/src/file_test.c
@@ -85,7 +85,7 @@ mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
* File.directory?(".")
*/
-mrb_value
+static mrb_value
mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
{
#ifndef S_ISDIR
@@ -112,7 +112,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
* Returns <code>true</code> if the named file is a pipe.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -145,7 +145,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
* Returns <code>true</code> if the named file is a symbolic link.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -188,7 +188,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
* Returns <code>true</code> if the named file is a socket.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -232,7 +232,7 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
* Return <code>true</code> if the named file exists.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
{
struct stat st;
@@ -253,7 +253,7 @@ mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
* regular file.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
{
#ifndef S_ISREG
@@ -281,7 +281,7 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
* a zero size.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
{
struct stat st;
@@ -306,7 +306,7 @@ mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
* _file_name_ can be an IO object.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
{
struct stat st;
@@ -328,7 +328,7 @@ mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
* file otherwise.
*/
-mrb_value
+static mrb_value
mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
{
struct stat st;
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c
index 7d620a6a7..ef1283b51 100644
--- a/mrbgems/mruby-io/src/io.c
+++ b/mrbgems/mruby-io/src/io.c
@@ -341,7 +341,7 @@ option_to_fd(mrb_state *mrb, mrb_value hash, const char *key)
}
#ifdef _WIN32
-mrb_value
+static mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
mrb_value cmd, io;
@@ -439,14 +439,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
return io;
}
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
-mrb_value
+static mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
mrb_raise(mrb, E_NOTIMP_ERROR, "IO#popen is not supported on the platform");
return mrb_false_value();
}
#else
-mrb_value
+static mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
mrb_value cmd, io, result;
@@ -596,7 +596,7 @@ mrb_dup(mrb_state *mrb, int fd, mrb_bool *failed)
return new_fd;
}
-mrb_value
+static mrb_value
mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
{
mrb_value orig;
@@ -645,7 +645,44 @@ mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
return copy;
}
-mrb_value
+static void
+check_file_descriptor(mrb_state *mrb, mrb_int fd)
+{
+ struct stat sb;
+ int fdi = (int)fd;
+
+#if MRB_INT_MIN < INT_MIN || MRB_INT_MAX > INT_MAX
+ if (fdi != fd) {
+ goto badfd;
+ }
+#endif
+
+#ifdef _WIN32
+ {
+ DWORD err;
+ int len = sizeof(err);
+
+ if (getsockopt(fdi, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) {
+ return;
+ }
+ }
+
+ if (fdi < 0 || fdi > _getmaxstdio()) {
+ goto badfd;
+ }
+#endif /* _WIN32 */
+
+ if (fstat(fdi, &sb) != 0) {
+ goto badfd;
+ }
+
+ return;
+
+badfd:
+ mrb_sys_fail(mrb, "bad file descriptor");
+}
+
+static mrb_value
mrb_io_initialize(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -656,6 +693,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
mode = opt = mrb_nil_value();
mrb_get_args(mrb, "i|oo", &fd, &mode, &opt);
+ check_file_descriptor(mrb, fd);
if (mrb_nil_p(mode)) {
mode = mrb_str_new_cstr(mrb, "r");
}
@@ -747,7 +785,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
}
}
-mrb_value
+static mrb_value
mrb_io_check_readable(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr = io_get_open_fptr(mrb, self);
@@ -757,7 +795,7 @@ mrb_io_check_readable(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
-mrb_value
+static mrb_value
mrb_io_isatty(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -768,7 +806,7 @@ mrb_io_isatty(mrb_state *mrb, mrb_value self)
return mrb_true_value();
}
-mrb_value
+static mrb_value
mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
{
struct RClass *c = mrb_class_ptr(klass);
@@ -781,7 +819,7 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
return mrb_io_initialize(mrb, obj);
}
-mrb_value
+static mrb_value
mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
{
mrb_int fd;
@@ -792,7 +830,7 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
return mrb_fixnum_value(0);
}
-int
+static int
mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode)
{
int fd, retry = FALSE;
@@ -827,7 +865,7 @@ reopen:
return fd;
}
-mrb_value
+static mrb_value
mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
{
mrb_value path = mrb_nil_value();
@@ -857,7 +895,7 @@ mrb_sysread_dummy(int fd, void *buf, fsize_t nbytes, off_t offset)
return (mrb_io_read_write_size)read(fd, buf, nbytes);
}
-mrb_value
+static mrb_value
mrb_io_sysread(mrb_state *mrb, mrb_value io)
{
mrb_value buf = mrb_nil_value();
@@ -911,7 +949,7 @@ mrb_io_sysread_common(mrb_state *mrb,
return buf;
}
-mrb_value
+static mrb_value
mrb_io_sysseek(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -971,7 +1009,7 @@ mrb_syswrite_dummy(int fd, const void *buf, fsize_t nbytes, off_t offset)
return (mrb_io_read_write_size)write(fd, buf, nbytes);
}
-mrb_value
+static mrb_value
mrb_io_syswrite(mrb_state *mrb, mrb_value io)
{
mrb_value buf;
@@ -981,7 +1019,7 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io)
return mrb_io_syswrite_common(mrb, mrb_syswrite_dummy, io, buf, 0);
}
-mrb_value
+static mrb_value
mrb_io_close(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -990,7 +1028,7 @@ mrb_io_close(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
-mrb_value
+static mrb_value
mrb_io_close_write(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -1001,7 +1039,7 @@ mrb_io_close_write(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
-mrb_value
+static mrb_value
mrb_io_closed(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -1013,7 +1051,7 @@ mrb_io_closed(mrb_state *mrb, mrb_value io)
return mrb_true_value();
}
-mrb_value
+static mrb_value
mrb_io_pid(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -1147,6 +1185,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
for (i = 0; i < RARRAY_LEN(read); i++) {
read_io = RARRAY_PTR(read)[i];
fptr = io_get_open_fptr(mrb, read_io);
+ if (fptr->fd >= FD_SETSIZE) continue;
FD_SET(fptr->fd, rp);
if (mrb_io_read_data_pending(mrb, read_io)) {
pending++;
@@ -1169,6 +1208,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
FD_ZERO(wp);
for (i = 0; i < RARRAY_LEN(write); i++) {
fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]);
+ if (fptr->fd >= FD_SETSIZE) continue;
FD_SET(fptr->fd, wp);
if (max < fptr->fd)
max = fptr->fd;
@@ -1188,6 +1228,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
FD_ZERO(ep);
for (i = 0; i < RARRAY_LEN(except); i++) {
fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]);
+ if (fptr->fd >= FD_SETSIZE) continue;
FD_SET(fptr->fd, ep);
if (max < fptr->fd)
max = fptr->fd;
@@ -1276,7 +1317,7 @@ mrb_io_fileno_m(mrb_state *mrb, mrb_value io)
return mrb_fixnum_value(fd);
}
-mrb_value
+static mrb_value
mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
{
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
@@ -1300,7 +1341,7 @@ mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
#endif
}
-mrb_value
+static mrb_value
mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
{
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
@@ -1336,7 +1377,7 @@ mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
#endif
}
-mrb_value
+static mrb_value
mrb_io_set_sync(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -1348,7 +1389,7 @@ mrb_io_set_sync(mrb_state *mrb, mrb_value self)
return mrb_bool_value(b);
}
-mrb_value
+static mrb_value
mrb_io_sync(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -1363,22 +1404,7 @@ mrb_io_sync(mrb_state *mrb, mrb_value self)
static off_t
value2off(mrb_state *mrb, mrb_value offv)
{
- switch (mrb_type(offv)) {
-#ifndef MRB_WITHOUT_FLOAT
- case MRB_TT_FLOAT:
- {
- mrb_float tmp = mrb_float(offv);
- if (tmp < INT64_MIN || tmp > INT64_MAX) {
- /* fall through to use convert by `mrb_int()` (and raise error if out of range) */
- } else {
- return (off_t)tmp;
- }
- }
- /* fall through */
-#endif /* MRB_WITHOUT_FLOAT */
- default:
- return (off_t)mrb_int(mrb, offv);
- }
+ return (off_t)mrb_int(mrb, offv);
}
/*
@@ -1452,7 +1478,8 @@ mrb_io_readchar(mrb_state *mrb, mrb_value self)
#endif
mrb_get_args(mrb, "S", &buf);
- mrb_assert(RSTRING_PTR(buf) > 0);
+ mrb_assert(RSTRING_LEN(buf) > 0);
+ mrb_assert(RSTRING_PTR(buf) != NULL);
mrb_str_modify(mrb, RSTRING(buf));
#ifdef MRB_UTF8_STRING
c = RSTRING_PTR(buf)[0];
diff --git a/mrbgems/mruby-io/test/file.rb b/mrbgems/mruby-io/test/file.rb
index 03917ef09..ef4d7fcb1 100644
--- a/mrbgems/mruby-io/test/file.rb
+++ b/mrbgems/mruby-io/test/file.rb
@@ -110,18 +110,22 @@ assert('File.join') do
end
assert('File.realpath') do
- if File::ALT_SEPARATOR
- readme_path = File._getwd + File::ALT_SEPARATOR + "README.md"
- assert_equal readme_path, File.realpath("README.md")
- else
- dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
- begin
- dir1 = File.realpath($mrbtest_io_rfname)
- dir2 = File.realpath("./#{dir}//./../#{$mrbtest_io_symlinkname}")
- assert_equal dir1, dir2
- ensure
- MRubyIOTestUtil.rmdir dir
+ dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
+ begin
+ sep = File::ALT_SEPARATOR || File::SEPARATOR
+ relative_path = "#{File.basename(dir)}#{sep}realpath_test"
+ path = "#{File._getwd}#{sep}#{relative_path}"
+ File.open(path, "w"){}
+ assert_equal path, File.realpath(relative_path)
+
+ unless MRubyIOTestUtil.win?
+ path1 = File.realpath($mrbtest_io_rfname)
+ path2 = File.realpath($mrbtest_io_symlinkname)
+ assert_equal path1, path2
end
+ ensure
+ File.delete path rescue nil
+ MRubyIOTestUtil.rmdir dir
end
assert_raise(ArgumentError) { File.realpath("TO\0DO") }
@@ -129,7 +133,9 @@ end
assert("File.readlink") do
begin
- assert_equal $mrbtest_io_rfname, File.readlink($mrbtest_io_symlinkname)
+ exp = File.basename($mrbtest_io_rfname)
+ act = File.readlink($mrbtest_io_symlinkname)
+ assert_equal exp, act
rescue NotImplementedError => e
skip e.message
end
diff --git a/mrbgems/mruby-io/test/io.rb b/mrbgems/mruby-io/test/io.rb
index 458d2cdc2..2088a61e3 100644
--- a/mrbgems/mruby-io/test/io.rb
+++ b/mrbgems/mruby-io/test/io.rb
@@ -24,6 +24,10 @@ def assert_io_open(meth)
end
end
io2.close unless meth == :open
+
+ assert_raise(RuntimeError) { IO.__send__(meth, 1023) } # For Windows
+ assert_raise(RuntimeError) { IO.__send__(meth, 1 << 26) }
+ assert_raise(RuntimeError) { IO.__send__(meth, 1 << 32) } if (1 << 32).kind_of?(Integer)
end
end
diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c
index 4dce48c26..eb3f6108c 100644
--- a/mrbgems/mruby-io/test/mruby_io_test.c
+++ b/mrbgems/mruby-io/test/mruby_io_test.c
@@ -54,6 +54,7 @@ mkdtemp(char *temp)
#include <unistd.h>
#include <sys/un.h>
#include <fcntl.h>
+ #include <libgen.h>
#endif
#include <sys/stat.h>
@@ -99,17 +100,16 @@ sock_test_out:
static mrb_value
mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
{
- char rfname[] = "tmp.mruby-io-test-r.XXXXXXXX";
- char wfname[] = "tmp.mruby-io-test-w.XXXXXXXX";
- char symlinkname[] = "tmp.mruby-io-test-l.XXXXXXXX";
- char socketname[] = "tmp.mruby-io-test-s.XXXXXXXX";
+#define GVNAME(n) "$mrbtest_io_" #n "name"
+ enum {IDX_READ, IDX_WRITE, IDX_LINK, IDX_SOCKET, IDX_COUNT};
+ const char *gvnames[] = {GVNAME(rf), GVNAME(wf), GVNAME(symlink), GVNAME(socket)};
+ char *fnames[IDX_COUNT];
+ int fds[IDX_COUNT];
char msg[] = "mruby io test\n";
mode_t mask;
- int fd0, fd1;
FILE *fp;
-
+ int i;
#if !defined(_WIN32) && !defined(_WIN64)
- int fd2, fd3;
struct sockaddr_un sun0;
if(!(socket_available_p = mrb_io_socket_available())) {
@@ -121,33 +121,37 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
}
#endif
- mask = umask(077);
- fd0 = mkstemp(rfname);
- fd1 = mkstemp(wfname);
- if (fd0 == -1 || fd1 == -1) {
- mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
- return mrb_nil_value();
- }
- close(fd0);
- close(fd1);
+ mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
+ mask = umask(077);
+ for (i = 0; i < IDX_COUNT; i++) {
+ mrb_value fname = mrb_str_new_capa(mrb, 0);
#if !defined(_WIN32) && !defined(_WIN64)
- fd2 = mkstemp(symlinkname);
- fd3 = mkstemp(socketname);
- if (fd2 == -1 || fd3 == -1) {
- mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
- return mrb_nil_value();
- }
+ /*
+ * Workaround for not being able to bind a socket to some file systems
+ * (e.g. vboxsf, NFS). [#4981]
+ */
+ char *tmpdir = getenv("TMPDIR");
+ if (tmpdir && strlen(tmpdir) > 0) {
+ mrb_str_cat_cstr(mrb, fname, tmpdir);
+ if (*(RSTRING_END(fname)-1) != '/') mrb_str_cat_lit(mrb, fname, "/");
+ } else {
+ mrb_str_cat_lit(mrb, fname, "/tmp/");
+ }
#endif
+ mrb_str_cat_cstr(mrb, fname, gvnames[i]+1);
+ mrb_str_cat_cstr(mrb, fname, ".XXXXXXXX");
+ fnames[i] = RSTRING_PTR(fname);
+ fds[i] = mkstemp(fnames[i]);
+ if (fds[i] == -1) {
+ mrb_raise(mrb, E_RUNTIME_ERROR, "can't create temporary file");
+ }
+ close(fds[i]);
+ mrb_gv_set(mrb, mrb_intern_cstr(mrb, gvnames[i]), fname);
+ }
umask(mask);
- mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_rfname"), mrb_str_new_cstr(mrb, rfname));
- mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_wfname"), mrb_str_new_cstr(mrb, wfname));
- mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_symlinkname"), mrb_str_new_cstr(mrb, symlinkname));
- mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_socketname"), mrb_str_new_cstr(mrb, socketname));
- mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$mrbtest_io_msg"), mrb_str_new_cstr(mrb, msg));
-
- fp = fopen(rfname, "wb");
+ fp = fopen(fnames[IDX_READ], "wb");
if (fp == NULL) {
mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
return mrb_nil_value();
@@ -155,7 +159,7 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
fputs(msg, fp);
fclose(fp);
- fp = fopen(wfname, "wb");
+ fp = fopen(fnames[IDX_WRITE], "wb");
if (fp == NULL) {
mrb_raise(mrb, E_RUNTIME_ERROR, "can't open temporary file");
return mrb_nil_value();
@@ -163,29 +167,29 @@ mrb_io_test_io_setup(mrb_state *mrb, mrb_value self)
fclose(fp);
#if !defined(_WIN32) && !defined(_WIN64)
- unlink(symlinkname);
- close(fd2);
- if (symlink(rfname, symlinkname) == -1) {
+ unlink(fnames[IDX_LINK]);
+ if (symlink(basename(fnames[IDX_READ]), fnames[IDX_LINK]) == -1) {
mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link");
}
- unlink(socketname);
- close(fd3);
- fd3 = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd3 == -1) {
+ unlink(fnames[IDX_SOCKET]);
+ fds[IDX_SOCKET] = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fds[IDX_SOCKET] == -1) {
mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a socket");
}
sun0.sun_family = AF_UNIX;
- strncpy(sun0.sun_path, socketname, sizeof(sun0.sun_path));
- if (bind(fd3, (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
+ strncpy(sun0.sun_path, fnames[IDX_SOCKET], sizeof(sun0.sun_path)-1);
+ sun0.sun_path[sizeof(sun0.sun_path)-1] = 0;
+ if (bind(fds[IDX_SOCKET], (struct sockaddr *)&sun0, sizeof(sun0)) == -1) {
mrb_raisef(mrb, E_RUNTIME_ERROR, "can't bind AF_UNIX socket to %s: %d",
sun0.sun_path,
errno);
}
- close(fd3);
+ close(fds[IDX_SOCKET]);
#endif
return mrb_true_value();
+#undef GVNAME
}
static mrb_value
@@ -251,7 +255,7 @@ mrb_io_test_rmdir(mrb_state *mrb, mrb_value klass)
return mrb_true_value();
}
-mrb_value
+static mrb_value
mrb_io_win_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)