#include "optutils.h"
#include "pidutils.h"
-/* operation flags that determine for what to get the inode, i.e. pidfs, namespace... */
enum {
- GETINO_PIDFS = 1,
+ GETINO_OP_PIDFS,
+ GETINO_OP_NAMESPACE,
+};
+
+enum {
GETINO_CGROUP_NAMESPACE,
GETINO_IPC_NAMESPACE,
GETINO_NET_NAMESPACE,
GETINO_UTS_NAMESPACE,
};
-#define IS_NAMESPACE_OP(op) ((op > GETINO_PIDFS && op <= GETINO_UTS_NAMESPACE) ? 1 : 0)
struct getino_context {
- int op_flag; /* controls for what to get the inode, i.e. GETINO_* */
+ int op; /* basic operation: GETINO_OP_* */
+ int ns_type; /* namespace type: GETINO_*_NAMESPACE */
pid_t pid; /* PID provided on the command line */
uint64_t pidfd_ino; /* pidfd inode provided on the command line (PID:inode) */
- unsigned int pidfd_ioctl; /* pidfs ioctl command for namespace fd */
bool print_pid; /* print the pid and inode, colon-separated */
};
[GETINO_UTS_NAMESPACE] = { .name = "uts", .ioctl = PIDFD_GET_UTS_NAMESPACE },
};
-static int get_pidfd_ns_ioctl(struct getino_context *ctx)
-{
- if(!IS_NAMESPACE_OP(ctx->op_flag))
- return -1;
-
- return ns_info[ctx->op_flag].ioctl;
-}
-
-static int pidfd_get_nsfd_or_err(struct getino_context *ctx, int pidfd)
+static int get_ns_fd(struct getino_context *ctx, int pidfd)
{
- int nsfd, pidfd_ioctl;
-
- pidfd_ioctl = get_pidfd_ns_ioctl(ctx);
- if (pidfd_ioctl < 0)
- errx(EXIT_FAILURE, _("no appropriate ioctl for the desired namespace"));
+ struct ns_desc *ns = &ns_info[ctx->ns_type];
+ int nsfd;
- nsfd = ioctl(pidfd, pidfd_ioctl, 0);
+ nsfd = ioctl(pidfd, ns->ioctl, 0);
if (nsfd < 0)
err(EXIT_FAILURE, _("failed to determine %s namespace for process %d"),
- ns_info[ctx->op_flag].name, ctx->pid);
+ ns->name, ctx->pid);
return nsfd;
}
pidfd = ul_get_valid_pidfd_or_err(ctx->pid, ctx->pidfd_ino);
- if (IS_NAMESPACE_OP(ctx->op_flag)) {
- target_fd = pidfd_get_nsfd_or_err(ctx, pidfd);
+ switch (ctx->op) {
+ case GETINO_OP_NAMESPACE:
+ target_fd = get_ns_fd(ctx, pidfd);
close(pidfd);
- } else {
+ break;
+ case GETINO_OP_PIDFS:
+ default:
target_fd = pidfd;
+ break;
}
ino = pidfd_get_inode(target_fd);
- if (ctx->print_pid) {
- printf("%d:%"PRIu64"\n", ctx->pid, ino);
- } else {
- printf("%"PRIu64"\n", ino);
- }
+ if (ctx->print_pid)
+ printf("%d:%" PRIu64 "\n", ctx->pid, ino);
+ else
+ printf("%" PRIu64 "\n", ino);
close(target_fd);
}
{
int c, rc = 0;
struct getino_context ctx = {
- .print_pid = false,
- .op_flag = GETINO_PIDFS,
+ .op = GETINO_OP_PIDFS,
+ .ns_type = -1,
};
enum {
switch (c) {
case OPT_PIDFS:
- ctx.op_flag = GETINO_PIDFS;
+ ctx.op = GETINO_OP_PIDFS;
+ ctx.ns_type = -1;
break;
case OPT_CGROUPNS:
- ctx.op_flag = GETINO_CGROUP_NAMESPACE;
+ ctx.ns_type = GETINO_CGROUP_NAMESPACE;
break;
case OPT_IPCNS:
- ctx.op_flag = GETINO_IPC_NAMESPACE;
+ ctx.ns_type = GETINO_IPC_NAMESPACE;
break;
case OPT_NETNS:
- ctx.op_flag = GETINO_NET_NAMESPACE;
+ ctx.ns_type = GETINO_NET_NAMESPACE;
break;
case OPT_MNTNS:
- ctx.op_flag = GETINO_MNT_NAMESPACE;
+ ctx.ns_type = GETINO_MNT_NAMESPACE;
break;
case OPT_PIDNS:
- ctx.op_flag = GETINO_PID_NAMESPACE;
+ ctx.ns_type = GETINO_PID_NAMESPACE;
break;
case OPT_TIMENS:
- ctx.op_flag = GETINO_TIME_NAMESPACE;
+ ctx.ns_type = GETINO_TIME_NAMESPACE;
break;
case OPT_USERNS:
- ctx.op_flag = GETINO_USER_NAMESPACE;
+ ctx.ns_type = GETINO_USER_NAMESPACE;
break;
case OPT_UTSNS:
- ctx.op_flag = GETINO_UTS_NAMESPACE;
+ ctx.ns_type = GETINO_UTS_NAMESPACE;
break;
case 'p':
ctx.print_pid = true;
}
}
+ if (ctx.ns_type >= 0)
+ ctx.op = GETINO_OP_NAMESPACE;
+
if (argc - optind < 1) {
warnx(_("no process specified"));
errtryhelp(EXIT_FAILURE);