Re: [RFC PATCH] getvalues(2) prototype

Miklos Szeredi
2022-03-22T19:30:34Z

[-- Attachment #1: Type: text/plain, Size: 242 bytes --]

On Tue, Mar 22, 2022 at 8:27 PM Miklos Szeredi <mszeredi@redhat.com> wrote:
>
> Add a new userspace API that allows getting multiple short values in a
> single syscall.

Attaching a test program that allows arbitrary queries.

Thanks,
Miklos

[-- Attachment #2: getvalues.c --]
[-- Type: text/x-csrc, Size: 1293 bytes --]

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <err.h>
#include <stdint.h>
#include <sys/uio.h>

struct name_val {
const char *name; /* in */
struct iovec value_in; /* in */
struct iovec value_out; /* out */
uint32_t error; /* out */
uint32_t reserved;
};

int getvalues(int dfd, const char *path, struct name_val *vec, size_t num,
unsigned int flags)
{
return syscall(451, dfd, path, vec, num, flags);
}

int main(int argc, char *argv[])
{
char *s, buf[4096];
int res, i, o, num = argc - 2;
struct name_val nvs[256] = {};

if (argc < 3)
errx(1, "usage: %s path name [...]", argv[0]);
if (num > 256)
errx(1, "too many arguments");

for (i = 0; i < num; i++)
nvs[i].name = argv[i + 2];

nvs[0].value_in.iov_base = buf;
nvs[0].value_in.iov_len = sizeof(buf);

res = getvalues(AT_FDCWD, argv[1], nvs, num, 0);
if (res == -1)
err(1, NULL);

num = res;
for (i = 0; i < num; i++) {
printf("[%s] = ", nvs[i].name);
res = nvs[i].error;
if (res) {
printf(" ERROR: %s (%i)\n", strerror(res), res);
} else {
res = nvs[i].value_out.iov_len;
s = nvs[i].value_out.iov_base;

for (o = 0; o < res; o += strlen(s + o) + 1)
printf("\"%.*s\" ", res - o, s + o);

printf("(len=%i)\n", res);
}
}
return 0;
}