aboutsummaryrefslogtreecommitdiff
path: root/example/cuse_client.c
diff options
context:
space:
mode:
authorGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-09 21:05:54 -0700
committerGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-09 22:03:07 -0700
commit35ce627e35d1e293b25cfa8bdec2fb82c7da4630 (patch)
tree74fbfd1e580bf741d49c243fb405b05ab8a115b1 /example/cuse_client.c
parentcf4159156ba08694feb2d75773ec49e25e8ba4fb (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-xexample/cuse_client.c153
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;
+}