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,
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 $@'
== 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*.
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.
#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 },
};
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;
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
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
"$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
"$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