diff options
| -rw-r--r-- | mrbgem.rake | 4 | ||||
| -rw-r--r-- | mrblib/file_constants.rb | 2 | ||||
| -rw-r--r-- | mrblib/io.rb | 38 | ||||
| -rw-r--r-- | src/file.c | 13 | ||||
| -rw-r--r-- | src/io.c | 29 |
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)); + } @@ -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()); |
