cmpi-bindings 0.5.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/cmpi-bindings/cmpi_wrap.c +1339 -1191
- data/ext/src/cmpi_provider.c +63 -13
- data/ext/src/target_ruby.c +124 -74
- data/lib/cmpi/provider.rb +3 -0
- data/lib/cmpi.rb +79 -1
- metadata +63 -81
data/ext/src/cmpi_provider.c
CHANGED
@@ -46,10 +46,12 @@
|
|
46
46
|
/* Needed for kill() */
|
47
47
|
#include <signal.h>
|
48
48
|
|
49
|
+
static int cmpi_bindings_trace_level = 0; /* increase by setenv CMPI_BINDINGS_TRACE_LEVEL */
|
50
|
+
|
49
51
|
/* A simple stderr logging/tracing facility. */
|
50
52
|
#ifndef _SBLIM_TRACE
|
51
|
-
#define _SBLIM_TRACE(tracelevel,args) _logstderr args
|
52
|
-
void _logstderr(char *fmt,...)
|
53
|
+
#define _SBLIM_TRACE(tracelevel,args) if (tracelevel <= cmpi_bindings_trace_level) { _logstderr args; }
|
54
|
+
static void _logstderr(char *fmt,...)
|
53
55
|
{
|
54
56
|
va_list ap;
|
55
57
|
va_start(ap,fmt);
|
@@ -142,20 +144,23 @@ proplist2target(const char** cplist)
|
|
142
144
|
static char *
|
143
145
|
fmtstr(const char* fmt, ...)
|
144
146
|
{
|
147
|
+
static char buf[1];
|
145
148
|
va_list ap;
|
146
149
|
int len;
|
147
150
|
char* str;
|
148
151
|
|
149
152
|
va_start(ap, fmt);
|
150
|
-
len = vsnprintf(
|
153
|
+
len = vsnprintf(buf, 1, fmt, ap); /* vsnprintf(NULL, 0, ...) should work. bnc#762684 */
|
151
154
|
va_end(ap);
|
152
155
|
if (len <= 0)
|
153
156
|
{
|
157
|
+
fprintf(stderr, "*Err: vsnprintf(%s) = %d\n", fmt, len);
|
154
158
|
return NULL;
|
155
159
|
}
|
156
160
|
str = (char*)malloc(len+1);
|
157
161
|
if (str == NULL)
|
158
162
|
{
|
163
|
+
fprintf(stderr, "*Err: malloc(%d) failed\n", len+1);
|
159
164
|
return NULL;
|
160
165
|
}
|
161
166
|
va_start(ap, fmt);
|
@@ -868,6 +873,28 @@ references(
|
|
868
873
|
return status;
|
869
874
|
}
|
870
875
|
|
876
|
+
|
877
|
+
#if defined(SWIGRUBY)
|
878
|
+
/*
|
879
|
+
* Check type of VALUE
|
880
|
+
*
|
881
|
+
* return 0 if ok
|
882
|
+
* return -1 if bad type, set status accordingly
|
883
|
+
*
|
884
|
+
*/
|
885
|
+
|
886
|
+
static int
|
887
|
+
check_ruby_type( VALUE value, int type, const char *message, CMPIStatus *status, ProviderMIHandle* hdl )
|
888
|
+
{
|
889
|
+
if (TYPE(value) != type) {
|
890
|
+
status->rc = CMPI_RC_ERR_TYPE_MISMATCH;
|
891
|
+
status->msg = CMNewString(hdl->broker, message, NULL);
|
892
|
+
return -1;
|
893
|
+
}
|
894
|
+
return 0;
|
895
|
+
}
|
896
|
+
#endif
|
897
|
+
|
871
898
|
/*
|
872
899
|
* invokeMethod
|
873
900
|
*/
|
@@ -891,55 +918,72 @@ invokeMethod(
|
|
891
918
|
TARGET_THREAD_BEGIN_BLOCK;
|
892
919
|
_ctx = SWIG_NewPointerObj((void*) ctx, SWIGTYPE_p__CMPIContext, 0);
|
893
920
|
_objName = SWIG_NewPointerObj((void*) objName, SWIGTYPE_p__CMPIObjectPath, 0);
|
921
|
+
|
922
|
+
/* Ruby style method invocation */
|
894
923
|
#if defined(SWIGRUBY)
|
924
|
+
|
925
|
+
/* de-camelize method name, might need 2time length */
|
895
926
|
char *methodname = alloca(strlen(method) * 2 + 1);
|
896
927
|
decamelize(method, methodname);
|
928
|
+
|
929
|
+
/* access method arguments information via <decamelized>_args */
|
897
930
|
int argsnamesize = strlen(methodname) + 5 + 1;
|
898
931
|
char *argsname = alloca(argsnamesize); /* "<name>_args" */
|
899
932
|
snprintf(argsname, argsnamesize, "%s_args", methodname);
|
933
|
+
|
900
934
|
/* get the args array, gives names of input and output arguments */
|
901
935
|
VALUE args = rb_funcall(((ProviderMIHandle*)self->hdl)->implementation, rb_intern(argsname), 0);
|
902
|
-
|
936
|
+
if (check_ruby_type(args, T_ARRAY, "invoke: <method>_args must be Array", &status, (ProviderMIHandle*)self->hdl ) < 0)
|
937
|
+
return status;
|
938
|
+
|
903
939
|
VALUE argsin = rb_ary_entry(args, 0); /* array of input arg names */
|
904
|
-
|
940
|
+
if (check_ruby_type(argsin, T_ARRAY, "invoke: Input arguments must be Array", &status, (ProviderMIHandle*)self->hdl ) < 0)
|
941
|
+
return status;
|
942
|
+
|
905
943
|
int number_of_arguments = RARRAY_LEN(argsin) / 2;
|
944
|
+
_SBLIM_TRACE(1,("%s -> %d input args", argsname, number_of_arguments));
|
906
945
|
/* 3 args will be added by TargetCall, 2 args are added here, others are input args to function */
|
907
946
|
VALUE *input = alloca((3 + 2 + number_of_arguments) * sizeof(VALUE));
|
908
947
|
input[3] = _ctx;
|
909
948
|
input[4] = _objName;
|
910
949
|
/* loop over input arg names and types and get CMPIData via CMGetArg() */
|
911
950
|
int i;
|
912
|
-
for (i = 0; i < number_of_arguments; i
|
951
|
+
for (i = 0; i < number_of_arguments; ++i) {
|
913
952
|
const char *argname;
|
914
953
|
CMPIData data;
|
915
|
-
argname = target_charptr(rb_ary_entry(argsin, i));
|
954
|
+
argname = target_charptr(rb_ary_entry(argsin, i*2));
|
916
955
|
data = CMGetArg(in, argname, &status);
|
917
956
|
if (status.rc != CMPI_RC_OK) {
|
918
957
|
if ((data.state & CMPI_nullValue)
|
919
958
|
||(data.state & CMPI_notFound)) {
|
920
|
-
input[5+
|
959
|
+
input[5+i] = Target_Null;
|
921
960
|
continue;
|
922
961
|
}
|
923
962
|
_SBLIM_TRACE(1,("Failed (rc %d) to get input arg %d:%s for %s", status.rc, i>>1, argname, method));
|
924
963
|
return status;
|
925
964
|
}
|
926
|
-
input[5+
|
965
|
+
input[5+i] = data_value(&data);
|
927
966
|
}
|
967
|
+
|
968
|
+
/* actual provider call, passes output args and return value via 'result' */
|
928
969
|
VALUE result = TargetCall((ProviderMIHandle*)self->hdl, &status, methodname, -(2+number_of_arguments), input);
|
970
|
+
|
929
971
|
/* argsout is array of [<return_type>, <output_arg_name>, <output_arg_type>, ... */
|
930
972
|
VALUE argsout = rb_ary_entry(args, 1);
|
931
973
|
CMPIValue value;
|
932
974
|
CMPIType expected_type;
|
933
975
|
CMPIType actual_type;
|
934
|
-
|
935
|
-
|
976
|
+
if (check_ruby_type(argsout, T_ARRAY, "invoke: Output arguments must be Array", &status, (ProviderMIHandle*)self->hdl) < 0)
|
977
|
+
return status;
|
978
|
+
number_of_arguments = (RARRAY_LEN(argsout) - 1);
|
936
979
|
|
937
980
|
if (number_of_arguments > 0) {
|
938
981
|
/* if output args are defined, result must be an array
|
939
982
|
* result[0] is the return value
|
940
983
|
* result[1..n] are the output args in argsout order
|
941
984
|
*/
|
942
|
-
|
985
|
+
if (check_ruby_type(result, T_ARRAY, "invoke: function with output arguments must return Array", &status, (ProviderMIHandle*)self->hdl) < 0)
|
986
|
+
return status;
|
943
987
|
|
944
988
|
/* loop over output arg names and types and set CMPIData via CMSetArg() */
|
945
989
|
for (i = 0; i < number_of_arguments; i += 2) {
|
@@ -1260,7 +1304,13 @@ static CMPIInstanceMIFT InstanceMIFT__={
|
|
1260
1304
|
static int
|
1261
1305
|
createInit(ProviderMIHandle* miHdl, CMPIStatus* st)
|
1262
1306
|
{
|
1263
|
-
|
1307
|
+
const char *trace_level = getenv("CMPI_BINDINGS_TRACE_LEVEL");
|
1308
|
+
_SBLIM_TRACE(0,("\n>>>>> createInit() called, broker %p, miname= %s (ctx=%p), status %p, trace_level %s\n", miHdl->broker, miHdl->miName, miHdl->context, st, trace_level?trace_level:"(null)"));
|
1309
|
+
|
1310
|
+
if (trace_level) {
|
1311
|
+
cmpi_bindings_trace_level = *trace_level - '0';
|
1312
|
+
_SBLIM_TRACE(0,("tracing at level %d\n", cmpi_bindings_trace_level));
|
1313
|
+
}
|
1264
1314
|
return TargetInitialize(miHdl, st);
|
1265
1315
|
}
|
1266
1316
|
|
data/ext/src/target_ruby.c
CHANGED
@@ -117,7 +117,7 @@ load_provider(VALUE arg)
|
|
117
117
|
char *filename = alloca(strlen(classname) * 2 + 1);
|
118
118
|
decamelize(classname, filename);
|
119
119
|
ruby_script(filename);
|
120
|
-
_SBLIM_TRACE(1,("Ruby: loading (%s)", filename));
|
120
|
+
_SBLIM_TRACE(1,("<%d> Ruby: loading (%s)", getpid(), filename));
|
121
121
|
req = rb_require(filename);
|
122
122
|
/* Qtrue == just loaded, Qfalse = already loaded, else: fail */
|
123
123
|
if ((req != Qtrue) && (req != Qfalse)) {
|
@@ -126,12 +126,12 @@ load_provider(VALUE arg)
|
|
126
126
|
}
|
127
127
|
/* Get Cmpi::Provider */
|
128
128
|
VALUE val = rb_const_get(rb_cObject, rb_intern(RB_MODULE_NAME));
|
129
|
-
if (val
|
129
|
+
if (NIL_P(val)) {
|
130
130
|
_SBLIM_TRACE(1,("<%d> No such module '%s'", getpid(), RB_MODULE_NAME));
|
131
131
|
return val;
|
132
132
|
}
|
133
133
|
val = rb_const_get(val, rb_intern(classname));
|
134
|
-
if (val
|
134
|
+
if (NIL_P(val)) {
|
135
135
|
_SBLIM_TRACE(1,("<%d> No such class '%s::%s'", getpid(), RB_MODULE_NAME, classname));
|
136
136
|
}
|
137
137
|
return val;
|
@@ -161,19 +161,28 @@ call_mi(VALUE args)
|
|
161
161
|
/*
|
162
162
|
* get Ruby exception trace -> CMPIString
|
163
163
|
*
|
164
|
+
* returns NULL if called without exception
|
164
165
|
*/
|
165
166
|
|
166
167
|
#define TB_ERROR(str) {tbstr = str; goto cleanup;}
|
167
168
|
static CMPIString *
|
168
169
|
get_exc_trace(const CMPIBroker* broker)
|
169
170
|
{
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
171
|
+
VALUE exception = rb_gv_get("$!"); /* get last exception */
|
172
|
+
VALUE reason = rb_funcall(exception, rb_intern("to_s"), 0 );
|
173
|
+
VALUE trace = rb_gv_get("$@"); /* get last exception trace */
|
174
|
+
VALUE backtrace;
|
175
|
+
char* tmp;
|
176
|
+
CMPIString *result;
|
177
|
+
|
178
|
+
if (NIL_P(exception)) {
|
179
|
+
return NULL;
|
180
|
+
}
|
181
|
+
backtrace = rb_funcall(trace, rb_intern("join"), 1, rb_str_new("\n\t", 2));
|
182
|
+
tmp = fmtstr("%s\n\t%s", StringValuePtr(reason), StringValuePtr(backtrace));
|
183
|
+
result = broker->eft->newString(broker, tmp, NULL);
|
184
|
+
free(tmp);
|
185
|
+
return result;
|
177
186
|
}
|
178
187
|
|
179
188
|
|
@@ -189,19 +198,13 @@ get_exc_trace(const CMPIBroker* broker)
|
|
189
198
|
static int
|
190
199
|
RbGlobalInitialize(const CMPIBroker* broker, CMPIStatus* st)
|
191
200
|
{
|
192
|
-
int error = 0;
|
193
201
|
char *loadpath;
|
194
202
|
VALUE searchpath;
|
195
203
|
|
196
|
-
|
197
|
-
return error;
|
198
|
-
}
|
199
|
-
_TARGET_INIT=1; /* safe, since mutex is locked */
|
200
|
-
|
201
|
-
_SBLIM_TRACE(1,("<%d> Ruby: Loading", getpid()));
|
202
|
-
|
204
|
+
_SBLIM_TRACE(1,("<%d> Ruby: RbGlobalInitialize, stack @ %p", getpid(), &searchpath));
|
203
205
|
ruby_init();
|
204
206
|
ruby_init_loadpath();
|
207
|
+
|
205
208
|
extern void SWIG_init();
|
206
209
|
SWIG_init();
|
207
210
|
|
@@ -214,16 +217,20 @@ RbGlobalInitialize(const CMPIBroker* broker, CMPIStatus* st)
|
|
214
217
|
if (loadpath) {
|
215
218
|
struct stat buf;
|
216
219
|
if (stat(loadpath, &buf)) {
|
217
|
-
_SBLIM_TRACE(1,("<%d> Can't stat
|
220
|
+
_SBLIM_TRACE(1,("<%d> Can't stat $%s '%s'", getpid(), RUBY_PROVIDERS_DIR_ENV, loadpath));
|
218
221
|
return -1;
|
219
222
|
}
|
220
223
|
if ((buf.st_mode & S_IFDIR) == 0) {
|
221
|
-
_SBLIM_TRACE(1,("<%d> Not a directory:
|
224
|
+
_SBLIM_TRACE(1,("<%d> Not a directory: $%s '%s'", getpid(), RUBY_PROVIDERS_DIR_ENV, loadpath));
|
222
225
|
return -1;
|
223
226
|
}
|
227
|
+
_SBLIM_TRACE(1,("<%d> Loading providers from: $%s '%s'", getpid(), RUBY_PROVIDERS_DIR_ENV, loadpath));
|
224
228
|
rb_ary_push(searchpath, rb_str_new2(loadpath));
|
225
229
|
}
|
226
|
-
|
230
|
+
else {
|
231
|
+
_SBLIM_TRACE(0, ("<%d> Hmm, %s not set ?!", getpid(), RUBY_PROVIDERS_DIR_ENV));
|
232
|
+
}
|
233
|
+
return 0;
|
227
234
|
}
|
228
235
|
|
229
236
|
|
@@ -238,8 +245,9 @@ RbGlobalInitialize(const CMPIBroker* broker, CMPIStatus* st)
|
|
238
245
|
static int
|
239
246
|
TargetInitialize(ProviderMIHandle* hdl, CMPIStatus* st)
|
240
247
|
{
|
241
|
-
VALUE args[6];
|
242
|
-
|
248
|
+
VALUE args[6] = { Qnil };
|
249
|
+
VALUE gc = Qnil;
|
250
|
+
int error = 0;
|
243
251
|
int have_lock = 0;
|
244
252
|
|
245
253
|
/* Set _CMPI_INIT, protected by _CMPI_INIT_MUTEX
|
@@ -249,7 +257,22 @@ TargetInitialize(ProviderMIHandle* hdl, CMPIStatus* st)
|
|
249
257
|
perror("Can't lock _CMPI_INIT_MUTEX");
|
250
258
|
abort();
|
251
259
|
}
|
252
|
-
|
260
|
+
if (_TARGET_INIT == 0) {
|
261
|
+
_TARGET_INIT = 1; /* safe, since mutex is locked */
|
262
|
+
error = RbGlobalInitialize(hdl->broker, st);
|
263
|
+
}
|
264
|
+
#if 0
|
265
|
+
else {
|
266
|
+
/* Enforce GC.disable in provider upcalls; Ruby 1.9 crashes without */
|
267
|
+
gc = rb_const_get(rb_cObject, rb_intern("GC"));
|
268
|
+
if (NIL_P(gc)) {
|
269
|
+
_SBLIM_TRACE(0,("<%d> No such module 'GC'", getpid()));
|
270
|
+
}
|
271
|
+
else {
|
272
|
+
rb_funcall(gc, rb_intern("disable"), 0 );
|
273
|
+
}
|
274
|
+
}
|
275
|
+
#endif
|
253
276
|
pthread_mutex_unlock(&_CMPI_INIT_MUTEX);
|
254
277
|
if (error != 0) {
|
255
278
|
if (st != NULL) {
|
@@ -259,10 +282,11 @@ TargetInitialize(ProviderMIHandle* hdl, CMPIStatus* st)
|
|
259
282
|
goto fail;
|
260
283
|
}
|
261
284
|
|
262
|
-
_SBLIM_TRACE(1,("<%d> TargetInitialize(Ruby) called, miName '%s'", getpid(), hdl->miName));
|
285
|
+
_SBLIM_TRACE(1,("<%d> TargetInitialize(Ruby) called, miName '%s', stack @ %p, pthread %p", getpid(), hdl->miName, &have_lock, pthread_self()));
|
263
286
|
|
264
287
|
if (pthread_mutex_trylock(&_stack_init_mutex) == 0) {
|
265
288
|
have_lock = 1;
|
289
|
+
_SBLIM_TRACE(1,("<%d> RUBY_INIT_STACK for pthread %p", getpid(), pthread_self()));
|
266
290
|
RUBY_INIT_STACK
|
267
291
|
}
|
268
292
|
|
@@ -271,6 +295,7 @@ TargetInitialize(ProviderMIHandle* hdl, CMPIStatus* st)
|
|
271
295
|
*/
|
272
296
|
args[0] = rb_protect(load_provider, (VALUE)hdl->miName, &error);
|
273
297
|
if (error) {
|
298
|
+
_SBLIM_TRACE(1,("Ruby: load_provider(%s) failed !", hdl->miName));
|
274
299
|
if (st != NULL) {
|
275
300
|
st->rc = CMPI_RC_ERR_INVALID_CLASS;
|
276
301
|
st->msg = CMNewString(hdl->broker, "Failed to load provider", NULL);
|
@@ -284,11 +309,13 @@ TargetInitialize(ProviderMIHandle* hdl, CMPIStatus* st)
|
|
284
309
|
args[4] = SWIG_NewPointerObj((void*) hdl->broker, SWIGTYPE_p__CMPIBroker, 0);
|
285
310
|
args[5] = SWIG_NewPointerObj((void*) hdl->context, SWIGTYPE_p__CMPIContext, 0);
|
286
311
|
hdl->implementation = rb_protect(call_mi, (VALUE)args, &error);
|
312
|
+
if (error) {
|
313
|
+
_SBLIM_TRACE(1,("Ruby: %s.new() failed !", hdl->miName));
|
314
|
+
}
|
287
315
|
|
288
316
|
fail:
|
289
317
|
if (error) {
|
290
318
|
CMPIString *trace = get_exc_trace(hdl->broker);
|
291
|
-
_SBLIM_TRACE(1,("Ruby: FAILED creating %s: %s", hdl->miName, CMGetCharPtr(trace)));
|
292
319
|
if (st != NULL) {
|
293
320
|
st->rc = CMPI_RC_ERR_INVALID_CLASS;
|
294
321
|
st->msg = trace;
|
@@ -302,7 +329,10 @@ fail:
|
|
302
329
|
}
|
303
330
|
if (have_lock)
|
304
331
|
pthread_mutex_unlock(&_stack_init_mutex);
|
305
|
-
|
332
|
+
if (!NIL_P(gc)) {
|
333
|
+
rb_funcall(gc, rb_intern("enable"), 0 );
|
334
|
+
}
|
335
|
+
_SBLIM_TRACE(1,("TargetInitialize() %s", (error == 0)?"succeeded":"failed"));
|
306
336
|
return error;
|
307
337
|
}
|
308
338
|
|
@@ -311,6 +341,15 @@ fail:
|
|
311
341
|
* TargetCall
|
312
342
|
*
|
313
343
|
* Call function 'opname' with nargs arguments within managed interface hdl->implementation
|
344
|
+
*
|
345
|
+
* If nargs < 0: 'invoke method' call to provider
|
346
|
+
* nargs is followed by a VALUE* array of -nargs+3 elements
|
347
|
+
* [0] = undef
|
348
|
+
* [1] = undef
|
349
|
+
* [2] = undef
|
350
|
+
* [3] = _ctx;
|
351
|
+
* [4] = _objName;
|
352
|
+
* [5...] = function arguments
|
314
353
|
*/
|
315
354
|
|
316
355
|
static Target_Type
|
@@ -322,12 +361,17 @@ TargetCall(ProviderMIHandle* hdl, CMPIStatus* st,
|
|
322
361
|
int i;
|
323
362
|
VALUE *args, result, op = rb_intern(opname);
|
324
363
|
va_list vargs;
|
364
|
+
_SBLIM_TRACE(5,("TargetCall([hdl %p]%s:%d args, pthread %p)", hdl, opname, nargs, pthread_self()));
|
325
365
|
|
326
366
|
if (pthread_mutex_trylock(&_stack_init_mutex) == 0) {
|
327
367
|
have_lock = 1;
|
368
|
+
#if (RUBY_API_VERSION_MAJOR > 1) || (RUBY_API_VERSION_MAJOR == 1 && RUBY_API_VERSION_MINOR < 9)
|
369
|
+
_SBLIM_TRACE(1,("<%d> RUBY_INIT_STACK", getpid()));
|
328
370
|
RUBY_INIT_STACK
|
371
|
+
#endif
|
329
372
|
}
|
330
373
|
if (invoke) {
|
374
|
+
/* invoke style: get pre-allocated array of arguments */
|
331
375
|
va_start(vargs, nargs);
|
332
376
|
args = va_arg(vargs, VALUE *);
|
333
377
|
va_end(vargs);
|
@@ -345,17 +389,15 @@ TargetCall(ProviderMIHandle* hdl, CMPIStatus* st,
|
|
345
389
|
args[0] = (VALUE)(hdl->implementation);
|
346
390
|
args[1] = op;
|
347
391
|
args[2] = (VALUE)(nargs-3);
|
348
|
-
if (!invoke && (nargs > 3))
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
value = va_arg(vargs, VALUE);
|
355
|
-
args[i] = (value == (VALUE)NULL) ? Qnil : value;
|
356
|
-
}
|
357
|
-
va_end(vargs);
|
392
|
+
if (!invoke && (nargs > 3)) {
|
393
|
+
va_start(vargs, nargs);
|
394
|
+
for (i = 3; i < nargs; ++i) {
|
395
|
+
VALUE value;
|
396
|
+
value = va_arg(vargs, VALUE);
|
397
|
+
args[i] = (value == (VALUE)NULL) ? Qnil : value;
|
358
398
|
}
|
399
|
+
va_end(vargs);
|
400
|
+
}
|
359
401
|
|
360
402
|
/* call the Ruby function
|
361
403
|
* possible results:
|
@@ -366,51 +408,59 @@ TargetCall(ProviderMIHandle* hdl, CMPIStatus* st,
|
|
366
408
|
*/
|
367
409
|
result = rb_protect(call_mi, (VALUE)args, &i);
|
368
410
|
|
369
|
-
if (i) /* exception ? */
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL);
|
376
|
-
goto done;
|
411
|
+
if (i) { /* exception ? */
|
412
|
+
CMPIString *trace = get_exc_trace(hdl->broker);
|
413
|
+
char *trace_s;
|
414
|
+
char* str;
|
415
|
+
if (trace) {
|
416
|
+
trace_s = CMGetCharPtr(trace);
|
377
417
|
}
|
378
|
-
|
379
|
-
|
380
|
-
st->rc = CMPI_RC_ERR_NOT_SUPPORTED;
|
381
|
-
goto done;
|
418
|
+
else {
|
419
|
+
trace_s = "Unknown reason";
|
382
420
|
}
|
421
|
+
str = fmtstr("Ruby: calling '%s' failed: %s", opname, trace_s);
|
422
|
+
if (trace)
|
423
|
+
trace->ft->release(trace);
|
424
|
+
_SBLIM_TRACE(1,("%s", str));
|
425
|
+
st->rc = CMPI_RC_ERR_FAILED;
|
426
|
+
st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL);
|
427
|
+
free(str);
|
428
|
+
goto done;
|
429
|
+
}
|
430
|
+
if (NIL_P(result)) { /* not or wrongly implemented */
|
431
|
+
st->rc = CMPI_RC_ERR_NOT_SUPPORTED;
|
432
|
+
goto done;
|
433
|
+
}
|
383
434
|
|
384
435
|
if (invoke) {
|
385
436
|
st->rc = CMPI_RC_OK;
|
386
437
|
goto done;
|
387
438
|
}
|
388
439
|
|
389
|
-
if (result != Qtrue)
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL);
|
408
|
-
goto done;
|
409
|
-
}
|
410
|
-
st->rc = FIX2LONG(rc);
|
411
|
-
st->msg = hdl->broker->eft->newString(hdl->broker, StringValuePtr(msg), NULL);
|
440
|
+
if (result != Qtrue) {
|
441
|
+
VALUE resulta = rb_check_array_type(result);
|
442
|
+
VALUE rc, msg;
|
443
|
+
if (NIL_P(resulta)) {
|
444
|
+
char* str = fmtstr("Ruby: calling '%s' returned unknown result", opname);
|
445
|
+
st->rc = CMPI_RC_ERR_FAILED;
|
446
|
+
st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL);
|
447
|
+
free(str);
|
448
|
+
goto done;
|
449
|
+
}
|
450
|
+
|
451
|
+
rc = rb_ary_entry(resulta, 0);
|
452
|
+
msg = rb_ary_entry(resulta, 1);
|
453
|
+
if (!FIXNUM_P(rc)){
|
454
|
+
char* str = fmtstr("Ruby: calling '%s' returned non-numeric rc code", opname);
|
455
|
+
st->rc = CMPI_RC_ERR_FAILED;
|
456
|
+
st->msg = hdl->broker->eft->newString(hdl->broker, str, NULL);
|
457
|
+
free(str);
|
412
458
|
goto done;
|
413
459
|
}
|
460
|
+
st->rc = FIX2LONG(rc);
|
461
|
+
st->msg = hdl->broker->eft->newString(hdl->broker, StringValuePtr(msg), NULL);
|
462
|
+
goto done;
|
463
|
+
}
|
414
464
|
|
415
465
|
/* all is fine */
|
416
466
|
st->rc = CMPI_RC_OK;
|
@@ -428,7 +478,7 @@ done:
|
|
428
478
|
static void
|
429
479
|
TargetCleanup(ProviderMIHandle * hdl)
|
430
480
|
{
|
431
|
-
_SBLIM_TRACE(1,("TargetCleanup(hdl %p)", hdl));
|
481
|
+
_SBLIM_TRACE(1,("Ruby: TargetCleanup(hdl %p)", hdl));
|
432
482
|
/* free() provider instance */
|
433
483
|
if (hdl && hdl->implementation) {
|
434
484
|
_SBLIM_TRACE(1,("unregister(%p)", hdl->implementation));
|
@@ -454,7 +504,7 @@ TargetCleanup(ProviderMIHandle * hdl)
|
|
454
504
|
{
|
455
505
|
_SBLIM_TRACE(1,("Calling ruby_finalize()"));
|
456
506
|
ruby_finalize();
|
457
|
-
_TARGET_INIT=0; // false
|
507
|
+
_TARGET_INIT = 0; // false
|
458
508
|
}
|
459
509
|
pthread_mutex_unlock(&_CMPI_INIT_MUTEX);
|
460
510
|
return;
|
data/lib/cmpi/provider.rb
CHANGED
data/lib/cmpi.rb
CHANGED
@@ -179,6 +179,83 @@ module Cmpi
|
|
179
179
|
CMPI_ARRAY | self.charsptrA
|
180
180
|
end
|
181
181
|
|
182
|
+
#
|
183
|
+
# Convert CIM DateTime string representation (see DSP0004, 2.2.1)
|
184
|
+
# to Ruby Time (timestamp) or Float (interval, as seconds with fraction)
|
185
|
+
# 00000000001111111111222222
|
186
|
+
# 01234567890123456789012345
|
187
|
+
# East: yyyymmddhhmmss.mmmmmm+utc -> Time (utc = offset in minutes)
|
188
|
+
# West: yyyymmddhhmmss.mmmmmm-utc -> Time
|
189
|
+
# Interval: ddddddddhhmmss.mmmmmm:000 -> Float (interval in seconds, with fraction)
|
190
|
+
#
|
191
|
+
def self.cimdatetime_to_ruby str
|
192
|
+
# puts "Cmpi.cimdatetime_to_ruby(#{str})"
|
193
|
+
case str[21,1]
|
194
|
+
when '+', '-'
|
195
|
+
# create Time from yyyymmddhhmmss and utc
|
196
|
+
t = Time.new(str[0,4].to_i, str[4,2].to_i, str[6,2].to_i, str[8,2].to_i, str[10,2].to_i, str[12,2].to_i, str[22,3].to_i * ((str[21,1]=='+')?60:-60))
|
197
|
+
off = str[15,6].to_i / 1000
|
198
|
+
# Add fractional part
|
199
|
+
return t + off
|
200
|
+
when ':'
|
201
|
+
# time offset
|
202
|
+
off = str[0,8].to_i * 24 * 60 * 60
|
203
|
+
off += str[8,2].to_i * 60 * 60 + str[10,2].to_i * 60 + str[12,2].to_i
|
204
|
+
off += str[15,6].to_i / 1000
|
205
|
+
return off
|
206
|
+
else
|
207
|
+
raise "Invalid CIM DateTime '#{str}'"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
#
|
212
|
+
# Convert Ruby value to CIM DateTime string representation (see DSP0004, 2.2.1)
|
213
|
+
# 00000000001111111111222222
|
214
|
+
# 01234567890123456789012345
|
215
|
+
# East: yyyymmddhhmmss.mmmmmm+utc -> Time (utc = offset in minutes, mmmmmm is the microsecond within the second
|
216
|
+
# West: yyyymmddhhmmss.mmmmmm-utc -> Time
|
217
|
+
# Interval: ddddddddhhmmss.mmmmmm:000 -> Float (interval in seconds, with fraction)
|
218
|
+
#
|
219
|
+
def self.ruby_to_cimdatetime val
|
220
|
+
require 'date'
|
221
|
+
# puts "Cmpi.ruby_to_cimdatetime(#{val}[#{val.class}])"
|
222
|
+
t = nil
|
223
|
+
case val
|
224
|
+
when Time
|
225
|
+
s = val.strftime "%Y%m%d%H%M%S.%6N"
|
226
|
+
utc = val.utc_offset # offset in seconds
|
227
|
+
if utc < 0
|
228
|
+
s << "-"
|
229
|
+
utc = -utc
|
230
|
+
else
|
231
|
+
s << "+"
|
232
|
+
end
|
233
|
+
val = s + ("%03d" % (utc/60))
|
234
|
+
when Numeric
|
235
|
+
if val < 0
|
236
|
+
# treat it as seconds before epoch
|
237
|
+
val = self.ruby_to_cimdatetime( Time.at(val) )
|
238
|
+
else
|
239
|
+
# treat as interval in microseconds
|
240
|
+
secs = (val / 1000000).to_i
|
241
|
+
usecs = (val % 1000000).to_i
|
242
|
+
days = secs / (24 * 60 * 60)
|
243
|
+
secs = secs % (24 * 60 * 60) # seconds within the day
|
244
|
+
hours = (secs / (60 * 60)).to_i
|
245
|
+
secs = secs % (60 * 60)
|
246
|
+
mins = (secs / 60).to_i
|
247
|
+
secs = secs % 60
|
248
|
+
val = "%08d%02d%02d%02d.%06d:000" % [ days, hours, mins, secs, usecs ]
|
249
|
+
end
|
250
|
+
when /^\d{14}\.\d{6}[-+:]\d{3}$/
|
251
|
+
# fallthru
|
252
|
+
when String
|
253
|
+
val = self.ruby_to_cimdatetime val.to_f # retry as Numeric
|
254
|
+
else
|
255
|
+
val = self.ruby_to_cimdatetime val.to_s # retry as string
|
256
|
+
end
|
257
|
+
val
|
258
|
+
end
|
182
259
|
#
|
183
260
|
# Base class for ValueMap/Values classes from genprovider
|
184
261
|
#
|
@@ -247,7 +324,8 @@ module Cmpi
|
|
247
324
|
# -> http://blog.sidu.in/2008/02/loading-classes-from-strings-in-ruby.html
|
248
325
|
@typemap ||= Cmpi.const_get(self.objectpath.classname).typemap
|
249
326
|
t = @typemap[n] if @typemap
|
250
|
-
# STDERR.
|
327
|
+
# STDERR.printf "Instance.#{n} = #{v}[#{v.class}]:#{t}" % [n, v, v.class, t]
|
328
|
+
STDERR.printf "Instance.%s = %s[%s]:%04x\n" % [n, v, v.class, t]
|
251
329
|
self[n,v] = t
|
252
330
|
else
|
253
331
|
# STDERR.puts "CMPIInstance.#{name} -> #{self[s].inspect}"
|