From 053e6e240f3fb5b2427fb28f8f09c652e2bdb39a Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Wed, 4 Nov 2020 10:00:31 -0500 Subject: [PATCH] port: set shm size with ftruncate before writing According to POSIX, the size of shared memory object must be set with ftruncate before writing to it. This happenen to work on Linux because the implementation simply creates files on a tmpfs but on FreeBSD it is implemented using actual shared memory objects and as such requires the size to be set first. Signed-off-by: Michael Jeanson Signed-off-by: Mathieu Desnoyers Change-Id: I048f65104d7c34142025337ec1f6777650bfd62f --- libringbuffer/shm.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/libringbuffer/shm.c b/libringbuffer/shm.c index 9160c218..566ed467 100644 --- a/libringbuffer/shm.c +++ b/libringbuffer/shm.c @@ -128,19 +128,27 @@ struct shm_object *_shm_object_table_alloc_shm(struct shm_object_table *table, } memcpy(obj->wait_fd, waitfd, sizeof(waitfd)); - /* create shm */ + /* + * Set POSIX shared memory object size + * + * First, use ftruncate() to set its size, some implementations won't + * allow writes past the size set by ftruncate. + * Then, use write() to fill it with zeros, this allows us to fully + * allocate it and detect a shortage of shm space without dealing with + * a SIGBUS. + */ shmfd = stream_fd; - ret = zero_file(shmfd, memory_map_size); - if (ret) { - PERROR("zero_file"); - goto error_zero_file; - } ret = ftruncate(shmfd, memory_map_size); if (ret) { PERROR("ftruncate"); goto error_ftruncate; } + ret = zero_file(shmfd, memory_map_size); + if (ret) { + PERROR("zero_file"); + goto error_zero_file; + } /* * Also ensure the file metadata is synced with the storage by using * fsync(2). -- 2.34.1