You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.4 KiB

  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. This program can be distributed under the terms of the GNU GPL.
  6. See the file COPYING.
  7. gcc -Wall fioclient.c -o fioclient
  8. */
  9. #include <sys/types.h>
  10. #include <sys/fcntl.h>
  11. #include <sys/stat.h>
  12. #include <sys/ioctl.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <ctype.h>
  16. #include <errno.h>
  17. #include "fioc.h"
  18. const char *usage =
  19. "Usage: fioclient FIOC_FILE COMMAND\n"
  20. "\n"
  21. "COMMANDS\n"
  22. " s [SIZE] : get size if SIZE is omitted, set size otherwise\n"
  23. " r SIZE [OFF] : read SIZE bytes @ OFF (dfl 0) and output to stdout\n"
  24. " w SIZE [OFF] : write SIZE bytes @ OFF (dfl 0) from stdin\n"
  25. "\n";
  26. static int do_rw(int fd, int is_read, size_t size, off_t offset,
  27. size_t *prev_size, size_t *new_size)
  28. {
  29. struct fioc_rw_arg arg = { .offset = offset };
  30. ssize_t ret;
  31. arg.buf = calloc(1, size);
  32. if (!arg.buf) {
  33. fprintf(stderr, "failed to allocated %zu bytes\n", size);
  34. return -1;
  35. }
  36. if (is_read) {
  37. arg.size = size;
  38. ret = ioctl(fd, FIOC_READ, &arg);
  39. if (ret >= 0)
  40. fwrite(arg.buf, 1, ret, stdout);
  41. } else {
  42. arg.size = fread(arg.buf, 1, size, stdin);
  43. fprintf(stderr, "Writing %zu bytes\n", arg.size);
  44. ret = ioctl(fd, FIOC_WRITE, &arg);
  45. }
  46. if (ret >= 0) {
  47. *prev_size = arg.prev_size;
  48. *new_size = arg.new_size;
  49. } else
  50. perror("ioctl");
  51. free(arg.buf);
  52. return ret;
  53. }
  54. int main(int argc, char **argv)
  55. {
  56. size_t param[2] = { };
  57. size_t size, prev_size = 0, new_size = 0;
  58. char cmd;
  59. int fd, i, rc;
  60. if (argc < 3)
  61. goto usage;
  62. fd = open(argv[1], O_RDWR);
  63. if (fd < 0) {
  64. perror("open");
  65. return 1;
  66. }
  67. cmd = tolower(argv[2][0]);
  68. argc -= 3;
  69. argv += 3;
  70. for (i = 0; i < argc; i++) {
  71. char *endp;
  72. param[i] = strtoul(argv[i], &endp, 0);
  73. if (endp == argv[i] || *endp != '\0')
  74. goto usage;
  75. }
  76. switch (cmd) {
  77. case 's':
  78. if (!argc) {
  79. if (ioctl(fd, FIOC_GET_SIZE, &size)) {
  80. perror("ioctl");
  81. return 1;
  82. }
  83. printf("%zu\n", size);
  84. } else {
  85. size = param[0];
  86. if (ioctl(fd, FIOC_SET_SIZE, &size)) {
  87. perror("ioctl");
  88. return 1;
  89. }
  90. }
  91. return 0;
  92. case 'r':
  93. case 'w':
  94. rc = do_rw(fd, cmd == 'r', param[0], param[1],
  95. &prev_size, &new_size);
  96. if (rc < 0)
  97. return 1;
  98. fprintf(stderr, "transferred %d bytes (%zu -> %zu)\n",
  99. rc, prev_size, new_size);
  100. return 0;
  101. }
  102. usage:
  103. fprintf(stderr, "%s", usage);
  104. return 1;
  105. }