#include "c.h"
#include "xalloc.h"
#include "test_mkfds.h"
+ #include "exitcodes.h"
#include <arpa/inet.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
- #define EXIT_ENOSYS 17
#define EXIT_EPERM 18
#define EXIT_ENOPROTOOPT 19
#define EXIT_EPROTONOSUPPORT 20
fprintf(out, " %s [options] FACTORY FD... [PARAM=VAL...]\n", program_invocation_short_name);
fputs("\nOptions:\n", out);
+ fputs(" -a, --is-available <factory> exit 0 if the factory is available\n", out);
fputs(" -l, --list list available file descriptor factories and exit\n", out);
fputs(" -I, --parameters <factory> list parameters the factory takes\n", out);
fputs(" -r, --comm <name> rename self\n", out);
v = NULL;
}
}
- arg.v = ptype_classes [p->type].read (v, &p->defv);
+ arg.v = ptype_classes [p->type].read(v, &p->defv);
arg.free = ptype_classes [p->type].free;
return arg;
}
}
}
+ #ifdef F_OFD_SETLK
static void lock_fn_ofd_r_(int fd, const char *fname, int dupfd)
{
struct flock r = {
err(EXIT_FAILURE, "failed to lock(write)");
}
}
+ #endif /* F_OFD_SETLK */
static void lock_fn_lease_w(int fd, const char *fname, int dupfd)
{
if (iWrite_bytes < 3)
iWrite_bytes = 3;
lock_fn = lock_fn_posix_rw;
+ #ifdef F_OFD_SETLK
} else if (strcmp(sLock, "ofd-r-") == 0) {
bReadable = true;
if (iWrite_bytes < 1)
if (iWrite_bytes < 3)
iWrite_bytes = 3;
lock_fn = lock_fn_ofd_rw;
+ #else
+ } else if (strcmp(sLock, "ofd-r-") == 0
+ || strcmp(sLock, "ofd--w") == 0
+ || strcmp(sLock, "ofd-rw") == 0) {
+ errx(EXIT_ENOSYS, "no availability for ofd lock");
+ #endif /* F_OFD_SETLK */
} else if (strcmp(sLock, "lease-w") == 0)
lock_fn = lock_fn_lease_w;
else
int e = errno;
close(fd);
unlink(fname);
- free (fname);
+ free(fname);
errno = e;
err(EXIT_FAILURE, "failed to dup %d -> %d", fd, fdescs[0].fd);
}
errno = e;
err(EXIT_FAILURE, "failed in dup2");
}
- data = xmalloc(sizeof (iDupfd));
+ data = xmalloc(sizeof(iDupfd));
*((int *)data) = iDupfd;
}
if (data) {
int *fdp = data;
close(*fdp);
- free (data);
+ free(data);
}
}
"failed to specify a buffer spec to a packet socket");
}
- munmap_data = xmalloc(sizeof (*munmap_data));
+ munmap_data = xmalloc(sizeof(*munmap_data));
munmap_data->len = (size_t) req.tp_block_size * req.tp_block_nr;
munmap_data->ptr = mmap(NULL, munmap_data->len, PROT_WRITE, MAP_SHARED, sd, 0);
if (munmap_data->ptr == MAP_FAILED) {
int fd = pidfd_open(pid, 0);
if (fd < 0)
- err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
- "failed in pidfd_open(%d)", (int)pid);
+ err_nosys(EXIT_FAILURE, "failed in pidfd_open(%d)", (int)pid);
free_arg(&target_pid);
if (fd != fdescs[0].fd) {
(struct sockaddr *)&in6);
}
+ #ifdef SIOCGSKNS
static void *make_netns(const struct factory *factory _U_, struct fdesc fdescs[],
int argc _U_, char ** argv _U_)
{
int ns = ioctl(sd, SIOCGSKNS);
if (ns < 0)
- err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
- "failed in ioctl(SIOCGSKNS)");
+ err_nosys(EXIT_FAILURE, "failed in ioctl(SIOCGSKNS)");
close(sd);
if (ns != fdescs[0].fd) {
return NULL;
}
+ #endif /* SIOCGSKNS */
static void *make_netlink(const struct factory *factory, struct fdesc fdescs[],
int argc, char ** argv)
for (size_t j = i; j > 0; j--)
close(fdescs[j].fd);
errno = e;
- err (EXIT_FAILURE,
- "failed to add fd %d to the eventpoll fd with epoll_ctl",
- fdescs[i].fd);
+ err(EXIT_FAILURE,
+ "failed to add fd %d to the eventpoll fd with epoll_ctl",
+ fdescs[i].fd);
}
}
bfd = syscall(SYS_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
if (bfd < 0)
- err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
- "failed in bpf(BPF_PROG_LOAD)");
+ err_nosys(EXIT_FAILURE, "failed in bpf(BPF_PROG_LOAD)");
if (bfd != fdescs[0].fd) {
if (dup2(bfd, fdescs[0].fd) < 0) {
bfd = syscall(SYS_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
if (bfd < 0)
- err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
- "failed in bpf(BPF_MAP_CREATE)");
+ err_nosys(EXIT_FAILURE, "failed in bpf(BPF_MAP_CREATE)");
if (bfd != fdescs[0].fd) {
if (dup2(bfd, fdescs[0].fd) < 0) {
PARAM_END
}
},
+ #ifdef SIOCGSKNS
{
.name = "netns",
.desc = "open a file specifying a netns",
PARAM_END
}
},
+ #endif
{
.name = "netlink",
.desc = "AF_NETLINK sockets",
puts(multiplexers[i].name);
}
+ static bool is_available(const char *factory)
+ {
+ for (size_t i = 0; i < ARRAY_SIZE(factories); i++)
+ if (strcmp(factories[i].name, factory) == 0)
+ return true;
+
+ return false;
+ }
+
int main(int argc, char **argv)
{
int c;
struct multiplexer *wait_event = NULL;
static const struct option longopts[] = {
+ { "is-available",required_argument,NULL, 'a' },
{ "list", no_argument, NULL, 'l' },
{ "parameters", required_argument, NULL, 'I' },
{ "comm", required_argument, NULL, 'r' },
{ NULL, 0, NULL, 0 },
};
- while ((c = getopt_long(argc, argv, "lhqcI:r:w:WX", longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "a:lhqcI:r:w:WX", longopts, NULL)) != -1) {
switch (c) {
case 'h':
usage(stdout, EXIT_SUCCESS);
+ case 'a':
+ exit(is_available(optarg)? 0: 1);
case 'l':
list_factories();
exit(EXIT_SUCCESS);
fdescs[i].close(fdescs[i].fd, fdescs[i].data);
if (factory->free)
- factory->free (factory, data);
+ factory->free(factory, data);
exit(EXIT_SUCCESS);
}