diff options
author | Nikolaus Rath <Nikolaus@rath.org> | 2016-10-09 21:05:54 -0700 |
---|---|---|
committer | Nikolaus Rath <Nikolaus@rath.org> | 2016-10-09 22:03:07 -0700 |
commit | 35ce627e35d1e293b25cfa8bdec2fb82c7da4630 (patch) | |
tree | 74fbfd1e580bf741d49c243fb405b05ab8a115b1 /example/cuse_client.c | |
parent | cf4159156ba08694feb2d75773ec49e25e8ba4fb (diff) |
Renamed cuses example and added test program
An earlier version of the fioclient.c example was intended to be
used together with cusexmp.c. The former has since evolved into
ioctl_client.c and no longer has the function necessary to test
CUSE. Therefore, we've added a new cuse_client.c that is clearly
associated with the cuse.c example file system.
Diffstat (limited to 'example/cuse_client.c')
-rwxr-xr-x | example/cuse_client.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/example/cuse_client.c b/example/cuse_client.c new file mode 100755 index 0000000..3e47635 --- /dev/null +++ b/example/cuse_client.c @@ -0,0 +1,153 @@ +/* + FUSE fioclient: FUSE ioctl example client + Copyright (C) 2008 SUSE Linux Products GmbH + Copyright (C) 2008 Tejun Heo <teheo@suse.de> + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. +*/ + +/** @file + * @tableofcontents + * + * This program tests the cuse.c example file system. + * + * Example usage (assuming that /dev/foobar is a CUSE device provided + * by the cuse.c example file system): + * + * $ cuse_client /dev/foobar s + * 0 + * + * $ echo "hello" | cuse_client /dev/foobar w 6 + * Writing 6 bytes + * transferred 6 bytes (0 -> 6) + * + * $ cuse_client /dev/foobar s + * 6 + * + * $ cuse_client /dev/foobar r 10 + * hello + * transferred 6 bytes (6 -> 6) + * + * \section section_compile compiling this example + * + * gcc -Wall cuse_client.c -o cuse_client + * + * \section section_source the complete source + * \include cuse_client.c + */ + + +#include <config.h> + +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <errno.h> +#include "ioctl.h" + +const char *usage = +"Usage: cuse_client FIOC_FILE COMMAND\n" +"\n" +"COMMANDS\n" +" s [SIZE] : get size if SIZE is omitted, set size otherwise\n" +" r SIZE [OFF] : read SIZE bytes @ OFF (dfl 0) and output to stdout\n" +" w SIZE [OFF] : write SIZE bytes @ OFF (dfl 0) from stdin\n" +"\n"; + +static int do_rw(int fd, int is_read, size_t size, off_t offset, + size_t *prev_size, size_t *new_size) +{ + struct fioc_rw_arg arg = { .offset = offset }; + ssize_t ret; + + arg.buf = calloc(1, size); + if (!arg.buf) { + fprintf(stderr, "failed to allocated %zu bytes\n", size); + return -1; + } + + if (is_read) { + arg.size = size; + ret = ioctl(fd, FIOC_READ, &arg); + if (ret >= 0) + fwrite(arg.buf, 1, ret, stdout); + } else { + arg.size = fread(arg.buf, 1, size, stdin); + fprintf(stderr, "Writing %zu bytes\n", arg.size); + ret = ioctl(fd, FIOC_WRITE, &arg); + } + + if (ret >= 0) { + *prev_size = arg.prev_size; + *new_size = arg.new_size; + } else + perror("ioctl"); + + free(arg.buf); + return ret; +} + +int main(int argc, char **argv) +{ + size_t param[2] = { }; + size_t size, prev_size = 0, new_size = 0; + char cmd; + int fd, i, rc; + + if (argc < 3) + goto usage; + + fd = open(argv[1], O_RDWR); + if (fd < 0) { + perror("open"); + return 1; + } + + cmd = tolower(argv[2][0]); + argc -= 3; + argv += 3; + + for (i = 0; i < argc; i++) { + char *endp; + param[i] = strtoul(argv[i], &endp, 0); + if (endp == argv[i] || *endp != '\0') + goto usage; + } + + switch (cmd) { + case 's': + if (!argc) { + if (ioctl(fd, FIOC_GET_SIZE, &size)) { + perror("ioctl"); + return 1; + } + printf("%zu\n", size); + } else { + size = param[0]; + if (ioctl(fd, FIOC_SET_SIZE, &size)) { + perror("ioctl"); + return 1; + } + } + return 0; + + case 'r': + case 'w': + rc = do_rw(fd, cmd == 'r', param[0], param[1], + &prev_size, &new_size); + if (rc < 0) + return 1; + fprintf(stderr, "transferred %d bytes (%zu -> %zu)\n", + rc, prev_size, new_size); + return 0; + } + + usage: + fprintf(stderr, "%s", usage); + return 1; +} |