]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
enosys: add support for alternative error codes
authorThomas Weißschuh <thomas@t-8ch.de>
Sun, 4 Feb 2024 10:56:58 +0000 (11:56 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 22 Feb 2024 09:35:57 +0000 (10:35 +0100)
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
meson.build
misc-utils/Makemodule.am
misc-utils/enosys.1.adoc
misc-utils/enosys.c
tests/expected/misc/enosys-basic
tests/expected/misc/enosys-ioctl
tests/ts/misc/enosys

index fbed1f79fbe37711c23c3180acddc4551f429453..307c2365403202a6a1d87bf93aa173e50fd0ba42 100644 (file)
@@ -3018,7 +3018,7 @@ syscalls_h = custom_target('syscalls.h',
 if cc.compiles(fs.read('include/audit-arch.h'), name : 'has AUDIT_ARCH_NATIVE')
   exe = executable(
     'enosys',
-    'misc-utils/enosys.c', syscalls_h,
+    'misc-utils/enosys.c', syscalls_h, errnos_h,
     include_directories : includes,
     link_with : [lib_common],
     install_dir : usrbin_exec_dir,
index 7524056ed047e7153761c432a2e900e6caf7eee9..514b27adceb130e6085bb77bd915c50e5da634b1 100644 (file)
@@ -330,7 +330,7 @@ endif
 
 if BUILD_ENOSYS
 
-misc-utils/enosys.c: syscalls.h
+misc-utils/enosys.c: syscalls.h errnos.h
 
 syscalls.h: $(top_srcdir)/tools/all_syscalls
        @echo '  GEN      $@'
index 71452e078ea6caca661c3408b9cf9afe5f8bf500..7eba7efffc2c381f7b7f2699874c9fdec46c6f7a 100644 (file)
@@ -25,10 +25,12 @@ syscalls as would happen when running on old kernels.
 == OPTIONS
 
 *-s*, *--syscall*::
-Syscall to block. Can be specified multiple times.
+Syscall to block with *ENOSYS*. Can be specified multiple times.
+An alternative error number or name can be specified with a colon.
 
 *-i*, *--ioctl*::
-Ioctl to block. Can be specified multiple times.
+Ioctl to block with *ENOTTY*. Can be specified multiple times.
+An alternative error number or name can be specified with a colon.
 
 *-l*, *--list*::
 List syscalls known to *enosys*.
@@ -43,6 +45,26 @@ The dump can for example be used by *setpriv --seccomp-filter*.
 
 include::man-common/help-version.adoc[]
 
+== EXAMPLES
+
+ # fail syscall "fallocate" with ENOSYS
+ enosys -s fallocate ...
+
+ # fail syscall "fallocate" with ENOMEM
+ enosys -s fallocate:ENOMEM ...
+
+ # fail syscall "fallocate" with value 12/ENOMEM
+ enosys -s fallocate:12 ...
+
+ # fail ioctl FIOCLEX with ENOTTY
+ enosys -i FIOCLEX ...
+
+ # fail ioctl FIOCLEX with ENOMEM
+ enosys -i FIOCLEX:ENOMEM ...
+
+ # fail ioctl FIOCLEX with value 12/ENOMEM
+ enosys -i FIOCLEX:12 ...
+
 == EXIT STATUS
 
 *enosys* exits with the status code of the executed process.
index d9328f1c73b968b8d3884e8a37874c9d529d6fd5..dc120cd83d4f19ec8484c323a6a029d0ab762fcf 100644 (file)
@@ -63,6 +63,12 @@ static const struct syscall syscalls[] = {
 #undef UL_SYSCALL
 };
 
+static const struct syscall errnos[] = {
+#define UL_ERRNO(name, nr) { name, nr },
+#include "errnos.h"
+#undef UL_ERRNO
+};
+
 static const struct syscall ioctls[] = {
        { "FIOCLEX", FIOCLEX },
 };
@@ -94,24 +100,46 @@ struct blocked_number {
        int ret;
 };
 
-static struct blocked_number *parse_block(const char *s, int ret, const struct syscall syscalls[], size_t nsyscalls)
+static struct blocked_number *parse_block(const char *s, int ret, const struct syscall entities[], size_t n_entities)
 {
        struct blocked_number *blocked;
+       const char *name, *error_name;
        long blocked_number;
+       char *colon;
        bool found;
        size_t i;
 
+       colon = strchr(s, ':');
+       if (colon) {
+               name = xstrndup(s, colon - s);
+               error_name = colon + 1;
+
+               found = 0;
+               for (i = 0; i < ARRAY_SIZE(errnos); i++) {
+                       if (strcmp(error_name, errnos[i].name) == 0) {
+                               ret = errnos[i].number;
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       ret = str2num_or_err(
+                                       colon + 1, 10, _("Unknown errno"), 0, INT_MAX);
+       } else {
+               name = s;
+       }
+
        found = 0;
-       for (i = 0; i < nsyscalls; i++) {
-               if (strcmp(s, syscalls[i].name) == 0) {
-                       blocked_number = syscalls[i].number;
+       for (i = 0; i < n_entities; i++) {
+               if (strcmp(name, entities[i].name) == 0) {
+                       blocked_number = entities[i].number;
                        found = 1;
                        break;
                }
        }
        if (!found)
                blocked_number = str2num_or_err(
-                               s, 10, _("Unknown syscall"), 0, LONG_MAX);
+                               name, 10, _("Unknown syscall"), 0, LONG_MAX);
 
        blocked = xmalloc(sizeof(*blocked));
        blocked->number = blocked_number;
index 6552946f5646f9332eee19a602de4ee92d590dce..1569e897662f585cf7c6b905d084c793094209d1 100644 (file)
@@ -2,3 +2,5 @@ test_enosys: fallocate r=-1 errno=Bad file descriptor
 test_enosys: fallocate r=-1 errno=Function not implemented
 test_enosys: fallocate r=-1 errno=Function not implemented
 test_enosys: fallocate r=-1 errno=Function not implemented
+test_enosys: fallocate r=-1 errno=Cannot allocate memory
+test_enosys: fallocate r=-1 errno=Cannot allocate memory
index 7ab1efd15ac3cfb1b3d757adbb86ccdc1ee5ca94..ffa521d614d1cab691ffcded6ab93f0d56eaccb8 100644 (file)
@@ -3,3 +3,5 @@ test_enosys: ioctl r=-1 errno=Function not implemented
 test_enosys: ioctl r=-1 errno=Inappropriate ioctl for device
 test_enosys: ioctl r=-1 errno=Inappropriate ioctl for device
 test_enosys: ioctl r=-1 errno=Function not implemented
+test_enosys: ioctl r=-1 errno=Cannot allocate memory
+test_enosys: ioctl r=-1 errno=Cannot allocate memory
index ae93c630665d9a24dbb32efcf20e9117a8bf0a2a..e10cf008ba0ec6ceca3d90a6b6995cfc484b34f2 100755 (executable)
@@ -31,6 +31,8 @@ $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 "$TS_CMD_ENOSYS" -s fallocate $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 "$TS_CMD_ENOSYS" -s fsopen -s fallocate $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 "$TS_CMD_ENOSYS" -s fallocate -s fsopen $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
+"$TS_CMD_ENOSYS" -s fallocate:12 $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
+"$TS_CMD_ENOSYS" -s fallocate:ENOMEM $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 
 ts_finalize_subtest
 
@@ -52,6 +54,8 @@ $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 "$TS_CMD_ENOSYS" -i FIOCLEX $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 "$TS_CMD_ENOSYS" -i "$("$TS_CMD_ENOSYS" -m | grep FIOCLEX | awk '{ print $1 }')" $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 "$TS_CMD_ENOSYS" -s ioctl -i FIOCLEX $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
+"$TS_CMD_ENOSYS" -i FIOCLEX:12 $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
+"$TS_CMD_ENOSYS" -i FIOCLEX:ENOMEM $FALLOCATE_TEST > /dev/null 2>> "$TS_OUTPUT"
 
 ts_finalize_subtest