libfuse

cuse_client.c
Go to the documentation of this file.
1 /*
2 FUSE fioclient: FUSE ioctl example client
3 Copyright (C) 2008 SUSE Linux Products GmbH
4 Copyright (C) 2008 Tejun Heo <teheo@suse.de>
5
6 This program can be distributed under the terms of the GNU GPL.
7 See the file COPYING.
8 */
9
40 #include <sys/types.h>
41 #include <fcntl.h>
42 #include <sys/stat.h>
43 #include <sys/ioctl.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <ctype.h>
47 #include <errno.h>
48 #include "ioctl.h"
49
50 const char *usage =
51 "Usage: cuse_client FIOC_FILE COMMAND\n"
52 "\n"
53 "COMMANDS\n"
54 " s [SIZE] : get size if SIZE is omitted, set size otherwise\n"
55 " r SIZE [OFF] : read SIZE bytes @ OFF (dfl 0) and output to stdout\n"
56 " w SIZE [OFF] : write SIZE bytes @ OFF (dfl 0) from stdin\n"
57 "\n";
58
59 static int do_rw(int fd, int is_read, size_t size, off_t offset,
60 size_t *prev_size, size_t *new_size)
61 {
62 struct fioc_rw_arg arg = { .offset = offset };
63 ssize_t ret;
64
65 arg.buf = calloc(1, size);
66 if (!arg.buf) {
67 fprintf(stderr, "failed to allocated %zu bytes\n", size);
68 return -1;
69 }
70
71 if (is_read) {
72 arg.size = size;
73 ret = ioctl(fd, FIOC_READ, &arg);
74 if (ret >= 0)
75 fwrite(arg.buf, 1, ret, stdout);
76 } else {
77 arg.size = fread(arg.buf, 1, size, stdin);
78 fprintf(stderr, "Writing %zu bytes\n", arg.size);
79 ret = ioctl(fd, FIOC_WRITE, &arg);
80 }
81
82 if (ret >= 0) {
83 *prev_size = arg.prev_size;
84 *new_size = arg.new_size;
85 } else
86 perror("ioctl");
87
88 free(arg.buf);
89 return ret;
90 }
91
92 int main(int argc, char **argv)
93 {
94 size_t param[2] = { };
95 size_t size, prev_size = 0, new_size = 0;
96 char cmd;
97 int fd, i, rc;
98
99 if (argc < 3)
100 goto usage;
101
102 fd = open(argv[1], O_RDWR);
103 if (fd < 0) {
104 perror("open");
105 return 1;
106 }
107
108 cmd = tolower(argv[2][0]);
109 argc -= 3;
110 argv += 3;
111
112 for (i = 0; i < argc; i++) {
113 char *endp;
114 param[i] = strtoul(argv[i], &endp, 0);
115 if (endp == argv[i] || *endp != '\0')
116 goto usage;
117 }
118
119 switch (cmd) {
120 case 's':
121 if (!argc) {
122 if (ioctl(fd, FIOC_GET_SIZE, &size)) {
123 perror("ioctl");
124 return 1;
125 }
126 printf("%zu\n", size);
127 } else {
128 size = param[0];
129 if (ioctl(fd, FIOC_SET_SIZE, &size)) {
130 perror("ioctl");
131 return 1;
132 }
133 }
134 return 0;
135
136 case 'r':
137 case 'w':
138 rc = do_rw(fd, cmd == 'r', param[0], param[1],
139 &prev_size, &new_size);
140 if (rc < 0)
141 return 1;
142 fprintf(stderr, "transferred %d bytes (%zu -> %zu)\n",
143 rc, prev_size, new_size);
144 return 0;
145 }
146
147 usage:
148 fprintf(stderr, "%s", usage);
149 return 1;
150 }
ioctl.h