diff --git a/src/libach_posix.c b/src/libach_posix.c index 0eed222..5f09413 100644 --- a/src/libach_posix.c +++ b/src/libach_posix.c @@ -605,7 +605,11 @@ libach_open_posix( ach_channel_t *chan, const char *channel_name, return ACH_BAD_SHM_FILE; /* calculate mmaping size */ - len = sizeof(ach_header_t) + sizeof(ach_index_t)*shm->index_cnt + shm->data_size; + len = sizeof(ach_header_t) + sizeof(ach_index_t)*shm->index_cnt + + shm->data_size + 3 * sizeof(uint64_t); + if( len != shm->len ) + return ACH_BAD_SHM_FILE; + /* remap */ if( -1 == munmap( shm, sizeof(ach_header_t) ) ) diff --git a/src/test/achtest.c b/src/test/achtest.c index d5498f0..bc2cf27 100644 --- a/src/test/achtest.c +++ b/src/test/achtest.c @@ -228,6 +228,44 @@ int test_basic() { return 0; } +/* + * Test opening channel immediately after creating it which may fail if + * size of trailing guard isn't properly accounted for while opening channel. + */ +int test_guard() { + /* unlink */ + ach_status_t r = ach_unlink(opt_channel_name); + if( ! ach_status_match(r, ACH_MASK_OK | ACH_MASK_ENOENT) ) { + fprintf(stderr, "ach_unlink failed: %s\n", + ach_result_to_string(r)); + return -1; + } + + size_t frame_size; + + for (frame_size = 1; frame_size < 4096; ++ frame_size) { + /* create */ + r = ach_create(opt_channel_name, 1ul, frame_size, NULL ); + test(r, "ach_create"); + + ach_channel_t chan; + + /* open */ + r = ach_open(&chan, opt_channel_name, NULL); + test(r, "ach_open"); + + /* close */ + r = ach_close(&chan); + test(r, "ach_close"); + + /* unlink */ + r = ach_unlink(opt_channel_name); + test(r, "ach_unlink"); + } + + fprintf(stderr, "guard ok\n"); + return 0; +} static int publisher( int32_t i ) { ach_channel_t chan; @@ -417,6 +455,9 @@ int main( int argc, char **argv ){ r = test_basic(); if( 0 != r ) return r; + r = test_guard(); + if( 0 != r ) return r; + r = test_multi(); if( 0 != r ) return r;