about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--ext/posix_mq/posix_mq.c28
-rw-r--r--test/test_posix_mq.rb14
2 files changed, 27 insertions, 15 deletions
diff --git a/ext/posix_mq/posix_mq.c b/ext/posix_mq/posix_mq.c
index b634a91..26c4514 100644
--- a/ext/posix_mq/posix_mq.c
+++ b/ext/posix_mq/posix_mq.c
@@ -14,10 +14,6 @@
 #  define NUM2TIMET NUM2INT
 #endif
 
-#ifndef RB_GC_GUARD
-#  define RB_GC_GUARD(v) (*(volatile VALUE *)&(v))
-#endif
-
 #include <time.h>
 #include <mqueue.h>
 #include <fcntl.h>
@@ -303,17 +299,21 @@ static struct posix_mq *get(VALUE self, int need_valid)
         return mq;
 }
 
+static void check_struct_type(VALUE astruct)
+{
+        if (CLASS_OF(astruct) == cAttr)
+                return;
+        astruct = rb_inspect(astruct);
+        rb_raise(rb_eTypeError, "not a POSIX_MQ::Attr: %s",
+                 StringValuePtr(astruct));
+}
+
 /* converts the POSIX_MQ::Attr astruct into a struct mq_attr attr */
 static void attr_from_struct(struct mq_attr *attr, VALUE astruct, int all)
 {
         VALUE *ptr;
 
-        if (CLASS_OF(astruct) != cAttr) {
-                RB_GC_GUARD(astruct) = rb_inspect(astruct);
-                rb_raise(rb_eArgError, "not a POSIX_MQ::Attr: %s",
-                         RSTRING_PTR(astruct));
-        }
-
+        check_struct_type(astruct);
         ptr = RSTRUCT_PTR(astruct);
 
         attr->mq_flags = NUM2LONG(ptr[0]);
@@ -369,10 +369,10 @@ static VALUE init(int argc, VALUE *argv, VALUE self)
                 else if (oflags == sym_rw)
                         x.oflags = O_CREAT|O_RDWR;
                 else {
-                        RB_GC_GUARD(oflags) = oflags;
+                        oflags = rb_inspect(oflags);
                         rb_raise(rb_eArgError,
                                  "symbol must be :r, :w, or :rw: %s",
-                                 RSTRING_PTR(oflags));
+                                 StringValuePtr(oflags));
                 }
                 break;
         case T_BIGNUM:
@@ -413,9 +413,7 @@ static VALUE init(int argc, VALUE *argv, VALUE self)
         case T_NIL:
                 break;
         default:
-                RB_GC_GUARD(attr) = rb_inspect(attr);
-                rb_raise(rb_eArgError, "attr must be a POSIX_MQ::Attr: %s",
-                         RSTRING_PTR(attr));
+                check_struct_type(attr);
         }
 
         mq->des = (mqd_t)xopen(&x);
diff --git a/test/test_posix_mq.rb b/test/test_posix_mq.rb
index 1f5c9b4..b4c49c7 100644
--- a/test/test_posix_mq.rb
+++ b/test/test_posix_mq.rb
@@ -322,4 +322,18 @@ class Test_POSIX_MQ < Test::Unit::TestCase
     assert x.instance_of?(Thread)
     assert Thread.current != x
   end if POSIX_MQ.method_defined?(:notify)
+
+  def test_bad_open_mode
+    assert_raises(ArgumentError) { mq = POSIX_MQ.new(@path, "rw") }
+  end
+
+  def test_bad_open_attr
+    assert_raises(TypeError) { POSIX_MQ.new(@path, :rw, 0666, [0, 1, 1, 0]) }
+  end
+
+  def test_bad_setattr
+    @mq = POSIX_MQ.new @path, IO::CREAT|IO::WRONLY, 0666
+    assert_raises(TypeError) { @mq.attr = {} }
+    assert_raises(TypeError) { @mq.attr = Struct.new(:a,:b,:c,:d).new }
+  end
 end