65
65
caml_invalid_argument("Bigarray.create: negative dimension");
67
67
/* Determine file size */
68
caml_enter_blocking_section();
68
69
currpos = lseek(fd, 0, SEEK_CUR);
69
if (currpos == -1) caml_sys_error(NO_ARG);
71
caml_leave_blocking_section();
72
caml_sys_error(NO_ARG);
70
74
file_size = lseek(fd, 0, SEEK_END);
71
if (file_size == -1) caml_sys_error(NO_ARG);
75
if (file_size == -1) {
76
caml_leave_blocking_section();
77
caml_sys_error(NO_ARG);
72
79
/* Determine array size in bytes (or size of array without the major
73
80
dimension if that dimension wasn't specified) */
74
81
array_size = caml_ba_element_size[flags & CAML_BA_KIND_MASK];
77
84
/* Check if the major dimension is unknown */
78
85
if (dim[major_dim] == -1) {
79
86
/* Determine major dimension from file size */
80
if (file_size < startpos)
87
if (file_size < startpos) {
88
caml_leave_blocking_section();
81
89
caml_failwith("Bigarray.mmap: file position exceeds file size");
82
91
data_size = file_size - startpos;
83
92
dim[major_dim] = (uintnat) (data_size / array_size);
84
93
array_size = dim[major_dim] * array_size;
85
if (array_size != data_size)
94
if (array_size != data_size) {
95
caml_leave_blocking_section();
86
96
caml_failwith("Bigarray.mmap: file size doesn't match array dimensions");
88
99
/* Check that file is large enough, and grow it otherwise */
89
100
if (file_size < startpos + array_size) {
90
if (lseek(fd, startpos + array_size - 1, SEEK_SET) == -1)
101
if (lseek(fd, startpos + array_size - 1, SEEK_SET) == -1) {
102
caml_leave_blocking_section();
91
103
caml_sys_error(NO_ARG);
93
if (write(fd, &c, 1) != 1) caml_sys_error(NO_ARG);
106
if (write(fd, &c, 1) != 1) {
107
caml_leave_blocking_section();
108
caml_sys_error(NO_ARG);
96
112
/* Restore original file position */
102
118
shared = Bool_val(vshared) ? MAP_SHARED : MAP_PRIVATE;
103
119
addr = mmap(NULL, array_size + delta, PROT_READ | PROT_WRITE,
104
120
shared, fd, startpos - delta);
121
caml_leave_blocking_section();
105
122
if (addr == (void *) MAP_FAILED) caml_sys_error(NO_ARG);
106
123
addr = (void *) ((uintnat) addr + delta);
107
124
/* Build and return the Caml bigarray */