commit 97635b3ce8afb4d9ee60a371cb20424619931c9c
parent 7dc9f5290ba34113a2af64ba44f02f50127cf9a4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 16 Oct 2023 14:55:49 +0200
Detect whether memory mapping is enabled when loading from stdin
In this case, print a specific error message at the start of the loading
procedure before any loading problems occur. To test this, we can now
provide the "-" option as an input argument to the test_sck_load
program, which means "read data from stdin".
Diffstat:
2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/src/sck.c b/src/sck.c
@@ -30,10 +30,22 @@
#include <errno.h>
#include <string.h>
#include <sys/mman.h> /* mmap */
+#include <sys/stat.h> /* fstat */
/*******************************************************************************
* Helper functions
******************************************************************************/
+static INLINE int
+is_stdin(FILE* stream)
+{
+ struct stat stream_buf;
+ struct stat stdin_buf;
+ ASSERT(stream);
+ CHK(fstat(fileno(stream), &stream_buf) == 0);
+ CHK(fstat(STDIN_FILENO, &stdin_buf) == 0);
+ return stream_buf.st_dev == stdin_buf.st_dev;
+}
+
static INLINE res_T
check_sck_create_args(const struct sck_create_args* args)
{
@@ -49,9 +61,15 @@ check_sck_load_args(const struct sck_load_args* args)
}
static INLINE res_T
-check_sck_load_stream_args(const struct sck_load_stream_args* args)
+check_sck_load_stream_args
+ (struct sck* sck,
+ const struct sck_load_stream_args* args)
{
if(!args || !args->stream || !args->name) return RES_BAD_ARG;
+ if(args->memory_mapping && is_stdin(args->stream)) {
+ log_err(sck, "unable to use memory mapping on data loaded from stdin\n");
+ return RES_BAD_ARG;
+ }
return RES_OK;
}
@@ -462,7 +480,7 @@ load_stream(struct sck* sck, const struct sck_load_stream_args* args)
size_t iband;
uint64_t nbands;
res_T res = RES_OK;
- ASSERT(sck && check_sck_load_stream_args(args) == RES_OK);
+ ASSERT(sck && check_sck_load_stream_args(sck, args) == RES_OK);
reset_sck(sck);
@@ -724,7 +742,7 @@ sck_load_stream(struct sck* sck, const struct sck_load_stream_args* args)
{
res_T res = RES_OK;
if(!sck) return RES_BAD_ARG;
- res = check_sck_load_stream_args(args);
+ res = check_sck_load_stream_args(sck, args);
if(res != RES_OK) return res;
return load_stream(sck, args);
}
diff --git a/src/test_sck_load.c b/src/test_sck_load.c
@@ -400,16 +400,26 @@ test_load_files(struct sck* sck, int argc, char** argv)
CHK(sck);
FOR_EACH(i, 1, argc) {
hash256_T hash;
- struct sck_load_args args = SCK_LOAD_ARGS_NULL;
size_t nnodes;
size_t nbands;
size_t iband;
- printf("Load %s\n", argv[1]);
-
- args.path = argv[i];
- args.memory_mapping = 1;
- CHK(sck_load(sck, &args) == RES_OK);
+ if(!strcmp(argv[i], "-")) {
+ struct sck_load_stream_args args = SCK_LOAD_STREAM_ARGS_NULL;
+ printf("Load from stdin\n");
+ args.stream = stdin;
+ args.name = "stdin";
+ args.memory_mapping = 1;
+ CHK(sck_load_stream(sck, &args) == RES_BAD_ARG);
+ args.memory_mapping = 0;
+ CHK(sck_load_stream(sck, &args) == RES_OK);
+ } else {
+ struct sck_load_args args = SCK_LOAD_ARGS_NULL;
+ printf("Load %s\n", argv[1]);
+ args.path = argv[i];
+ args.memory_mapping = 1;
+ CHK(sck_load(sck, &args) == RES_OK);
+ }
nbands = sck_get_bands_count(sck);
nnodes = sck_get_nodes_count(sck);
CHK(nbands);