16881f68fSopenharmony_ci/* 26881f68fSopenharmony_ci FUSE fioclient: FUSE ioctl example client 36881f68fSopenharmony_ci Copyright (C) 2008 SUSE Linux Products GmbH 46881f68fSopenharmony_ci Copyright (C) 2008 Tejun Heo <teheo@suse.de> 56881f68fSopenharmony_ci 66881f68fSopenharmony_ci This program can be distributed under the terms of the GNU GPLv2. 76881f68fSopenharmony_ci See the file COPYING. 86881f68fSopenharmony_ci*/ 96881f68fSopenharmony_ci 106881f68fSopenharmony_ci/** @file 116881f68fSopenharmony_ci * 126881f68fSopenharmony_ci * This program tests the cuse.c example file system. 136881f68fSopenharmony_ci * 146881f68fSopenharmony_ci * Example usage (assuming that /dev/foobar is a CUSE device provided 156881f68fSopenharmony_ci * by the cuse.c example file system): 166881f68fSopenharmony_ci * 176881f68fSopenharmony_ci * $ cuse_client /dev/foobar s 186881f68fSopenharmony_ci * 0 196881f68fSopenharmony_ci * 206881f68fSopenharmony_ci * $ echo "hello" | cuse_client /dev/foobar w 6 216881f68fSopenharmony_ci * Writing 6 bytes 226881f68fSopenharmony_ci * transferred 6 bytes (0 -> 6) 236881f68fSopenharmony_ci * 246881f68fSopenharmony_ci * $ cuse_client /dev/foobar s 256881f68fSopenharmony_ci * 6 266881f68fSopenharmony_ci * 276881f68fSopenharmony_ci * $ cuse_client /dev/foobar r 10 286881f68fSopenharmony_ci * hello 296881f68fSopenharmony_ci * transferred 6 bytes (6 -> 6) 306881f68fSopenharmony_ci * 316881f68fSopenharmony_ci * Compiling this example 326881f68fSopenharmony_ci * 336881f68fSopenharmony_ci * gcc -Wall cuse_client.c -o cuse_client 346881f68fSopenharmony_ci * 356881f68fSopenharmony_ci * ## Source Code ## 366881f68fSopenharmony_ci * \include cuse_client.c 376881f68fSopenharmony_ci */ 386881f68fSopenharmony_ci 396881f68fSopenharmony_ci 406881f68fSopenharmony_ci#include <sys/types.h> 416881f68fSopenharmony_ci#include <fcntl.h> 426881f68fSopenharmony_ci#include <sys/stat.h> 436881f68fSopenharmony_ci#include <sys/ioctl.h> 446881f68fSopenharmony_ci#include <stdio.h> 456881f68fSopenharmony_ci#include <stdlib.h> 466881f68fSopenharmony_ci#include <ctype.h> 476881f68fSopenharmony_ci#include <errno.h> 486881f68fSopenharmony_ci#include <unistd.h> 496881f68fSopenharmony_ci#include "ioctl.h" 506881f68fSopenharmony_ci 516881f68fSopenharmony_ciconst char *usage = 526881f68fSopenharmony_ci"Usage: cuse_client FIOC_FILE COMMAND\n" 536881f68fSopenharmony_ci"\n" 546881f68fSopenharmony_ci"COMMANDS\n" 556881f68fSopenharmony_ci" s [SIZE] : get size if SIZE is omitted, set size otherwise\n" 566881f68fSopenharmony_ci" r SIZE [OFF] : read SIZE bytes @ OFF (dfl 0) and output to stdout\n" 576881f68fSopenharmony_ci" w SIZE [OFF] : write SIZE bytes @ OFF (dfl 0) from stdin\n" 586881f68fSopenharmony_ci"\n"; 596881f68fSopenharmony_ci 606881f68fSopenharmony_cistatic int do_rw(int fd, int is_read, size_t size, off_t offset, 616881f68fSopenharmony_ci size_t *prev_size, size_t *new_size) 626881f68fSopenharmony_ci{ 636881f68fSopenharmony_ci struct fioc_rw_arg arg = { .offset = offset }; 646881f68fSopenharmony_ci ssize_t ret; 656881f68fSopenharmony_ci 666881f68fSopenharmony_ci arg.buf = calloc(1, size); 676881f68fSopenharmony_ci if (!arg.buf) { 686881f68fSopenharmony_ci fprintf(stderr, "failed to allocated %zu bytes\n", size); 696881f68fSopenharmony_ci return -1; 706881f68fSopenharmony_ci } 716881f68fSopenharmony_ci 726881f68fSopenharmony_ci if (is_read) { 736881f68fSopenharmony_ci arg.size = size; 746881f68fSopenharmony_ci ret = ioctl(fd, FIOC_READ, &arg); 756881f68fSopenharmony_ci if (ret >= 0) 766881f68fSopenharmony_ci fwrite(arg.buf, 1, ret, stdout); 776881f68fSopenharmony_ci } else { 786881f68fSopenharmony_ci arg.size = fread(arg.buf, 1, size, stdin); 796881f68fSopenharmony_ci fprintf(stderr, "Writing %zu bytes\n", arg.size); 806881f68fSopenharmony_ci ret = ioctl(fd, FIOC_WRITE, &arg); 816881f68fSopenharmony_ci } 826881f68fSopenharmony_ci 836881f68fSopenharmony_ci if (ret >= 0) { 846881f68fSopenharmony_ci *prev_size = arg.prev_size; 856881f68fSopenharmony_ci *new_size = arg.new_size; 866881f68fSopenharmony_ci } else 876881f68fSopenharmony_ci perror("ioctl"); 886881f68fSopenharmony_ci 896881f68fSopenharmony_ci free(arg.buf); 906881f68fSopenharmony_ci return ret; 916881f68fSopenharmony_ci} 926881f68fSopenharmony_ci 936881f68fSopenharmony_ciint main(int argc, char **argv) 946881f68fSopenharmony_ci{ 956881f68fSopenharmony_ci size_t param[2] = { }; 966881f68fSopenharmony_ci size_t size, prev_size = 0, new_size = 0; 976881f68fSopenharmony_ci char cmd; 986881f68fSopenharmony_ci int fd, i, rc; 996881f68fSopenharmony_ci 1006881f68fSopenharmony_ci if (argc < 3) 1016881f68fSopenharmony_ci goto usage; 1026881f68fSopenharmony_ci 1036881f68fSopenharmony_ci fd = open(argv[1], O_RDWR); 1046881f68fSopenharmony_ci if (fd < 0) { 1056881f68fSopenharmony_ci perror("open"); 1066881f68fSopenharmony_ci return 1; 1076881f68fSopenharmony_ci } 1086881f68fSopenharmony_ci 1096881f68fSopenharmony_ci cmd = tolower(argv[2][0]); 1106881f68fSopenharmony_ci argc -= 3; 1116881f68fSopenharmony_ci argv += 3; 1126881f68fSopenharmony_ci 1136881f68fSopenharmony_ci for (i = 0; i < argc; i++) { 1146881f68fSopenharmony_ci char *endp; 1156881f68fSopenharmony_ci param[i] = strtoul(argv[i], &endp, 0); 1166881f68fSopenharmony_ci if (endp == argv[i] || *endp != '\0') 1176881f68fSopenharmony_ci goto usage; 1186881f68fSopenharmony_ci } 1196881f68fSopenharmony_ci 1206881f68fSopenharmony_ci switch (cmd) { 1216881f68fSopenharmony_ci case 's': 1226881f68fSopenharmony_ci if (!argc) { 1236881f68fSopenharmony_ci if (ioctl(fd, FIOC_GET_SIZE, &size)) { 1246881f68fSopenharmony_ci perror("ioctl"); 1256881f68fSopenharmony_ci goto error; 1266881f68fSopenharmony_ci } 1276881f68fSopenharmony_ci printf("%zu\n", size); 1286881f68fSopenharmony_ci } else { 1296881f68fSopenharmony_ci size = param[0]; 1306881f68fSopenharmony_ci if (ioctl(fd, FIOC_SET_SIZE, &size)) { 1316881f68fSopenharmony_ci perror("ioctl"); 1326881f68fSopenharmony_ci goto error; 1336881f68fSopenharmony_ci } 1346881f68fSopenharmony_ci } 1356881f68fSopenharmony_ci close(fd); 1366881f68fSopenharmony_ci return 0; 1376881f68fSopenharmony_ci 1386881f68fSopenharmony_ci case 'r': 1396881f68fSopenharmony_ci case 'w': 1406881f68fSopenharmony_ci rc = do_rw(fd, cmd == 'r', param[0], param[1], 1416881f68fSopenharmony_ci &prev_size, &new_size); 1426881f68fSopenharmony_ci if (rc < 0) 1436881f68fSopenharmony_ci goto error; 1446881f68fSopenharmony_ci fprintf(stderr, "transferred %d bytes (%zu -> %zu)\n", 1456881f68fSopenharmony_ci rc, prev_size, new_size); 1466881f68fSopenharmony_ci close(fd); 1476881f68fSopenharmony_ci return 0; 1486881f68fSopenharmony_ci } 1496881f68fSopenharmony_ci 1506881f68fSopenharmony_ciusage: 1516881f68fSopenharmony_ci fprintf(stderr, "%s", usage); 1526881f68fSopenharmony_ci return 1; 1536881f68fSopenharmony_ci 1546881f68fSopenharmony_cierror: 1556881f68fSopenharmony_ci close(fd); 1566881f68fSopenharmony_ci return 1; 1576881f68fSopenharmony_ci} 158