zookeeper 1.0.6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.dotfiles/rvmrc +1 -0
- data/.travis.yml +5 -0
- data/CHANGELOG +13 -0
- data/Gemfile +3 -0
- data/Guardfile +6 -0
- data/README.markdown +16 -12
- data/Rakefile +5 -0
- data/cause-abort.rb +117 -0
- data/ext/Rakefile +34 -21
- data/ext/c_zookeeper.rb +181 -70
- data/ext/common.h +7 -0
- data/ext/depend +2 -2
- data/ext/{zookeeper_lib.c → event_lib.c} +107 -66
- data/ext/{zookeeper_lib.h → event_lib.h} +4 -3
- data/ext/extconf.rb +12 -8
- data/ext/generate_gvl_code.rb +9 -2
- data/ext/{zookeeper_c.c → zkrb.c} +415 -176
- data/ext/zookeeper_base.rb +7 -26
- data/lib/zookeeper/client_methods.rb +1 -1
- data/lib/zookeeper/common.rb +3 -2
- data/lib/zookeeper/constants.rb +1 -0
- data/lib/zookeeper/continuation.rb +155 -0
- data/lib/zookeeper/exceptions.rb +7 -0
- data/lib/zookeeper/logger.rb +7 -0
- data/lib/zookeeper/monitor.rb +19 -0
- data/lib/zookeeper/version.rb +1 -1
- data/lib/zookeeper.rb +3 -0
- data/spec/forked_connection_spec.rb +11 -4
- data/spec/shared/connection_examples.rb +24 -22
- data/spec/spec_helper.rb +2 -2
- data/spec/support/zookeeper_spec_helpers.rb +1 -1
- metadata +12 -9
- data/spec/fork_hook_specs.rb +0 -53
data/ext/common.h
ADDED
data/ext/depend
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
1
|
+
event_lib.c: event_lib.h common.h
|
2
2
|
zkrb_wrapper_compat.c: zkrb_wrapper_compat.h
|
3
3
|
zkrb_wrapper.c: zkrb_wrapper_compat.c zkrb_wrapper.h
|
4
|
-
|
4
|
+
zkrb.c: event_lib.c event_lib.h zkrb_wrapper.c zkrb_wrapper.h dbg.h common.h
|
5
5
|
|
@@ -7,20 +7,21 @@ This file contains three sets of helpers:
|
|
7
7
|
|
8
8
|
wickman@twitter.com
|
9
9
|
|
10
|
-
|
11
|
-
*
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
|
11
|
+
NOTE: be *very careful* in these functions, calling *ANY* ruby interpreter
|
12
|
+
function when you're not in an interpreter thread can hork ruby, trigger a
|
13
|
+
[BUG], corrupt the stack, kill your dog, knock up your daughter, etc. etc.
|
14
|
+
|
15
|
+
NOTE: the above is only true when you're running in THREADED mode, in
|
16
|
+
single-threaded, everything is called on an interpreter thread.
|
17
|
+
|
17
18
|
|
18
19
|
slyphon@gmail.com
|
19
20
|
|
20
21
|
*/
|
21
22
|
|
22
23
|
#include "ruby.h"
|
23
|
-
#include "
|
24
|
+
#include "event_lib.h"
|
24
25
|
#include "c-client-src/zookeeper.h"
|
25
26
|
#include <errno.h>
|
26
27
|
#include <stdio.h>
|
@@ -28,13 +29,15 @@ slyphon@gmail.com
|
|
28
29
|
#include <pthread.h>
|
29
30
|
#include <unistd.h>
|
30
31
|
#include <inttypes.h>
|
32
|
+
#include "common.h"
|
31
33
|
#include "dbg.h"
|
32
34
|
|
33
35
|
#define GET_SYM(str) ID2SYM(rb_intern(str))
|
34
36
|
|
35
37
|
int ZKRBDebugging;
|
36
38
|
|
37
|
-
|
39
|
+
#ifdef THREADED
|
40
|
+
|
38
41
|
pthread_mutex_t zkrb_q_mutex = PTHREAD_MUTEX_INITIALIZER;
|
39
42
|
|
40
43
|
inline static int global_mutex_lock() {
|
@@ -66,6 +69,42 @@ void atfork_child() {
|
|
66
69
|
// and children
|
67
70
|
/*pthread_atfork(atfork_prepare, atfork_parent, atfork_child);*/
|
68
71
|
|
72
|
+
// delegates to the system malloc (we can't use xmalloc in the threaded case,
|
73
|
+
// as we can't touch the interpreter)
|
74
|
+
|
75
|
+
inline static void* zk_malloc(size_t size) {
|
76
|
+
return malloc(size);
|
77
|
+
}
|
78
|
+
|
79
|
+
inline static void zk_free(void *ptr) {
|
80
|
+
free(ptr);
|
81
|
+
}
|
82
|
+
|
83
|
+
#else
|
84
|
+
|
85
|
+
inline static int global_mutex_lock() {
|
86
|
+
return 0;
|
87
|
+
}
|
88
|
+
|
89
|
+
inline static int global_mutex_unlock() {
|
90
|
+
return 0;
|
91
|
+
}
|
92
|
+
|
93
|
+
// we can use the ruby xmalloc/xfree that will raise errors
|
94
|
+
// in the case of a failure to allocate memory, and can cycle
|
95
|
+
// the garbage collector in some cases.
|
96
|
+
|
97
|
+
inline static void* zk_malloc(size_t size) {
|
98
|
+
return xmalloc(size);
|
99
|
+
}
|
100
|
+
|
101
|
+
inline static void zk_free(void *ptr) {
|
102
|
+
xfree(ptr);
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
#endif /* THREADED */
|
107
|
+
|
69
108
|
|
70
109
|
void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
|
71
110
|
if (q == NULL) {
|
@@ -81,7 +120,7 @@ void zkrb_enqueue(zkrb_queue_t *q, zkrb_event_t *elt) {
|
|
81
120
|
global_mutex_lock();
|
82
121
|
|
83
122
|
q->tail->event = elt;
|
84
|
-
q->tail->next = (zkrb_event_ll_t *)
|
123
|
+
q->tail->next = (zkrb_event_ll_t *)zk_malloc(sizeof(zkrb_event_ll_t));
|
85
124
|
q->tail = q->tail->next;
|
86
125
|
q->tail->event = NULL;
|
87
126
|
q->tail->next = NULL;
|
@@ -134,7 +173,7 @@ zkrb_event_t* zkrb_dequeue(zkrb_queue_t *q, int need_lock) {
|
|
134
173
|
if (need_lock)
|
135
174
|
global_mutex_unlock();
|
136
175
|
|
137
|
-
|
176
|
+
zk_free(old_root);
|
138
177
|
return rv;
|
139
178
|
}
|
140
179
|
|
@@ -150,7 +189,7 @@ void zkrb_signal(zkrb_queue_t *q) {
|
|
150
189
|
}
|
151
190
|
|
152
191
|
zkrb_event_ll_t *zkrb_event_ll_t_alloc(void) {
|
153
|
-
zkrb_event_ll_t *rv =
|
192
|
+
zkrb_event_ll_t *rv = zk_malloc(sizeof(zkrb_event_ll_t));
|
154
193
|
|
155
194
|
if (!rv) return NULL;
|
156
195
|
|
@@ -166,7 +205,7 @@ zkrb_queue_t *zkrb_queue_alloc(void) {
|
|
166
205
|
|
167
206
|
check(pipe(pfd) == 0, "creating the signal pipe failed");
|
168
207
|
|
169
|
-
rq =
|
208
|
+
rq = zk_malloc(sizeof(zkrb_queue_t));
|
170
209
|
check_mem(rq);
|
171
210
|
|
172
211
|
rq->orig_pid = getpid();
|
@@ -181,7 +220,7 @@ zkrb_queue_t *zkrb_queue_alloc(void) {
|
|
181
220
|
return rq;
|
182
221
|
|
183
222
|
error:
|
184
|
-
|
223
|
+
zk_free(rq);
|
185
224
|
return NULL;
|
186
225
|
}
|
187
226
|
|
@@ -193,15 +232,15 @@ void zkrb_queue_free(zkrb_queue_t *queue) {
|
|
193
232
|
zkrb_event_free(elt);
|
194
233
|
}
|
195
234
|
|
196
|
-
|
235
|
+
zk_free(queue->head);
|
197
236
|
close(queue->pipe_read);
|
198
237
|
close(queue->pipe_write);
|
199
238
|
|
200
|
-
|
239
|
+
zk_free(queue);
|
201
240
|
}
|
202
241
|
|
203
242
|
zkrb_event_t *zkrb_event_alloc(void) {
|
204
|
-
zkrb_event_t *rv =
|
243
|
+
zkrb_event_t *rv = zk_malloc(sizeof(zkrb_event_t));
|
205
244
|
return rv;
|
206
245
|
}
|
207
246
|
|
@@ -209,58 +248,58 @@ void zkrb_event_free(zkrb_event_t *event) {
|
|
209
248
|
switch (event->type) {
|
210
249
|
case ZKRB_DATA: {
|
211
250
|
struct zkrb_data_completion *data_ctx = event->completion.data_completion;
|
212
|
-
|
213
|
-
|
214
|
-
|
251
|
+
zk_free(data_ctx->data);
|
252
|
+
zk_free(data_ctx->stat);
|
253
|
+
zk_free(data_ctx);
|
215
254
|
break;
|
216
255
|
}
|
217
256
|
case ZKRB_STAT: {
|
218
257
|
struct zkrb_stat_completion *stat_ctx = event->completion.stat_completion;
|
219
|
-
|
220
|
-
|
258
|
+
zk_free(stat_ctx->stat);
|
259
|
+
zk_free(stat_ctx);
|
221
260
|
break;
|
222
261
|
}
|
223
262
|
case ZKRB_STRING: {
|
224
263
|
struct zkrb_string_completion *string_ctx = event->completion.string_completion;
|
225
|
-
|
226
|
-
|
264
|
+
zk_free(string_ctx->value);
|
265
|
+
zk_free(string_ctx);
|
227
266
|
break;
|
228
267
|
}
|
229
268
|
case ZKRB_STRINGS: {
|
230
269
|
struct zkrb_strings_completion *strings_ctx = event->completion.strings_completion;
|
231
270
|
int k;
|
232
271
|
if (strings_ctx->values)
|
233
|
-
for (k = 0; k < strings_ctx->values->count; ++k)
|
234
|
-
|
235
|
-
|
272
|
+
for (k = 0; k < strings_ctx->values->count; ++k) zk_free(strings_ctx->values->data[k]);
|
273
|
+
zk_free(strings_ctx->values);
|
274
|
+
zk_free(strings_ctx);
|
236
275
|
break;
|
237
276
|
}
|
238
277
|
case ZKRB_STRINGS_STAT: {
|
239
278
|
struct zkrb_strings_stat_completion *strings_stat_ctx = event->completion.strings_stat_completion;
|
240
279
|
int k;
|
241
280
|
if (strings_stat_ctx->values)
|
242
|
-
for (k = 0; k < strings_stat_ctx->values->count; ++k)
|
243
|
-
|
281
|
+
for (k = 0; k < strings_stat_ctx->values->count; ++k) zk_free(strings_stat_ctx->values->data[k]);
|
282
|
+
zk_free(strings_stat_ctx->values);
|
244
283
|
|
245
284
|
if (strings_stat_ctx->stat)
|
246
|
-
|
247
|
-
|
285
|
+
zk_free(strings_stat_ctx->stat);
|
286
|
+
zk_free(strings_stat_ctx);
|
248
287
|
break;
|
249
288
|
}
|
250
289
|
case ZKRB_ACL: {
|
251
290
|
struct zkrb_acl_completion *acl_ctx = event->completion.acl_completion;
|
252
291
|
if (acl_ctx->acl) {
|
253
292
|
deallocate_ACL_vector(acl_ctx->acl);
|
254
|
-
|
293
|
+
zk_free(acl_ctx->acl);
|
255
294
|
}
|
256
|
-
|
257
|
-
|
295
|
+
zk_free(acl_ctx->stat);
|
296
|
+
zk_free(acl_ctx);
|
258
297
|
break;
|
259
298
|
}
|
260
299
|
case ZKRB_WATCHER: {
|
261
300
|
struct zkrb_watcher_completion *watcher_ctx = event->completion.watcher_completion;
|
262
|
-
|
263
|
-
|
301
|
+
zk_free(watcher_ctx->path);
|
302
|
+
zk_free(watcher_ctx);
|
264
303
|
break;
|
265
304
|
}
|
266
305
|
case ZKRB_VOID: {
|
@@ -270,7 +309,7 @@ void zkrb_event_free(zkrb_event_t *event) {
|
|
270
309
|
log_err("unrecognized event in event_free!");
|
271
310
|
}
|
272
311
|
|
273
|
-
|
312
|
+
zk_free(event);
|
274
313
|
}
|
275
314
|
|
276
315
|
/* this is called only from a method_get_latest_event, so the hash is
|
@@ -289,6 +328,7 @@ VALUE zkrb_event_to_ruby(zkrb_event_t *event) {
|
|
289
328
|
|
290
329
|
switch (event->type) {
|
291
330
|
case ZKRB_DATA: {
|
331
|
+
zkrb_debug("zkrb_event_to_ruby ZKRB_DATA\n");
|
292
332
|
struct zkrb_data_completion *data_ctx = event->completion.data_completion;
|
293
333
|
if (ZKRBDebugging) zkrb_print_stat(data_ctx->stat);
|
294
334
|
rb_hash_aset(hash, GET_SYM("data"), data_ctx->data ? rb_str_new(data_ctx->data, data_ctx->data_len) : Qnil);
|
@@ -329,7 +369,6 @@ VALUE zkrb_event_to_ruby(zkrb_event_t *event) {
|
|
329
369
|
}
|
330
370
|
case ZKRB_WATCHER: {
|
331
371
|
zkrb_debug("zkrb_event_to_ruby ZKRB_WATCHER\n");
|
332
|
-
struct zkrb_acl_completion *acl_ctx = event->completion.acl_completion;
|
333
372
|
struct zkrb_watcher_completion *watcher_ctx = event->completion.watcher_completion;
|
334
373
|
rb_hash_aset(hash, GET_SYM("type"), INT2FIX(watcher_ctx->type));
|
335
374
|
rb_hash_aset(hash, GET_SYM("state"), INT2FIX(watcher_ctx->state));
|
@@ -365,7 +404,7 @@ void zkrb_print_stat(const struct Stat *s) {
|
|
365
404
|
}
|
366
405
|
|
367
406
|
zkrb_calling_context *zkrb_calling_context_alloc(int64_t req_id, zkrb_queue_t *queue) {
|
368
|
-
zkrb_calling_context *ctx =
|
407
|
+
zkrb_calling_context *ctx = zk_malloc(sizeof(zkrb_calling_context));
|
369
408
|
if (!ctx) return NULL;
|
370
409
|
|
371
410
|
ctx->req_id = req_id;
|
@@ -374,6 +413,10 @@ zkrb_calling_context *zkrb_calling_context_alloc(int64_t req_id, zkrb_queue_t *q
|
|
374
413
|
return ctx;
|
375
414
|
}
|
376
415
|
|
416
|
+
void zkrb_calling_context_free(zkrb_calling_context *ctx) {
|
417
|
+
zk_free(ctx);
|
418
|
+
}
|
419
|
+
|
377
420
|
void zkrb_print_calling_context(zkrb_calling_context *ctx) {
|
378
421
|
fprintf(stderr, "calling context (%p){\n", ctx);
|
379
422
|
fprintf(stderr, "\treq_id = %"PRId64"\n", ctx->req_id);
|
@@ -394,7 +437,7 @@ void zkrb_print_calling_context(zkrb_calling_context *ctx) {
|
|
394
437
|
zkrb_event_t *eptr = zkrb_event_alloc(); \
|
395
438
|
eptr->req_id = ctx->req_id; \
|
396
439
|
zkrb_queue_t *qptr = ctx->queue; \
|
397
|
-
if (eptr->req_id != ZKRB_GLOBAL_REQ)
|
440
|
+
if (eptr->req_id != ZKRB_GLOBAL_REQ) zk_free(ctx)
|
398
441
|
|
399
442
|
void zkrb_state_callback(
|
400
443
|
zhandle_t *zh, int type, int state, const char *path, void *calling_ctx) {
|
@@ -404,7 +447,7 @@ void zkrb_state_callback(
|
|
404
447
|
type, state, (void *) path, path ? path : "NULL");
|
405
448
|
|
406
449
|
/* save callback context */
|
407
|
-
struct zkrb_watcher_completion *wc =
|
450
|
+
struct zkrb_watcher_completion *wc = zk_malloc(sizeof(struct zkrb_watcher_completion));
|
408
451
|
wc->type = type;
|
409
452
|
wc->state = state;
|
410
453
|
wc->path = strdup(path);
|
@@ -416,7 +459,7 @@ void zkrb_state_callback(
|
|
416
459
|
event->req_id = ctx->req_id;
|
417
460
|
zkrb_queue_t *queue = ctx->queue;
|
418
461
|
if (type != ZOO_SESSION_EVENT) {
|
419
|
-
|
462
|
+
zk_free(ctx);
|
420
463
|
ctx = NULL;
|
421
464
|
}
|
422
465
|
|
@@ -426,8 +469,6 @@ void zkrb_state_callback(
|
|
426
469
|
zkrb_enqueue(queue, event);
|
427
470
|
}
|
428
471
|
|
429
|
-
|
430
|
-
|
431
472
|
void zkrb_data_callback(
|
432
473
|
int rc, const char *value, int value_len, const struct Stat *stat, const void *calling_ctx) {
|
433
474
|
|
@@ -436,18 +477,18 @@ void zkrb_data_callback(
|
|
436
477
|
rc, zerror(rc), value ? value : "NULL", value_len);
|
437
478
|
|
438
479
|
/* copy data completion */
|
439
|
-
struct zkrb_data_completion *dc =
|
480
|
+
struct zkrb_data_completion *dc = zk_malloc(sizeof(struct zkrb_data_completion));
|
440
481
|
dc->data = NULL;
|
441
482
|
dc->stat = NULL;
|
442
483
|
dc->data_len = 0;
|
443
484
|
|
444
485
|
if (value != NULL) {
|
445
|
-
dc->data =
|
486
|
+
dc->data = zk_malloc(value_len); // xmalloc may raise an exception, which means the above completion will leak
|
446
487
|
dc->data_len = value_len;
|
447
488
|
memcpy(dc->data, value, value_len);
|
448
489
|
}
|
449
490
|
|
450
|
-
if (stat != NULL) { dc->stat
|
491
|
+
if (stat != NULL) { dc->stat = zk_malloc(sizeof(struct Stat)); memcpy(dc->stat, stat, sizeof(struct Stat)); }
|
451
492
|
|
452
493
|
ZKH_SETUP_EVENT(queue, event);
|
453
494
|
event->rc = rc;
|
@@ -462,9 +503,9 @@ void zkrb_stat_callback(
|
|
462
503
|
zkrb_debug("ZOOKEEPER_C_STAT WATCHER "
|
463
504
|
"rc = %d (%s)\n", rc, zerror(rc));
|
464
505
|
|
465
|
-
struct zkrb_stat_completion *sc =
|
506
|
+
struct zkrb_stat_completion *sc = zk_malloc(sizeof(struct zkrb_stat_completion));
|
466
507
|
sc->stat = NULL;
|
467
|
-
if (stat != NULL) { sc->stat =
|
508
|
+
if (stat != NULL) { sc->stat = zk_malloc(sizeof(struct Stat)); memcpy(sc->stat, stat, sizeof(struct Stat)); }
|
468
509
|
|
469
510
|
ZKH_SETUP_EVENT(queue, event);
|
470
511
|
event->rc = rc;
|
@@ -480,7 +521,7 @@ void zkrb_string_callback(
|
|
480
521
|
zkrb_debug("ZOOKEEPER_C_STRING WATCHER "
|
481
522
|
"rc = %d (%s)\n", rc, zerror(rc));
|
482
523
|
|
483
|
-
struct zkrb_string_completion *sc =
|
524
|
+
struct zkrb_string_completion *sc = zk_malloc(sizeof(struct zkrb_string_completion));
|
484
525
|
sc->value = NULL;
|
485
526
|
if (string)
|
486
527
|
sc->value = strdup(string);
|
@@ -499,7 +540,7 @@ void zkrb_strings_callback(
|
|
499
540
|
"rc = %d (%s), calling_ctx = %p\n", rc, zerror(rc), calling_ctx);
|
500
541
|
|
501
542
|
/* copy string vector */
|
502
|
-
struct zkrb_strings_completion *sc =
|
543
|
+
struct zkrb_strings_completion *sc = zk_malloc(sizeof(struct zkrb_strings_completion));
|
503
544
|
sc->values = (strings != NULL) ? zkrb_clone_string_vector(strings) : NULL;
|
504
545
|
|
505
546
|
ZKH_SETUP_EVENT(queue, event);
|
@@ -515,9 +556,9 @@ void zkrb_strings_stat_callback(
|
|
515
556
|
zkrb_debug("ZOOKEEPER_C_STRINGS_STAT WATCHER "
|
516
557
|
"rc = %d (%s), calling_ctx = %p\n", rc, zerror(rc), calling_ctx);
|
517
558
|
|
518
|
-
struct zkrb_strings_stat_completion *sc =
|
559
|
+
struct zkrb_strings_stat_completion *sc = zk_malloc(sizeof(struct zkrb_strings_stat_completion));
|
519
560
|
sc->stat = NULL;
|
520
|
-
if (stat != NULL) { sc->stat =
|
561
|
+
if (stat != NULL) { sc->stat = zk_malloc(sizeof(struct Stat)); memcpy(sc->stat, stat, sizeof(struct Stat)); }
|
521
562
|
|
522
563
|
sc->values = (strings != NULL) ? zkrb_clone_string_vector(strings) : NULL;
|
523
564
|
|
@@ -545,11 +586,11 @@ void zkrb_acl_callback(
|
|
545
586
|
int rc, struct ACL_vector *acls, struct Stat *stat, const void *calling_ctx) {
|
546
587
|
zkrb_debug("ZOOKEEPER_C_ACL WATCHER rc = %d (%s)\n", rc, zerror(rc));
|
547
588
|
|
548
|
-
struct zkrb_acl_completion *ac =
|
589
|
+
struct zkrb_acl_completion *ac = zk_malloc(sizeof(struct zkrb_acl_completion));
|
549
590
|
ac->acl = NULL;
|
550
591
|
ac->stat = NULL;
|
551
592
|
if (acls != NULL) { ac->acl = zkrb_clone_acl_vector(acls); }
|
552
|
-
if (stat != NULL) { ac->stat =
|
593
|
+
if (stat != NULL) { ac->stat = zk_malloc(sizeof(struct Stat)); memcpy(ac->stat, stat, sizeof(struct Stat)); }
|
553
594
|
|
554
595
|
ZKH_SETUP_EVENT(queue, event);
|
555
596
|
event->rc = rc;
|
@@ -574,12 +615,12 @@ VALUE zkrb_acl_to_ruby(struct ACL *acl) {
|
|
574
615
|
return hash;
|
575
616
|
}
|
576
617
|
|
577
|
-
|
578
|
-
|
618
|
+
// [wickman] TODO test zkrb_ruby_to_aclvector
|
619
|
+
// [slyphon] TODO size checking on acl_ary (cast to int)
|
579
620
|
struct ACL_vector * zkrb_ruby_to_aclvector(VALUE acl_ary) {
|
580
621
|
Check_Type(acl_ary, T_ARRAY);
|
581
622
|
|
582
|
-
struct ACL_vector *v =
|
623
|
+
struct ACL_vector *v = zk_malloc(sizeof(struct ACL_vector));
|
583
624
|
allocate_ACL_vector(v, (int)RARRAY_LEN(acl_ary));
|
584
625
|
|
585
626
|
int k;
|
@@ -591,7 +632,7 @@ struct ACL_vector * zkrb_ruby_to_aclvector(VALUE acl_ary) {
|
|
591
632
|
return v;
|
592
633
|
}
|
593
634
|
|
594
|
-
|
635
|
+
// [wickman] TODO test zkrb_ruby_to_aclvector
|
595
636
|
struct ACL zkrb_ruby_to_acl(VALUE rubyacl) {
|
596
637
|
struct ACL acl;
|
597
638
|
|
@@ -603,7 +644,7 @@ struct ACL zkrb_ruby_to_acl(VALUE rubyacl) {
|
|
603
644
|
return acl;
|
604
645
|
}
|
605
646
|
|
606
|
-
|
647
|
+
// [wickman] TODO zkrb_ruby_to_id error checking? test
|
607
648
|
struct Id zkrb_ruby_to_id(VALUE rubyid) {
|
608
649
|
struct Id id;
|
609
650
|
|
@@ -611,7 +652,7 @@ struct Id zkrb_ruby_to_id(VALUE rubyid) {
|
|
611
652
|
VALUE ident = rb_iv_get(rubyid, "@id");
|
612
653
|
|
613
654
|
if (scheme != Qnil) {
|
614
|
-
id.scheme =
|
655
|
+
id.scheme = zk_malloc(RSTRING_LEN(scheme) + 1);
|
615
656
|
strncpy(id.scheme, RSTRING_PTR(scheme), RSTRING_LEN(scheme));
|
616
657
|
id.scheme[RSTRING_LEN(scheme)] = '\0';
|
617
658
|
} else {
|
@@ -619,7 +660,7 @@ struct Id zkrb_ruby_to_id(VALUE rubyid) {
|
|
619
660
|
}
|
620
661
|
|
621
662
|
if (ident != Qnil) {
|
622
|
-
id.id =
|
663
|
+
id.id = zk_malloc(RSTRING_LEN(ident) + 1);
|
623
664
|
strncpy(id.id, RSTRING_PTR(ident), RSTRING_LEN(ident));
|
624
665
|
id.id[RSTRING_LEN(ident)] = '\0';
|
625
666
|
} else {
|
@@ -678,9 +719,9 @@ VALUE zkrb_stat_to_rhash(const struct Stat *stat) {
|
|
678
719
|
return ary;
|
679
720
|
}
|
680
721
|
|
681
|
-
|
722
|
+
// [wickman] TODO test zkrb_clone_acl_vector
|
682
723
|
struct ACL_vector * zkrb_clone_acl_vector(struct ACL_vector * src) {
|
683
|
-
struct ACL_vector * dst =
|
724
|
+
struct ACL_vector * dst = zk_malloc(sizeof(struct ACL_vector));
|
684
725
|
allocate_ACL_vector(dst, src->count);
|
685
726
|
int k;
|
686
727
|
for (k = 0; k < src->count; ++k) {
|
@@ -692,9 +733,9 @@ struct ACL_vector * zkrb_clone_acl_vector(struct ACL_vector * src) {
|
|
692
733
|
return dst;
|
693
734
|
}
|
694
735
|
|
695
|
-
|
736
|
+
// [wickman] TODO test zkrb_clone_string_vector
|
696
737
|
struct String_vector * zkrb_clone_string_vector(const struct String_vector * src) {
|
697
|
-
struct String_vector * dst =
|
738
|
+
struct String_vector * dst = zk_malloc(sizeof(struct String_vector));
|
698
739
|
allocate_String_vector(dst, src->count);
|
699
740
|
int k;
|
700
741
|
for (k = 0; k < src->count; ++k) {
|