From 955a7cd3bba7152996a132c11a304a79f7a0ed4a Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 16 Apr 2025 09:19:10 +0200 Subject: [PATCH] New API call iso_local_create_dev() --- libisofs/aaip-os-dummy.c | 25 ++++++++++++++++++++- libisofs/aaip-os-freebsd.c | 43 +++++++++++++++++++++++++++++++++++- libisofs/aaip-os-linux.c | 45 +++++++++++++++++++++++++++++++++++++- libisofs/libisofs.h | 43 ++++++++++++++++++++++++++++++++++++ libisofs/libisofs.ver | 1 + libisofs/messages.c | 4 ++++ 6 files changed, 158 insertions(+), 3 deletions(-) diff --git a/libisofs/aaip-os-dummy.c b/libisofs/aaip-os-dummy.c index 3d65b41..2933250 100644 --- a/libisofs/aaip-os-dummy.c +++ b/libisofs/aaip-os-dummy.c @@ -11,7 +11,7 @@ To be included by aaip_0_2.c - Copyright (c) 2009 - 2024 Thomas Schmitt + Copyright (c) 2009 - 2025 Thomas Schmitt This file is part of the libisofs project; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -176,3 +176,26 @@ int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag) } + +/* -------- API for creating device files in the local filesystem --------- */ + + +/* API */ +/* @param flag bit0= do not issue error messages +*/ +int iso_local_create_dev(char *disk_path, mode_t st_mode, dev_t dev, + int *os_errno, int flag) +{ + /* From man mknod: + POSIX.1-2001 says: "The only portable use of mknod() is to create a + FIFO-special file. If mode is not S_IFIFO or dev is not 0, the behav‐ + ior of mknod() is unspecified." + */ + *os_errno= 0; + if(!(flag & 1)) + iso_msg_submit(-1, ISO_DEV_NO_CREATION, 0, + "File \"%s\" cannot be created because device file creation is not enabled", + disk_path); + return ISO_DEV_NO_CREATION; +} + diff --git a/libisofs/aaip-os-freebsd.c b/libisofs/aaip-os-freebsd.c index 7457747..229fac6 100644 --- a/libisofs/aaip-os-freebsd.c +++ b/libisofs/aaip-os-freebsd.c @@ -7,7 +7,7 @@ To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD - Copyright (c) 2009 - 2024 Thomas Schmitt + Copyright (c) 2009 - 2025 Thomas Schmitt This file is part of the libisofs project; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -1146,3 +1146,44 @@ int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag) } +/* -------- API for creating device files in the local filesystem --------- */ + + +/* API */ +/* @param flag bit0= do not issue error messages +*/ +int iso_local_create_dev(char *disk_path, mode_t st_mode, dev_t dev, + int *os_errno, int flag) +{ + int ret; + + *os_errno= 0; + if((st_mode & S_IFMT) != S_IFBLK && (st_mode & S_IFMT) != S_IFCHR) { + if(!(flag & 1)) + iso_msg_submit(-1, ISO_DEV_NO_CREATION, 0, +"Device file \"%s\" cannot be created because not of type S_IFBLK or S_IFCHR", + disk_path); + return ISO_DEV_NO_CREATION; + } + st_mode&= (S_IFMT | 07777); + ret= mknod(disk_path, st_mode, dev); + if(ret == -1) { + *os_errno= errno; + if(!(flag & 1)) { + if(errno > 0) { + iso_msg_submit(-1, ISO_DEV_NOT_CREATED, 0, + "Creation of device file \"%s\" failed with %d '%s'", + disk_path, errno, strerror(errno)); + } else { + iso_msg_submit(-1, ISO_DEV_NOT_CREATED, 0, + "Creation of device file \"%s\" failed without error code", + disk_path); + } + } + return ISO_DEV_NOT_CREATED; + } + return(ISO_SUCCESS); +} + + + diff --git a/libisofs/aaip-os-linux.c b/libisofs/aaip-os-linux.c index 611f6c6..e0a1f7b 100644 --- a/libisofs/aaip-os-linux.c +++ b/libisofs/aaip-os-linux.c @@ -7,7 +7,7 @@ To be included by aaip_0_2.c for Linux - Copyright (c) 2009 - 2024 Thomas Schmitt + Copyright (c) 2009 - 2025 Thomas Schmitt This file is part of the libisofs project; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -1125,3 +1126,45 @@ int aaip_set_projid(char *path, uint32_t projid, int *os_errno, int flag) return(ret); } + +/* -------- API for creating device files in the local filesystem --------- */ + + +/* API */ +/* @param flag bit0= do not issue error messages +*/ +int iso_local_create_dev(char *disk_path, mode_t st_mode, dev_t dev, + int *os_errno, int flag) +{ + int ret; + + *os_errno= 0; + if((st_mode & S_IFMT) != S_IFBLK && (st_mode & S_IFMT) != S_IFCHR) { + if(!(flag & 1)) + iso_msg_submit(-1, ISO_DEV_NO_CREATION, 0, +"Device file \"%s\" cannot be created because not of type S_IFBLK or S_IFCHR", + disk_path); + return ISO_DEV_NO_CREATION; + } + st_mode&= (S_IFMT | 07777); + ret= mknod(disk_path, st_mode, dev); + if(ret == -1) { + *os_errno= errno; + if(!(flag & 1)) { + if(errno > 0) { + iso_msg_submit(-1, ISO_DEV_NOT_CREATED, 0, + "Creation of device file \"%s\" failed with %d '%s'", + disk_path, errno, strerror(errno)); + } else { + iso_msg_submit(-1, ISO_DEV_NOT_CREATED, 0, + "Creation of device file \"%s\" failed without error code", + disk_path); + } + } + return ISO_DEV_NOT_CREATED; + } + return(ISO_SUCCESS); +} + + + diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 08314e4..c165fdb 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -8379,7 +8379,43 @@ int iso_local_get_projid(char *disk_path, uint32_t *projid, int *os_errno, */ int iso_local_set_projid(char *disk_path, uint32_t projid, int *os_errno, int flag); + + +/* -------- API for creating device files in the local filesystem --------- */ + +/** + * Create a device file in the local filesystem. + * Equivalent of non-portable and possibly obsolete mknod(2). + * Whether this makes sense on modern systems is very questionable. But as + * libisofs records device files, it should try to restore them where + * device creation might be supported. + * + * @param disk_path + * Path in the local filesystem where to create the file. + * @param st_mode + * File type and permission bits as of man stat(2) field st_mode. + * Possibly supported file types are: S_IFCHR , S_IFBLK + * @param dev + * System specific parameters for the new device file. It should have + * been originally obtained by a stat(2) call on a system with compatible + * device parameters. + * @param os_errno + * Will get filled with errno if a system call fails. + * Else it will be filled with 0. + * @param flag + * Bitfield for control purposes. + * bit0= do not issue error messages + * @return + * ISO_SUCCESS or <0 to indicate error. + * + * @since 1.5.8 + */ +int iso_local_create_dev(char *disk_path, mode_t st_mode, dev_t dev, + int *os_errno, int flag); + +/* ------------------------------------------------------------------------- */ + /* Default in case that the compile environment has no macro PATH_MAX. */ @@ -9910,6 +9946,13 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len, /** More than 4294967295 bytes of Continuation area (WARNING,HIGH, -441) */ #define ISO_INSANE_CE_SIZE 0xD030FE47 +/** Creation of device file in local filesystem failed (FAILURE,HIGH, -442) */ +#define ISO_DEV_NOT_CREATED 0xE830FE46 + +/** Creation of device file type in local filesystem is not enabled + (FAILURE,HIGH, -443) */ +#define ISO_DEV_NO_CREATION 0xE830FE45 + /* Internal developer note: Place new error codes directly above this comment. diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index 4247776..9fbb3cb 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -386,6 +386,7 @@ local: *; }; LIBISOFS6_1.5.8 { +iso_local_create_dev; iso_local_get_lfa_flags; iso_local_get_projid; iso_local_set_lfa_flags; diff --git a/libisofs/messages.c b/libisofs/messages.c index 8fa3bc7..5f5d50b 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -597,6 +597,10 @@ const char *iso_error_to_msg(int errcode) return "Size calculation mismatch with directory record or continuation area"; case ISO_INSANE_CE_SIZE: return "More than 4294967295 bytes of Continuation area"; + case ISO_DEV_NOT_CREATED: + return "Creation of device file in local filesystem failed"; + case ISO_DEV_NO_CREATION: + return "Creation of device file type in local filesystem not enabled"; default: return "Unknown error"; }