cmpi-bindings 0.5.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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}"
|