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 }