summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgem.rake4
-rw-r--r--mrblib/file_constants.rb2
-rw-r--r--mrblib/io.rb38
-rw-r--r--src/file.c13
-rw-r--r--src/io.c29
5 files changed, 59 insertions, 27 deletions
diff --git a/mrbgem.rake b/mrbgem.rake
index 77ad101af..8120f7832 100644
--- a/mrbgem.rake
+++ b/mrbgem.rake
@@ -10,5 +10,7 @@ MRuby::Gem::Specification.new('mruby-io') do |spec|
#spec.cc.include_paths += ["C:/Windows/system/include"]
spec.linker.library_paths += ["C:/Windows/system"]
end
-
+ if build.kind_of?(MRuby::CrossBuild) && %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target)
+ spec.linker.libraries += ['ws2_32']
+ end
end
diff --git a/mrblib/file_constants.rb b/mrblib/file_constants.rb
index c2552bf56..a68ee2598 100644
--- a/mrblib/file_constants.rb
+++ b/mrblib/file_constants.rb
@@ -1,7 +1,5 @@
class File
module Constants
- NULL = "/dev/null"
-
RDONLY = 0
WRONLY = 1
RDWR = 2
diff --git a/mrblib/io.rb b/mrblib/io.rb
index fceea1171..c838b96e5 100644
--- a/mrblib/io.rb
+++ b/mrblib/io.rb
@@ -11,10 +11,6 @@ class IO
BUF_SIZE = 4096
- def self.for_fd *args
- self.new(*args)
- end
-
def self.open(*args, &block)
io = self.new(*args)
@@ -183,29 +179,30 @@ class IO
end
end
- str = ''
+ array = []
+ start_pos = @pos
while 1
begin
_read_buf
rescue EOFError => e
- str = nil if str.empty? and (not length.nil?) and length != 0
+ array = nil if array.empty? and (not length.nil?) and length != 0
break
end
- if length && (str.size + @buf.size) >= length
- len = length - str.size
- str += @buf[0, len]
+ if length && (@pos - start_pos + @buf.size) >= length
+ len = length - (@pos - start_pos)
+ array.push @buf[0, len]
@pos += len
@buf = @buf[len, @buf.size - len]
break
else
- str += @buf
+ array.push @buf
@pos += @buf.size
@buf = ''
end
end
- str
+ array && array.join
end
def readline(arg = $/, limit = nil)
@@ -227,37 +224,38 @@ class IO
rs = $/ + $/
end
- str = ""
+ array = []
+ start_pos = @pos
while 1
begin
_read_buf
rescue EOFError => e
- str = nil if str.empty?
+ array = nil if array.empty?
break
end
- if limit && (str.size + @buf.size) >= limit
- len = limit - str.size
- str += @buf[0, len]
+ if limit && (@pos - start_pos + @buf.size) >= limit
+ len = limit - (@pos - start_pos)
+ array.push @buf[0, len]
@pos += len
@buf = @buf[len, @buf.size - len]
break
elsif idx = @buf.index(rs)
len = idx + rs.size
- str += @buf[0, len]
+ array.push @buf[0, len]
@pos += len
@buf = @buf[len, @buf.size - len]
break
else
- str += @buf
+ array.push @buf
@pos += @buf.size
@buf = ''
end
end
- raise EOFError.new "end of file reached" if str.nil?
+ raise EOFError.new "end of file reached" if array.nil?
- str
+ array.join
end
def gets(*args)
diff --git a/src/file.c b/src/file.c
index c2419c2cc..feb8558ed 100644
--- a/src/file.c
+++ b/src/file.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32) || defined(_WIN64)
+ #define NULL_FILE "NUL"
#define UNLINK _unlink
#define GETCWD _getcwd
#define CHMOD(a, b) 0
@@ -34,6 +35,7 @@
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
#include <direct.h>
#else
+ #define NULL_FILE "/dev/null"
#include <unistd.h>
#define UNLINK unlink
#define GETCWD getcwd
@@ -44,7 +46,13 @@
#include <pwd.h>
#endif
-#define FILE_SEPARATOR "/"
+#if defined(_WIN32) || defined(_WIN64)
+ #define PATH_SEPARATOR ";"
+ #define FILE_SEPARATOR "\\"
+#else
+ #define PATH_SEPARATOR ":"
+ #define FILE_SEPARATOR "/"
+#endif
#ifndef LOCK_SH
#define LOCK_SH 1
@@ -311,4 +319,7 @@ mrb_init_file(mrb_state *mrb)
mrb_define_const(mrb, cnst, "LOCK_UN", mrb_fixnum_value(LOCK_UN));
mrb_define_const(mrb, cnst, "LOCK_NB", mrb_fixnum_value(LOCK_NB));
mrb_define_const(mrb, cnst, "SEPARATOR", mrb_str_new_cstr(mrb, FILE_SEPARATOR));
+ mrb_define_const(mrb, cnst, "PATH_SEPARATOR", mrb_str_new_cstr(mrb, PATH_SEPARATOR));
+ mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE));
+
}
diff --git a/src/io.c b/src/io.c
index 3f299775e..1d2f98f3c 100644
--- a/src/io.c
+++ b/src/io.c
@@ -384,12 +384,34 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise)
}
}
+#if !defined(_WIN32) && !defined(_WIN64)
+ if (fptr->pid != 0) {
+ pid_t pid;
+ do {
+ pid = waitpid(fptr->pid, NULL, 0);
+ } while (pid == -1 && errno == EINTR);
+ }
+#endif
+
if (!noraise && n != 0) {
mrb_sys_fail(mrb, "fptr_finalize failed.");
}
}
mrb_value
+mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
+{
+ struct RClass *c = mrb_class_ptr(klass);
+ enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
+ mrb_value obj;
+
+ /* copied from mrb_instance_alloc() */
+ if (ttype == 0) ttype = MRB_TT_OBJECT;
+ obj = mrb_obj_value((struct RObject*)mrb_obj_alloc(mrb, ttype, c));
+ return mrb_io_initialize(mrb, obj);
+}
+
+mrb_value
mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
{
mrb_int fd;
@@ -470,7 +492,7 @@ mrb_io_sysread(mrb_state *mrb, mrb_value io)
}
if (mrb_nil_p(buf)) {
- buf = mrb_str_new(mrb, "", maxlen);
+ buf = mrb_str_new(mrb, NULL, maxlen);
}
if (RSTRING_LEN(buf) != maxlen) {
buf = mrb_str_resize(mrb, buf, maxlen);
@@ -487,7 +509,7 @@ mrb_io_sysread(mrb_state *mrb, mrb_value io)
}
break;
case -1: /* Error */
- mrb_raise(mrb, E_IO_ERROR, "sysread failed");
+ mrb_sys_fail(mrb, "sysread failed");
break;
default:
if (RSTRING_LEN(buf) != ret) {
@@ -771,7 +793,7 @@ retry:
fptr = (struct mrb_io *)mrb_get_datatype(mrb, RARRAY_PTR(except)[i], &mrb_io_type);
if (FD_ISSET(fptr->fd, ep)) {
mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]);
- } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, wp)) {
+ } else if (fptr->fd2 >= 0 && FD_ISSET(fptr->fd2, ep)) {
mrb_ary_push(mrb, list, RARRAY_PTR(except)[i]);
}
}
@@ -897,6 +919,7 @@ mrb_init_io(mrb_state *mrb)
mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "_sysclose", mrb_io_s_sysclose, MRB_ARGS_REQ(1));
#endif
+ mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY());