mmap2 2.2.7 → 2.2.8
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.
- checksums.yaml +4 -4
- data/ext/mmap/mmap.c +883 -1110
- data/lib/mmap/version.rb +1 -1
- data/lib/mmap.rb +1 -1
- data/test/test_mmap.rb +24 -21
- metadata +3 -2
data/ext/mmap/mmap.c
CHANGED
@@ -1,24 +1,25 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <fcntl.h>
|
3
1
|
#include <ctype.h>
|
4
|
-
#include <
|
2
|
+
#include <fcntl.h>
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <sys/mman.h>
|
5
5
|
#include <sys/stat.h>
|
6
|
+
#include <sys/types.h>
|
6
7
|
#include <unistd.h>
|
7
|
-
#include <sys/mman.h>
|
8
8
|
|
9
9
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
10
|
-
#include <sys/shm.h>
|
11
10
|
#include <sys/ipc.h>
|
12
11
|
#include <sys/sem.h>
|
12
|
+
#include <sys/shm.h>
|
13
13
|
#endif
|
14
14
|
|
15
15
|
#include <ruby/io.h>
|
16
16
|
#include <ruby/re.h>
|
17
17
|
|
18
18
|
#ifndef StringValue
|
19
|
-
#define StringValue(x)
|
20
|
-
|
21
|
-
|
19
|
+
#define StringValue(x) \
|
20
|
+
do { \
|
21
|
+
if (TYPE(x) != T_STRING) x = rb_str_to_str(x); \
|
22
|
+
} while (0)
|
22
23
|
#endif
|
23
24
|
|
24
25
|
#ifndef StringValuePtr
|
@@ -31,11 +32,11 @@
|
|
31
32
|
|
32
33
|
#ifndef MADV_NORMAL
|
33
34
|
#ifdef POSIX_MADV_NORMAL
|
34
|
-
#define MADV_NORMAL
|
35
|
-
#define MADV_RANDOM
|
35
|
+
#define MADV_NORMAL POSIX_MADV_NORMAL
|
36
|
+
#define MADV_RANDOM POSIX_MADV_RANDOM
|
36
37
|
#define MADV_SEQUENTIAL POSIX_MADV_SEQUENTIAL
|
37
|
-
#define MADV_WILLNEED
|
38
|
-
#define MADV_DONTNEED
|
38
|
+
#define MADV_WILLNEED POSIX_MADV_WILLNEED
|
39
|
+
#define MADV_DONTNEED POSIX_MADV_DONTNEED
|
39
40
|
#define madvise posix_madvise
|
40
41
|
#endif
|
41
42
|
#endif
|
@@ -98,18 +99,17 @@ typedef struct {
|
|
98
99
|
#define MM_CHANGE (MM_MODIFY | 4)
|
99
100
|
#define MM_PROTECT 8
|
100
101
|
|
101
|
-
#define MM_FROZEN (1<<0)
|
102
|
-
#define MM_FIXED
|
103
|
-
#define MM_ANON
|
104
|
-
#define MM_LOCK
|
105
|
-
#define MM_IPC
|
106
|
-
#define MM_TMP
|
102
|
+
#define MM_FROZEN (1 << 0)
|
103
|
+
#define MM_FIXED (1 << 1)
|
104
|
+
#define MM_ANON (1 << 2)
|
105
|
+
#define MM_LOCK (1 << 3)
|
106
|
+
#define MM_IPC (1 << 4)
|
107
|
+
#define MM_TMP (1 << 5)
|
107
108
|
|
108
109
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
109
110
|
static char template[1024];
|
110
111
|
|
111
|
-
union semun
|
112
|
-
{
|
112
|
+
union semun {
|
113
113
|
int val;
|
114
114
|
struct semid_ds *buf;
|
115
115
|
unsigned short int *array;
|
@@ -117,111 +117,104 @@ union semun
|
|
117
117
|
};
|
118
118
|
#endif
|
119
119
|
|
120
|
-
static void
|
121
|
-
mm_free(mm_ipc * i_mm)
|
122
|
-
{
|
120
|
+
static void mm_free(mm_ipc *i_mm) {
|
123
121
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
124
122
|
if (i_mm->t->flag & MM_IPC) {
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
}
|
138
|
-
|
139
|
-
free(i_mm->t);
|
123
|
+
struct shmid_ds buf;
|
124
|
+
|
125
|
+
if (shmctl(i_mm->t->shmid, IPC_STAT, &buf) != -1) {
|
126
|
+
if (buf.shm_nattch == 1 && (i_mm->t->flag & MM_TMP)) {
|
127
|
+
semctl(i_mm->t->semid, 0, IPC_RMID);
|
128
|
+
if (i_mm->t->template) {
|
129
|
+
unlink(i_mm->t->template);
|
130
|
+
free(i_mm->t->template);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
shmdt(i_mm->t);
|
135
|
+
} else {
|
136
|
+
free(i_mm->t);
|
140
137
|
}
|
141
138
|
#endif
|
142
139
|
if (i_mm->t->path) {
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
140
|
+
munmap(i_mm->t->addr, i_mm->t->len);
|
141
|
+
if (i_mm->t->path != (char *)-1) {
|
142
|
+
if (i_mm->t->real < i_mm->t->len &&
|
143
|
+
i_mm->t->vscope != MAP_PRIVATE &&
|
144
|
+
truncate(i_mm->t->path, i_mm->t->real) == -1) {
|
145
|
+
free(i_mm->t->path);
|
146
|
+
free(i_mm);
|
147
|
+
rb_raise(rb_eTypeError, "truncate");
|
148
|
+
}
|
149
|
+
free(i_mm->t->path);
|
150
|
+
}
|
153
151
|
}
|
154
152
|
free(i_mm);
|
155
153
|
}
|
156
154
|
|
157
|
-
static void
|
158
|
-
|
159
|
-
mm_ipc *i_mm;
|
160
|
-
int wait_lock;
|
155
|
+
static void mm_lock(i_mm, wait_lock) mm_ipc *i_mm;
|
156
|
+
int wait_lock;
|
161
157
|
{
|
162
158
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
163
159
|
struct sembuf sem_op;
|
164
160
|
|
165
161
|
if (i_mm->t->flag & MM_IPC) {
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
162
|
+
i_mm->count++;
|
163
|
+
if (i_mm->count == 1) {
|
164
|
+
retry:
|
165
|
+
sem_op.sem_num = 0;
|
166
|
+
sem_op.sem_op = -1;
|
167
|
+
sem_op.sem_flg = IPC_NOWAIT;
|
168
|
+
if (semop(i_mm->t->semid, &sem_op, 1) == -1) {
|
169
|
+
if (errno == EAGAIN) {
|
170
|
+
if (!wait_lock) {
|
171
|
+
rb_raise(rb_const_get(rb_mErrno, rb_intern("EAGAIN")),
|
172
|
+
"EAGAIN");
|
173
|
+
}
|
174
|
+
rb_thread_sleep(1);
|
175
|
+
goto retry;
|
176
|
+
}
|
177
|
+
rb_sys_fail("semop()");
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
184
181
|
#endif
|
185
182
|
}
|
186
183
|
|
187
|
-
static void
|
188
|
-
mm_unlock(i_mm)
|
189
|
-
mm_ipc *i_mm;
|
184
|
+
static void mm_unlock(i_mm) mm_ipc *i_mm;
|
190
185
|
{
|
191
186
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
192
187
|
struct sembuf sem_op;
|
193
188
|
|
194
189
|
if (i_mm->t->flag & MM_IPC) {
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
190
|
+
i_mm->count--;
|
191
|
+
if (!i_mm->count) {
|
192
|
+
retry:
|
193
|
+
sem_op.sem_num = 0;
|
194
|
+
sem_op.sem_op = 1;
|
195
|
+
sem_op.sem_flg = IPC_NOWAIT;
|
196
|
+
if (semop(i_mm->t->semid, &sem_op, 1) == -1) {
|
197
|
+
if (errno == EAGAIN) {
|
198
|
+
rb_thread_sleep(1);
|
199
|
+
goto retry;
|
200
|
+
}
|
201
|
+
rb_sys_fail("semop()");
|
202
|
+
}
|
203
|
+
}
|
209
204
|
}
|
210
205
|
#endif
|
211
206
|
}
|
212
207
|
|
213
|
-
#define GetMmap(obj, i_mm, t_modify)
|
214
|
-
Data_Get_Struct(obj, mm_ipc, i_mm);
|
215
|
-
if (!i_mm->t->path) {
|
216
|
-
|
217
|
-
}
|
218
|
-
if ((t_modify & MM_MODIFY) && (i_mm->t->flag & MM_FROZEN)) {
|
219
|
-
|
208
|
+
#define GetMmap(obj, i_mm, t_modify) \
|
209
|
+
Data_Get_Struct(obj, mm_ipc, i_mm); \
|
210
|
+
if (!i_mm->t->path) { \
|
211
|
+
rb_raise(rb_eIOError, "unmapped file"); \
|
212
|
+
} \
|
213
|
+
if ((t_modify & MM_MODIFY) && (i_mm->t->flag & MM_FROZEN)) { \
|
214
|
+
rb_error_frozen("mmap"); \
|
220
215
|
}
|
221
216
|
|
222
|
-
static VALUE
|
223
|
-
mm_vunlock(obj)
|
224
|
-
VALUE obj;
|
217
|
+
static VALUE mm_vunlock(obj) VALUE obj;
|
225
218
|
{
|
226
219
|
mm_ipc *i_mm;
|
227
220
|
|
@@ -235,28 +228,25 @@ mm_vunlock(obj)
|
|
235
228
|
*
|
236
229
|
* Create a lock
|
237
230
|
*/
|
238
|
-
static VALUE
|
239
|
-
|
240
|
-
int argc;
|
241
|
-
VALUE *argv, obj;
|
231
|
+
static VALUE mm_semlock(argc, argv, obj) int argc;
|
232
|
+
VALUE *argv, obj;
|
242
233
|
{
|
243
234
|
mm_ipc *i_mm;
|
244
235
|
|
245
236
|
GetMmap(obj, i_mm, 0);
|
246
237
|
if (!(i_mm->t->flag & MM_IPC)) {
|
247
|
-
|
248
|
-
|
249
|
-
}
|
250
|
-
else {
|
238
|
+
rb_warning("useless use of #semlock");
|
239
|
+
rb_yield(obj);
|
240
|
+
} else {
|
251
241
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
242
|
+
VALUE a;
|
243
|
+
int wait_lock = Qtrue;
|
244
|
+
|
245
|
+
if (rb_scan_args(argc, argv, "01", &a)) {
|
246
|
+
wait_lock = RTEST(a);
|
247
|
+
}
|
248
|
+
mm_lock(i_mm, wait_lock);
|
249
|
+
rb_ensure(rb_yield, obj, mm_vunlock, obj);
|
260
250
|
#endif
|
261
251
|
}
|
262
252
|
return Qnil;
|
@@ -267,15 +257,13 @@ mm_semlock(argc, argv, obj)
|
|
267
257
|
*
|
268
258
|
* Get the ipc key
|
269
259
|
*/
|
270
|
-
static VALUE
|
271
|
-
mm_ipc_key(obj)
|
272
|
-
VALUE obj;
|
260
|
+
static VALUE mm_ipc_key(obj) VALUE obj;
|
273
261
|
{
|
274
262
|
mm_ipc *i_mm;
|
275
263
|
|
276
264
|
GetMmap(obj, i_mm, 0);
|
277
265
|
if (i_mm->t->flag & MM_IPC) {
|
278
|
-
|
266
|
+
return INT2NUM(i_mm->t->key);
|
279
267
|
}
|
280
268
|
return INT2NUM(-1);
|
281
269
|
}
|
@@ -288,25 +276,24 @@ mm_ipc_key(obj)
|
|
288
276
|
*
|
289
277
|
* terminate the association
|
290
278
|
*/
|
291
|
-
static VALUE
|
292
|
-
mm_unmap(obj)
|
293
|
-
VALUE obj;
|
279
|
+
static VALUE mm_unmap(obj) VALUE obj;
|
294
280
|
{
|
295
281
|
mm_ipc *i_mm;
|
296
282
|
|
297
283
|
GetMmap(obj, i_mm, 0);
|
298
284
|
if (i_mm->t->path) {
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
285
|
+
mm_lock(i_mm, Qtrue);
|
286
|
+
munmap(i_mm->t->addr, i_mm->t->len);
|
287
|
+
if (i_mm->t->path != (char *)-1) {
|
288
|
+
if (i_mm->t->real < i_mm->t->len &&
|
289
|
+
i_mm->t->vscope != MAP_PRIVATE &&
|
290
|
+
truncate(i_mm->t->path, i_mm->t->real) == -1) {
|
291
|
+
rb_raise(rb_eTypeError, "truncate");
|
292
|
+
}
|
293
|
+
free(i_mm->t->path);
|
294
|
+
}
|
295
|
+
i_mm->t->path = NULL;
|
296
|
+
mm_unlock(i_mm);
|
310
297
|
}
|
311
298
|
return Qnil;
|
312
299
|
}
|
@@ -314,11 +301,9 @@ mm_unmap(obj)
|
|
314
301
|
/*
|
315
302
|
* call-seq: freeze
|
316
303
|
*
|
317
|
-
* freeze the current file
|
304
|
+
* freeze the current file
|
318
305
|
*/
|
319
|
-
static VALUE
|
320
|
-
mm_freeze(obj)
|
321
|
-
VALUE obj;
|
306
|
+
static VALUE mm_freeze(obj) VALUE obj;
|
322
307
|
{
|
323
308
|
mm_ipc *i_mm;
|
324
309
|
rb_obj_freeze(obj);
|
@@ -327,36 +312,34 @@ mm_freeze(obj)
|
|
327
312
|
return obj;
|
328
313
|
}
|
329
314
|
|
330
|
-
static VALUE
|
331
|
-
mm_str(VALUE obj, int modify)
|
332
|
-
{
|
315
|
+
static VALUE mm_str(VALUE obj, int modify) {
|
333
316
|
mm_ipc *i_mm;
|
334
317
|
VALUE ret = Qnil;
|
335
318
|
|
336
319
|
GetMmap(obj, i_mm, modify & ~MM_ORIGIN);
|
337
320
|
if (modify & MM_MODIFY) {
|
338
|
-
|
339
|
-
|
340
|
-
|
321
|
+
if (i_mm->t->flag & MM_FROZEN) rb_error_frozen("mmap");
|
322
|
+
if (!OBJ_TAINTED(ret) && rb_safe_level() >= 4)
|
323
|
+
rb_raise(rb_eSecurityError, "Insecure: can't modify mmap");
|
341
324
|
}
|
342
325
|
ret = rb_obj_alloc(rb_cString);
|
343
326
|
if (rb_obj_tainted(obj)) {
|
344
|
-
|
327
|
+
OBJ_TAINT(ret);
|
345
328
|
}
|
346
329
|
RSTRING(ret)->as.heap.ptr = i_mm->t->addr;
|
347
330
|
RSTRING(ret)->as.heap.aux.capa = i_mm->t->len;
|
348
331
|
RSTRING(ret)->as.heap.len = i_mm->t->real;
|
349
332
|
if (modify & MM_ORIGIN) {
|
350
333
|
#if HAVE_RB_DEFINE_ALLOC_FUNC
|
351
|
-
|
352
|
-
|
353
|
-
|
334
|
+
RSTRING(ret)->as.heap.aux.shared = obj;
|
335
|
+
FL_SET(ret, RSTRING_NOEMBED);
|
336
|
+
FL_SET(ret, FL_USER18);
|
354
337
|
#else
|
355
|
-
|
338
|
+
RSTRING(ret)->orig = ret;
|
356
339
|
#endif
|
357
340
|
}
|
358
341
|
if (i_mm->t->flag & MM_FROZEN) {
|
359
|
-
|
342
|
+
ret = rb_obj_freeze(ret);
|
360
343
|
}
|
361
344
|
return ret;
|
362
345
|
}
|
@@ -366,13 +349,9 @@ mm_str(VALUE obj, int modify)
|
|
366
349
|
*
|
367
350
|
* Convert object to a string
|
368
351
|
*/
|
369
|
-
static VALUE
|
370
|
-
|
371
|
-
|
372
|
-
{
|
373
|
-
return mm_str(obj, MM_ORIGIN);
|
374
|
-
}
|
375
|
-
|
352
|
+
static VALUE mm_to_str(obj) VALUE obj;
|
353
|
+
{ return mm_str(obj, MM_ORIGIN); }
|
354
|
+
|
376
355
|
extern char *ruby_strdup();
|
377
356
|
|
378
357
|
typedef struct {
|
@@ -380,91 +359,84 @@ typedef struct {
|
|
380
359
|
size_t len;
|
381
360
|
} mm_st;
|
382
361
|
|
383
|
-
static VALUE
|
384
|
-
mm_i_expand(st_mm)
|
385
|
-
mm_st *st_mm;
|
362
|
+
static VALUE mm_i_expand(st_mm) mm_st *st_mm;
|
386
363
|
{
|
387
364
|
int fd;
|
388
365
|
mm_ipc *i_mm = st_mm->i_mm;
|
389
366
|
size_t len = st_mm->len;
|
390
367
|
|
391
368
|
if (munmap(i_mm->t->addr, i_mm->t->len)) {
|
392
|
-
|
369
|
+
rb_raise(rb_eArgError, "munmap failed");
|
393
370
|
}
|
394
371
|
if ((fd = open(i_mm->t->path, i_mm->t->smode)) == -1) {
|
395
|
-
|
372
|
+
rb_raise(rb_eArgError, "Can't open %s", i_mm->t->path);
|
396
373
|
}
|
397
374
|
if (len > i_mm->t->len) {
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
}
|
405
|
-
|
406
|
-
rb_raise(rb_eIOError, "Can't truncate %s", i_mm->t->path);
|
375
|
+
if (lseek(fd, len - i_mm->t->len - 1, SEEK_END) == -1) {
|
376
|
+
rb_raise(rb_eIOError, "Can't lseek %lu", len - i_mm->t->len - 1);
|
377
|
+
}
|
378
|
+
if (write(fd, "\000", 1) != 1) {
|
379
|
+
rb_raise(rb_eIOError, "Can't extend %s", i_mm->t->path);
|
380
|
+
}
|
381
|
+
} else if (len < i_mm->t->len && truncate(i_mm->t->path, len) == -1) {
|
382
|
+
rb_raise(rb_eIOError, "Can't truncate %s", i_mm->t->path);
|
407
383
|
}
|
408
|
-
i_mm->t->addr =
|
384
|
+
i_mm->t->addr =
|
385
|
+
mmap(0, len, i_mm->t->pmode, i_mm->t->vscope, fd, i_mm->t->offset);
|
409
386
|
close(fd);
|
410
387
|
if (i_mm->t->addr == MAP_FAILED) {
|
411
|
-
|
388
|
+
rb_raise(rb_eArgError, "mmap failed");
|
412
389
|
}
|
413
390
|
#ifdef MADV_NORMAL
|
414
391
|
if (i_mm->t->advice && madvise(i_mm->t->addr, len, i_mm->t->advice) == -1) {
|
415
|
-
|
392
|
+
rb_raise(rb_eArgError, "madvise(%d)", errno);
|
416
393
|
}
|
417
394
|
#endif
|
418
395
|
if ((i_mm->t->flag & MM_LOCK) && mlock(i_mm->t->addr, len) == -1) {
|
419
|
-
|
396
|
+
rb_raise(rb_eArgError, "mlock(%d)", errno);
|
420
397
|
}
|
421
|
-
i_mm->t->len
|
398
|
+
i_mm->t->len = len;
|
422
399
|
return Qnil;
|
423
400
|
}
|
424
401
|
|
425
|
-
static void
|
426
|
-
|
427
|
-
mm_ipc *i_mm;
|
428
|
-
size_t len;
|
402
|
+
static void mm_expandf(i_mm, len) mm_ipc *i_mm;
|
403
|
+
size_t len;
|
429
404
|
{
|
430
405
|
int status;
|
431
406
|
mm_st st_mm;
|
432
407
|
|
433
408
|
if (i_mm->t->vscope == MAP_PRIVATE) {
|
434
|
-
|
409
|
+
rb_raise(rb_eTypeError, "expand for a private map");
|
435
410
|
}
|
436
411
|
if (i_mm->t->flag & MM_FIXED) {
|
437
|
-
|
412
|
+
rb_raise(rb_eTypeError, "expand for a fixed map");
|
438
413
|
}
|
439
414
|
if (!i_mm->t->path || i_mm->t->path == (char *)-1) {
|
440
|
-
|
415
|
+
rb_raise(rb_eTypeError, "expand for an anonymous map");
|
441
416
|
}
|
442
417
|
st_mm.i_mm = i_mm;
|
443
418
|
st_mm.len = len;
|
444
419
|
if (i_mm->t->flag & MM_IPC) {
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
}
|
452
|
-
|
453
|
-
mm_i_expand(&st_mm);
|
420
|
+
mm_lock(i_mm, Qtrue);
|
421
|
+
rb_protect(mm_i_expand, (VALUE)&st_mm, &status);
|
422
|
+
mm_unlock(i_mm);
|
423
|
+
if (status) {
|
424
|
+
rb_jump_tag(status);
|
425
|
+
}
|
426
|
+
} else {
|
427
|
+
mm_i_expand(&st_mm);
|
454
428
|
}
|
455
429
|
}
|
456
430
|
|
457
|
-
static void
|
458
|
-
|
459
|
-
mm_ipc *i_mm;
|
460
|
-
size_t len;
|
431
|
+
static void mm_realloc(i_mm, len) mm_ipc *i_mm;
|
432
|
+
size_t len;
|
461
433
|
{
|
462
434
|
if (i_mm->t->flag & MM_FROZEN) rb_error_frozen("mmap");
|
463
435
|
if (len > i_mm->t->len) {
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
436
|
+
if ((len - i_mm->t->len) < i_mm->t->incr) {
|
437
|
+
len = i_mm->t->len + i_mm->t->incr;
|
438
|
+
}
|
439
|
+
mm_expandf(i_mm, len);
|
468
440
|
}
|
469
441
|
}
|
470
442
|
|
@@ -472,11 +444,9 @@ mm_realloc(i_mm, len)
|
|
472
444
|
* call-seq:
|
473
445
|
* extend(count)
|
474
446
|
*
|
475
|
-
* add <em>count</em> bytes to the file (i.e. pre-extend the file)
|
447
|
+
* add <em>count</em> bytes to the file (i.e. pre-extend the file)
|
476
448
|
*/
|
477
|
-
static VALUE
|
478
|
-
mm_extend(obj, a)
|
479
|
-
VALUE obj, a;
|
449
|
+
static VALUE mm_extend(obj, a) VALUE obj, a;
|
480
450
|
{
|
481
451
|
mm_ipc *i_mm;
|
482
452
|
long len;
|
@@ -484,14 +454,12 @@ mm_extend(obj, a)
|
|
484
454
|
GetMmap(obj, i_mm, MM_MODIFY);
|
485
455
|
len = NUM2LONG(a);
|
486
456
|
if (len > 0) {
|
487
|
-
|
457
|
+
mm_expandf(i_mm, i_mm->t->len + len);
|
488
458
|
}
|
489
459
|
return UINT2NUM(i_mm->t->len);
|
490
460
|
}
|
491
461
|
|
492
|
-
static VALUE
|
493
|
-
mm_i_options(arg, obj)
|
494
|
-
VALUE arg, obj;
|
462
|
+
static VALUE mm_i_options(arg, obj) VALUE arg, obj;
|
495
463
|
{
|
496
464
|
mm_ipc *i_mm;
|
497
465
|
char *options;
|
@@ -503,51 +471,47 @@ mm_i_options(arg, obj)
|
|
503
471
|
key = rb_obj_as_string(key);
|
504
472
|
options = StringValuePtr(key);
|
505
473
|
if (strcmp(options, "length") == 0) {
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
else if (strcmp(options, "offset") == 0) {
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
else if (strcmp(options, "advice") == 0) {
|
520
|
-
|
521
|
-
}
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
}
|
529
|
-
else if (strcmp(options, "initialize") == 0) {
|
474
|
+
i_mm->t->len = NUM2UINT(value);
|
475
|
+
if (i_mm->t->len <= 0) {
|
476
|
+
rb_raise(rb_eArgError, "Invalid value for length %zu",
|
477
|
+
i_mm->t->len);
|
478
|
+
}
|
479
|
+
i_mm->t->flag |= MM_FIXED;
|
480
|
+
} else if (strcmp(options, "offset") == 0) {
|
481
|
+
i_mm->t->offset = NUM2INT(value);
|
482
|
+
if (i_mm->t->offset < 0) {
|
483
|
+
rb_raise(rb_eArgError, "Invalid value for offset %lld",
|
484
|
+
i_mm->t->offset);
|
485
|
+
}
|
486
|
+
i_mm->t->flag |= MM_FIXED;
|
487
|
+
} else if (strcmp(options, "advice") == 0) {
|
488
|
+
i_mm->t->advice = NUM2INT(value);
|
489
|
+
} else if (strcmp(options, "increment") == 0) {
|
490
|
+
int incr = NUM2INT(value);
|
491
|
+
if (incr < 0) {
|
492
|
+
rb_raise(rb_eArgError, "Invalid value for increment %d", incr);
|
493
|
+
}
|
494
|
+
i_mm->t->incr = incr;
|
495
|
+
} else if (strcmp(options, "initialize") == 0) {
|
530
496
|
}
|
531
497
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
532
498
|
else if (strcmp(options, "ipc") == 0) {
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
499
|
+
if (value != Qtrue && TYPE(value) != T_HASH) {
|
500
|
+
rb_raise(rb_eArgError, "Expected an Hash for :ipc");
|
501
|
+
}
|
502
|
+
i_mm->t->shmid = value;
|
503
|
+
i_mm->t->flag |= (MM_IPC | MM_TMP);
|
538
504
|
}
|
539
505
|
#endif
|
540
506
|
else {
|
541
|
-
|
507
|
+
rb_warning("Unknown option `%s'", options);
|
542
508
|
}
|
543
509
|
return Qnil;
|
544
510
|
}
|
545
511
|
|
546
512
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
547
513
|
|
548
|
-
static VALUE
|
549
|
-
mm_i_ipc(arg, obj)
|
550
|
-
VALUE arg, obj;
|
514
|
+
static VALUE mm_i_ipc(arg, obj) VALUE arg, obj;
|
551
515
|
{
|
552
516
|
mm_ipc *i_mm;
|
553
517
|
char *options;
|
@@ -559,18 +523,15 @@ mm_i_ipc(arg, obj)
|
|
559
523
|
key = rb_obj_as_string(key);
|
560
524
|
options = StringValuePtr(key);
|
561
525
|
if (strcmp(options, "key") == 0) {
|
562
|
-
|
563
|
-
}
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
else
|
570
|
-
|
571
|
-
}
|
572
|
-
else {
|
573
|
-
rb_warning("Unknown option `%s'", options);
|
526
|
+
i_mm->t->key = rb_funcall2(value, rb_intern("to_int"), 0, 0);
|
527
|
+
} else if (strcmp(options, "permanent") == 0) {
|
528
|
+
if (RTEST(value)) {
|
529
|
+
i_mm->t->flag &= ~MM_TMP;
|
530
|
+
}
|
531
|
+
} else if (strcmp(options, "mode") == 0) {
|
532
|
+
i_mm->t->semid = NUM2INT(value);
|
533
|
+
} else {
|
534
|
+
rb_warning("Unknown option `%s'", options);
|
574
535
|
}
|
575
536
|
return Qnil;
|
576
537
|
}
|
@@ -582,56 +543,52 @@ mm_i_ipc(arg, obj)
|
|
582
543
|
* new(file, mode = "r", protection = Mmap::MAP_SHARED, options = {})
|
583
544
|
*
|
584
545
|
* create a new Mmap object
|
585
|
-
*
|
546
|
+
*
|
586
547
|
* * <em>file</em>
|
587
|
-
*
|
548
|
+
*
|
588
549
|
* Pathname of the file, if <em>nil</em> is given an anonymous map
|
589
550
|
* is created <em>Mmanp::MAP_ANON</em>
|
590
|
-
*
|
551
|
+
*
|
591
552
|
* * <em>mode</em>
|
592
|
-
*
|
553
|
+
*
|
593
554
|
* Mode to open the file, it can be "r", "w", "rw", "a"
|
594
|
-
*
|
555
|
+
*
|
595
556
|
* * <em>protection</em>
|
596
|
-
*
|
557
|
+
*
|
597
558
|
* specify the nature of the mapping
|
598
|
-
*
|
559
|
+
*
|
599
560
|
* * <em>Mmap::MAP_SHARED</em>
|
600
|
-
*
|
601
|
-
* Creates a mapping that's shared with all other processes
|
602
|
-
* mapping the same areas of the file.
|
561
|
+
*
|
562
|
+
* Creates a mapping that's shared with all other processes
|
563
|
+
* mapping the same areas of the file.
|
603
564
|
* The default value is <em>Mmap::MAP_SHARED</em>
|
604
|
-
*
|
565
|
+
*
|
605
566
|
* * <em>Mmap::MAP_PRIVATE</em>
|
606
|
-
*
|
567
|
+
*
|
607
568
|
* Creates a private copy-on-write mapping, so changes to the
|
608
569
|
* contents of the mmap object will be private to this process
|
609
|
-
*
|
570
|
+
*
|
610
571
|
* * <em>options</em>
|
611
|
-
*
|
572
|
+
*
|
612
573
|
* Hash. If one of the options <em>length</em> or <em>offset</em>
|
613
574
|
* is specified it will not possible to modify the size of
|
614
575
|
* the mapped file.
|
615
|
-
*
|
576
|
+
*
|
616
577
|
* length:: maps <em>length</em> bytes from the file
|
617
|
-
*
|
578
|
+
*
|
618
579
|
* offset:: the mapping begin at <em>offset</em>
|
619
|
-
*
|
580
|
+
*
|
620
581
|
* advice:: the type of the access (see #madvise)
|
621
582
|
*/
|
622
|
-
static VALUE
|
623
|
-
|
624
|
-
int argc;
|
625
|
-
VALUE *argv, obj;
|
583
|
+
static VALUE mm_s_new(argc, argv, obj) int argc;
|
584
|
+
VALUE *argv, obj;
|
626
585
|
{
|
627
586
|
VALUE res = rb_funcall2(obj, rb_intern("allocate"), 0, 0);
|
628
587
|
rb_obj_call_init(res, argc, argv);
|
629
588
|
return res;
|
630
589
|
}
|
631
590
|
|
632
|
-
static VALUE
|
633
|
-
mm_s_alloc(obj)
|
634
|
-
VALUE obj;
|
591
|
+
static VALUE mm_s_alloc(obj) VALUE obj;
|
635
592
|
{
|
636
593
|
VALUE res;
|
637
594
|
mm_ipc *i_mm;
|
@@ -648,10 +605,8 @@ mm_s_alloc(obj)
|
|
648
605
|
*
|
649
606
|
* Create a new Mmap object
|
650
607
|
*/
|
651
|
-
static VALUE
|
652
|
-
|
653
|
-
VALUE obj, *argv;
|
654
|
-
int argc;
|
608
|
+
static VALUE mm_init(argc, argv, obj) VALUE obj, *argv;
|
609
|
+
int argc;
|
655
610
|
{
|
656
611
|
struct stat st;
|
657
612
|
int fd, smode = 0, pmode = 0, vscope, perm, init;
|
@@ -665,8 +620,8 @@ mm_init(argc, argv, obj)
|
|
665
620
|
|
666
621
|
options = Qnil;
|
667
622
|
if (argc > 1 && TYPE(argv[argc - 1]) == T_HASH) {
|
668
|
-
|
669
|
-
|
623
|
+
options = argv[argc - 1];
|
624
|
+
argc--;
|
670
625
|
}
|
671
626
|
rb_scan_args(argc, argv, "12", &fname, &vmode, &scope);
|
672
627
|
vscope = 0;
|
@@ -676,47 +631,45 @@ mm_init(argc, argv, obj)
|
|
676
631
|
fdv = Qnil;
|
677
632
|
#ifdef MAP_ANON
|
678
633
|
if (NIL_P(fname)) {
|
679
|
-
|
680
|
-
|
681
|
-
}
|
682
|
-
else
|
634
|
+
vscope = MAP_ANON | MAP_SHARED;
|
635
|
+
anonymous = 1;
|
636
|
+
} else
|
683
637
|
#endif
|
684
638
|
{
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
vscope = NUM2INT(scope);
|
639
|
+
if (rb_safe_level() > 0 && OBJ_TAINTED(fname)) {
|
640
|
+
rb_raise(rb_eSecurityError, "Insecure operation");
|
641
|
+
}
|
642
|
+
rb_secure(4);
|
643
|
+
if (rb_respond_to(fname, rb_intern("fileno"))) {
|
644
|
+
fdv = rb_funcall2(fname, rb_intern("fileno"), 0, 0);
|
645
|
+
}
|
646
|
+
if (NIL_P(fdv)) {
|
647
|
+
fname = rb_str_to_str(fname);
|
648
|
+
SafeStringValue(fname);
|
649
|
+
path = StringValuePtr(fname);
|
650
|
+
} else {
|
651
|
+
fd = NUM2INT(fdv);
|
652
|
+
if (fd < 0) {
|
653
|
+
rb_raise(rb_eArgError, "invalid file descriptor %d", fd);
|
654
|
+
}
|
655
|
+
}
|
656
|
+
if (!NIL_P(scope)) {
|
657
|
+
vscope = NUM2INT(scope);
|
705
658
|
#ifdef MAP_ANON
|
706
|
-
|
707
|
-
|
708
|
-
|
659
|
+
if (vscope & MAP_ANON) {
|
660
|
+
rb_raise(rb_eArgError,
|
661
|
+
"filename specified for an anonymous map");
|
662
|
+
}
|
709
663
|
#endif
|
710
|
-
|
664
|
+
}
|
711
665
|
}
|
712
666
|
vscope |= NIL_P(scope) ? MAP_SHARED : NUM2INT(scope);
|
713
667
|
size = 0;
|
714
668
|
perm = 0666;
|
715
669
|
if (!anonymous) {
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
else if (rb_respond_to(vmode, rb_intern("to_ary"))) {
|
670
|
+
if (NIL_P(vmode)) {
|
671
|
+
mode = "r";
|
672
|
+
} else if (rb_respond_to(vmode, rb_intern("to_ary"))) {
|
720
673
|
VALUE tmp;
|
721
674
|
|
722
675
|
vmode = rb_convert_type(vmode, T_ARRAY, "Array", "to_ary");
|
@@ -724,200 +677,191 @@ mm_init(argc, argv, obj)
|
|
724
677
|
rb_raise(rb_eArgError, "Invalid length %ld (expected 2)",
|
725
678
|
RARRAY_LEN(vmode));
|
726
679
|
}
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
}
|
763
|
-
else {
|
764
|
-
fd = -1;
|
765
|
-
if (!NIL_P(vmode) && TYPE(vmode) != T_STRING) {
|
766
|
-
size = NUM2INT(vmode);
|
767
|
-
}
|
680
|
+
tmp = rb_ary_entry(vmode, 0);
|
681
|
+
mode = StringValuePtr(tmp);
|
682
|
+
perm = NUM2INT(rb_ary_entry(vmode, 1));
|
683
|
+
} else {
|
684
|
+
mode = StringValuePtr(vmode);
|
685
|
+
}
|
686
|
+
if (strcmp(mode, "r") == 0) {
|
687
|
+
smode = O_RDONLY;
|
688
|
+
pmode = PROT_READ;
|
689
|
+
} else if (strcmp(mode, "w") == 0) {
|
690
|
+
smode = O_RDWR | O_TRUNC;
|
691
|
+
pmode = PROT_READ | PROT_WRITE;
|
692
|
+
} else if (strcmp(mode, "rw") == 0 || strcmp(mode, "wr") == 0) {
|
693
|
+
smode = O_RDWR;
|
694
|
+
pmode = PROT_READ | PROT_WRITE;
|
695
|
+
} else if (strcmp(mode, "a") == 0) {
|
696
|
+
smode = O_RDWR | O_CREAT;
|
697
|
+
pmode = PROT_READ | PROT_WRITE;
|
698
|
+
} else {
|
699
|
+
rb_raise(rb_eArgError, "Invalid mode %s", mode);
|
700
|
+
}
|
701
|
+
if (NIL_P(fdv)) {
|
702
|
+
if ((fd = open(path, smode, perm)) == -1) {
|
703
|
+
rb_raise(rb_eArgError, "Can't open %s", path);
|
704
|
+
}
|
705
|
+
}
|
706
|
+
if (fstat(fd, &st) == -1) {
|
707
|
+
rb_raise(rb_eArgError, "Can't stat %s", path);
|
708
|
+
}
|
709
|
+
size = st.st_size;
|
710
|
+
} else {
|
711
|
+
fd = -1;
|
712
|
+
if (!NIL_P(vmode) && TYPE(vmode) != T_STRING) {
|
713
|
+
size = NUM2INT(vmode);
|
714
|
+
}
|
768
715
|
}
|
769
716
|
Data_Get_Struct(obj, mm_ipc, i_mm);
|
770
717
|
if (i_mm->t->flag & MM_FROZEN) {
|
771
|
-
|
718
|
+
rb_raise(rb_eArgError, "frozen mmap");
|
772
719
|
}
|
773
720
|
i_mm->t->shmid = 0;
|
774
721
|
i_mm->t->semid = 0;
|
775
722
|
offset = 0;
|
776
723
|
if (options != Qnil) {
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
724
|
+
rb_iterate(rb_each, options, mm_i_options, obj);
|
725
|
+
if (path && (i_mm->t->len + i_mm->t->offset) > st.st_size) {
|
726
|
+
rb_raise(rb_eArgError,
|
727
|
+
"invalid value for length (%ld) or offset (%lld)",
|
728
|
+
i_mm->t->len, i_mm->t->offset);
|
729
|
+
}
|
730
|
+
if (i_mm->t->len) size = i_mm->t->len;
|
731
|
+
offset = i_mm->t->offset;
|
784
732
|
#if HAVE_SEMCTL && HAVE_SHMCTL
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
strcpy(i_mm->t->template, template);
|
851
|
-
}
|
733
|
+
if (i_mm->t->flag & MM_IPC) {
|
734
|
+
key_t key;
|
735
|
+
int shmid, semid, mode;
|
736
|
+
union semun sem_val;
|
737
|
+
struct shmid_ds buf;
|
738
|
+
mm_mmap *data;
|
739
|
+
|
740
|
+
if (!(vscope & MAP_SHARED)) {
|
741
|
+
rb_warning("Probably it will not do what you expect ...");
|
742
|
+
}
|
743
|
+
i_mm->t->key = -1;
|
744
|
+
i_mm->t->semid = 0;
|
745
|
+
if (TYPE(i_mm->t->shmid) == T_HASH) {
|
746
|
+
rb_iterate(rb_each, i_mm->t->shmid, mm_i_ipc, obj);
|
747
|
+
}
|
748
|
+
i_mm->t->shmid = 0;
|
749
|
+
if (i_mm->t->semid) {
|
750
|
+
mode = i_mm->t->semid;
|
751
|
+
i_mm->t->semid = 0;
|
752
|
+
} else {
|
753
|
+
mode = 0644;
|
754
|
+
}
|
755
|
+
if ((int)i_mm->t->key <= 0) {
|
756
|
+
mode |= IPC_CREAT;
|
757
|
+
strcpy(template, "/tmp/ruby_mmap.XXXXXX");
|
758
|
+
if (mkstemp(template) == -1) {
|
759
|
+
rb_sys_fail("mkstemp()");
|
760
|
+
}
|
761
|
+
if ((key = ftok(template, 'R')) == -1) {
|
762
|
+
rb_sys_fail("ftok()");
|
763
|
+
}
|
764
|
+
} else {
|
765
|
+
key = (key_t)i_mm->t->key;
|
766
|
+
}
|
767
|
+
if ((shmid = shmget(key, sizeof(mm_ipc), mode)) == -1) {
|
768
|
+
rb_sys_fail("shmget()");
|
769
|
+
}
|
770
|
+
data = shmat(shmid, (void *)0, 0);
|
771
|
+
if (data == (mm_mmap *)-1) {
|
772
|
+
rb_sys_fail("shmat()");
|
773
|
+
}
|
774
|
+
if (i_mm->t->flag & MM_TMP) {
|
775
|
+
if (shmctl(shmid, IPC_RMID, &buf) == -1) {
|
776
|
+
rb_sys_fail("shmctl()");
|
777
|
+
}
|
778
|
+
}
|
779
|
+
if ((semid = semget(key, 1, mode)) == -1) {
|
780
|
+
rb_sys_fail("semget()");
|
781
|
+
}
|
782
|
+
if (mode & IPC_CREAT) {
|
783
|
+
sem_val.val = 1;
|
784
|
+
if (semctl(semid, 0, SETVAL, sem_val) == -1) {
|
785
|
+
rb_sys_fail("semctl()");
|
786
|
+
}
|
787
|
+
}
|
788
|
+
memcpy(data, i_mm->t, sizeof(mm_mmap));
|
789
|
+
free(i_mm->t);
|
790
|
+
i_mm->t = data;
|
791
|
+
i_mm->t->key = key;
|
792
|
+
i_mm->t->semid = semid;
|
793
|
+
i_mm->t->shmid = shmid;
|
794
|
+
if (i_mm->t->flag & MM_TMP) {
|
795
|
+
i_mm->t->template = ALLOC_N(char, strlen(template) + 1);
|
796
|
+
strcpy(i_mm->t->template, template);
|
797
|
+
}
|
852
798
|
}
|
853
799
|
#endif
|
854
800
|
}
|
855
801
|
init = 0;
|
856
802
|
if (anonymous) {
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
}
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
}
|
803
|
+
if (size <= 0) {
|
804
|
+
rb_raise(rb_eArgError, "length not specified for an anonymous map");
|
805
|
+
}
|
806
|
+
if (offset) {
|
807
|
+
rb_warning("Ignoring offset for an anonymous map");
|
808
|
+
offset = 0;
|
809
|
+
}
|
810
|
+
smode = O_RDWR;
|
811
|
+
pmode = PROT_READ | PROT_WRITE;
|
812
|
+
i_mm->t->flag |= MM_FIXED | MM_ANON;
|
813
|
+
} else {
|
814
|
+
if (size == 0 && (smode & O_RDWR)) {
|
815
|
+
if (lseek(fd, i_mm->t->incr - 1, SEEK_END) == -1) {
|
816
|
+
rb_raise(rb_eIOError, "Can't lseek %lu", i_mm->t->incr - 1);
|
817
|
+
}
|
818
|
+
if (write(fd, "\000", 1) != 1) {
|
819
|
+
rb_raise(rb_eIOError, "Can't extend %s", path);
|
820
|
+
}
|
821
|
+
init = 1;
|
822
|
+
size = i_mm->t->incr;
|
823
|
+
}
|
824
|
+
if (!NIL_P(fdv)) {
|
825
|
+
i_mm->t->flag |= MM_FIXED;
|
826
|
+
}
|
882
827
|
}
|
883
828
|
addr = mmap(0, size, pmode, vscope, fd, offset);
|
884
829
|
if (NIL_P(fdv) && !anonymous) {
|
885
|
-
|
830
|
+
close(fd);
|
886
831
|
}
|
887
832
|
if (addr == MAP_FAILED || !addr) {
|
888
|
-
|
833
|
+
rb_raise(rb_eArgError, "mmap failed (%d)", errno);
|
889
834
|
}
|
890
835
|
#ifdef MADV_NORMAL
|
891
836
|
if (i_mm->t->advice && madvise(addr, size, i_mm->t->advice) == -1) {
|
892
|
-
|
837
|
+
rb_raise(rb_eArgError, "madvise(%d)", errno);
|
893
838
|
}
|
894
839
|
#endif
|
895
840
|
if (anonymous && TYPE(options) == T_HASH) {
|
896
|
-
|
897
|
-
|
841
|
+
VALUE val;
|
842
|
+
char *ptr;
|
898
843
|
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
844
|
+
val = rb_hash_aref(options, rb_str_new2("initialize"));
|
845
|
+
if (!NIL_P(val)) {
|
846
|
+
ptr = StringValuePtr(val);
|
847
|
+
memset(addr, ptr[0], size);
|
848
|
+
}
|
904
849
|
}
|
905
|
-
i_mm->t->addr
|
850
|
+
i_mm->t->addr = addr;
|
906
851
|
i_mm->t->len = size;
|
907
852
|
if (!init) i_mm->t->real = size;
|
908
853
|
i_mm->t->pmode = pmode;
|
909
854
|
i_mm->t->vscope = vscope;
|
910
855
|
i_mm->t->smode = smode & ~O_TRUNC;
|
911
|
-
i_mm->t->path = (path)?ruby_strdup(path):(char *)-1;
|
856
|
+
i_mm->t->path = (path) ? ruby_strdup(path) : (char *)-1;
|
912
857
|
if (smode == O_RDONLY) {
|
913
|
-
|
914
|
-
|
915
|
-
}
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
OBJ_TAINT(obj);
|
858
|
+
obj = rb_obj_freeze(obj);
|
859
|
+
i_mm->t->flag |= MM_FROZEN;
|
860
|
+
} else {
|
861
|
+
if (smode == O_WRONLY) {
|
862
|
+
i_mm->t->flag |= MM_FIXED;
|
863
|
+
}
|
864
|
+
OBJ_TAINT(obj);
|
921
865
|
}
|
922
866
|
return obj;
|
923
867
|
}
|
@@ -931,10 +875,8 @@ mm_init(argc, argv, obj)
|
|
931
875
|
*
|
932
876
|
* flush the file
|
933
877
|
*/
|
934
|
-
static VALUE
|
935
|
-
|
936
|
-
int argc;
|
937
|
-
VALUE *argv, obj;
|
878
|
+
static VALUE mm_msync(argc, argv, obj) int argc;
|
879
|
+
VALUE *argv, obj;
|
938
880
|
{
|
939
881
|
mm_ipc *i_mm;
|
940
882
|
VALUE oflag;
|
@@ -942,15 +884,15 @@ mm_msync(argc, argv, obj)
|
|
942
884
|
int flag = MS_SYNC;
|
943
885
|
|
944
886
|
if (argc) {
|
945
|
-
|
946
|
-
|
887
|
+
rb_scan_args(argc, argv, "01", &oflag);
|
888
|
+
flag = NUM2INT(oflag);
|
947
889
|
}
|
948
890
|
GetMmap(obj, i_mm, MM_MODIFY);
|
949
891
|
if ((ret = msync(i_mm->t->addr, i_mm->t->len, flag)) != 0) {
|
950
|
-
|
892
|
+
rb_raise(rb_eArgError, "msync(%d)", ret);
|
951
893
|
}
|
952
894
|
if (i_mm->t->real < i_mm->t->len && i_mm->t->vscope != MAP_PRIVATE)
|
953
|
-
|
895
|
+
mm_expandf(i_mm, i_mm->t->real);
|
954
896
|
return obj;
|
955
897
|
}
|
956
898
|
|
@@ -962,9 +904,7 @@ mm_msync(argc, argv, obj)
|
|
962
904
|
*
|
963
905
|
* change the mode, value must be "r", "w" or "rw"
|
964
906
|
*/
|
965
|
-
static VALUE
|
966
|
-
mm_mprotect(obj, a)
|
967
|
-
VALUE obj, a;
|
907
|
+
static VALUE mm_mprotect(obj, a) VALUE obj, a;
|
968
908
|
{
|
969
909
|
mm_ipc *i_mm;
|
970
910
|
int ret, pmode;
|
@@ -972,35 +912,36 @@ mm_mprotect(obj, a)
|
|
972
912
|
|
973
913
|
GetMmap(obj, i_mm, 0);
|
974
914
|
if (TYPE(a) == T_STRING) {
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
915
|
+
smode = StringValuePtr(a);
|
916
|
+
if (strcmp(smode, "r") == 0)
|
917
|
+
pmode = PROT_READ;
|
918
|
+
else if (strcmp(smode, "w") == 0)
|
919
|
+
pmode = PROT_WRITE;
|
920
|
+
else if (strcmp(smode, "rw") == 0 || strcmp(smode, "wr") == 0)
|
921
|
+
pmode = PROT_READ | PROT_WRITE;
|
922
|
+
else {
|
923
|
+
rb_raise(rb_eArgError, "Invalid mode %s", smode);
|
924
|
+
}
|
925
|
+
} else {
|
926
|
+
pmode = NUM2INT(a);
|
986
927
|
}
|
987
|
-
if ((pmode & PROT_WRITE) && (i_mm->t->flag & MM_FROZEN))
|
988
|
-
|
928
|
+
if ((pmode & PROT_WRITE) && (i_mm->t->flag & MM_FROZEN))
|
929
|
+
rb_error_frozen("mmap");
|
989
930
|
if ((ret = mprotect(i_mm->t->addr, i_mm->t->len, pmode | PROT_READ)) != 0) {
|
990
|
-
|
931
|
+
rb_raise(rb_eArgError, "mprotect(%d)", ret);
|
991
932
|
}
|
992
933
|
i_mm->t->pmode = pmode;
|
993
934
|
if (pmode & PROT_READ) {
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
else if (pmode & PROT_WRITE) {
|
1002
|
-
|
1003
|
-
|
935
|
+
if (pmode & PROT_WRITE)
|
936
|
+
i_mm->t->smode = O_RDWR;
|
937
|
+
else {
|
938
|
+
i_mm->t->smode = O_RDONLY;
|
939
|
+
obj = rb_obj_freeze(obj);
|
940
|
+
i_mm->t->flag |= MM_FROZEN;
|
941
|
+
}
|
942
|
+
} else if (pmode & PROT_WRITE) {
|
943
|
+
i_mm->t->flag |= MM_FIXED;
|
944
|
+
i_mm->t->smode = O_WRONLY;
|
1004
945
|
}
|
1005
946
|
return obj;
|
1006
947
|
}
|
@@ -1017,41 +958,36 @@ mm_mprotect(obj, a)
|
|
1017
958
|
* <em>Mmap::MADV_WILLNEED</em>, <em>Mmap::MADV_DONTNEED</em>
|
1018
959
|
*
|
1019
960
|
*/
|
1020
|
-
static VALUE
|
1021
|
-
mm_madvise(obj, a)
|
1022
|
-
VALUE obj, a;
|
961
|
+
static VALUE mm_madvise(obj, a) VALUE obj, a;
|
1023
962
|
{
|
1024
963
|
mm_ipc *i_mm;
|
1025
|
-
|
964
|
+
|
1026
965
|
GetMmap(obj, i_mm, 0);
|
1027
966
|
if (madvise(i_mm->t->addr, i_mm->t->len, NUM2INT(a)) == -1) {
|
1028
|
-
|
967
|
+
rb_raise(rb_eTypeError, "madvise(%d)", errno);
|
1029
968
|
}
|
1030
969
|
i_mm->t->advice = NUM2INT(a);
|
1031
970
|
return Qnil;
|
1032
971
|
}
|
1033
972
|
#endif
|
1034
973
|
|
1035
|
-
#define StringMmap(b, bp, bl)
|
1036
|
-
do {
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
VALUE val;
|
1053
|
-
long beg;
|
1054
|
-
long len;
|
974
|
+
#define StringMmap(b, bp, bl) \
|
975
|
+
do { \
|
976
|
+
if (TYPE(b) == T_DATA && RDATA(b)->dfree == (RUBY_DATA_FUNC)mm_free) { \
|
977
|
+
mm_ipc *b_mm; \
|
978
|
+
GetMmap(b, b_mm, 0); \
|
979
|
+
bp = b_mm->t->addr; \
|
980
|
+
bl = b_mm->t->real; \
|
981
|
+
} else { \
|
982
|
+
bp = StringValuePtr(b); \
|
983
|
+
bl = RSTRING_LEN(b); \
|
984
|
+
} \
|
985
|
+
} while (0);
|
986
|
+
|
987
|
+
static void mm_update(str, beg, len, val) mm_ipc *str;
|
988
|
+
VALUE val;
|
989
|
+
long beg;
|
990
|
+
long len;
|
1055
991
|
{
|
1056
992
|
char *valp;
|
1057
993
|
long vall;
|
@@ -1060,17 +996,17 @@ mm_update(str, beg, len, val)
|
|
1060
996
|
if (len < 0) rb_raise(rb_eIndexError, "negative length %ld", len);
|
1061
997
|
mm_lock(str, Qtrue);
|
1062
998
|
if (beg < 0) {
|
1063
|
-
|
999
|
+
beg += str->t->real;
|
1064
1000
|
}
|
1065
1001
|
if (beg < 0 || str->t->real < (size_t)beg) {
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1002
|
+
if (beg < 0) {
|
1003
|
+
beg -= str->t->real;
|
1004
|
+
}
|
1005
|
+
mm_unlock(str);
|
1006
|
+
rb_raise(rb_eIndexError, "index %ld out of string", beg);
|
1071
1007
|
}
|
1072
1008
|
if (str->t->real < (size_t)(beg + len)) {
|
1073
|
-
|
1009
|
+
len = str->t->real - beg;
|
1074
1010
|
}
|
1075
1011
|
|
1076
1012
|
mm_unlock(str);
|
@@ -1078,23 +1014,22 @@ mm_update(str, beg, len, val)
|
|
1078
1014
|
mm_lock(str, Qtrue);
|
1079
1015
|
|
1080
1016
|
if ((str->t->flag & MM_FIXED) && vall != len) {
|
1081
|
-
|
1082
|
-
|
1017
|
+
mm_unlock(str);
|
1018
|
+
rb_raise(rb_eTypeError, "try to change the size of a fixed map");
|
1083
1019
|
}
|
1084
1020
|
if (len < vall) {
|
1085
|
-
|
1021
|
+
mm_realloc(str, str->t->real + vall - len);
|
1086
1022
|
}
|
1087
1023
|
|
1088
1024
|
if (vall != len) {
|
1089
|
-
|
1090
|
-
|
1091
|
-
str->t->real - (beg + len));
|
1025
|
+
memmove((char *)str->t->addr + beg + vall,
|
1026
|
+
(char *)str->t->addr + beg + len, str->t->real - (beg + len));
|
1092
1027
|
}
|
1093
1028
|
if (str->t->real < (size_t)beg && len < 0) {
|
1094
|
-
|
1029
|
+
MEMZERO(str->t->addr + str->t->real, char, -len);
|
1095
1030
|
}
|
1096
1031
|
if (vall > 0) {
|
1097
|
-
|
1032
|
+
memmove((char *)str->t->addr + beg, valp, vall);
|
1098
1033
|
}
|
1099
1034
|
str->t->real += vall - len;
|
1100
1035
|
mm_unlock(str);
|
@@ -1103,60 +1038,56 @@ mm_update(str, beg, len, val)
|
|
1103
1038
|
/*
|
1104
1039
|
* call-seq: =~(other)
|
1105
1040
|
*
|
1106
|
-
* return an index of the match
|
1041
|
+
* return an index of the match
|
1107
1042
|
*/
|
1108
|
-
static VALUE
|
1109
|
-
mm_match(x, y)
|
1110
|
-
VALUE x, y;
|
1043
|
+
static VALUE mm_match(x, y) VALUE x, y;
|
1111
1044
|
{
|
1112
1045
|
VALUE reg, res;
|
1113
1046
|
long start;
|
1114
1047
|
|
1115
1048
|
x = mm_str(x, MM_ORIGIN);
|
1116
1049
|
if (TYPE(y) == T_DATA && RDATA(y)->dfree == (RUBY_DATA_FUNC)mm_free) {
|
1117
|
-
|
1050
|
+
y = mm_to_str(y);
|
1118
1051
|
}
|
1119
1052
|
switch (TYPE(y)) {
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1053
|
+
case T_REGEXP:
|
1054
|
+
res = rb_reg_match(y, x);
|
1055
|
+
break;
|
1056
|
+
|
1057
|
+
case T_STRING:
|
1058
|
+
reg = rb_reg_regcomp(y);
|
1059
|
+
start = rb_reg_search(reg, x, 0, 0);
|
1060
|
+
if (start == -1)
|
1061
|
+
res = Qnil;
|
1062
|
+
else
|
1063
|
+
res = INT2NUM(start);
|
1064
|
+
break;
|
1065
|
+
|
1066
|
+
default:
|
1067
|
+
res = rb_funcall(y, rb_intern("=~"), 1, x);
|
1068
|
+
break;
|
1134
1069
|
}
|
1135
1070
|
return res;
|
1136
1071
|
}
|
1137
1072
|
|
1138
|
-
static VALUE
|
1139
|
-
get_pat(pat)
|
1140
|
-
VALUE pat;
|
1073
|
+
static VALUE get_pat(pat) VALUE pat;
|
1141
1074
|
{
|
1142
1075
|
switch (TYPE(pat)) {
|
1143
|
-
|
1144
|
-
|
1076
|
+
case T_REGEXP:
|
1077
|
+
break;
|
1145
1078
|
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1079
|
+
case T_STRING:
|
1080
|
+
pat = rb_reg_regcomp(pat);
|
1081
|
+
break;
|
1149
1082
|
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1083
|
+
default:
|
1084
|
+
/* type failed */
|
1085
|
+
Check_Type(pat, T_REGEXP);
|
1153
1086
|
}
|
1154
1087
|
return pat;
|
1155
1088
|
}
|
1156
1089
|
|
1157
|
-
static int
|
1158
|
-
mm_correct_backref()
|
1159
|
-
{
|
1090
|
+
static int mm_correct_backref() {
|
1160
1091
|
VALUE match;
|
1161
1092
|
int i, start;
|
1162
1093
|
|
@@ -1165,19 +1096,19 @@ mm_correct_backref()
|
|
1165
1096
|
if (RMATCH(match)->BEG(0) == -1) return 0;
|
1166
1097
|
start = RMATCH(match)->BEG(0);
|
1167
1098
|
RMATCH(match)->str = rb_str_new(StringValuePtr(RMATCH(match)->str) + start,
|
1168
|
-
|
1099
|
+
RMATCH(match)->END(0) - start);
|
1169
1100
|
if (OBJ_TAINTED(match)) OBJ_TAINT(RMATCH(match)->str);
|
1170
|
-
for (i = 0; i < RMATCH(match)->rmatch->regs.num_regs &&
|
1171
|
-
|
1172
|
-
|
1101
|
+
for (i = 0; i < RMATCH(match)->rmatch->regs.num_regs &&
|
1102
|
+
RMATCH(match)->BEG(i) != -1;
|
1103
|
+
i++) {
|
1104
|
+
RMATCH(match)->BEG(i) -= start;
|
1105
|
+
RMATCH(match)->END(i) -= start;
|
1173
1106
|
}
|
1174
1107
|
rb_backref_set(match);
|
1175
1108
|
return start;
|
1176
1109
|
}
|
1177
1110
|
|
1178
|
-
static VALUE
|
1179
|
-
mm_sub_bang_int(bang_st)
|
1180
|
-
mm_bang *bang_st;
|
1111
|
+
static VALUE mm_sub_bang_int(bang_st) mm_bang *bang_st;
|
1181
1112
|
{
|
1182
1113
|
int argc = bang_st->argc;
|
1183
1114
|
VALUE *argv = bang_st->argv;
|
@@ -1190,14 +1121,12 @@ mm_sub_bang_int(bang_st)
|
|
1190
1121
|
mm_ipc *i_mm;
|
1191
1122
|
|
1192
1123
|
if (argc == 1 && rb_block_given_p()) {
|
1193
|
-
|
1194
|
-
}
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
else {
|
1200
|
-
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
|
1124
|
+
iter = 1;
|
1125
|
+
} else if (argc == 2) {
|
1126
|
+
repl = rb_str_to_str(argv[1]);
|
1127
|
+
if (OBJ_TAINTED(repl)) tainted = 1;
|
1128
|
+
} else {
|
1129
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
|
1201
1130
|
}
|
1202
1131
|
GetMmap(obj, i_mm, MM_MODIFY);
|
1203
1132
|
str = mm_str(obj, MM_MODIFY | MM_ORIGIN);
|
@@ -1205,39 +1134,40 @@ mm_sub_bang_int(bang_st)
|
|
1205
1134
|
pat = get_pat(argv[0]);
|
1206
1135
|
res = Qnil;
|
1207
1136
|
if (rb_reg_search(pat, str, 0, 0) >= 0) {
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1137
|
+
start = mm_correct_backref();
|
1138
|
+
match = rb_backref_get();
|
1139
|
+
regs = &RMATCH(match)->rmatch->regs;
|
1140
|
+
if (iter) {
|
1141
|
+
rb_match_busy(match);
|
1142
|
+
repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
|
1143
|
+
rb_backref_set(match);
|
1144
|
+
} else {
|
1145
|
+
RSTRING(str)->as.heap.ptr += start;
|
1146
|
+
repl = rb_reg_regsub(repl, str, regs, match);
|
1147
|
+
RSTRING(str)->as.heap.ptr -= start;
|
1148
|
+
}
|
1149
|
+
if (OBJ_TAINTED(repl)) tainted = 1;
|
1150
|
+
plen = RMATCH(match)->END(0) - RMATCH(match)->BEG(0);
|
1151
|
+
if (RSTRING_LEN(repl) > plen) {
|
1152
|
+
mm_realloc(i_mm, RSTRING_LEN(str) + RSTRING_LEN(repl) - plen);
|
1153
|
+
RSTRING(str)->as.heap.ptr = i_mm->t->addr;
|
1154
|
+
}
|
1155
|
+
if (RSTRING_LEN(repl) != plen) {
|
1156
|
+
if (i_mm->t->flag & MM_FIXED) {
|
1157
|
+
rb_raise(rb_eTypeError,
|
1158
|
+
"try to change the size of a fixed map");
|
1159
|
+
}
|
1160
|
+
memmove(RSTRING_PTR(str) + start + RMATCH(match)->BEG(0) +
|
1161
|
+
RSTRING_LEN(repl),
|
1162
|
+
RSTRING_PTR(str) + start + RMATCH(match)->BEG(0) + plen,
|
1163
|
+
RSTRING_LEN(str) - start - RMATCH(match)->BEG(0) - plen);
|
1164
|
+
}
|
1165
|
+
memcpy(RSTRING_PTR(str) + start + RMATCH(match)->BEG(0),
|
1166
|
+
RSTRING_PTR(repl), RSTRING_LEN(repl));
|
1167
|
+
i_mm->t->real += RSTRING_LEN(repl) - plen;
|
1168
|
+
if (tainted) OBJ_TAINT(obj);
|
1169
|
+
|
1170
|
+
res = obj;
|
1241
1171
|
}
|
1242
1172
|
rb_gc_force_recycle(str);
|
1243
1173
|
return res;
|
@@ -1248,13 +1178,11 @@ mm_sub_bang_int(bang_st)
|
|
1248
1178
|
* str.sub!(pattern, replacement) => str or nil
|
1249
1179
|
* str.sub!(pattern) {|match| block } => str or nil
|
1250
1180
|
*
|
1251
|
-
* substitution
|
1181
|
+
* substitution
|
1252
1182
|
*/
|
1253
|
-
static VALUE
|
1254
|
-
|
1255
|
-
|
1256
|
-
VALUE *argv;
|
1257
|
-
VALUE obj;
|
1183
|
+
static VALUE mm_sub_bang(argc, argv, obj) int argc;
|
1184
|
+
VALUE *argv;
|
1185
|
+
VALUE obj;
|
1258
1186
|
{
|
1259
1187
|
VALUE res;
|
1260
1188
|
mm_bang bang_st;
|
@@ -1265,18 +1193,15 @@ mm_sub_bang(argc, argv, obj)
|
|
1265
1193
|
bang_st.obj = obj;
|
1266
1194
|
GetMmap(obj, i_mm, MM_MODIFY);
|
1267
1195
|
if (i_mm->t->flag & MM_IPC) {
|
1268
|
-
|
1269
|
-
|
1270
|
-
}
|
1271
|
-
|
1272
|
-
res = mm_sub_bang_int(&bang_st);
|
1196
|
+
mm_lock(i_mm, Qtrue);
|
1197
|
+
res = rb_ensure(mm_sub_bang_int, (VALUE)&bang_st, mm_vunlock, obj);
|
1198
|
+
} else {
|
1199
|
+
res = mm_sub_bang_int(&bang_st);
|
1273
1200
|
}
|
1274
1201
|
return res;
|
1275
1202
|
}
|
1276
1203
|
|
1277
|
-
static VALUE
|
1278
|
-
mm_gsub_bang_int(bang_st)
|
1279
|
-
mm_bang *bang_st;
|
1204
|
+
static VALUE mm_gsub_bang_int(bang_st) mm_bang *bang_st;
|
1280
1205
|
{
|
1281
1206
|
int argc = bang_st->argc;
|
1282
1207
|
VALUE *argv = bang_st->argv;
|
@@ -1290,14 +1215,12 @@ mm_gsub_bang_int(bang_st)
|
|
1290
1215
|
mm_ipc *i_mm;
|
1291
1216
|
|
1292
1217
|
if (argc == 1 && rb_block_given_p()) {
|
1293
|
-
|
1294
|
-
}
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
else {
|
1300
|
-
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
|
1218
|
+
iter = 1;
|
1219
|
+
} else if (argc == 2) {
|
1220
|
+
repl = rb_str_to_str(argv[1]);
|
1221
|
+
if (OBJ_TAINTED(repl)) tainted = 1;
|
1222
|
+
} else {
|
1223
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
|
1301
1224
|
}
|
1302
1225
|
GetMmap(obj, i_mm, MM_MODIFY);
|
1303
1226
|
str = mm_str(obj, MM_MODIFY | MM_ORIGIN);
|
@@ -1306,49 +1229,51 @@ mm_gsub_bang_int(bang_st)
|
|
1306
1229
|
offset = 0;
|
1307
1230
|
beg = rb_reg_search(pat, str, 0, 0);
|
1308
1231
|
if (beg < 0) {
|
1309
|
-
|
1310
|
-
|
1232
|
+
rb_gc_force_recycle(str);
|
1233
|
+
return Qnil;
|
1311
1234
|
}
|
1312
1235
|
while (beg >= 0) {
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1236
|
+
start = mm_correct_backref();
|
1237
|
+
match = rb_backref_get();
|
1238
|
+
regs = &RMATCH(match)->rmatch->regs;
|
1239
|
+
if (iter) {
|
1240
|
+
rb_match_busy(match);
|
1241
|
+
val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
|
1242
|
+
rb_backref_set(match);
|
1243
|
+
} else {
|
1244
|
+
RSTRING(str)->as.heap.ptr += start;
|
1245
|
+
val = rb_reg_regsub(repl, str, regs, match);
|
1246
|
+
RSTRING(str)->as.heap.ptr -= start;
|
1247
|
+
}
|
1248
|
+
if (OBJ_TAINTED(repl)) tainted = 1;
|
1249
|
+
plen = RMATCH(match)->END(0) - RMATCH(match)->BEG(0);
|
1250
|
+
if ((i_mm->t->real + RSTRING_LEN(val) - plen) > i_mm->t->len) {
|
1251
|
+
mm_realloc(i_mm, RSTRING_LEN(str) + RSTRING_LEN(val) - plen);
|
1252
|
+
}
|
1253
|
+
if (RSTRING_LEN(val) != plen) {
|
1254
|
+
if (i_mm->t->flag & MM_FIXED) {
|
1255
|
+
rb_raise(rb_eTypeError,
|
1256
|
+
"try to change the size of a fixed map");
|
1257
|
+
}
|
1258
|
+
memmove(RSTRING_PTR(str) + start + RMATCH(match)->BEG(0) +
|
1259
|
+
RSTRING_LEN(val),
|
1260
|
+
RSTRING_PTR(str) + start + RMATCH(match)->BEG(0) + plen,
|
1261
|
+
RSTRING_LEN(str) - start - RMATCH(match)->BEG(0) - plen);
|
1262
|
+
}
|
1263
|
+
memcpy(RSTRING_PTR(str) + start + RMATCH(match)->BEG(0),
|
1264
|
+
RSTRING_PTR(val), RSTRING_LEN(val));
|
1265
|
+
RSTRING(str)->as.heap.len += RSTRING_LEN(val) - plen;
|
1266
|
+
i_mm->t->real = RSTRING_LEN(str);
|
1267
|
+
if (RMATCH(match)->BEG(0) == RMATCH(match)->END(0)) {
|
1268
|
+
offset = start + RMATCH(match)->END(0) +
|
1269
|
+
0; // TODO: fix mm_gsub_bang_int //
|
1270
|
+
// mbclen2(RSTRING_PTR(str)[RMATCH(match)->END(0)], pat);
|
1271
|
+
offset += RSTRING_LEN(val) - plen;
|
1272
|
+
} else {
|
1273
|
+
offset = start + RMATCH(match)->END(0) + RSTRING_LEN(val) - plen;
|
1274
|
+
}
|
1275
|
+
if (offset > RSTRING_LEN(str)) break;
|
1276
|
+
beg = rb_reg_search(pat, str, offset, 0);
|
1352
1277
|
}
|
1353
1278
|
rb_backref_set(match);
|
1354
1279
|
if (tainted) OBJ_TAINT(obj);
|
@@ -1363,11 +1288,9 @@ mm_gsub_bang_int(bang_st)
|
|
1363
1288
|
*
|
1364
1289
|
* global substitution
|
1365
1290
|
*/
|
1366
|
-
static VALUE
|
1367
|
-
|
1368
|
-
|
1369
|
-
VALUE *argv;
|
1370
|
-
VALUE obj;
|
1291
|
+
static VALUE mm_gsub_bang(argc, argv, obj) int argc;
|
1292
|
+
VALUE *argv;
|
1293
|
+
VALUE obj;
|
1371
1294
|
{
|
1372
1295
|
VALUE res;
|
1373
1296
|
mm_bang bang_st;
|
@@ -1378,11 +1301,10 @@ mm_gsub_bang(argc, argv, obj)
|
|
1378
1301
|
bang_st.obj = obj;
|
1379
1302
|
GetMmap(obj, i_mm, MM_MODIFY);
|
1380
1303
|
if (i_mm->t->flag & MM_IPC) {
|
1381
|
-
|
1382
|
-
|
1383
|
-
}
|
1384
|
-
|
1385
|
-
res = mm_gsub_bang_int(&bang_st);
|
1304
|
+
mm_lock(i_mm, Qtrue);
|
1305
|
+
res = rb_ensure(mm_gsub_bang_int, (VALUE)&bang_st, mm_vunlock, obj);
|
1306
|
+
} else {
|
1307
|
+
res = mm_gsub_bang_int(&bang_st);
|
1386
1308
|
}
|
1387
1309
|
return res;
|
1388
1310
|
}
|
@@ -1391,28 +1313,26 @@ static VALUE mm_index __((int, VALUE *, VALUE));
|
|
1391
1313
|
|
1392
1314
|
#if HAVE_RB_DEFINE_ALLOC_FUNC
|
1393
1315
|
|
1394
|
-
static void
|
1395
|
-
|
1396
|
-
|
1397
|
-
int offset;
|
1398
|
-
VALUE val;
|
1316
|
+
static void mm_subpat_set(obj, re, offset, val) VALUE obj, re;
|
1317
|
+
int offset;
|
1318
|
+
VALUE val;
|
1399
1319
|
{
|
1400
1320
|
VALUE str, match;
|
1401
1321
|
int start, end, len;
|
1402
1322
|
mm_ipc *i_mm;
|
1403
|
-
|
1323
|
+
|
1404
1324
|
str = mm_str(obj, MM_MODIFY | MM_ORIGIN);
|
1405
1325
|
if (rb_reg_search(re, str, 0, 0) < 0) {
|
1406
|
-
|
1326
|
+
rb_raise(rb_eIndexError, "regexp not matched");
|
1407
1327
|
}
|
1408
1328
|
match = rb_backref_get();
|
1409
1329
|
if (offset >= RMATCH(match)->rmatch->regs.num_regs) {
|
1410
|
-
|
1330
|
+
rb_raise(rb_eIndexError, "index %d out of regexp", offset);
|
1411
1331
|
}
|
1412
1332
|
|
1413
1333
|
start = RMATCH(match)->BEG(offset);
|
1414
1334
|
if (start == -1) {
|
1415
|
-
|
1335
|
+
rb_raise(rb_eIndexError, "regexp group %d not matched", offset);
|
1416
1336
|
}
|
1417
1337
|
end = RMATCH(match)->END(offset);
|
1418
1338
|
len = end - start;
|
@@ -1422,72 +1342,68 @@ mm_subpat_set(obj, re, offset, val)
|
|
1422
1342
|
|
1423
1343
|
#endif
|
1424
1344
|
|
1425
|
-
static VALUE
|
1426
|
-
|
1427
|
-
VALUE str;
|
1428
|
-
VALUE indx, val;
|
1345
|
+
static VALUE mm_aset(str, indx, val) VALUE str;
|
1346
|
+
VALUE indx, val;
|
1429
1347
|
{
|
1430
1348
|
long idx;
|
1431
1349
|
mm_ipc *i_mm;
|
1432
1350
|
|
1433
1351
|
GetMmap(str, i_mm, MM_MODIFY);
|
1434
1352
|
switch (TYPE(indx)) {
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
case T_REGEXP:
|
1353
|
+
case T_FIXNUM:
|
1354
|
+
num_index:
|
1355
|
+
idx = NUM2INT(indx);
|
1356
|
+
if (idx < 0) {
|
1357
|
+
idx += i_mm->t->real;
|
1358
|
+
}
|
1359
|
+
if (idx < 0 || i_mm->t->real <= (size_t)idx) {
|
1360
|
+
rb_raise(rb_eIndexError, "index %ld out of string", idx);
|
1361
|
+
}
|
1362
|
+
if (FIXNUM_P(val)) {
|
1363
|
+
if (i_mm->t->real == (size_t)idx) {
|
1364
|
+
i_mm->t->real += 1;
|
1365
|
+
mm_realloc(i_mm, i_mm->t->real);
|
1366
|
+
}
|
1367
|
+
((char *)i_mm->t->addr)[idx] = NUM2INT(val) & 0xff;
|
1368
|
+
} else {
|
1369
|
+
mm_update(i_mm, idx, 1, val);
|
1370
|
+
}
|
1371
|
+
return val;
|
1372
|
+
|
1373
|
+
case T_REGEXP:
|
1457
1374
|
#if HAVE_RB_DEFINE_ALLOC_FUNC
|
1458
|
-
|
1459
|
-
#else
|
1375
|
+
mm_subpat_set(str, indx, 0, val);
|
1376
|
+
#else
|
1460
1377
|
{
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1378
|
+
VALUE args[2];
|
1379
|
+
args[0] = indx;
|
1380
|
+
args[1] = val;
|
1381
|
+
mm_sub_bang(2, args, str);
|
1382
|
+
}
|
1466
1383
|
#endif
|
1467
|
-
|
1384
|
+
return val;
|
1468
1385
|
|
1469
|
-
|
1470
|
-
|
1471
|
-
VALUE res;
|
1386
|
+
case T_STRING: {
|
1387
|
+
VALUE res;
|
1472
1388
|
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1389
|
+
res = mm_index(1, &indx, str);
|
1390
|
+
if (!NIL_P(res)) {
|
1391
|
+
mm_update(i_mm, NUM2LONG(res), RSTRING_LEN(indx), val);
|
1392
|
+
}
|
1393
|
+
return val;
|
1394
|
+
}
|
1479
1395
|
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1396
|
+
default:
|
1397
|
+
/* check if indx is Range */
|
1398
|
+
{
|
1399
|
+
long beg, len;
|
1400
|
+
if (rb_range_beg_len(indx, &beg, &len, i_mm->t->real, 2)) {
|
1401
|
+
mm_update(i_mm, beg, len, val);
|
1402
|
+
return val;
|
1403
|
+
}
|
1404
|
+
}
|
1405
|
+
idx = NUM2LONG(indx);
|
1406
|
+
goto num_index;
|
1491
1407
|
}
|
1492
1408
|
}
|
1493
1409
|
|
@@ -1505,37 +1421,34 @@ mm_aset(str, indx, val)
|
|
1505
1421
|
* change substring from <em>start</em> to <em>last</em> with <em>val</em>
|
1506
1422
|
*
|
1507
1423
|
* self[start, len] = val
|
1508
|
-
*
|
1424
|
+
*
|
1509
1425
|
* replace <em>length</em> characters from <em>start</em> with <em>val</em>.
|
1510
|
-
*
|
1426
|
+
*
|
1511
1427
|
*/
|
1512
|
-
static VALUE
|
1513
|
-
|
1514
|
-
|
1515
|
-
VALUE *argv;
|
1516
|
-
VALUE str;
|
1428
|
+
static VALUE mm_aset_m(argc, argv, str) int argc;
|
1429
|
+
VALUE *argv;
|
1430
|
+
VALUE str;
|
1517
1431
|
{
|
1518
1432
|
mm_ipc *i_mm;
|
1519
1433
|
|
1520
1434
|
GetMmap(str, i_mm, MM_MODIFY);
|
1521
1435
|
if (argc == 3) {
|
1522
|
-
|
1436
|
+
long beg, len;
|
1523
1437
|
|
1524
1438
|
#if HAVE_RB_DEFINE_ALLOC_FUNC
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
else
|
1439
|
+
if (TYPE(argv[0]) == T_REGEXP) {
|
1440
|
+
mm_subpat_set(str, argv[0], NUM2INT(argv[1]), argv[2]);
|
1441
|
+
} else
|
1529
1442
|
#endif
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1443
|
+
{
|
1444
|
+
beg = NUM2INT(argv[0]);
|
1445
|
+
len = NUM2INT(argv[1]);
|
1446
|
+
mm_update(i_mm, beg, len, argv[2]);
|
1447
|
+
}
|
1448
|
+
return argv[2];
|
1536
1449
|
}
|
1537
1450
|
if (argc != 2) {
|
1538
|
-
|
1451
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc);
|
1539
1452
|
}
|
1540
1453
|
return mm_aset(str, argv[0], argv[1]);
|
1541
1454
|
}
|
@@ -1547,19 +1460,16 @@ mm_aset_m(argc, argv, str)
|
|
1547
1460
|
*
|
1548
1461
|
* insert <em>str</em> at <em>index</em>
|
1549
1462
|
*/
|
1550
|
-
static VALUE
|
1551
|
-
mm_insert(str, idx, str2)
|
1552
|
-
VALUE str, idx, str2;
|
1463
|
+
static VALUE mm_insert(str, idx, str2) VALUE str, idx, str2;
|
1553
1464
|
{
|
1554
1465
|
mm_ipc *i_mm;
|
1555
1466
|
long pos = NUM2LONG(idx);
|
1556
1467
|
|
1557
1468
|
GetMmap(str, i_mm, MM_MODIFY);
|
1558
1469
|
if (pos == -1) {
|
1559
|
-
|
1560
|
-
}
|
1561
|
-
|
1562
|
-
pos++;
|
1470
|
+
pos = RSTRING_LEN(str);
|
1471
|
+
} else if (pos < 0) {
|
1472
|
+
pos++;
|
1563
1473
|
}
|
1564
1474
|
mm_update(i_mm, pos, 0, str2);
|
1565
1475
|
return str;
|
@@ -1574,64 +1484,57 @@ static VALUE mm_aref_m _((int, VALUE *, VALUE));
|
|
1574
1484
|
*
|
1575
1485
|
* delete the specified portion of the file
|
1576
1486
|
*/
|
1577
|
-
static VALUE
|
1578
|
-
|
1579
|
-
|
1580
|
-
VALUE *argv;
|
1581
|
-
VALUE str;
|
1487
|
+
static VALUE mm_slice_bang(argc, argv, str) int argc;
|
1488
|
+
VALUE *argv;
|
1489
|
+
VALUE str;
|
1582
1490
|
{
|
1583
1491
|
VALUE result;
|
1584
1492
|
VALUE buf[3];
|
1585
1493
|
int i;
|
1586
1494
|
|
1587
1495
|
if (argc < 1 || 2 < argc) {
|
1588
|
-
|
1496
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)", argc);
|
1589
1497
|
}
|
1590
1498
|
for (i = 0; i < argc; i++) {
|
1591
|
-
|
1499
|
+
buf[i] = argv[i];
|
1592
1500
|
}
|
1593
|
-
buf[i] = rb_str_new(0,0);
|
1501
|
+
buf[i] = rb_str_new(0, 0);
|
1594
1502
|
result = mm_aref_m(argc, buf, str);
|
1595
1503
|
if (!NIL_P(result)) {
|
1596
|
-
|
1504
|
+
mm_aset_m(argc + 1, buf, str);
|
1597
1505
|
}
|
1598
1506
|
return result;
|
1599
1507
|
}
|
1600
1508
|
|
1601
|
-
static VALUE
|
1602
|
-
|
1603
|
-
|
1604
|
-
const char *ptr;
|
1605
|
-
long len;
|
1509
|
+
static VALUE mm_cat(str, ptr, len) VALUE str;
|
1510
|
+
const char *ptr;
|
1511
|
+
long len;
|
1606
1512
|
{
|
1607
1513
|
mm_ipc *i_mm;
|
1608
1514
|
char *sptr;
|
1609
1515
|
|
1610
1516
|
GetMmap(str, i_mm, MM_MODIFY);
|
1611
1517
|
if (len > 0) {
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
mm_unlock(i_mm);
|
1518
|
+
int poffset = -1;
|
1519
|
+
sptr = (char *)i_mm->t->addr;
|
1520
|
+
|
1521
|
+
if (sptr <= ptr && ptr < sptr + i_mm->t->real) {
|
1522
|
+
poffset = ptr - sptr;
|
1523
|
+
}
|
1524
|
+
mm_lock(i_mm, Qtrue);
|
1525
|
+
mm_realloc(i_mm, i_mm->t->real + len);
|
1526
|
+
sptr = (char *)i_mm->t->addr;
|
1527
|
+
if (ptr) {
|
1528
|
+
if (poffset >= 0) ptr = sptr + poffset;
|
1529
|
+
memcpy(sptr + i_mm->t->real, ptr, len);
|
1530
|
+
}
|
1531
|
+
i_mm->t->real += len;
|
1532
|
+
mm_unlock(i_mm);
|
1628
1533
|
}
|
1629
1534
|
return str;
|
1630
1535
|
}
|
1631
1536
|
|
1632
|
-
static VALUE
|
1633
|
-
mm_append(str1, str2)
|
1634
|
-
VALUE str1, str2;
|
1537
|
+
static VALUE mm_append(str1, str2) VALUE str1, str2;
|
1635
1538
|
{
|
1636
1539
|
str2 = rb_str_to_str(str2);
|
1637
1540
|
str1 = mm_cat(str1, StringValuePtr(str2), RSTRING_LEN(str2));
|
@@ -1646,16 +1549,14 @@ mm_append(str1, str2)
|
|
1646
1549
|
*
|
1647
1550
|
* append the contents of <em>other</em>
|
1648
1551
|
*/
|
1649
|
-
static VALUE
|
1650
|
-
mm_concat(str1, str2)
|
1651
|
-
VALUE str1, str2;
|
1552
|
+
static VALUE mm_concat(str1, str2) VALUE str1, str2;
|
1652
1553
|
{
|
1653
1554
|
if (FIXNUM_P(str2)) {
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1555
|
+
int i = FIX2INT(str2);
|
1556
|
+
if (0 <= i && i <= 0xff) { /* byte */
|
1557
|
+
char c = i;
|
1558
|
+
return mm_cat(str1, &c, 1);
|
1559
|
+
}
|
1659
1560
|
}
|
1660
1561
|
str1 = mm_append(str1, str2);
|
1661
1562
|
return str1;
|
@@ -1668,9 +1569,7 @@ mm_concat(str1, str2)
|
|
1668
1569
|
*
|
1669
1570
|
* removes leading and trailing whitespace
|
1670
1571
|
*/
|
1671
|
-
static VALUE
|
1672
|
-
mm_strip_bang(str)
|
1673
|
-
VALUE str;
|
1572
|
+
static VALUE mm_strip_bang(str) VALUE str;
|
1674
1573
|
{
|
1675
1574
|
char *s, *t, *e;
|
1676
1575
|
mm_ipc *i_mm;
|
@@ -1685,18 +1584,16 @@ mm_strip_bang(str)
|
|
1685
1584
|
t++;
|
1686
1585
|
|
1687
1586
|
if (i_mm->t->real != (t - s) && (i_mm->t->flag & MM_FIXED)) {
|
1688
|
-
|
1587
|
+
mm_unlock(i_mm);
|
1689
1588
|
rb_raise(rb_eTypeError, "try to change the size of a fixed map");
|
1690
1589
|
}
|
1691
|
-
i_mm->t->real = t-s;
|
1692
|
-
if (s > (char *)i_mm->t->addr) {
|
1590
|
+
i_mm->t->real = t - s;
|
1591
|
+
if (s > (char *)i_mm->t->addr) {
|
1693
1592
|
memmove(i_mm->t->addr, s, i_mm->t->real);
|
1694
1593
|
((char *)i_mm->t->addr)[i_mm->t->real] = '\0';
|
1695
|
-
}
|
1696
|
-
else if (t < e) {
|
1594
|
+
} else if (t < e) {
|
1697
1595
|
((char *)i_mm->t->addr)[i_mm->t->real] = '\0';
|
1698
|
-
}
|
1699
|
-
else {
|
1596
|
+
} else {
|
1700
1597
|
str = Qnil;
|
1701
1598
|
}
|
1702
1599
|
mm_unlock(i_mm);
|
@@ -1710,9 +1607,7 @@ mm_strip_bang(str)
|
|
1710
1607
|
*
|
1711
1608
|
* removes leading whitespace
|
1712
1609
|
*/
|
1713
|
-
static VALUE
|
1714
|
-
mm_lstrip_bang(str)
|
1715
|
-
VALUE str;
|
1610
|
+
static VALUE mm_lstrip_bang(str) VALUE str;
|
1716
1611
|
{
|
1717
1612
|
char *s, *t, *e;
|
1718
1613
|
mm_ipc *i_mm;
|
@@ -1724,15 +1619,15 @@ mm_lstrip_bang(str)
|
|
1724
1619
|
while (s < t && ISSPACE(*s)) s++;
|
1725
1620
|
|
1726
1621
|
if (i_mm->t->real != (size_t)(t - s) && (i_mm->t->flag & MM_FIXED)) {
|
1727
|
-
|
1728
|
-
|
1622
|
+
mm_unlock(i_mm);
|
1623
|
+
rb_raise(rb_eTypeError, "try to change the size of a fixed map");
|
1729
1624
|
}
|
1730
1625
|
i_mm->t->real = t - s;
|
1731
|
-
if (s > (char *)i_mm->t->addr) {
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1626
|
+
if (s > (char *)i_mm->t->addr) {
|
1627
|
+
memmove(i_mm->t->addr, s, i_mm->t->real);
|
1628
|
+
((char *)i_mm->t->addr)[i_mm->t->real] = '\0';
|
1629
|
+
mm_unlock(i_mm);
|
1630
|
+
return str;
|
1736
1631
|
}
|
1737
1632
|
mm_unlock(i_mm);
|
1738
1633
|
return Qnil;
|
@@ -1743,9 +1638,7 @@ mm_lstrip_bang(str)
|
|
1743
1638
|
*
|
1744
1639
|
* removes trailing whitespace
|
1745
1640
|
*/
|
1746
|
-
static VALUE
|
1747
|
-
mm_rstrip_bang(str)
|
1748
|
-
VALUE str;
|
1641
|
+
static VALUE mm_rstrip_bang(str) VALUE str;
|
1749
1642
|
{
|
1750
1643
|
char *s, *t, *e;
|
1751
1644
|
mm_ipc *i_mm;
|
@@ -1758,22 +1651,20 @@ mm_rstrip_bang(str)
|
|
1758
1651
|
while (s <= t && ISSPACE(*t)) t--;
|
1759
1652
|
t++;
|
1760
1653
|
if (i_mm->t->real != (size_t)(t - s) && (i_mm->t->flag & MM_FIXED)) {
|
1761
|
-
|
1762
|
-
|
1654
|
+
mm_unlock(i_mm);
|
1655
|
+
rb_raise(rb_eTypeError, "try to change the size of a fixed map");
|
1763
1656
|
}
|
1764
1657
|
i_mm->t->real = t - s;
|
1765
1658
|
if (t < e) {
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1659
|
+
((char *)i_mm->t->addr)[i_mm->t->real] = '\0';
|
1660
|
+
mm_unlock(i_mm);
|
1661
|
+
return str;
|
1769
1662
|
}
|
1770
1663
|
mm_unlock(i_mm);
|
1771
1664
|
return Qnil;
|
1772
1665
|
}
|
1773
1666
|
|
1774
|
-
static VALUE
|
1775
|
-
mm_strip_bang(str)
|
1776
|
-
VALUE str;
|
1667
|
+
static VALUE mm_strip_bang(str) VALUE str;
|
1777
1668
|
{
|
1778
1669
|
VALUE l = mm_lstrip_bang(str);
|
1779
1670
|
VALUE r = mm_rstrip_bang(str);
|
@@ -1784,27 +1675,23 @@ mm_strip_bang(str)
|
|
1784
1675
|
|
1785
1676
|
#endif
|
1786
1677
|
|
1787
|
-
#define MmapStr(b, recycle)
|
1788
|
-
do {
|
1789
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
}
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1678
|
+
#define MmapStr(b, recycle) \
|
1679
|
+
do { \
|
1680
|
+
recycle = 0; \
|
1681
|
+
if (TYPE(b) == T_DATA && RDATA(b)->dfree == (RUBY_DATA_FUNC)mm_free) { \
|
1682
|
+
recycle = 1; \
|
1683
|
+
b = mm_str(b, MM_ORIGIN); \
|
1684
|
+
} else { \
|
1685
|
+
b = rb_str_to_str(b); \
|
1686
|
+
} \
|
1687
|
+
} while (0);
|
1688
|
+
|
1800
1689
|
/*
|
1801
1690
|
* call-seq: <=>(other)
|
1802
1691
|
*
|
1803
1692
|
* comparison : return -1, 0, 1
|
1804
1693
|
*/
|
1805
|
-
static VALUE
|
1806
|
-
mm_cmp(a, b)
|
1807
|
-
VALUE a, b;
|
1694
|
+
static VALUE mm_cmp(a, b) VALUE a, b;
|
1808
1695
|
{
|
1809
1696
|
int result;
|
1810
1697
|
int recycle = 0;
|
@@ -1824,9 +1711,7 @@ mm_cmp(a, b)
|
|
1824
1711
|
*
|
1825
1712
|
* only with ruby >= 1.7.1
|
1826
1713
|
*/
|
1827
|
-
static VALUE
|
1828
|
-
mm_casecmp(a, b)
|
1829
|
-
VALUE a, b;
|
1714
|
+
static VALUE mm_casecmp(a, b) VALUE a, b;
|
1830
1715
|
{
|
1831
1716
|
VALUE result;
|
1832
1717
|
int recycle = 0;
|
@@ -1849,21 +1734,18 @@ mm_casecmp(a, b)
|
|
1849
1734
|
*
|
1850
1735
|
* comparison
|
1851
1736
|
*/
|
1852
|
-
static VALUE
|
1853
|
-
mm_equal(a, b)
|
1854
|
-
VALUE a, b;
|
1737
|
+
static VALUE mm_equal(a, b) VALUE a, b;
|
1855
1738
|
{
|
1856
1739
|
VALUE result;
|
1857
1740
|
mm_ipc *i_mm, *u_mm;
|
1858
1741
|
|
1859
1742
|
if (a == b) return Qtrue;
|
1860
1743
|
if (TYPE(b) != T_DATA || RDATA(b)->dfree != (RUBY_DATA_FUNC)mm_free)
|
1861
|
-
|
1744
|
+
return Qfalse;
|
1862
1745
|
|
1863
1746
|
GetMmap(a, i_mm, 0);
|
1864
1747
|
GetMmap(b, u_mm, 0);
|
1865
|
-
if (i_mm->t->real != u_mm->t->real)
|
1866
|
-
return Qfalse;
|
1748
|
+
if (i_mm->t->real != u_mm->t->real) return Qfalse;
|
1867
1749
|
a = mm_str(a, MM_ORIGIN);
|
1868
1750
|
b = mm_str(b, MM_ORIGIN);
|
1869
1751
|
result = rb_funcall2(a, rb_intern("=="), 1, &b);
|
@@ -1877,21 +1759,18 @@ mm_equal(a, b)
|
|
1877
1759
|
*
|
1878
1760
|
* Is this eql? to +other+ ?
|
1879
1761
|
*/
|
1880
|
-
static VALUE
|
1881
|
-
mm_eql(a, b)
|
1882
|
-
VALUE a, b;
|
1762
|
+
static VALUE mm_eql(a, b) VALUE a, b;
|
1883
1763
|
{
|
1884
1764
|
VALUE result;
|
1885
1765
|
mm_ipc *i_mm, *u_mm;
|
1886
|
-
|
1766
|
+
|
1887
1767
|
if (a == b) return Qtrue;
|
1888
1768
|
if (TYPE(b) != T_DATA || RDATA(b)->dfree != (RUBY_DATA_FUNC)mm_free)
|
1889
|
-
|
1769
|
+
return Qfalse;
|
1890
1770
|
|
1891
1771
|
GetMmap(a, i_mm, 0);
|
1892
1772
|
GetMmap(b, u_mm, 0);
|
1893
|
-
if (i_mm->t->real != u_mm->t->real)
|
1894
|
-
return Qfalse;
|
1773
|
+
if (i_mm->t->real != u_mm->t->real) return Qfalse;
|
1895
1774
|
a = mm_str(a, MM_ORIGIN);
|
1896
1775
|
b = mm_str(b, MM_ORIGIN);
|
1897
1776
|
result = rb_funcall2(a, rb_intern("eql?"), 1, &b);
|
@@ -1905,9 +1784,7 @@ mm_eql(a, b)
|
|
1905
1784
|
*
|
1906
1785
|
* Get the hash value
|
1907
1786
|
*/
|
1908
|
-
static VALUE
|
1909
|
-
mm_hash(a)
|
1910
|
-
VALUE a;
|
1787
|
+
static VALUE mm_hash(a) VALUE a;
|
1911
1788
|
{
|
1912
1789
|
VALUE b;
|
1913
1790
|
int res;
|
@@ -1924,9 +1801,7 @@ mm_hash(a)
|
|
1924
1801
|
*
|
1925
1802
|
* return the size of the file
|
1926
1803
|
*/
|
1927
|
-
static VALUE
|
1928
|
-
mm_size(a)
|
1929
|
-
VALUE a;
|
1804
|
+
static VALUE mm_size(a) VALUE a;
|
1930
1805
|
{
|
1931
1806
|
mm_ipc *i_mm;
|
1932
1807
|
|
@@ -1939,9 +1814,7 @@ mm_size(a)
|
|
1939
1814
|
*
|
1940
1815
|
* return <em>true</em> if the file is empty
|
1941
1816
|
*/
|
1942
|
-
static VALUE
|
1943
|
-
mm_empty(a)
|
1944
|
-
VALUE a;
|
1817
|
+
static VALUE mm_empty(a) VALUE a;
|
1945
1818
|
{
|
1946
1819
|
mm_ipc *i_mm;
|
1947
1820
|
|
@@ -1950,59 +1823,47 @@ mm_empty(a)
|
|
1950
1823
|
return Qfalse;
|
1951
1824
|
}
|
1952
1825
|
|
1953
|
-
static VALUE
|
1954
|
-
|
1955
|
-
VALUE *t;
|
1956
|
-
{
|
1957
|
-
return rb_funcall2(t[0], (ID)t[1], (int)t[2], (VALUE *)t[3]);
|
1958
|
-
}
|
1826
|
+
static VALUE mm_protect_bang(t) VALUE *t;
|
1827
|
+
{ return rb_funcall2(t[0], (ID)t[1], (int)t[2], (VALUE *)t[3]); }
|
1959
1828
|
|
1960
|
-
static VALUE
|
1961
|
-
mm_recycle(str)
|
1962
|
-
VALUE str;
|
1829
|
+
static VALUE mm_recycle(str) VALUE str;
|
1963
1830
|
{
|
1964
1831
|
rb_gc_force_recycle(str);
|
1965
1832
|
return str;
|
1966
1833
|
}
|
1967
1834
|
|
1968
|
-
static VALUE
|
1969
|
-
mm_i_bang(bang_st)
|
1970
|
-
mm_bang *bang_st;
|
1835
|
+
static VALUE mm_i_bang(bang_st) mm_bang *bang_st;
|
1971
1836
|
{
|
1972
1837
|
VALUE str, res;
|
1973
1838
|
mm_ipc *i_mm;
|
1974
|
-
|
1839
|
+
|
1975
1840
|
str = mm_str(bang_st->obj, bang_st->flag);
|
1976
1841
|
if (bang_st->flag & MM_PROTECT) {
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
}
|
1984
|
-
|
1985
|
-
|
1986
|
-
RB_GC_GUARD(res);
|
1842
|
+
VALUE tmp[4];
|
1843
|
+
tmp[0] = str;
|
1844
|
+
tmp[1] = (VALUE)bang_st->id;
|
1845
|
+
tmp[2] = (VALUE)bang_st->argc;
|
1846
|
+
tmp[3] = (VALUE)bang_st->argv;
|
1847
|
+
res = rb_ensure(mm_protect_bang, (VALUE)tmp, mm_recycle, str);
|
1848
|
+
} else {
|
1849
|
+
res = rb_funcall2(str, bang_st->id, bang_st->argc, bang_st->argv);
|
1850
|
+
RB_GC_GUARD(res);
|
1987
1851
|
}
|
1988
1852
|
if (res != Qnil) {
|
1989
|
-
|
1990
|
-
|
1853
|
+
GetMmap(bang_st->obj, i_mm, 0);
|
1854
|
+
i_mm->t->real = RSTRING_LEN(str);
|
1991
1855
|
}
|
1992
1856
|
return res;
|
1993
1857
|
}
|
1994
1858
|
|
1995
|
-
|
1996
|
-
static VALUE
|
1997
|
-
mm_bang_i(VALUE obj, int flag, ID id, int argc, VALUE *argv)
|
1998
|
-
{
|
1859
|
+
static VALUE mm_bang_i(VALUE obj, int flag, ID id, int argc, VALUE *argv) {
|
1999
1860
|
VALUE res;
|
2000
1861
|
mm_ipc *i_mm;
|
2001
1862
|
mm_bang bang_st;
|
2002
1863
|
|
2003
1864
|
GetMmap(obj, i_mm, 0);
|
2004
1865
|
if ((flag & MM_CHANGE) && (i_mm->t->flag & MM_FIXED)) {
|
2005
|
-
|
1866
|
+
rb_raise(rb_eTypeError, "try to change the size of a fixed map");
|
2006
1867
|
}
|
2007
1868
|
bang_st.obj = obj;
|
2008
1869
|
bang_st.flag = flag;
|
@@ -2010,15 +1871,13 @@ mm_bang_i(VALUE obj, int flag, ID id, int argc, VALUE *argv)
|
|
2010
1871
|
bang_st.argc = argc;
|
2011
1872
|
bang_st.argv = argv;
|
2012
1873
|
if (i_mm->t->flag & MM_IPC) {
|
2013
|
-
|
2014
|
-
|
2015
|
-
}
|
2016
|
-
|
2017
|
-
res = mm_i_bang(&bang_st);
|
1874
|
+
mm_lock(i_mm, Qtrue);
|
1875
|
+
res = rb_ensure(mm_i_bang, (VALUE)&bang_st, mm_vunlock, obj);
|
1876
|
+
} else {
|
1877
|
+
res = mm_i_bang(&bang_st);
|
2018
1878
|
}
|
2019
1879
|
if (res == Qnil) return res;
|
2020
|
-
return (flag & MM_ORIGIN)?res:obj;
|
2021
|
-
|
1880
|
+
return (flag & MM_ORIGIN) ? res : obj;
|
2022
1881
|
}
|
2023
1882
|
|
2024
1883
|
#if HAVE_RB_STR_MATCH
|
@@ -2029,12 +1888,8 @@ mm_bang_i(VALUE obj, int flag, ID id, int argc, VALUE *argv)
|
|
2029
1888
|
* convert <em>pattern</em> to a <em>Regexp</em> and then call
|
2030
1889
|
* <em>match</em> on <em>self</em>
|
2031
1890
|
*/
|
2032
|
-
static VALUE
|
2033
|
-
|
2034
|
-
VALUE a, b;
|
2035
|
-
{
|
2036
|
-
return mm_bang_i(a, MM_ORIGIN, rb_intern("match"), 1, &b);
|
2037
|
-
}
|
1891
|
+
static VALUE mm_match_m(a, b) VALUE a, b;
|
1892
|
+
{ return mm_bang_i(a, MM_ORIGIN, rb_intern("match"), 1, &b); }
|
2038
1893
|
|
2039
1894
|
#endif
|
2040
1895
|
|
@@ -2043,84 +1898,59 @@ mm_match_m(a, b)
|
|
2043
1898
|
*
|
2044
1899
|
* replaces all lowercase characters to downcase characters
|
2045
1900
|
*/
|
2046
|
-
static VALUE
|
2047
|
-
|
2048
|
-
VALUE a;
|
2049
|
-
{
|
2050
|
-
return mm_bang_i(a, MM_MODIFY, rb_intern("upcase!"), 0, 0);
|
2051
|
-
}
|
1901
|
+
static VALUE mm_upcase_bang(a) VALUE a;
|
1902
|
+
{ return mm_bang_i(a, MM_MODIFY, rb_intern("upcase!"), 0, 0); }
|
2052
1903
|
|
2053
1904
|
/*
|
2054
1905
|
* call-seq: downcase!
|
2055
1906
|
*
|
2056
1907
|
* change all uppercase character to lowercase character
|
2057
1908
|
*/
|
2058
|
-
static VALUE
|
2059
|
-
|
2060
|
-
VALUE a;
|
2061
|
-
{
|
2062
|
-
return mm_bang_i(a, MM_MODIFY, rb_intern("downcase!"), 0, 0);
|
2063
|
-
}
|
1909
|
+
static VALUE mm_downcase_bang(a) VALUE a;
|
1910
|
+
{ return mm_bang_i(a, MM_MODIFY, rb_intern("downcase!"), 0, 0); }
|
2064
1911
|
|
2065
1912
|
/*
|
2066
1913
|
* call-seq: capitalize!
|
2067
1914
|
*
|
2068
1915
|
* change the first character to uppercase letter
|
2069
1916
|
*/
|
2070
|
-
static VALUE
|
2071
|
-
|
2072
|
-
VALUE a;
|
2073
|
-
{
|
2074
|
-
return mm_bang_i(a, MM_MODIFY, rb_intern("capitalize!"), 0, 0);
|
2075
|
-
}
|
1917
|
+
static VALUE mm_capitalize_bang(a) VALUE a;
|
1918
|
+
{ return mm_bang_i(a, MM_MODIFY, rb_intern("capitalize!"), 0, 0); }
|
2076
1919
|
|
2077
1920
|
/*
|
2078
1921
|
* call-seq: swapcase!
|
2079
1922
|
*
|
2080
1923
|
* replaces all lowercase characters to uppercase characters, and vice-versa
|
2081
1924
|
*/
|
2082
|
-
static VALUE
|
2083
|
-
|
2084
|
-
|
2085
|
-
{
|
2086
|
-
return mm_bang_i(a, MM_MODIFY, rb_intern("swapcase!"), 0, 0);
|
2087
|
-
}
|
2088
|
-
|
1925
|
+
static VALUE mm_swapcase_bang(a) VALUE a;
|
1926
|
+
{ return mm_bang_i(a, MM_MODIFY, rb_intern("swapcase!"), 0, 0); }
|
1927
|
+
|
2089
1928
|
/*
|
2090
1929
|
* call-seq: reverse!
|
2091
1930
|
*
|
2092
|
-
* reverse the content of the file
|
1931
|
+
* reverse the content of the file
|
2093
1932
|
*/
|
2094
|
-
static VALUE
|
2095
|
-
|
2096
|
-
VALUE a;
|
2097
|
-
{
|
2098
|
-
return mm_bang_i(a, MM_MODIFY, rb_intern("reverse!"), 0, 0);
|
2099
|
-
}
|
1933
|
+
static VALUE mm_reverse_bang(a) VALUE a;
|
1934
|
+
{ return mm_bang_i(a, MM_MODIFY, rb_intern("reverse!"), 0, 0); }
|
2100
1935
|
|
2101
1936
|
/*
|
2102
1937
|
* call-seq: chop!
|
2103
1938
|
*
|
2104
1939
|
* chop off the last character
|
2105
1940
|
*/
|
2106
|
-
static VALUE
|
2107
|
-
|
2108
|
-
VALUE a;
|
2109
|
-
{
|
2110
|
-
return mm_bang_i(a, MM_CHANGE, rb_intern("chop!"), 0, 0);
|
2111
|
-
}
|
1941
|
+
static VALUE mm_chop_bang(a) VALUE a;
|
1942
|
+
{ return mm_bang_i(a, MM_CHANGE, rb_intern("chop!"), 0, 0); }
|
2112
1943
|
|
2113
1944
|
/*
|
2114
1945
|
* call-seq: chomp!(rs = $/)
|
2115
1946
|
*
|
2116
1947
|
* chop off the line ending character, specified by <em>rs</em>
|
2117
1948
|
*/
|
2118
|
-
static VALUE
|
2119
|
-
|
2120
|
-
int argc;
|
2121
|
-
VALUE *argv, obj;
|
1949
|
+
static VALUE mm_chomp_bang(argc, argv, obj) int argc;
|
1950
|
+
VALUE *argv, obj;
|
2122
1951
|
{
|
2123
|
-
return mm_bang_i(obj, MM_CHANGE | MM_PROTECT, rb_intern("chomp!"), argc,
|
1952
|
+
return mm_bang_i(obj, MM_CHANGE | MM_PROTECT, rb_intern("chomp!"), argc,
|
1953
|
+
argv);
|
2124
1954
|
}
|
2125
1955
|
|
2126
1956
|
/*
|
@@ -2128,12 +1958,11 @@ mm_chomp_bang(argc, argv, obj)
|
|
2128
1958
|
*
|
2129
1959
|
* delete every characters included in <em>str</em>
|
2130
1960
|
*/
|
2131
|
-
static VALUE
|
2132
|
-
|
2133
|
-
int argc;
|
2134
|
-
VALUE *argv, obj;
|
1961
|
+
static VALUE mm_delete_bang(argc, argv, obj) int argc;
|
1962
|
+
VALUE *argv, obj;
|
2135
1963
|
{
|
2136
|
-
return mm_bang_i(obj, MM_CHANGE | MM_PROTECT, rb_intern("delete!"), argc,
|
1964
|
+
return mm_bang_i(obj, MM_CHANGE | MM_PROTECT, rb_intern("delete!"), argc,
|
1965
|
+
argv);
|
2137
1966
|
}
|
2138
1967
|
|
2139
1968
|
/*
|
@@ -2141,22 +1970,19 @@ mm_delete_bang(argc, argv, obj)
|
|
2141
1970
|
*
|
2142
1971
|
* squeezes sequences of the same characters which is included in <em>str</em>
|
2143
1972
|
*/
|
2144
|
-
static VALUE
|
2145
|
-
|
2146
|
-
int argc;
|
2147
|
-
VALUE *argv, obj;
|
1973
|
+
static VALUE mm_squeeze_bang(argc, argv, obj) int argc;
|
1974
|
+
VALUE *argv, obj;
|
2148
1975
|
{
|
2149
|
-
return mm_bang_i(obj, MM_CHANGE | MM_PROTECT, rb_intern("squeeze!"), argc,
|
1976
|
+
return mm_bang_i(obj, MM_CHANGE | MM_PROTECT, rb_intern("squeeze!"), argc,
|
1977
|
+
argv);
|
2150
1978
|
}
|
2151
1979
|
|
2152
1980
|
/*
|
2153
1981
|
* call-seq: tr!(search, replace)
|
2154
1982
|
*
|
2155
|
-
* translate the character from <em>search</em> to <em>replace</em>
|
1983
|
+
* translate the character from <em>search</em> to <em>replace</em>
|
2156
1984
|
*/
|
2157
|
-
static VALUE
|
2158
|
-
mm_tr_bang(obj, a, b)
|
2159
|
-
VALUE obj, a, b;
|
1985
|
+
static VALUE mm_tr_bang(obj, a, b) VALUE obj, a, b;
|
2160
1986
|
{
|
2161
1987
|
VALUE tmp[2];
|
2162
1988
|
tmp[0] = a;
|
@@ -2168,11 +1994,9 @@ mm_tr_bang(obj, a, b)
|
|
2168
1994
|
* call-seq: tr_s!(search, replace)
|
2169
1995
|
*
|
2170
1996
|
* translate the character from <em>search</em> to <em>replace</em>, then
|
2171
|
-
* squeeze sequence of the same characters
|
1997
|
+
* squeeze sequence of the same characters
|
2172
1998
|
*/
|
2173
|
-
static VALUE
|
2174
|
-
mm_tr_s_bang(obj, a, b)
|
2175
|
-
VALUE obj, a, b;
|
1999
|
+
static VALUE mm_tr_s_bang(obj, a, b) VALUE obj, a, b;
|
2176
2000
|
{
|
2177
2001
|
VALUE tmp[2];
|
2178
2002
|
tmp[0] = a;
|
@@ -2183,35 +2007,25 @@ mm_tr_s_bang(obj, a, b)
|
|
2183
2007
|
/*
|
2184
2008
|
* call-seq: crypt
|
2185
2009
|
*
|
2186
|
-
* crypt with <em>salt</em>
|
2010
|
+
* crypt with <em>salt</em>
|
2187
2011
|
*/
|
2188
|
-
static VALUE
|
2189
|
-
|
2190
|
-
VALUE a, b;
|
2191
|
-
{
|
2192
|
-
return mm_bang_i(a, MM_ORIGIN, rb_intern("crypt"), 1, &b);
|
2193
|
-
}
|
2012
|
+
static VALUE mm_crypt(a, b) VALUE a, b;
|
2013
|
+
{ return mm_bang_i(a, MM_ORIGIN, rb_intern("crypt"), 1, &b); }
|
2194
2014
|
|
2195
2015
|
/*
|
2196
2016
|
* call-seq: include?(other)
|
2197
2017
|
*
|
2198
2018
|
* return <em>true</em> if <em>other</em> is found
|
2199
2019
|
*/
|
2200
|
-
static VALUE
|
2201
|
-
|
2202
|
-
VALUE a, b;
|
2203
|
-
{
|
2204
|
-
return mm_bang_i(a, MM_ORIGIN, rb_intern("include?"), 1, &b);
|
2205
|
-
}
|
2020
|
+
static VALUE mm_include(a, b) VALUE a, b;
|
2021
|
+
{ return mm_bang_i(a, MM_ORIGIN, rb_intern("include?"), 1, &b); }
|
2206
2022
|
|
2207
2023
|
/*
|
2208
2024
|
* call-seq: index
|
2209
2025
|
*
|
2210
|
-
* return the index of <em>substr</em>
|
2026
|
+
* return the index of <em>substr</em>
|
2211
2027
|
*/
|
2212
|
-
static VALUE
|
2213
|
-
mm_index(int argc, VALUE * argv, VALUE obj)
|
2214
|
-
{
|
2028
|
+
static VALUE mm_index(int argc, VALUE *argv, VALUE obj) {
|
2215
2029
|
return mm_bang_i(obj, MM_ORIGIN, rb_intern("index"), argc, argv);
|
2216
2030
|
}
|
2217
2031
|
|
@@ -2220,13 +2034,9 @@ mm_index(int argc, VALUE * argv, VALUE obj)
|
|
2220
2034
|
*
|
2221
2035
|
* return the index of the last occurrence of <em>substr</em>
|
2222
2036
|
*/
|
2223
|
-
static VALUE
|
2224
|
-
|
2225
|
-
|
2226
|
-
VALUE *argv, obj;
|
2227
|
-
{
|
2228
|
-
return mm_bang_i(obj, MM_ORIGIN, rb_intern("rindex"), argc, argv);
|
2229
|
-
}
|
2037
|
+
static VALUE mm_rindex(argc, argv, obj) int argc;
|
2038
|
+
VALUE *argv, obj;
|
2039
|
+
{ return mm_bang_i(obj, MM_ORIGIN, rb_intern("rindex"), argc, argv); }
|
2230
2040
|
|
2231
2041
|
/*
|
2232
2042
|
* Document-method: []
|
@@ -2235,22 +2045,20 @@ mm_rindex(argc, argv, obj)
|
|
2235
2045
|
* call-seq: [](args)
|
2236
2046
|
*
|
2237
2047
|
* Element reference - with the following syntax:
|
2238
|
-
*
|
2239
|
-
* self[nth]
|
2240
|
-
*
|
2048
|
+
*
|
2049
|
+
* self[nth]
|
2050
|
+
*
|
2241
2051
|
* retrieve the <em>nth</em> character
|
2242
|
-
*
|
2052
|
+
*
|
2243
2053
|
* self[start..last]
|
2244
|
-
*
|
2054
|
+
*
|
2245
2055
|
* return a substring from <em>start</em> to <em>last</em>
|
2246
|
-
*
|
2056
|
+
*
|
2247
2057
|
* self[start, length]
|
2248
|
-
*
|
2249
|
-
* return a substring of <em>lenght</em> characters from <em>start</em>
|
2058
|
+
*
|
2059
|
+
* return a substring of <em>lenght</em> characters from <em>start</em>
|
2250
2060
|
*/
|
2251
|
-
static VALUE
|
2252
|
-
mm_aref_m(int argc, VALUE *argv, VALUE obj)
|
2253
|
-
{
|
2061
|
+
static VALUE mm_aref_m(int argc, VALUE *argv, VALUE obj) {
|
2254
2062
|
return mm_bang_i(obj, MM_ORIGIN, rb_intern("[]"), argc, argv);
|
2255
2063
|
}
|
2256
2064
|
|
@@ -2259,60 +2067,42 @@ mm_aref_m(int argc, VALUE *argv, VALUE obj)
|
|
2259
2067
|
*
|
2260
2068
|
* return a checksum
|
2261
2069
|
*/
|
2262
|
-
static VALUE
|
2263
|
-
|
2264
|
-
|
2265
|
-
VALUE *argv, obj;
|
2266
|
-
{
|
2267
|
-
return mm_bang_i(obj, MM_ORIGIN, rb_intern("sum"), argc, argv);
|
2268
|
-
}
|
2070
|
+
static VALUE mm_sum(argc, argv, obj) int argc;
|
2071
|
+
VALUE *argv, obj;
|
2072
|
+
{ return mm_bang_i(obj, MM_ORIGIN, rb_intern("sum"), argc, argv); }
|
2269
2073
|
|
2270
2074
|
/*
|
2271
2075
|
* call-seq: split(sep, limit = 0)
|
2272
2076
|
*
|
2273
2077
|
* splits into a list of strings and return this array
|
2274
2078
|
*/
|
2275
|
-
static VALUE
|
2276
|
-
|
2277
|
-
|
2278
|
-
VALUE *argv, obj;
|
2279
|
-
{
|
2280
|
-
return mm_bang_i(obj, MM_ORIGIN, rb_intern("split"), argc, argv);
|
2281
|
-
}
|
2079
|
+
static VALUE mm_split(argc, argv, obj) int argc;
|
2080
|
+
VALUE *argv, obj;
|
2081
|
+
{ return mm_bang_i(obj, MM_ORIGIN, rb_intern("split"), argc, argv); }
|
2282
2082
|
|
2283
2083
|
/*
|
2284
2084
|
* call-seq: count(o1, *args)
|
2285
2085
|
*
|
2286
2086
|
* each parameter defines a set of character to count
|
2287
2087
|
*/
|
2288
|
-
static VALUE
|
2289
|
-
|
2290
|
-
|
2291
|
-
VALUE *argv, obj;
|
2292
|
-
{
|
2293
|
-
return mm_bang_i(obj, MM_ORIGIN, rb_intern("count"), argc, argv);
|
2294
|
-
}
|
2088
|
+
static VALUE mm_count(argc, argv, obj) int argc;
|
2089
|
+
VALUE *argv, obj;
|
2090
|
+
{ return mm_bang_i(obj, MM_ORIGIN, rb_intern("count"), argc, argv); }
|
2295
2091
|
|
2296
|
-
static VALUE
|
2297
|
-
|
2298
|
-
VALUE *tmp;
|
2299
|
-
{
|
2300
|
-
return rb_funcall2(tmp[0], (ID)tmp[1], (int)tmp[2], (VALUE *)tmp[3]);
|
2301
|
-
}
|
2092
|
+
static VALUE mm_internal_each(tmp) VALUE *tmp;
|
2093
|
+
{ return rb_funcall2(tmp[0], (ID)tmp[1], (int)tmp[2], (VALUE *)tmp[3]); }
|
2302
2094
|
|
2303
2095
|
/*
|
2304
2096
|
* call-seq: scan(pattern, &block)
|
2305
2097
|
*
|
2306
|
-
* return an array of all occurence matched by <em>pattern</em>
|
2098
|
+
* return an array of all occurence matched by <em>pattern</em>
|
2307
2099
|
*/
|
2308
|
-
static VALUE
|
2309
|
-
mm_scan(obj, a)
|
2310
|
-
VALUE obj, a;
|
2100
|
+
static VALUE mm_scan(obj, a) VALUE obj, a;
|
2311
2101
|
{
|
2312
2102
|
VALUE tmp[4];
|
2313
2103
|
|
2314
2104
|
if (!rb_block_given_p()) {
|
2315
|
-
|
2105
|
+
return rb_funcall(mm_str(obj, MM_ORIGIN), rb_intern("scan"), 1, a);
|
2316
2106
|
}
|
2317
2107
|
tmp[0] = mm_str(obj, MM_ORIGIN);
|
2318
2108
|
tmp[1] = (VALUE)rb_intern("scan");
|
@@ -2331,10 +2121,8 @@ mm_scan(obj, a)
|
|
2331
2121
|
*
|
2332
2122
|
* iterate on each line
|
2333
2123
|
*/
|
2334
|
-
static VALUE
|
2335
|
-
|
2336
|
-
int argc;
|
2337
|
-
VALUE obj, *argv;
|
2124
|
+
static VALUE mm_each_line(argc, argv, obj) int argc;
|
2125
|
+
VALUE obj, *argv;
|
2338
2126
|
{
|
2339
2127
|
VALUE tmp[4];
|
2340
2128
|
|
@@ -2351,10 +2139,8 @@ mm_each_line(argc, argv, obj)
|
|
2351
2139
|
*
|
2352
2140
|
* iterate on each byte
|
2353
2141
|
*/
|
2354
|
-
static VALUE
|
2355
|
-
|
2356
|
-
int argc;
|
2357
|
-
VALUE obj, *argv;
|
2142
|
+
static VALUE mm_each_byte(argc, argv, obj) int argc;
|
2143
|
+
VALUE obj, *argv;
|
2358
2144
|
{
|
2359
2145
|
VALUE tmp[4];
|
2360
2146
|
|
@@ -2373,15 +2159,13 @@ mm_each_byte(argc, argv, obj)
|
|
2373
2159
|
* call-seq:
|
2374
2160
|
* lockall(flag)
|
2375
2161
|
*
|
2376
|
-
* disable paging of all pages mapped. <em>flag</em> can be
|
2162
|
+
* disable paging of all pages mapped. <em>flag</em> can be
|
2377
2163
|
* <em>Mmap::MCL_CURRENT</em> or <em>Mmap::MCL_FUTURE</em>
|
2378
2164
|
*/
|
2379
|
-
static VALUE
|
2380
|
-
mm_mlockall(obj, flag)
|
2381
|
-
VALUE obj, flag;
|
2165
|
+
static VALUE mm_mlockall(obj, flag) VALUE obj, flag;
|
2382
2166
|
{
|
2383
2167
|
if (mlockall(NUM2INT(flag)) == -1) {
|
2384
|
-
|
2168
|
+
rb_raise(rb_eArgError, "mlockall(%d)", errno);
|
2385
2169
|
}
|
2386
2170
|
return Qnil;
|
2387
2171
|
}
|
@@ -2394,12 +2178,10 @@ mm_mlockall(obj, flag)
|
|
2394
2178
|
*
|
2395
2179
|
* reenable paging
|
2396
2180
|
*/
|
2397
|
-
static VALUE
|
2398
|
-
mm_munlockall(obj)
|
2399
|
-
VALUE obj;
|
2181
|
+
static VALUE mm_munlockall(obj) VALUE obj;
|
2400
2182
|
{
|
2401
2183
|
if (munlockall() == -1) {
|
2402
|
-
|
2184
|
+
rb_raise(rb_eArgError, "munlockall(%d)", errno);
|
2403
2185
|
}
|
2404
2186
|
return Qnil;
|
2405
2187
|
}
|
@@ -2412,21 +2194,19 @@ mm_munlockall(obj)
|
|
2412
2194
|
*
|
2413
2195
|
* disable paging
|
2414
2196
|
*/
|
2415
|
-
static VALUE
|
2416
|
-
mm_mlock(obj)
|
2417
|
-
VALUE obj;
|
2197
|
+
static VALUE mm_mlock(obj) VALUE obj;
|
2418
2198
|
{
|
2419
2199
|
mm_ipc *i_mm;
|
2420
2200
|
|
2421
2201
|
Data_Get_Struct(obj, mm_ipc, i_mm);
|
2422
2202
|
if (i_mm->t->flag & MM_LOCK) {
|
2423
|
-
|
2203
|
+
return obj;
|
2424
2204
|
}
|
2425
2205
|
if (i_mm->t->flag & MM_ANON) {
|
2426
|
-
|
2206
|
+
rb_raise(rb_eArgError, "mlock(anonymous)");
|
2427
2207
|
}
|
2428
2208
|
if (mlock(i_mm->t->addr, i_mm->t->len) == -1) {
|
2429
|
-
|
2209
|
+
rb_raise(rb_eArgError, "mlock(%d)", errno);
|
2430
2210
|
}
|
2431
2211
|
i_mm->t->flag |= MM_LOCK;
|
2432
2212
|
return obj;
|
@@ -2440,29 +2220,22 @@ mm_mlock(obj)
|
|
2440
2220
|
*
|
2441
2221
|
* reenable paging
|
2442
2222
|
*/
|
2443
|
-
static VALUE
|
2444
|
-
mm_munlock(obj)
|
2445
|
-
VALUE obj;
|
2223
|
+
static VALUE mm_munlock(obj) VALUE obj;
|
2446
2224
|
{
|
2447
2225
|
mm_ipc *i_mm;
|
2448
2226
|
|
2449
2227
|
Data_Get_Struct(obj, mm_ipc, i_mm);
|
2450
2228
|
if (!(i_mm->t->flag & MM_LOCK)) {
|
2451
|
-
|
2229
|
+
return obj;
|
2452
2230
|
}
|
2453
2231
|
if (munlock(i_mm->t->addr, i_mm->t->len) == -1) {
|
2454
|
-
|
2232
|
+
rb_raise(rb_eArgError, "munlock(%d)", errno);
|
2455
2233
|
}
|
2456
2234
|
i_mm->t->flag &= ~MM_LOCK;
|
2457
2235
|
return obj;
|
2458
2236
|
}
|
2459
2237
|
|
2460
|
-
void
|
2461
|
-
Init_mmap()
|
2462
|
-
{
|
2463
|
-
if (rb_const_defined_at(rb_cObject, rb_intern("Mmap"))) {
|
2464
|
-
rb_raise(rb_eNameError, "class already defined");
|
2465
|
-
}
|
2238
|
+
void Init_mmap() {
|
2466
2239
|
mm_cMap = rb_define_class("Mmap", rb_cObject);
|
2467
2240
|
rb_define_const(mm_cMap, "MS_SYNC", INT2FIX(MS_SYNC));
|
2468
2241
|
rb_define_const(mm_cMap, "MS_ASYNC", INT2FIX(MS_ASYNC));
|
@@ -2577,7 +2350,7 @@ Init_mmap()
|
|
2577
2350
|
rb_define_method(mm_cMap, "scan", mm_scan, 1);
|
2578
2351
|
|
2579
2352
|
rb_define_method(mm_cMap, "sub!", mm_sub_bang, -1);
|
2580
|
-
// TODO: fix mm_gsub_bang_int
|
2353
|
+
// TODO: fix mm_gsub_bang_int
|
2581
2354
|
// rb_define_method(mm_cMap, "gsub!", mm_gsub_bang, -1);
|
2582
2355
|
rb_define_method(mm_cMap, "strip!", mm_strip_bang, 0);
|
2583
2356
|
#if HAVE_RB_STR_LSTRIP
|