[macruby-changes] [1832] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Tue Jun 9 18:35:56 PDT 2009
Revision: 1832
http://trac.macosforge.org/projects/ruby/changeset/1832
Author: lsansonetti at apple.com
Date: 2009-06-09 18:35:55 -0700 (Tue, 09 Jun 2009)
Log Message:
-----------
fixing more stupid IO bugs
Modified Paths:
--------------
MacRuby/branches/experimental/gc.c
MacRuby/branches/experimental/include/ruby/io.h
MacRuby/branches/experimental/include/ruby/ruby.h
MacRuby/branches/experimental/io.c
MacRuby/branches/experimental/objc.h
Modified: MacRuby/branches/experimental/gc.c
===================================================================
--- MacRuby/branches/experimental/gc.c 2009-06-09 21:16:46 UTC (rev 1831)
+++ MacRuby/branches/experimental/gc.c 2009-06-10 01:35:55 UTC (rev 1832)
@@ -38,8 +38,6 @@
#endif
static auto_zone_t *__auto_zone = NULL;
-int rb_io_fptr_finalize(struct rb_io_t *io_struct);
-
static VALUE nomem_error;
static bool dont_gc = false;
@@ -725,30 +723,6 @@
}
}
-static CFMutableArrayRef __exit_finalize = NULL;
-
-static void
-rb_objc_finalize_pure_ruby_obj(VALUE obj)
-{
- switch (RBASIC(obj)->flags & T_MASK) {
- case T_FILE:
- if (RFILE(obj)->fptr != NULL) {
- rb_io_fptr_finalize(RFILE(obj)->fptr);
- }
- break;
- }
-}
-
-void
-rb_objc_keep_for_exit_finalize(VALUE v)
-{
- if (__exit_finalize == NULL) {
- __exit_finalize = CFArrayCreateMutable(NULL, 0,
- &kCFTypeArrayCallBacks);
- }
- CFArrayAppendValue(__exit_finalize, (void *)v);
-}
-
static void rb_call_os_finalizer2(VALUE, VALUE);
static void
@@ -760,19 +734,6 @@
void
rb_gc_call_finalizer_at_exit(void)
{
- if (__exit_finalize != NULL) {
- long i, count;
- for (i = 0, count = CFArrayGetCount((CFArrayRef)__exit_finalize);
- i < count;
- i++) {
- VALUE v;
- v = (VALUE)CFArrayGetValueAtIndex((CFArrayRef)__exit_finalize, i);
- rb_objc_finalize_pure_ruby_obj(v);
- }
- CFArrayRemoveAllValues(__exit_finalize);
- CFRelease(__exit_finalize);
- }
-
if (__os_finalizers != NULL) {
CFDictionaryApplyFunction((CFDictionaryRef)__os_finalizers,
os_finalize_cb, NULL);
@@ -1094,7 +1055,7 @@
Method m = class_getInstanceMethod((Class)objc_getClass("NSObject"), sel_registerName("finalize"));
assert(m != NULL);
method_setImplementation(m, (IMP)rb_obj_imp_finalize);
-
+
auto_collector_disable(__auto_zone);
}
Modified: MacRuby/branches/experimental/include/ruby/io.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/io.h 2009-06-09 21:16:46 UTC (rev 1831)
+++ MacRuby/branches/experimental/include/ruby/io.h 2009-06-10 01:35:55 UTC (rev 1832)
@@ -38,6 +38,7 @@
pid_t pid;
int lineno;
bool sync;
+ bool should_close_streams;
// For ungetc.
UInt8 *ungetc_buf;
Modified: MacRuby/branches/experimental/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/ruby.h 2009-06-09 21:16:46 UTC (rev 1831)
+++ MacRuby/branches/experimental/include/ruby/ruby.h 2009-06-10 01:35:55 UTC (rev 1832)
@@ -976,8 +976,6 @@
VALUE rb_require(const char*);
-void rb_objc_keep_for_exit_finalize(VALUE);
-
#ifdef __ia64
void ruby_init_stack(VALUE*, void*);
#define ruby_init_stack(addr) ruby_init_stack(addr, rb_ia64_bsp())
Modified: MacRuby/branches/experimental/io.c
===================================================================
--- MacRuby/branches/experimental/io.c 2009-06-09 21:16:46 UTC (rev 1831)
+++ MacRuby/branches/experimental/io.c 2009-06-10 01:35:55 UTC (rev 1832)
@@ -14,6 +14,7 @@
#include "ruby/util.h"
#include "ruby/node.h"
#include "vm.h"
+#include "objc.h"
#include <errno.h>
#include <paths.h>
@@ -34,7 +35,7 @@
VALUE rb_eEOFError;
VALUE rb_eIOError;
-VALUE rb_stdin, rb_stdout, rb_stderr;
+VALUE rb_stdin = 0, rb_stdout = 0, rb_stderr = 0;
VALUE rb_deferr; /* rescue VIM plugin */
static VALUE orig_stdout, orig_stderr;
@@ -264,7 +265,7 @@
static VALUE
io_alloc(VALUE klass, SEL sel)
{
- struct RFile *io = ALLOC(struct RFile);
+ NEWOBJ(io, struct RFile);
OBJSETUP(io, klass, T_FILE);
GC_WB(&io->fptr, ALLOC(rb_io_t));
return (VALUE)io;
@@ -275,7 +276,7 @@
CFWriteStreamRef _CFWriteStreamCreateFromFileDescriptor(CFAllocatorRef alloc, int fd);
static inline void
-prepare_io_from_fd(rb_io_t *io_struct, int fd, int mode)
+prepare_io_from_fd(rb_io_t *io_struct, int fd, int mode, bool should_close_streams)
{
// TODO we should really get rid of these FMODE_* constants and instead
// always use the POSIX ones.
@@ -296,80 +297,97 @@
}
assert(read || write);
+ VALUE stdio = 0;
+ switch (fd) {
+ case 0:
+ stdio = rb_stdin;
+ break;
+
+ case 1:
+ stdio = rb_stdout;
+ break;
+
+ case 2:
+ stdio = rb_stderr;
+ break;
+ }
+
if (read) {
- CFReadStreamRef r = _CFReadStreamCreateFromFileDescriptor(NULL, fd);
- if (r != NULL) {
- CFReadStreamOpen(r);
- GC_WB(&io_struct->readStream, r);
- CFMakeCollectable(r);
- }
+ if (stdio != 0) {
+ GC_WB(&io_struct->readStream, ExtractIOStruct(stdio)->readStream);
+ }
else {
- io_struct->readStream = NULL;
+ CFReadStreamRef r = _CFReadStreamCreateFromFileDescriptor(NULL, fd);
+ if (r != NULL) {
+ CFReadStreamOpen(r);
+ GC_WB(&io_struct->readStream, r);
+ CFMakeCollectable(r);
+ }
+ else {
+ io_struct->readStream = NULL;
+ }
}
}
if (write) {
- CFWriteStreamRef w = _CFWriteStreamCreateFromFileDescriptor(NULL, fd);
- if (w != NULL) {
- CFWriteStreamOpen(w);
- GC_WB(&io_struct->writeStream, w);
- CFMakeCollectable(w);
- }
+ if (stdio != 0) {
+ GC_WB(&io_struct->writeStream, ExtractIOStruct(stdio)->writeStream);
+ }
else {
- io_struct->writeStream = NULL;
+ CFWriteStreamRef w = _CFWriteStreamCreateFromFileDescriptor(NULL, fd);
+ if (w != NULL) {
+ CFWriteStreamOpen(w);
+ GC_WB(&io_struct->writeStream, w);
+ CFMakeCollectable(w);
+ }
+ else {
+ io_struct->writeStream = NULL;
+ }
}
}
+ io_struct->fd = fd;
io_struct->pid = -1;
-
- // TODO: Eventually make the ungetc_buf a ByteString
- io_struct->fd = fd;
io_struct->pipe = -1;
io_struct->ungetc_buf = NULL;
io_struct->ungetc_buf_len = 0;
io_struct->ungetc_buf_pos = 0;
io_struct->sync = mode & FMODE_SYNC;
+ io_struct->should_close_streams = should_close_streams;
}
static void
io_struct_close(rb_io_t *io_struct, bool close_read, bool close_write)
{
if (close_read && io_struct->readStream != NULL) {
- CFReadStreamClose(io_struct->readStream);
+ if (io_struct->should_close_streams) {
+ CFReadStreamClose(io_struct->readStream);
+ }
io_struct->readStream = NULL;
}
if (close_write && io_struct->writeStream != NULL) {
- CFWriteStreamClose(io_struct->writeStream);
+ if (io_struct->should_close_streams) {
+ CFWriteStreamClose(io_struct->writeStream);
+ }
io_struct->writeStream = NULL;
}
- if (io_struct->pipe != -1) {
- write(io_struct->pipe, "\0", 1);
- close(io_struct->pipe);
+ if (io_struct->pid != -1) {
+ // Don't commit sepuku!
+ if (io_struct->pid != 0 && io_struct->pid != getpid()) {
+ kill(io_struct->pid, SIGTERM);
+ }
+ io_struct->pid = -1;
}
rb_last_status_set(0, io_struct->pid);
- io_struct->pid = -1;
+ io_struct->fd = -1;
}
-int XXX_read(int fd)
-{
- char foo[10];
- return read(fd, foo, 1);
-}
-
-int
-rb_io_fptr_finalize(rb_io_t *io_struct)
-{
- io_struct_close(io_struct, true, true);
- return 1;
-}
-
static VALUE
-prep_io(int fd, int mode, VALUE klass)
+prep_io(int fd, int mode, VALUE klass, bool should_close_streams)
{
VALUE io = io_alloc(klass, 0);
rb_io_t *io_struct = ExtractIOStruct(io);
- prepare_io_from_fd(io_struct, fd, mode);
- rb_objc_keep_for_exit_finalize((VALUE)io);
+ prepare_io_from_fd(io_struct, fd, mode, should_close_streams);
return io;
}
@@ -918,11 +936,11 @@
static VALUE
rb_io_read_all(rb_io_t *io_struct, VALUE bytestring_buffer)
{
- long BUFSIZE = 512;
+ const long BUFSIZE = 512;
CFMutableDataRef data = rb_bytestring_wrapped_data(bytestring_buffer);
long bytes_read = 0;
- long original_position = (long)CFDataGetLength(data);
- for(;;) {
+ const long original_position = (long)CFDataGetLength(data);
+ for (;;) {
CFDataIncreaseLength(data, BUFSIZE);
UInt8 *b = CFDataGetMutableBytePtr(data) + original_position
+ bytes_read;
@@ -1849,7 +1867,7 @@
if (path != NULL && strcmp(path, "-") != 0) {
klass = rb_cFile;
}
- return prep_io(fd, convert_oflags_to_fmode(mode), klass);
+ return prep_io(fd, convert_oflags_to_fmode(mode), klass, true);
}
static VALUE
@@ -1956,7 +1974,7 @@
} \
} while(0)
-VALUE
+static VALUE
io_from_spawning_new_process(VALUE prog, VALUE mode)
{
VALUE io = io_alloc(rb_cIO, 0);
@@ -1990,7 +2008,7 @@
}
}
if (fmode != FMODE_READABLE) {
- w = _CFWriteStreamCreateFromFileDescriptor(NULL, fd[0]);
+ w = _CFWriteStreamCreateFromFileDescriptor(NULL, fd[1]);
if (w != NULL) {
CFWriteStreamOpen(w);
GC_WB(&io_struct->writeStream, w);
@@ -2010,7 +2028,7 @@
errno = posix_spawn(&pid, spawnedArgs[0], &actions, NULL, spawnedArgs,
*(_NSGetEnviron()));
- if(errno != 0) {
+ if (errno != 0) {
int err = errno;
close(fd[0]);
close(fd[1]);
@@ -2019,7 +2037,6 @@
}
posix_spawn_file_actions_destroy(&actions);
- // TODO: Eventually make the ungetc_buf a ByteString
io_struct->fd = fd[0];
io_struct->pipe = fd[1];
io_struct->ungetc_buf = NULL;
@@ -2028,7 +2045,6 @@
io_struct->pid = pid;
io_struct->sync = mode & FMODE_SYNC;
- rb_objc_keep_for_exit_finalize((VALUE)io);
return io;
}
@@ -2201,8 +2217,8 @@
rb_sys_fail(NULL);
}
rb_io_t *io_struct = ExtractIOStruct(io);
- prepare_io_from_fd(io_struct, fd, convert_mode_string_to_fmode(modes));
- GC_WB(&io_struct->path, path);
+ prepare_io_from_fd(io_struct, fd, convert_mode_string_to_fmode(modes), true);
+ GC_WB(&io_struct->path, path);
return io;
}
@@ -2658,10 +2674,21 @@
mode_flags = (NIL_P(mode) ? FMODE_READABLE
: convert_mode_string_to_fmode(mode));
- prepare_io_from_fd(io_struct, fd, mode_flags);
+ prepare_io_from_fd(io_struct, fd, mode_flags, false);
return io;
}
+static IMP rb_objc_io_finalize_super = NULL;
+
+static void
+rb_objc_io_finalize(void *rcv, SEL sel)
+{
+ rb_io_close((VALUE)rcv, 0);
+ if (rb_objc_io_finalize_super != NULL) {
+ ((void(*)(void *, SEL))rb_objc_io_finalize_super)(rcv, sel);
+ }
+}
+
/*
* call-seq:
* File.new(filename, mode="r") => file
@@ -2870,9 +2897,9 @@
// copy the groups and owners
fchown(fw, st.st_uid, st.st_gid);
}
- rb_stdout = prep_io(fw, FMODE_WRITABLE, rb_cFile);
+ rb_stdout = prep_io(fw, FMODE_WRITABLE, rb_cFile, true);
}
- ARGF.current_file = prep_io(fr, FMODE_READABLE, rb_cFile);
+ ARGF.current_file = prep_io(fr, FMODE_READABLE, rb_cFile, true);
}
#if 0 // TODO once we get encodings sorted out.
if (ARGF.encs.enc) {
@@ -3317,10 +3344,12 @@
rb_scan_args(argc, argv, "02", &ext_enc, &int_enc);
int fd[2] = {-1, -1};
- pipe(fd);
+ if (pipe(fd) == -1) {
+ rb_sys_fail("pipe() failed");
+ }
- rd = prep_io(fd[0], FMODE_READABLE, rb_cIO);
- wr = prep_io(fd[1], FMODE_WRITABLE, rb_cIO);
+ rd = prep_io(fd[0], FMODE_READABLE, rb_cIO, true);
+ wr = prep_io(fd[1], FMODE_WRITABLE, rb_cIO, true);
return rb_assoc_new(rd, wr);
}
@@ -4053,6 +4082,9 @@
rb_objc_define_method(rb_cIO, "initialize", rb_io_initialize, -1);
+ rb_objc_io_finalize_super = rb_objc_install_method2((Class)rb_cIO, "finalize",
+ (IMP)rb_objc_io_finalize);
+
rb_output_fs = Qnil;
rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter);
@@ -4146,16 +4178,16 @@
rb_objc_define_method(rb_cIO, "internal_encoding", rb_io_internal_encoding, 0);
rb_objc_define_method(rb_cIO, "set_encoding", rb_io_set_encoding, -1);
- rb_stdin = prep_io(fileno(stdin), FMODE_READABLE, rb_cIO);
+ rb_stdin = prep_io(fileno(stdin), FMODE_READABLE, rb_cIO, false);
rb_define_variable("$stdin", &rb_stdin);
rb_define_global_const("STDIN", rb_stdin);
- rb_stdout = prep_io(fileno(stdout), FMODE_WRITABLE, rb_cIO);
+ rb_stdout = prep_io(fileno(stdout), FMODE_WRITABLE, rb_cIO, false);
rb_define_hooked_variable("$stdout", &rb_stdout, 0, stdout_setter);
rb_define_hooked_variable("$>", &rb_stdout, 0, stdout_setter);
rb_define_global_const("STDOUT", rb_stdout);
- rb_stderr = prep_io(fileno(stderr), FMODE_WRITABLE|FMODE_SYNC, rb_cIO);
+ rb_stderr = prep_io(fileno(stderr), FMODE_WRITABLE|FMODE_SYNC, rb_cIO, false);
rb_define_hooked_variable("$stderr", &rb_stderr, 0, stdout_setter);
rb_define_global_const("STDERR", rb_stderr);
Modified: MacRuby/branches/experimental/objc.h
===================================================================
--- MacRuby/branches/experimental/objc.h 2009-06-09 21:16:46 UTC (rev 1831)
+++ MacRuby/branches/experimental/objc.h 2009-06-10 01:35:55 UTC (rev 1832)
@@ -32,33 +32,22 @@
void rb_objc_define_kvo_setter(VALUE klass, ID mid);
void rb_objc_change_ruby_method_signature(VALUE mod, ID mid, VALUE sig);
-static inline void
+static inline IMP
rb_objc_install_method(Class klass, SEL sel, IMP imp)
{
- Method method, method2;
-
- method = class_getInstanceMethod(klass, sel);
+ Method method = class_getInstanceMethod(klass, sel);
if (method == NULL) {
printf("method %s not found on class %p - aborting\n",
sel_getName(sel), klass);
abort();
}
- assert(method != NULL);
-
- method2 = class_getInstanceMethod((Class)RCLASS_SUPER(klass), sel);
- if (method == method2) {
- assert(class_addMethod(klass, sel, imp,
- method_getTypeEncoding(method)));
- }
- else {
- method_setImplementation(method, imp);
- }
+ return class_replaceMethod(klass, sel, imp, method_getTypeEncoding(method));
}
-static inline void
+static inline IMP
rb_objc_install_method2(Class klass, const char *selname, IMP imp)
{
- rb_objc_install_method(klass, sel_registerName(selname), imp);
+ return rb_objc_install_method(klass, sel_registerName(selname), imp);
}
static inline bool
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090609/2a2797a9/attachment-0001.html>
More information about the macruby-changes
mailing list