53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'ext/mmapscanner.c', line 53
static VALUE mmap_initialize(int argc, VALUE *argv, VALUE obj)
{
mmap_data_t *data;
VALUE file, voffset, vlength;
off_t offset = 0;
size_t length = 0;
int fd;
struct stat st;
void *ptr;
Data_Get_Struct(obj, mmap_data_t, data);
if (data->ptr)
rb_raise(rb_eRuntimeError, "already mapped");
rb_scan_args(argc, argv, "12", &file, &voffset, &vlength);
if (TYPE(file) != T_FILE)
rb_raise(rb_eTypeError, "File object required");
if (voffset != Qnil && NUM2LL(voffset) < 0)
rb_raise(rb_eRangeError, "offset out of range: %lld", NUM2LL(voffset));
if (vlength != Qnil && NUM2LL(vlength) < 0)
rb_raise(rb_eRangeError, "length out of range: %lld", NUM2LL(vlength));
fd = FIX2INT(rb_funcall(file, rb_intern("fileno"), 0));
if (fstat(fd, &st) < 0)
rb_sys_fail("fstat");
offset = voffset == Qnil ? 0 : NUM2SIZET(voffset);
length = vlength == Qnil ? st.st_size : NUM2SIZET(vlength);
if (offset + length > st.st_size)
length = st.st_size - offset;
if ((ptr = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, offset)) == MAP_FAILED)
rb_sys_fail("mmap");
data->ptr = ptr;
data->size = length;
return Qnil;
}
|