зеркало из https://github.com/github/ruby.git
security enhancement of dl library (need test).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3609 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
ab7dac4027
Коммит
ece972717b
9
eval.c
9
eval.c
|
@ -139,7 +139,7 @@ rb_secure(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_check_safe_str(x)
|
rb_check_safe_obj(x)
|
||||||
VALUE x;
|
VALUE x;
|
||||||
{
|
{
|
||||||
if (ruby_safe_level > 0 && OBJ_TAINTED(x)){
|
if (ruby_safe_level > 0 && OBJ_TAINTED(x)){
|
||||||
|
@ -152,6 +152,13 @@ rb_check_safe_str(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_check_safe_str(x)
|
||||||
|
VALUE x;
|
||||||
|
{
|
||||||
|
rb_check_safe_obj(x);
|
||||||
if (TYPE(x)!= T_STRING) {
|
if (TYPE(x)!= T_STRING) {
|
||||||
rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
|
||||||
rb_obj_classname(x));
|
rb_obj_classname(x));
|
||||||
|
|
97
ext/dl/dl.c
97
ext/dl/dl.c
|
@ -24,8 +24,8 @@ rb_dl_scan_callback_args(long stack[], const char *proto,
|
||||||
VALUE val;
|
VALUE val;
|
||||||
|
|
||||||
sp = stack;
|
sp = stack;
|
||||||
for( i=1; proto[i]; i++ ){
|
for (i=1; proto[i]; i++) {
|
||||||
switch( proto[i] ){
|
switch (proto[i]) {
|
||||||
case 'C':
|
case 'C':
|
||||||
{
|
{
|
||||||
char v;
|
char v;
|
||||||
|
@ -162,11 +162,11 @@ dlsizeof(const char *cstr)
|
||||||
|
|
||||||
len = strlen(cstr);
|
len = strlen(cstr);
|
||||||
size = 0;
|
size = 0;
|
||||||
for( i=0; i<len; i++ ){
|
for (i=0; i<len; i++) {
|
||||||
n = 1;
|
n = 1;
|
||||||
if( isdigit(cstr[i+1]) ){
|
if (isdigit(cstr[i+1])) {
|
||||||
dlen = 1;
|
dlen = 1;
|
||||||
while( isdigit(cstr[i+dlen]) ){ dlen ++; };
|
while (isdigit(cstr[i+dlen])) { dlen ++; };
|
||||||
dlen --;
|
dlen --;
|
||||||
d = ALLOCA_N(char, dlen + 1);
|
d = ALLOCA_N(char, dlen + 1);
|
||||||
strncpy(d, cstr + i + 1, dlen);
|
strncpy(d, cstr + i + 1, dlen);
|
||||||
|
@ -177,7 +177,7 @@ dlsizeof(const char *cstr)
|
||||||
dlen = 0;
|
dlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( cstr[i] ){
|
switch (cstr[i]) {
|
||||||
case 'I':
|
case 'I':
|
||||||
DLALIGN(0,size,INT_ALIGN);
|
DLALIGN(0,size,INT_ALIGN);
|
||||||
case 'i':
|
case 'i':
|
||||||
|
@ -234,9 +234,9 @@ c_farray(VALUE v, long *size)
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(float) * len;
|
*size = sizeof(float) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
ary[i] = (float)(RFLOAT(e)->value);
|
ary[i] = (float)(RFLOAT(e)->value);
|
||||||
break;
|
break;
|
||||||
|
@ -262,9 +262,9 @@ c_darray(VALUE v, long *size)
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(double) * len;
|
*size = sizeof(double) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
ary[i] = (double)(RFLOAT(e)->value);
|
ary[i] = (double)(RFLOAT(e)->value);
|
||||||
break;
|
break;
|
||||||
|
@ -290,9 +290,9 @@ c_larray(VALUE v, long *size)
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(long) * len;
|
*size = sizeof(long) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
ary[i] = (long)(NUM2INT(e));
|
ary[i] = (long)(NUM2INT(e));
|
||||||
|
@ -319,9 +319,9 @@ c_iarray(VALUE v, long *size)
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(int) * len;
|
*size = sizeof(int) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
ary[i] = (int)(NUM2INT(e));
|
ary[i] = (int)(NUM2INT(e));
|
||||||
|
@ -348,9 +348,9 @@ c_harray(VALUE v, long *size)
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(short) * len;
|
*size = sizeof(short) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
ary[i] = (short)(NUM2INT(e));
|
ary[i] = (short)(NUM2INT(e));
|
||||||
|
@ -377,9 +377,9 @@ c_carray(VALUE v, long *size)
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(char) * len;
|
*size = sizeof(char) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
ary[i] = (char)(NUM2INT(e));
|
ary[i] = (char)(NUM2INT(e));
|
||||||
|
@ -401,15 +401,23 @@ c_parray(VALUE v, long *size)
|
||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
void **ary;
|
void **ary;
|
||||||
VALUE e;
|
VALUE e, tmp;
|
||||||
|
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
*size = sizeof(void*) * len;
|
*size = sizeof(void*) * len;
|
||||||
ary = dlmalloc(*size);
|
ary = dlmalloc(*size);
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
e = rb_ary_entry(v, i);
|
e = rb_ary_entry(v, i);
|
||||||
switch( TYPE(e) ){
|
switch (TYPE(e)) {
|
||||||
|
default:
|
||||||
|
tmp = rb_check_string_type(e);
|
||||||
|
if (NIL_P(tmp)) {
|
||||||
|
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
||||||
|
}
|
||||||
|
e = tmp;
|
||||||
|
/* fall through */
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
|
rb_check_safe_str(e);
|
||||||
{
|
{
|
||||||
char *str, *src;
|
char *str, *src;
|
||||||
src = RSTRING(e)->ptr;
|
src = RSTRING(e)->ptr;
|
||||||
|
@ -421,7 +429,7 @@ c_parray(VALUE v, long *size)
|
||||||
ary[i] = NULL;
|
ary[i] = NULL;
|
||||||
break;
|
break;
|
||||||
case T_DATA:
|
case T_DATA:
|
||||||
if( rb_obj_is_kind_of(e, rb_cDLPtrData) ){
|
if (rb_obj_is_kind_of(e, rb_cDLPtrData)) {
|
||||||
struct ptr_data *pdata;
|
struct ptr_data *pdata;
|
||||||
Data_Get_Struct(e, struct ptr_data, pdata);
|
Data_Get_Struct(e, struct ptr_data, pdata);
|
||||||
ary[i] = (void*)(pdata->ptr);
|
ary[i] = (void*)(pdata->ptr);
|
||||||
|
@ -430,9 +438,6 @@ c_parray(VALUE v, long *size)
|
||||||
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
rb_raise(rb_eDLTypeError, "unexpected type of the element #%d", i);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,24 +450,26 @@ rb_ary2cary(char t, VALUE v, long *size)
|
||||||
int len;
|
int len;
|
||||||
VALUE val0;
|
VALUE val0;
|
||||||
|
|
||||||
if( TYPE(v) != T_ARRAY ){
|
val0 = rb_check_array_type(v);
|
||||||
|
if(NIL_P(TYPE(val0))) {
|
||||||
rb_raise(rb_eDLTypeError, "an array is expected.");
|
rb_raise(rb_eDLTypeError, "an array is expected.");
|
||||||
}
|
}
|
||||||
|
v = val0;
|
||||||
|
|
||||||
len = RARRAY(v)->len;
|
len = RARRAY(v)->len;
|
||||||
if( len == 0 ){
|
if (len == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !size ){
|
if (!size) {
|
||||||
size = ALLOCA_N(long,1);
|
size = ALLOCA_N(long,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
val0 = rb_ary_entry(v,0);
|
val0 = rb_ary_entry(v,0);
|
||||||
switch( TYPE(val0) ){
|
switch (TYPE(val0)) {
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
case T_BIGNUM:
|
case T_BIGNUM:
|
||||||
switch( t ){
|
switch (t) {
|
||||||
case 'C': case 'c':
|
case 'C': case 'c':
|
||||||
return (void*)c_carray(v,size);
|
return (void*)c_carray(v,size);
|
||||||
case 'H': case 'h':
|
case 'H': case 'h':
|
||||||
|
@ -477,7 +484,7 @@ rb_ary2cary(char t, VALUE v, long *size)
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
return (void*)c_parray(v,size);
|
return (void*)c_parray(v,size);
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
switch( t ){
|
switch (t) {
|
||||||
case 'F': case 'f':
|
case 'F': case 'f':
|
||||||
return (void*)c_farray(v,size);
|
return (void*)c_farray(v,size);
|
||||||
case 'D': case 'd': case 0:
|
case 'D': case 'd': case 0:
|
||||||
|
@ -485,7 +492,7 @@ rb_ary2cary(char t, VALUE v, long *size)
|
||||||
}
|
}
|
||||||
rb_raise(rb_eDLTypeError, "type mismatch");
|
rb_raise(rb_eDLTypeError, "type mismatch");
|
||||||
case T_DATA:
|
case T_DATA:
|
||||||
if( rb_obj_is_kind_of(val0, rb_cDLPtrData) ){
|
if (rb_obj_is_kind_of(val0, rb_cDLPtrData)) {
|
||||||
return (void*)c_parray(v,size);
|
return (void*)c_parray(v,size);
|
||||||
}
|
}
|
||||||
rb_raise(rb_eDLTypeError, "type mismatch");
|
rb_raise(rb_eDLTypeError, "type mismatch");
|
||||||
|
@ -516,7 +523,7 @@ rb_ary_to_ptr(int argc, VALUE argv[], VALUE self)
|
||||||
VALUE t;
|
VALUE t;
|
||||||
long size;
|
long size;
|
||||||
|
|
||||||
switch( rb_scan_args(argc, argv, "01", &t) ){
|
switch (rb_scan_args(argc, argv, "01", &t)) {
|
||||||
case 1:
|
case 1:
|
||||||
ptr = rb_ary2cary(StringValuePtr(t)[0], self, &size);
|
ptr = rb_ary2cary(StringValuePtr(t)[0], self, &size);
|
||||||
break;
|
break;
|
||||||
|
@ -556,15 +563,13 @@ rb_dl_malloc(VALUE self, VALUE size)
|
||||||
VALUE
|
VALUE
|
||||||
rb_dl_strdup(VALUE self, VALUE str)
|
rb_dl_strdup(VALUE self, VALUE str)
|
||||||
{
|
{
|
||||||
rb_secure(4);
|
SafeStringValue(str);
|
||||||
str = rb_String(str);
|
|
||||||
return rb_dlptr_new(strdup(RSTRING(str)->ptr), RSTRING(str)->len, dlfree);
|
return rb_dlptr_new(strdup(RSTRING(str)->ptr), RSTRING(str)->len, dlfree);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_dl_sizeof(VALUE self, VALUE str)
|
rb_dl_sizeof(VALUE self, VALUE str)
|
||||||
{
|
{
|
||||||
rb_secure(4);
|
|
||||||
return INT2NUM(dlsizeof(StringValuePtr(str)));
|
return INT2NUM(dlsizeof(StringValuePtr(str)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,9 +582,9 @@ rb_dl_callback(int argc, VALUE argv[], VALUE self)
|
||||||
|
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
proc = Qnil;
|
proc = Qnil;
|
||||||
switch( rb_scan_args(argc, argv, "11", &type, &proc) ){
|
switch (rb_scan_args(argc, argv, "11", &type, &proc)) {
|
||||||
case 1:
|
case 1:
|
||||||
if( rb_block_given_p() ){
|
if (rb_block_given_p()) {
|
||||||
proc = rb_f_lambda();
|
proc = rb_f_lambda();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -589,8 +594,8 @@ rb_dl_callback(int argc, VALUE argv[], VALUE self)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Check_Type(type, T_STRING);
|
StringValue(type);
|
||||||
switch( RSTRING(type)->ptr[0] ){
|
switch (RSTRING(type)->ptr[0]) {
|
||||||
case '0':
|
case '0':
|
||||||
rettype = 0x00;
|
rettype = 0x00;
|
||||||
break;
|
break;
|
||||||
|
@ -620,13 +625,13 @@ rb_dl_callback(int argc, VALUE argv[], VALUE self)
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = -1;
|
entry = -1;
|
||||||
for( i=0; i < MAX_CALLBACK; i++ ){
|
for (i=0; i < MAX_CALLBACK; i++) {
|
||||||
if( rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil ){
|
if (rb_hash_aref(DLFuncTable, rb_assoc_new(INT2NUM(rettype), INT2NUM(i))) == Qnil) {
|
||||||
entry = i;
|
entry = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( entry < 0 ){
|
if (entry < 0) {
|
||||||
rb_raise(rb_eDLError, "too many callbacks are defined.");
|
rb_raise(rb_eDLError, "too many callbacks are defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,9 +651,9 @@ rb_dl_remove_callback(VALUE mod, VALUE sym)
|
||||||
|
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
f = rb_dlsym2csym(sym);
|
f = rb_dlsym2csym(sym);
|
||||||
for( i=0; i < CALLBACK_TYPES; i++ ){
|
for (i=0; i < CALLBACK_TYPES; i++) {
|
||||||
for( j=0; j < MAX_CALLBACK; j++ ){
|
for (j=0; j < MAX_CALLBACK; j++) {
|
||||||
if( rb_dl_callback_table[i][j] == f ){
|
if (rb_dl_callback_table[i][j] == f) {
|
||||||
rb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil);
|
rb_hash_aset(DLFuncTable, rb_assoc_new(INT2NUM(i),INT2NUM(j)),Qnil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ VALUE rb_cDLHandle;
|
||||||
void
|
void
|
||||||
dlhandle_free(struct dl_handle *dlhandle)
|
dlhandle_free(struct dl_handle *dlhandle)
|
||||||
{
|
{
|
||||||
if( dlhandle->ptr && dlhandle->open && dlhandle->enable_close ){
|
if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) {
|
||||||
dlclose(dlhandle->ptr);
|
dlclose(dlhandle->ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self)
|
||||||
int cflag;
|
int cflag;
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
switch( rb_scan_args(argc, argv, "11", &lib, &flag) ){
|
switch (rb_scan_args(argc, argv, "11", &lib, &flag)) {
|
||||||
case 1:
|
case 1:
|
||||||
clib = StringValuePtr(lib);
|
clib = StringValuePtr(lib);
|
||||||
cflag = RTLD_LAZY | RTLD_GLOBAL;
|
cflag = RTLD_LAZY | RTLD_GLOBAL;
|
||||||
|
@ -65,24 +65,24 @@ rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self)
|
||||||
|
|
||||||
ptr = dlopen(clib, cflag);
|
ptr = dlopen(clib, cflag);
|
||||||
#if defined(HAVE_DLERROR)
|
#if defined(HAVE_DLERROR)
|
||||||
if( !ptr && (err = dlerror()) ){
|
if (!ptr && (err = dlerror())) {
|
||||||
rb_raise(rb_eRuntimeError, err);
|
rb_raise(rb_eRuntimeError, err);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( !ptr ){
|
if (!ptr) {
|
||||||
err = dlerror();
|
err = dlerror();
|
||||||
rb_raise(rb_eRuntimeError, err);
|
rb_raise(rb_eRuntimeError, err);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Data_Get_Struct(self, struct dl_handle, dlhandle);
|
Data_Get_Struct(self, struct dl_handle, dlhandle);
|
||||||
if( dlhandle->ptr && dlhandle->open && dlhandle->enable_close ){
|
if (dlhandle->ptr && dlhandle->open && dlhandle->enable_close) {
|
||||||
dlclose(dlhandle->ptr);
|
dlclose(dlhandle->ptr);
|
||||||
}
|
}
|
||||||
dlhandle->ptr = ptr;
|
dlhandle->ptr = ptr;
|
||||||
dlhandle->open = 1;
|
dlhandle->open = 1;
|
||||||
dlhandle->enable_close = 0;
|
dlhandle->enable_close = 0;
|
||||||
|
|
||||||
if( rb_block_given_p() ){
|
if (rb_block_given_p()) {
|
||||||
rb_ensure(rb_yield, self, rb_dlhandle_close, self);
|
rb_ensure(rb_yield, self, rb_dlhandle_close, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,14 +138,16 @@ rb_dlhandle_sym(int argc, VALUE argv[], VALUE self)
|
||||||
const char *name, *stype;
|
const char *name, *stype;
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
if( rb_scan_args(argc, argv, "11", &sym, &type) == 2 ){
|
rb_secure(4);
|
||||||
|
if (rb_scan_args(argc, argv, "11", &sym, &type) == 2) {
|
||||||
|
SafeStringValue(type);
|
||||||
stype = StringValuePtr(type);
|
stype = StringValuePtr(type);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
stype = NULL;
|
stype = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sym == Qnil ){
|
if (sym == Qnil) {
|
||||||
#if defined(RTLD_NEXT)
|
#if defined(RTLD_NEXT)
|
||||||
name = RTLD_NEXT;
|
name = RTLD_NEXT;
|
||||||
#else
|
#else
|
||||||
|
@ -153,21 +155,22 @@ rb_dlhandle_sym(int argc, VALUE argv[], VALUE self)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
SafeStringValue(sym);
|
||||||
name = StringValuePtr(sym);
|
name = StringValuePtr(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Data_Get_Struct(self, struct dl_handle, dlhandle);
|
Data_Get_Struct(self, struct dl_handle, dlhandle);
|
||||||
if( ! dlhandle->open ){
|
if (! dlhandle->open) {
|
||||||
rb_raise(rb_eRuntimeError, "Closed handle.");
|
rb_raise(rb_eRuntimeError, "Closed handle.");
|
||||||
}
|
}
|
||||||
handle = dlhandle->ptr;
|
handle = dlhandle->ptr;
|
||||||
|
|
||||||
func = dlsym(handle, name);
|
func = dlsym(handle, name);
|
||||||
#if defined(HAVE_DLERROR)
|
#if defined(HAVE_DLERROR)
|
||||||
if( !func && (err = dlerror()) )
|
if (!func && (err = dlerror()))
|
||||||
#else
|
#else
|
||||||
if( !func )
|
if (!func)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__)
|
#if defined(__CYGWIN__) || defined(WIN32) || defined(__MINGW32__)
|
||||||
|
@ -180,9 +183,9 @@ rb_dlhandle_sym(int argc, VALUE argv[], VALUE self)
|
||||||
func = dlsym(handle, name_a);
|
func = dlsym(handle, name_a);
|
||||||
dlfree(name_a);
|
dlfree(name_a);
|
||||||
#if defined(HAVE_DLERROR)
|
#if defined(HAVE_DLERROR)
|
||||||
if( !func && (err = dlerror()) )
|
if (!func && (err = dlerror()))
|
||||||
#else
|
#else
|
||||||
if( !func )
|
if (!func)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
rb_raise(rb_eRuntimeError, "Unknown symbol \"%sA\".", name);
|
rb_raise(rb_eRuntimeError, "Unknown symbol \"%sA\".", name);
|
||||||
|
|
152
ext/dl/ptr.c
152
ext/dl/ptr.c
|
@ -33,7 +33,7 @@ rb_dlmem_delete(void *ptr)
|
||||||
static void
|
static void
|
||||||
rb_dlmem_aset(void *ptr, VALUE obj)
|
rb_dlmem_aset(void *ptr, VALUE obj)
|
||||||
{
|
{
|
||||||
if( obj == Qnil ){
|
if (obj == Qnil) {
|
||||||
rb_dlmem_delete(ptr);
|
rb_dlmem_delete(ptr);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -53,22 +53,22 @@ rb_dlmem_aref(void *ptr)
|
||||||
void
|
void
|
||||||
dlptr_free(struct ptr_data *data)
|
dlptr_free(struct ptr_data *data)
|
||||||
{
|
{
|
||||||
if( data->ptr ){
|
if (data->ptr) {
|
||||||
DEBUG_CODE({
|
DEBUG_CODE({
|
||||||
printf("dlptr_free(): removing the pointer `0x%x' from the MemorySpace\n",
|
printf("dlptr_free(): removing the pointer `0x%x' from the MemorySpace\n",
|
||||||
data->ptr);
|
data->ptr);
|
||||||
});
|
});
|
||||||
rb_dlmem_delete(data->ptr);
|
rb_dlmem_delete(data->ptr);
|
||||||
if( data->free ){
|
if (data->free) {
|
||||||
DEBUG_CODE({
|
DEBUG_CODE({
|
||||||
printf("dlptr_free(): 0x%x(data->ptr:0x%x)\n",data->free,data->ptr);
|
printf("dlptr_free(): 0x%x(data->ptr:0x%x)\n",data->free,data->ptr);
|
||||||
});
|
});
|
||||||
(*(data->free))(data->ptr);
|
(*(data->free))(data->ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( data->stype ) dlfree(data->stype);
|
if (data->stype) dlfree(data->stype);
|
||||||
if( data->ssize ) dlfree(data->ssize);
|
if (data->ssize) dlfree(data->ssize);
|
||||||
if( data->ids ) dlfree(data->ids);
|
if (data->ids) dlfree(data->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -82,6 +82,7 @@ dlptr_init(VALUE val)
|
||||||
data->ptr);
|
data->ptr);
|
||||||
});
|
});
|
||||||
rb_dlmem_aset(data->ptr, val);
|
rb_dlmem_aset(data->ptr, val);
|
||||||
|
OBJ_TAINT(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -91,9 +92,9 @@ rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
||||||
VALUE val;
|
VALUE val;
|
||||||
|
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
if( ptr ){
|
if (ptr) {
|
||||||
val = rb_dlmem_aref(ptr);
|
val = rb_dlmem_aref(ptr);
|
||||||
if( val == Qnil ){
|
if (val == Qnil) {
|
||||||
val = Data_Make_Struct(klass, struct ptr_data,
|
val = Data_Make_Struct(klass, struct ptr_data,
|
||||||
0, dlptr_free, data);
|
0, dlptr_free, data);
|
||||||
data->ptr = ptr;
|
data->ptr = ptr;
|
||||||
|
@ -108,7 +109,7 @@ rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
||||||
dlptr_init(val);
|
dlptr_init(val);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if( func ){
|
if (func) {
|
||||||
Data_Get_Struct(val, struct ptr_data, data);
|
Data_Get_Struct(val, struct ptr_data, data);
|
||||||
data->free = func;
|
data->free = func;
|
||||||
}
|
}
|
||||||
|
@ -144,11 +145,11 @@ rb_dlptr2cptr(VALUE val)
|
||||||
struct ptr_data *data;
|
struct ptr_data *data;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
if( rb_obj_is_kind_of(val, rb_cDLPtrData) ){
|
if (rb_obj_is_kind_of(val, rb_cDLPtrData)) {
|
||||||
Data_Get_Struct(val, struct ptr_data, data);
|
Data_Get_Struct(val, struct ptr_data, data);
|
||||||
ptr = data->ptr;
|
ptr = data->ptr;
|
||||||
}
|
}
|
||||||
else if( val == Qnil ){
|
else if (val == Qnil) {
|
||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -188,7 +189,7 @@ rb_dlptr_initialize(int argc, VALUE argv[], VALUE self)
|
||||||
freefunc_t f = NULL;
|
freefunc_t f = NULL;
|
||||||
long s = 0;
|
long s = 0;
|
||||||
|
|
||||||
switch( rb_scan_args(argc, argv, "12", &ptr, &size, &sym) ){
|
switch (rb_scan_args(argc, argv, "12", &ptr, &size, &sym)) {
|
||||||
case 1:
|
case 1:
|
||||||
p = (void*)(DLNUM2LONG(rb_Integer(ptr)));
|
p = (void*)(DLNUM2LONG(rb_Integer(ptr)));
|
||||||
break;
|
break;
|
||||||
|
@ -205,9 +206,9 @@ rb_dlptr_initialize(int argc, VALUE argv[], VALUE self)
|
||||||
rb_bug("rb_dlptr_initialize");
|
rb_bug("rb_dlptr_initialize");
|
||||||
}
|
}
|
||||||
|
|
||||||
if( p ){
|
if (p) {
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
if( data->ptr && data->free ){
|
if (data->ptr && data->free) {
|
||||||
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
|
/* Free previous memory. Use of inappropriate initialize may cause SEGV. */
|
||||||
(*(data->free))(data->ptr);
|
(*(data->free))(data->ptr);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +227,7 @@ rb_dlptr_s_malloc(int argc, VALUE argv[], VALUE klass)
|
||||||
int s;
|
int s;
|
||||||
freefunc_t f = NULL;
|
freefunc_t f = NULL;
|
||||||
|
|
||||||
switch( rb_scan_args(argc, argv, "11", &size, &sym) ){
|
switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
|
||||||
case 1:
|
case 1:
|
||||||
s = NUM2INT(size);
|
s = NUM2INT(size);
|
||||||
break;
|
break;
|
||||||
|
@ -313,14 +314,14 @@ rb_dlptr_to_array(int argc, VALUE argv[], VALUE self)
|
||||||
|
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
|
|
||||||
switch( rb_scan_args(argc, argv, "11", &type, &size) ){
|
switch (rb_scan_args(argc, argv, "11", &type, &size)) {
|
||||||
case 2:
|
case 2:
|
||||||
t = StringValuePtr(type)[0];
|
t = StringValuePtr(type)[0];
|
||||||
n = NUM2INT(size);
|
n = NUM2INT(size);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
t = StringValuePtr(type)[0];
|
t = StringValuePtr(type)[0];
|
||||||
switch( t ){
|
switch (t) {
|
||||||
case 'C':
|
case 'C':
|
||||||
n = data->size;
|
n = data->size;
|
||||||
break;
|
break;
|
||||||
|
@ -343,9 +344,9 @@ rb_dlptr_to_array(int argc, VALUE argv[], VALUE self)
|
||||||
n = data->size / sizeof(void*);
|
n = data->size / sizeof(void*);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if( t == 'p' || t == 's' ){
|
if (t == 'p' || t == 's') {
|
||||||
int i;
|
int i;
|
||||||
for( i=0; ((void**)(data->ptr))[i]; i++ ){};
|
for (i=0; ((void**)(data->ptr))[i]; i++) {};
|
||||||
n = i;
|
n = i;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -359,8 +360,8 @@ rb_dlptr_to_array(int argc, VALUE argv[], VALUE self)
|
||||||
|
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
|
|
||||||
for( i=0; i < n; i++ ){
|
for (i=0; i < n; i++) {
|
||||||
switch( t ){
|
switch (t) {
|
||||||
case 'C':
|
case 'C':
|
||||||
rb_ary_push(ary, INT2NUM(((char*)(data->ptr))[i]));
|
rb_ary_push(ary, INT2NUM(((char*)(data->ptr))[i]));
|
||||||
break;
|
break;
|
||||||
|
@ -381,7 +382,7 @@ rb_dlptr_to_array(int argc, VALUE argv[], VALUE self)
|
||||||
case 'S':
|
case 'S':
|
||||||
{
|
{
|
||||||
char *str = ((char**)(data->ptr))[i];
|
char *str = ((char**)(data->ptr))[i];
|
||||||
if( str ){
|
if (str) {
|
||||||
rb_ary_push(ary, rb_tainted_str_new2(str));
|
rb_ary_push(ary, rb_tainted_str_new2(str));
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -392,7 +393,7 @@ rb_dlptr_to_array(int argc, VALUE argv[], VALUE self)
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
char *str = ((char**)(data->ptr))[i];
|
char *str = ((char**)(data->ptr))[i];
|
||||||
if( str ){
|
if (str) {
|
||||||
rb_ary_push(ary, rb_tainted_str_new2(str));
|
rb_ary_push(ary, rb_tainted_str_new2(str));
|
||||||
xfree(str);
|
xfree(str);
|
||||||
}
|
}
|
||||||
|
@ -423,7 +424,7 @@ rb_dlptr_to_s(int argc, VALUE argv[], VALUE self)
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
switch( rb_scan_args(argc, argv, "01", &arg1) ){
|
switch (rb_scan_args(argc, argv, "01", &arg1)) {
|
||||||
case 0:
|
case 0:
|
||||||
val = rb_tainted_str_new2((char*)(data->ptr));
|
val = rb_tainted_str_new2((char*)(data->ptr));
|
||||||
break;
|
break;
|
||||||
|
@ -446,7 +447,7 @@ rb_dlptr_to_str(int argc, VALUE argv[], VALUE self)
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
switch( rb_scan_args(argc, argv, "01", &arg1) ){
|
switch (rb_scan_args(argc, argv, "01", &arg1)) {
|
||||||
case 0:
|
case 0:
|
||||||
val = rb_tainted_str_new((char*)(data->ptr),data->size);
|
val = rb_tainted_str_new((char*)(data->ptr),data->size);
|
||||||
break;
|
break;
|
||||||
|
@ -527,16 +528,16 @@ rb_dlptr_define_data_type(int argc, VALUE argv[], VALUE self)
|
||||||
rb_scan_args(argc, argv, "11*", &data_type, &type, &rest);
|
rb_scan_args(argc, argv, "11*", &data_type, &type, &rest);
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
|
|
||||||
if( argc == 1 || (argc == 2 && type == Qnil) ){
|
if (argc == 1 || (argc == 2 && type == Qnil)) {
|
||||||
if( NUM2INT(data_type) == DLPTR_CTYPE_UNKNOWN ){
|
if (NUM2INT(data_type) == DLPTR_CTYPE_UNKNOWN) {
|
||||||
data->ctype = DLPTR_CTYPE_UNKNOWN;
|
data->ctype = DLPTR_CTYPE_UNKNOWN;
|
||||||
data->slen = 0;
|
data->slen = 0;
|
||||||
data->ids_num = 0;
|
data->ids_num = 0;
|
||||||
if( data->stype ){
|
if (data->stype) {
|
||||||
dlfree(data->stype);
|
dlfree(data->stype);
|
||||||
data->stype = NULL;
|
data->stype = NULL;
|
||||||
}
|
}
|
||||||
if( data->ids ){
|
if (data->ids) {
|
||||||
dlfree(data->ids);
|
dlfree(data->ids);
|
||||||
data->ids = NULL;
|
data->ids = NULL;
|
||||||
}
|
}
|
||||||
|
@ -551,32 +552,29 @@ rb_dlptr_define_data_type(int argc, VALUE argv[], VALUE self)
|
||||||
StringValue(type);
|
StringValue(type);
|
||||||
Check_Type(rest, T_ARRAY);
|
Check_Type(rest, T_ARRAY);
|
||||||
num = RARRAY(rest)->len;
|
num = RARRAY(rest)->len;
|
||||||
for( i=0; i<num; i++ ){
|
for (i=0; i<num; i++) {
|
||||||
vid = rb_ary_entry(rest,i);
|
rb_to_id(rb_ary_entry(rest,i));
|
||||||
if( !(TYPE(vid)==T_STRING || TYPE(vid)==T_SYMBOL) ){
|
|
||||||
rb_raise(rb_eTypeError, "#%d must be a string or symbol", i + 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data->ctype = t;
|
data->ctype = t;
|
||||||
data->slen = num;
|
data->slen = num;
|
||||||
data->ids_num = num;
|
data->ids_num = num;
|
||||||
if( data->stype ) dlfree(data->stype);
|
if (data->stype) dlfree(data->stype);
|
||||||
data->stype = (char*)dlmalloc(sizeof(char) * num);
|
data->stype = (char*)dlmalloc(sizeof(char) * num);
|
||||||
if( data->ssize ) dlfree(data->ssize);
|
if (data->ssize) dlfree(data->ssize);
|
||||||
data->ssize = (int*)dlmalloc(sizeof(int) * num);
|
data->ssize = (int*)dlmalloc(sizeof(int) * num);
|
||||||
if( data->ids ) dlfree(data->ids);
|
if (data->ids) dlfree(data->ids);
|
||||||
data->ids = (ID*)dlmalloc(sizeof(ID) * data->ids_num);
|
data->ids = (ID*)dlmalloc(sizeof(ID) * data->ids_num);
|
||||||
|
|
||||||
ctype = StringValuePtr(type);
|
ctype = StringValuePtr(type);
|
||||||
for( i=0; i<num; i++ ){
|
for (i=0; i<num; i++) {
|
||||||
vid = rb_ary_entry(rest,i);
|
vid = rb_ary_entry(rest,i);
|
||||||
data->ids[i] = rb_to_id(vid);
|
data->ids[i] = rb_to_id(vid);
|
||||||
data->stype[i] = *ctype;
|
data->stype[i] = *ctype;
|
||||||
ctype ++;
|
ctype ++;
|
||||||
if( isdigit(*ctype) ){
|
if (isdigit(*ctype)) {
|
||||||
char *p, *d;
|
char *p, *d;
|
||||||
for( p=ctype; isdigit(*p); p++ ) ;
|
for (p=ctype; isdigit(*p); p++) ;
|
||||||
d = ALLOCA_N(char, p - ctype + 1);
|
d = ALLOCA_N(char, p - ctype + 1);
|
||||||
strncpy(d, ctype, p - ctype);
|
strncpy(d, ctype, p - ctype);
|
||||||
d[p - ctype] = '\0';
|
d[p - ctype] = '\0';
|
||||||
|
@ -588,11 +586,11 @@ rb_dlptr_define_data_type(int argc, VALUE argv[], VALUE self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( *ctype ){
|
if (*ctype) {
|
||||||
rb_raise(rb_eArgError, "too few/many arguments");
|
rb_raise(rb_eArgError, "too few/many arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !data->size )
|
if (!data->size)
|
||||||
data->size = dlsizeof(RSTRING(type)->ptr);
|
data->size = dlsizeof(RSTRING(type)->ptr);
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -607,7 +605,7 @@ rb_dlptr_define_struct(int argc, VALUE argv[], VALUE self)
|
||||||
pass_argc = argc + 1;
|
pass_argc = argc + 1;
|
||||||
pass_argv = ALLOCA_N(VALUE, pass_argc);
|
pass_argv = ALLOCA_N(VALUE, pass_argc);
|
||||||
pass_argv[0] = INT2FIX(DLPTR_CTYPE_STRUCT);
|
pass_argv[0] = INT2FIX(DLPTR_CTYPE_STRUCT);
|
||||||
for( i=1; i<pass_argc; i++ ){
|
for (i=1; i<pass_argc; i++) {
|
||||||
pass_argv[i] = argv[i-1];
|
pass_argv[i] = argv[i-1];
|
||||||
}
|
}
|
||||||
return rb_dlptr_define_data_type(pass_argc, pass_argv, self);
|
return rb_dlptr_define_data_type(pass_argc, pass_argv, self);
|
||||||
|
@ -622,7 +620,7 @@ rb_dlptr_define_union(int argc, VALUE argv[], VALUE self)
|
||||||
pass_argc = argc + 1;
|
pass_argc = argc + 1;
|
||||||
pass_argv = ALLOCA_N(VALUE, pass_argc);
|
pass_argv = ALLOCA_N(VALUE, pass_argc);
|
||||||
pass_argv[0] = INT2FIX(DLPTR_CTYPE_UNION);
|
pass_argv[0] = INT2FIX(DLPTR_CTYPE_UNION);
|
||||||
for( i=1; i<pass_argc; i++ ){
|
for (i=1; i<pass_argc; i++) {
|
||||||
pass_argv[i] = argv[i-1];
|
pass_argv[i] = argv[i-1];
|
||||||
}
|
}
|
||||||
return rb_dlptr_define_data_type(pass_argc, pass_argv, self);
|
return rb_dlptr_define_data_type(pass_argc, pass_argv, self);
|
||||||
|
@ -634,7 +632,7 @@ rb_dlptr_get_data_type(VALUE self)
|
||||||
struct ptr_data *data;
|
struct ptr_data *data;
|
||||||
|
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
if( data->stype )
|
if (data->stype)
|
||||||
return rb_assoc_new(INT2FIX(data->ctype),
|
return rb_assoc_new(INT2FIX(data->ctype),
|
||||||
rb_tainted_str_new(data->stype, data->slen));
|
rb_tainted_str_new(data->stype, data->slen));
|
||||||
else
|
else
|
||||||
|
@ -648,11 +646,11 @@ cary2ary(void *ptr, char t, int len)
|
||||||
VALUE elem;
|
VALUE elem;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( len < 1 )
|
if (len < 1)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
|
||||||
if( len == 1 ){
|
if (len == 1) {
|
||||||
switch( t ){
|
switch (t) {
|
||||||
case 'I':
|
case 'I':
|
||||||
elem = INT2NUM(*((int*)ptr));
|
elem = INT2NUM(*((int*)ptr));
|
||||||
ptr = (char *)ptr + sizeof(int);
|
ptr = (char *)ptr + sizeof(int);
|
||||||
|
@ -689,8 +687,8 @@ cary2ary(void *ptr, char t, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
for( i=0; i < len; i++ ){
|
for (i=0; i < len; i++) {
|
||||||
switch( t ){
|
switch (t) {
|
||||||
case 'I':
|
case 'I':
|
||||||
elem = INT2NUM(*((int*)ptr));
|
elem = INT2NUM(*((int*)ptr));
|
||||||
ptr = (char *)ptr + sizeof(int);
|
ptr = (char *)ptr + sizeof(int);
|
||||||
|
@ -738,28 +736,28 @@ rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
|
||||||
int i;
|
int i;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
if( rb_scan_args(argc, argv, "11", &key, &num) == 1 ){
|
if (rb_scan_args(argc, argv, "11", &key, &num) == 1) {
|
||||||
num = INT2NUM(0);
|
num = INT2NUM(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM ){
|
if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) {
|
||||||
VALUE pass[1];
|
VALUE pass[1];
|
||||||
pass[0] = num;
|
pass[0] = num;
|
||||||
return rb_dlptr_to_str(1, pass, rb_dlptr_plus(self, key));
|
return rb_dlptr_to_str(1, pass, rb_dlptr_plus(self, key));
|
||||||
}
|
}
|
||||||
|
rb_to_id(key);
|
||||||
if( ! (TYPE(key) == T_STRING || TYPE(key) == T_SYMBOL ) ){
|
if (! (TYPE(key) == T_STRING || TYPE(key) == T_SYMBOL)) {
|
||||||
rb_raise(rb_eTypeError, "the key must be a string or symbol");
|
rb_raise(rb_eTypeError, "the key must be a string or symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
id = rb_to_id(key);
|
id = rb_to_id(key);
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
switch( data->ctype ){
|
switch (data->ctype) {
|
||||||
case DLPTR_CTYPE_STRUCT:
|
case DLPTR_CTYPE_STRUCT:
|
||||||
for( i=0; i < data->ids_num; i++ ){
|
for (i=0; i < data->ids_num; i++) {
|
||||||
if( data->ids[i] == id ){
|
if (data->ids[i] == id) {
|
||||||
switch( data->stype[i] ){
|
switch (data->stype[i]) {
|
||||||
case 'I':
|
case 'I':
|
||||||
DLALIGN(data->ptr,offset,INT_ALIGN);
|
DLALIGN(data->ptr,offset,INT_ALIGN);
|
||||||
break;
|
break;
|
||||||
|
@ -786,7 +784,7 @@ rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
|
||||||
}
|
}
|
||||||
return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);
|
return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);
|
||||||
}
|
}
|
||||||
switch( data->stype[i] ){
|
switch (data->stype[i]) {
|
||||||
case 'I':
|
case 'I':
|
||||||
offset += sizeof(int) * data->ssize[i];
|
offset += sizeof(int) * data->ssize[i];
|
||||||
break;
|
break;
|
||||||
|
@ -815,8 +813,8 @@ rb_dlptr_aref(int argc, VALUE argv[], VALUE self)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DLPTR_CTYPE_UNION:
|
case DLPTR_CTYPE_UNION:
|
||||||
for( i=0; i < data->ids_num; i++ ){
|
for (i=0; i < data->ids_num; i++) {
|
||||||
if( data->ids[i] == id ){
|
if (data->ids[i] == id) {
|
||||||
return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);
|
return cary2ary((char *)data->ptr + offset, data->stype[i], data->ssize[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -834,7 +832,7 @@ ary2cary(char t, VALUE val, long *size)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
if( TYPE(val) == T_ARRAY ){
|
if (TYPE(val) == T_ARRAY) {
|
||||||
ptr = rb_ary2cary(t, val, size);
|
ptr = rb_ary2cary(t, val, size);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -855,14 +853,14 @@ rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
|
||||||
void *memimg;
|
void *memimg;
|
||||||
|
|
||||||
rb_secure(4);
|
rb_secure(4);
|
||||||
switch( rb_scan_args(argc, argv, "21", &key, &num, &val) ){
|
switch (rb_scan_args(argc, argv, "21", &key, &num, &val)) {
|
||||||
case 2:
|
case 2:
|
||||||
val = num;
|
val = num;
|
||||||
num = Qnil;
|
num = Qnil;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM ){
|
if (TYPE(key) == T_FIXNUM || TYPE(key) == T_BIGNUM) {
|
||||||
void *dst, *src;
|
void *dst, *src;
|
||||||
long len;
|
long len;
|
||||||
|
|
||||||
|
@ -871,29 +869,25 @@ rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
|
||||||
dst = (void*)((long)(data->ptr) + DLNUM2LONG(key));
|
dst = (void*)((long)(data->ptr) + DLNUM2LONG(key));
|
||||||
src = RSTRING(val)->ptr;
|
src = RSTRING(val)->ptr;
|
||||||
len = RSTRING(val)->len;
|
len = RSTRING(val)->len;
|
||||||
if( num == Qnil ){
|
if (num == Qnil) {
|
||||||
memcpy(dst, src, len);
|
memcpy(dst, src, len);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
long n = NUM2INT(num);
|
long n = NUM2INT(num);
|
||||||
memcpy(dst, src, n < len ? n : len);
|
memcpy(dst, src, n < len ? n : len);
|
||||||
if( n > len ) MEMZERO((char*)dst + len, char, n - len);
|
if (n > len) MEMZERO((char*)dst + len, char, n - len);
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ! (TYPE(key) == T_STRING || TYPE(key) == T_SYMBOL ) ){
|
|
||||||
rb_raise(rb_eTypeError, "the key must be a string or symbol");
|
|
||||||
}
|
|
||||||
|
|
||||||
id = rb_to_id(key);
|
id = rb_to_id(key);
|
||||||
Data_Get_Struct(self, struct ptr_data, data);
|
Data_Get_Struct(self, struct ptr_data, data);
|
||||||
switch( data->ctype ){
|
switch (data->ctype) {
|
||||||
case DLPTR_CTYPE_STRUCT:
|
case DLPTR_CTYPE_STRUCT:
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for( i=0; i < data->ids_num; i++ ){
|
for (i=0; i < data->ids_num; i++) {
|
||||||
if( data->ids[i] == id ){
|
if (data->ids[i] == id) {
|
||||||
switch( data->stype[i] ){
|
switch (data->stype[i]) {
|
||||||
case 'I':
|
case 'I':
|
||||||
DLALIGN(data->ptr,offset,INT_ALIGN);
|
DLALIGN(data->ptr,offset,INT_ALIGN);
|
||||||
break;
|
break;
|
||||||
|
@ -922,7 +916,7 @@ rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
|
||||||
memcpy((char *)data->ptr + offset, memimg, memsize);
|
memcpy((char *)data->ptr + offset, memimg, memsize);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
switch( data->stype[i] ){
|
switch (data->stype[i]) {
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'i':
|
case 'i':
|
||||||
offset += sizeof(int) * data->ssize[i];
|
offset += sizeof(int) * data->ssize[i];
|
||||||
|
@ -960,9 +954,9 @@ rb_dlptr_aset(int argc, VALUE argv[], VALUE self)
|
||||||
return val;
|
return val;
|
||||||
/* break; */
|
/* break; */
|
||||||
case DLPTR_CTYPE_UNION:
|
case DLPTR_CTYPE_UNION:
|
||||||
for( i=0; i < data->ids_num; i++ ){
|
for (i=0; i < data->ids_num; i++) {
|
||||||
if( data->ids[i] == id ){
|
if (data->ids[i] == id) {
|
||||||
switch( data->stype[i] ){
|
switch (data->stype[i]) {
|
||||||
case 'I': case 'i':
|
case 'I': case 'i':
|
||||||
memsize = sizeof(int) * data->ssize[i];
|
memsize = sizeof(int) * data->ssize[i];
|
||||||
break;
|
break;
|
||||||
|
@ -1007,7 +1001,7 @@ rb_dlptr_size(int argc, VALUE argv[], VALUE self)
|
||||||
{
|
{
|
||||||
VALUE size;
|
VALUE size;
|
||||||
|
|
||||||
if( rb_scan_args(argc, argv, "01", &size) == 0){
|
if (rb_scan_args(argc, argv, "01", &size) == 0){
|
||||||
return DLLONG2NUM(RDLPTR(self)->size);
|
return DLLONG2NUM(RDLPTR(self)->size);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
20
ext/dl/sym.c
20
ext/dl/sym.c
|
@ -330,7 +330,7 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self)
|
||||||
long ftype;
|
long ftype;
|
||||||
void *func;
|
void *func;
|
||||||
|
|
||||||
rb_secure(4);
|
rb_secure(2);
|
||||||
Data_Get_Struct(self, struct sym_data, sym);
|
Data_Get_Struct(self, struct sym_data, sym);
|
||||||
DEBUG_CODE({
|
DEBUG_CODE({
|
||||||
printf("rb_dlsym_call(): type = '%s', func = 0x%x\n", sym->type, sym->func);
|
printf("rb_dlsym_call(): type = '%s', func = 0x%x\n", sym->type, sym->func);
|
||||||
|
@ -457,20 +457,20 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self)
|
||||||
ANY2S(args[i]) = DLSTR(0);
|
ANY2S(args[i]) = DLSTR(0);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if( TYPE(argv[i]) != T_STRING ){
|
VALUE str = argv[i];
|
||||||
rb_raise(rb_eDLError, "#%d must be a string",i);
|
SafeStringValue(str);
|
||||||
}
|
ANY2S(args[i]) = DLSTR(RSTRING(str)->ptr);
|
||||||
ANY2S(args[i]) = DLSTR(RSTRING(argv[i])->ptr);
|
|
||||||
}
|
}
|
||||||
PUSH_P(ftype);
|
PUSH_P(ftype);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if( TYPE(argv[i]) != T_STRING ){
|
{
|
||||||
rb_raise(rb_eDLError, "#%d must be a string",i);
|
VALUE str = argv[i];
|
||||||
}
|
SafeStringValue(str);
|
||||||
ANY2S(args[i]) = DLSTR(dlmalloc(RSTRING(argv[i])->len + 1));
|
ANY2S(args[i]) = DLSTR(dlmalloc(RSTRING(str)->len + 1));
|
||||||
memcpy((char*)(ANY2S(args[i])), RSTRING(argv[i])->ptr, RSTRING(argv[i])->len + 1);
|
memcpy((char*)(ANY2S(args[i])), RSTRING(str)->ptr, RSTRING(str)->len + 1);
|
||||||
dtypes[i] = 's';
|
dtypes[i] = 's';
|
||||||
|
}
|
||||||
PUSH_P(ftype);
|
PUSH_P(ftype);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -19,9 +19,9 @@ class String
|
||||||
PATTERN_EUC = '[\xa1-\xfe][\xa1-\xfe]'
|
PATTERN_EUC = '[\xa1-\xfe][\xa1-\xfe]'
|
||||||
PATTERN_UTF8 = '[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]'
|
PATTERN_UTF8 = '[\xc0-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf][\x80-\xbf]'
|
||||||
|
|
||||||
RE_SJIS = Regexp.new(PATTERN_SJIS, 'n')
|
RE_SJIS = Regexp.new(PATTERN_SJIS, 0, 'n')
|
||||||
RE_EUC = Regexp.new(PATTERN_EUC, 'n')
|
RE_EUC = Regexp.new(PATTERN_EUC, 0, 'n')
|
||||||
RE_UTF8 = Regexp.new(PATTERN_UTF8, 'n')
|
RE_UTF8 = Regexp.new(PATTERN_UTF8, 0, 'n')
|
||||||
|
|
||||||
SUCC = {}
|
SUCC = {}
|
||||||
SUCC['s'] = Hash.new(1)
|
SUCC['s'] = Hash.new(1)
|
||||||
|
|
6
object.c
6
object.c
|
@ -773,12 +773,14 @@ ID
|
||||||
rb_to_id(name)
|
rb_to_id(name)
|
||||||
VALUE name;
|
VALUE name;
|
||||||
{
|
{
|
||||||
|
VALUE tmp;
|
||||||
ID id;
|
ID id;
|
||||||
|
|
||||||
switch (TYPE(name)) {
|
switch (TYPE(name)) {
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
return rb_intern(RSTRING(name)->ptr);
|
return rb_intern(RSTRING(name)->ptr);
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
|
rb_warn("do not use Fixnums as Symbols");
|
||||||
id = FIX2LONG(name);
|
id = FIX2LONG(name);
|
||||||
if (!rb_id2name(id)) {
|
if (!rb_id2name(id)) {
|
||||||
rb_raise(rb_eArgError, "%ld is not a symbol", id);
|
rb_raise(rb_eArgError, "%ld is not a symbol", id);
|
||||||
|
@ -788,6 +790,10 @@ rb_to_id(name)
|
||||||
id = SYM2ID(name);
|
id = SYM2ID(name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
tmp = rb_check_string_type(name);
|
||||||
|
if (!NIL_P(tmp)) {
|
||||||
|
return rb_intern(RSTRING(tmp)->ptr);
|
||||||
|
}
|
||||||
rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING(rb_inspect(name))->ptr);
|
rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING(rb_inspect(name))->ptr);
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
|
|
6
ruby.h
6
ruby.h
|
@ -215,12 +215,14 @@ VALUE rb_string_value _((volatile VALUE*));
|
||||||
char *rb_string_value_ptr _((volatile VALUE*));
|
char *rb_string_value_ptr _((volatile VALUE*));
|
||||||
|
|
||||||
#define StringValue(v) if (TYPE(v) != T_STRING) rb_string_value(&(v))
|
#define StringValue(v) if (TYPE(v) != T_STRING) rb_string_value(&(v))
|
||||||
|
#define StringValuePtr(v) rb_string_value_ptr(&(v))
|
||||||
|
|
||||||
|
void rb_check_safe_obj _((VALUE));
|
||||||
void rb_check_safe_str _((VALUE));
|
void rb_check_safe_str _((VALUE));
|
||||||
#define SafeStringValue(v) do {\
|
#define SafeStringValue(v) do {\
|
||||||
StringValue(v);\
|
StringValue(v);\
|
||||||
rb_check_safe_str(v);\
|
rb_check_safe_obj(v);\
|
||||||
} while (0)
|
} while (0)
|
||||||
#define StringValuePtr(v) rb_string_value_ptr(&(v))
|
|
||||||
/* obsolete macro - use SafeStringValue(v) */
|
/* obsolete macro - use SafeStringValue(v) */
|
||||||
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
|
#define Check_SafeStr(v) rb_check_safe_str((VALUE)(v))
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#define RUBY_VERSION "1.8.0"
|
#define RUBY_VERSION "1.8.0"
|
||||||
#define RUBY_RELEASE_DATE "2003-03-23"
|
#define RUBY_RELEASE_DATE "2003-03-24"
|
||||||
#define RUBY_VERSION_CODE 180
|
#define RUBY_VERSION_CODE 180
|
||||||
#define RUBY_RELEASE_CODE 20030323
|
#define RUBY_RELEASE_CODE 20030324
|
||||||
|
|
||||||
#define RUBY_VERSION_MAJOR 1
|
#define RUBY_VERSION_MAJOR 1
|
||||||
#define RUBY_VERSION_MINOR 8
|
#define RUBY_VERSION_MINOR 8
|
||||||
#define RUBY_VERSION_TEENY 0
|
#define RUBY_VERSION_TEENY 0
|
||||||
#define RUBY_RELEASE_YEAR 2003
|
#define RUBY_RELEASE_YEAR 2003
|
||||||
#define RUBY_RELEASE_MONTH 03
|
#define RUBY_RELEASE_MONTH 3
|
||||||
#define RUBY_RELEASE_DAY 23
|
#define RUBY_RELEASE_DAY 24
|
||||||
|
|
Загрузка…
Ссылка в новой задаче