From 346c56846a0a1a4627a8ebde55f2e5ce87016b5a Mon Sep 17 00:00:00 2001 From: Broc Going Date: Thu, 23 Apr 2026 15:49:57 -0700 Subject: [PATCH] compat (fd): Adds cross-platform-compatible file descriptor type Creates and uses new libnvme_fd_t to handle differences in file descriptor types across platforms. Also defines platform-specific values for invalid file descriptors and test file descriptors. These values are defined in a new lib-compat.h that can be used to host other library-specific cross-platform utilities in the future. Signed-off-by: Broc Going Signed-off-by: Brandon Capener --- libnvme/src/meson.build | 1 + libnvme/src/nvme/ioctl.c | 2 +- libnvme/src/nvme/lib-compat.h | 27 +++++++++++++++++++++++++++ libnvme/src/nvme/lib.c | 4 ++-- libnvme/src/nvme/lib.h | 6 ++++-- libnvme/src/nvme/private.h | 3 ++- libnvme/test/ioctl/ana.c | 3 +-- libnvme/test/ioctl/discovery.c | 3 +-- libnvme/test/ioctl/features.c | 3 +-- libnvme/test/ioctl/identify.c | 3 +-- libnvme/test/ioctl/logs.c | 3 +-- libnvme/test/ioctl/misc.c | 3 +-- libnvme/test/ioctl/mock.c | 12 ++++++------ libnvme/test/ioctl/mock.h | 2 +- libnvme/test/ioctl/zns.c | 3 +-- 15 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 libnvme/src/nvme/lib-compat.h diff --git a/libnvme/src/meson.build b/libnvme/src/meson.build index 2099222c1c..fbaba95c1f 100644 --- a/libnvme/src/meson.build +++ b/libnvme/src/meson.build @@ -29,6 +29,7 @@ headers = [ 'nvme/endian.h', 'nvme/filters.h', 'nvme/ioctl.h', + 'nvme/lib-compat.h', 'nvme/lib-types.h', 'nvme/lib.h', 'nvme/linux.h', diff --git a/libnvme/src/nvme/ioctl.c b/libnvme/src/nvme/ioctl.c index ad6b828810..285cb9f950 100644 --- a/libnvme/src/nvme/ioctl.c +++ b/libnvme/src/nvme/ioctl.c @@ -99,7 +99,7 @@ __public int libnvme_update_block_size(struct libnvme_transport_handle *hdl, int block_size) { int ret; - int fd = libnvme_transport_handle_get_fd(hdl); + libnvme_fd_t fd = libnvme_transport_handle_get_fd(hdl); ret = ioctl(fd, BLKBSZSET, &block_size); if (ret < 0) diff --git a/libnvme/src/nvme/lib-compat.h b/libnvme/src/nvme/lib-compat.h new file mode 100644 index 0000000000..908a4c67fa --- /dev/null +++ b/libnvme/src/nvme/lib-compat.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * This file is part of libnvme. + * Copyright (c) 2026 Micron Technology, Inc. + * + * Cross-platform compatibility definitions, types, and utilities. + * + * Authors: Brandon Capener + */ +#pragma once + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN /* keeps windows.h from including winsock */ +#include + +typedef HANDLE libnvme_fd_t; +#define LIBNVME_INVALID_FD INVALID_HANDLE_VALUE +#define LIBNVME_TEST_FD ((HANDLE)0xFD) + +#else + +typedef int libnvme_fd_t; +#define LIBNVME_INVALID_FD -1 +#define LIBNVME_TEST_FD 0xFD + +#endif diff --git a/libnvme/src/nvme/lib.c b/libnvme/src/nvme/lib.c index 350a6a1ca4..0dd2c1d1f5 100644 --- a/libnvme/src/nvme/lib.c +++ b/libnvme/src/nvme/lib.c @@ -243,7 +243,7 @@ __public int libnvme_open(struct libnvme_global_ctx *ctx, const char *name, if (!strncmp(name, "NVME_TEST_FD", 12)) { hdl->type = LIBNVME_TRANSPORT_HANDLE_TYPE_DIRECT; - hdl->fd = 0xFD; + hdl->fd = LIBNVME_TEST_FD; if (!strcmp(name, "NVME_TEST_FD64")) hdl->ioctl_admin64 = true; @@ -287,7 +287,7 @@ __public void libnvme_close(struct libnvme_transport_handle *hdl) } } -__public int libnvme_transport_handle_get_fd(struct libnvme_transport_handle *hdl) +__public libnvme_fd_t libnvme_transport_handle_get_fd(struct libnvme_transport_handle *hdl) { return hdl->fd; } diff --git a/libnvme/src/nvme/lib.h b/libnvme/src/nvme/lib.h index 92b8cd3762..e2ca0ffa27 100644 --- a/libnvme/src/nvme/lib.h +++ b/libnvme/src/nvme/lib.h @@ -11,6 +11,7 @@ #include #include +#include #include enum libnvme_log_level { @@ -94,9 +95,10 @@ void libnvme_close(struct libnvme_transport_handle *hdl); * If the device handle is for a ioctl based device, * libnvme_transport_handle_get_fd will return a valid file descriptor. * - * Return: File descriptor for an IOCTL based transport handle, otherwise -1. + * Return: File descriptor for an IOCTL based transport handle, + * otherwise LIBNVME_INVALID_FD. */ -int libnvme_transport_handle_get_fd(struct libnvme_transport_handle *hdl); +libnvme_fd_t libnvme_transport_handle_get_fd(struct libnvme_transport_handle *hdl); /** * libnvme_transport_handle_get_name - Return name of the device diff --git a/libnvme/src/nvme/private.h b/libnvme/src/nvme/private.h index 36c51f4ef1..09d7b91056 100644 --- a/libnvme/src/nvme/private.h +++ b/libnvme/src/nvme/private.h @@ -13,6 +13,7 @@ #include #include "nvme/nvme-types.h" +#include "nvme/lib-compat.h" #include "nvme/lib-types.h" #include @@ -156,7 +157,7 @@ struct libnvme_transport_handle { __u32 timeout; /* direct */ - int fd; + libnvme_fd_t fd; struct stat stat; bool ioctl_admin64; bool ioctl_io64; diff --git a/libnvme/test/ioctl/ana.c b/libnvme/test/ioctl/ana.c index f981993457..f4f9adece1 100644 --- a/libnvme/test/ioctl/ana.c +++ b/libnvme/test/ioctl/ana.c @@ -13,7 +13,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define PDU_SIZE NVME_LOG_PAGE_PDU_SIZE static struct libnvme_transport_handle *test_hdl; @@ -631,7 +630,7 @@ int main(void) struct libnvme_global_ctx *ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD", &test_hdl), "opening test link failed"); diff --git a/libnvme/test/ioctl/discovery.c b/libnvme/test/ioctl/discovery.c index 07ae897350..34d96cad2d 100644 --- a/libnvme/test/ioctl/discovery.c +++ b/libnvme/test/ioctl/discovery.c @@ -13,7 +13,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define HEADER_LEN 20 static struct libnvme_transport_handle *test_hdl; @@ -441,7 +440,7 @@ int main(void) struct libnvme_global_ctx *ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD", &test_hdl), "opening test link failed"); diff --git a/libnvme/test/ioctl/features.c b/libnvme/test/ioctl/features.c index 20db4f7389..3ec7b38534 100644 --- a/libnvme/test/ioctl/features.c +++ b/libnvme/test/ioctl/features.c @@ -8,7 +8,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define TEST_TIMEOUT 1234 #define TEST_NSID 0x89ABCDEF #define TEST_CDW11 0x11111111 @@ -1625,7 +1624,7 @@ int main(void) struct libnvme_global_ctx *ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD64", &test_hdl), "opening test link failed"); diff --git a/libnvme/test/ioctl/identify.c b/libnvme/test/ioctl/identify.c index 7fc679df89..0028a738e4 100644 --- a/libnvme/test/ioctl/identify.c +++ b/libnvme/test/ioctl/identify.c @@ -8,7 +8,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define TEST_NSID 0x12345678 #define TEST_NVMSETID 0xABCD #define TEST_UUID 123 @@ -647,7 +646,7 @@ int main(void) struct libnvme_global_ctx * ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD", &test_hdl), "opening test link failed"); diff --git a/libnvme/test/ioctl/logs.c b/libnvme/test/ioctl/logs.c index a5c63d04c6..a348e261ec 100644 --- a/libnvme/test/ioctl/logs.c +++ b/libnvme/test/ioctl/logs.c @@ -5,7 +5,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define TEST_NSID 0x12345678 #define TEST_NVMSETID 0xABCD #define TEST_CSI NVME_CSI_KV @@ -1105,7 +1104,7 @@ int main(void) struct libnvme_global_ctx * ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD", &test_hdl), "opening test link failed"); diff --git a/libnvme/test/ioctl/misc.c b/libnvme/test/ioctl/misc.c index f5cda2f0df..7d57f414c2 100644 --- a/libnvme/test/ioctl/misc.c +++ b/libnvme/test/ioctl/misc.c @@ -8,7 +8,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define TEST_NSID 0x12345678 #define TEST_CSI NVME_CSI_KV #define TEST_COPY_NR 0x12 @@ -1464,7 +1463,7 @@ int main(void) struct libnvme_global_ctx *ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD64", &test_hdl), "opening test link failed"); diff --git a/libnvme/test/ioctl/mock.c b/libnvme/test/ioctl/mock.c index 894968cf8f..c55ea8a2c7 100644 --- a/libnvme/test/ioctl/mock.c +++ b/libnvme/test/ioctl/mock.c @@ -21,7 +21,7 @@ struct mock_cmds { size_t remaining_cmds; }; -static int mock_fd = -1; +static libnvme_fd_t mock_fd = LIBNVME_INVALID_FD; static struct mock_cmds mock_admin_cmds = {.name = "admin"}; static struct mock_cmds mock_io_cmds = {.name = "IO"}; @@ -39,7 +39,7 @@ static void mock_cmds_done(const struct mock_cmds *mock_cmds) mock_cmds->remaining_cmds, mock_cmds->name); } -void set_mock_fd(int fd) +void set_mock_fd(libnvme_fd_t fd) { mock_fd = fd; } @@ -122,11 +122,11 @@ void end_mock_cmds(void) }) #if defined(HAVE_GLIBC_IOCTL) && HAVE_GLIBC_IOCTL == 1 -typedef int (*ioctl_func_t)(int, unsigned long, void *); -int ioctl(int fd, unsigned long request, ...) +typedef int (*ioctl_func_t)(libnvme_fd_t, unsigned long, void *); +int ioctl(libnvme_fd_t fd, unsigned long request, ...) #else -typedef int (*ioctl_func_t)(int, int, void *); -int ioctl(int fd, int request, ...) +typedef int (*ioctl_func_t)(libnvme_fd_t, int, void *); +int ioctl(libnvme_fd_t fd, int request, ...) #endif { ioctl_func_t real_ioctl = NULL; diff --git a/libnvme/test/ioctl/mock.h b/libnvme/test/ioctl/mock.h index c4b4bd6ac1..8304f76921 100644 --- a/libnvme/test/ioctl/mock.h +++ b/libnvme/test/ioctl/mock.h @@ -61,7 +61,7 @@ struct mock_cmd { * set_mock_fd() - sets the expected file descriptor for NVMe passthru ioctls() * @fd: file descriptor expected to be passed to ioctl() */ -void set_mock_fd(int fd); +void set_mock_fd(libnvme_fd_t fd); /** * set_mock_admin_cmds() - mocks NVMe admin passthru ioctl() invocations diff --git a/libnvme/test/ioctl/zns.c b/libnvme/test/ioctl/zns.c index 60767bffcf..16f8ef45e5 100644 --- a/libnvme/test/ioctl/zns.c +++ b/libnvme/test/ioctl/zns.c @@ -7,7 +7,6 @@ #include "mock.h" #include "util.h" -#define TEST_FD 0xFD #define TEST_NSID 0x12345678 #define TEST_SLBA 0xffffffff12345678 @@ -165,7 +164,7 @@ int main(void) struct libnvme_global_ctx *ctx = libnvme_create_global_ctx(stdout, LIBNVME_DEFAULT_LOGLEVEL); - set_mock_fd(TEST_FD); + set_mock_fd(LIBNVME_TEST_FD); check(!libnvme_open(ctx, "NVME_TEST_FD", &test_hdl), "opening test link failed");