@@ -176,5 +176,53 @@ int main() {
176
176
printf ("/yolo/sharedoffset.txt content=%s %d\n" , buffer + offset , offset );
177
177
fclose (fd );
178
178
}
179
+
180
+ /**
181
+ * MMAP to and expanded file
182
+ *
183
+ * When appending to a file, the buffer is expanded in chunks, and so the actual length
184
+ * of the file could be less than the buffer length.
185
+ *
186
+ * When using mmap for an expanded file, we have to make sure that content from the buffer
187
+ * is not written beyond the allocated memory area for the mmap operation.
188
+ */
189
+ {
190
+ const char * path = "/yolo/expandedfile.txt" ;
191
+
192
+ int fd = open (path , O_RDWR | O_CREAT , (mode_t )0600 );
193
+ assert (fd != -1 );
194
+
195
+ size_t textsize = 33 ;
196
+
197
+ // multiple calls to write so that the file is expanded
198
+ for (int n = 0 ;n < textsize ;n ++ ) {
199
+ assert (write (fd , "a" , 1 ) != -1 );
200
+ }
201
+
202
+ EM_ASM_ ({
203
+ const stream = FS .streams .find (stream = > stream .path .indexOf ('/yolo/expandedfile.txt' )>=0 );
204
+ assert (stream .node .usedBytes == = $0 ,
205
+ 'Used bytes on the expanded file (' + stream .node .usedBytes + ') ' +
206
+ 'should be 33'
207
+ );
208
+ assert (stream .node .contents .length > stream .node .usedBytes ,
209
+ 'Used bytes on the expanded file (' + stream .node .usedBytes + ') ' +
210
+ 'should be less than the length of the content buffer (' + stream .node .contents .length + ')'
211
+ );
212
+ stream .node .contents [stream .node .usedBytes ] = 98 ; // 'b', we don't want to see this in the mmap area
213
+ }, textsize );
214
+
215
+ char * map ;
216
+
217
+ map = (char * )mmap (NULL , textsize , PROT_READ , 0 , fd , 0 );
218
+
219
+ assert (map [textsize - 1 ] == 'a' );
220
+
221
+ // Assert that content from the expanded file buffer are not written beyond the maps allocated memory
222
+ assert (map [textsize ] != 'b' );
223
+
224
+ close (fd );
225
+ }
226
+
179
227
return 0 ;
180
228
}
0 commit comments