123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #include "libbb.h"
- #include <linux/fs.h>
- enum {
- ARG_NONE = 0,
- ARG_INT = 1,
- ARG_ULONG = 2,
-
- ARG_U64 = 3,
- ARG_MASK = 3,
- FL_USRARG = 4,
- FL_NORESULT = 8,
- FL_SCALE512 = 16,
- };
- struct bdc {
- uint32_t ioc;
- const char name[sizeof("flushbufs")];
- uint8_t flags;
- int8_t argval;
- };
- static const struct bdc bdcommands[] = {
- {
- .ioc = BLKROSET,
- .name = "setro",
- .flags = ARG_INT + FL_NORESULT,
- .argval = 1,
- },{
- .ioc = BLKROSET,
- .name = "setrw",
- .flags = ARG_INT + FL_NORESULT,
- .argval = 0,
- },{
- .ioc = BLKROGET,
- .name = "getro",
- .flags = ARG_INT,
- .argval = -1,
- },{
- .ioc = BLKSSZGET,
- .name = "getss",
- .flags = ARG_INT,
- .argval = -1,
- },{
- .ioc = BLKBSZGET,
- .name = "getbsz",
- .flags = ARG_INT,
- .argval = -1,
- },{
- .ioc = BLKBSZSET,
- .name = "setbsz",
- .flags = ARG_INT + FL_NORESULT + FL_USRARG,
- .argval = 0,
- },{
- .ioc = BLKGETSIZE64,
- .name = "getsz",
- .flags = ARG_U64 + FL_SCALE512,
- .argval = -1,
- },{
- .ioc = BLKGETSIZE,
- .name = "getsize",
- .flags = ARG_ULONG,
- .argval = -1,
- },{
- .ioc = BLKGETSIZE64,
- .name = "getsize64",
- .flags = ARG_U64,
- .argval = -1,
- },{
- .ioc = BLKFLSBUF,
- .name = "flushbufs",
- .flags = ARG_NONE + FL_NORESULT,
- .argval = 0,
- },{
- .ioc = BLKRRPART,
- .name = "rereadpt",
- .flags = ARG_NONE + FL_NORESULT,
- .argval = 0,
- }
- };
- static const struct bdc *find_cmd(const char *s)
- {
- const struct bdc *bdcmd = bdcommands;
- if (s[0] == '-' && s[1] == '-') {
- s += 2;
- do {
- if (strcmp(s, bdcmd->name) == 0)
- return bdcmd;
- bdcmd++;
- } while (bdcmd != bdcommands + ARRAY_SIZE(bdcommands));
- }
- bb_show_usage();
- }
- int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
- int blockdev_main(int argc UNUSED_PARAM, char **argv)
- {
- const struct bdc *bdcmd;
- int fd;
- uint64_t u64;
- union {
- int i;
- unsigned long lu;
- uint64_t u64;
- } ioctl_val_on_stack;
- argv++;
- if (!argv[0] || !argv[1])
- bb_show_usage();
- bdcmd = find_cmd(*argv);
- u64 = (int)bdcmd->argval;
- if (bdcmd->flags & FL_USRARG)
- u64 = xatoi_positive(*++argv);
- argv++;
- if (!argv[0] || argv[1])
- bb_show_usage();
- fd = xopen(argv[0], O_RDONLY);
- ioctl_val_on_stack.u64 = u64;
- #if BB_BIG_ENDIAN
-
- switch (bdcmd->flags & ARG_MASK) {
- case ARG_INT:
- ioctl_val_on_stack.i = (int)u64;
- break;
- # if 0
- case ARG_ULONG:
- ioctl_val_on_stack.lu = (unsigned long)u64;
- break;
- # endif
- }
- #endif
- if (ioctl(fd, bdcmd->ioc, &ioctl_val_on_stack.u64) == -1)
- bb_simple_perror_msg_and_die(*argv);
-
- u64 = ioctl_val_on_stack.u64;
- if (bdcmd->flags & FL_SCALE512)
- u64 >>= 9;
-
- switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) {
- case ARG_INT:
-
- printf("%lld\n", (long long)(int)u64);
- break;
- case ARG_ULONG:
- u64 = (unsigned long)u64;
-
- case ARG_U64:
- printf("%llu\n", (unsigned long long)u64);
- break;
- }
- if (ENABLE_FEATURE_CLEAN_UP)
- close(fd);
- return EXIT_SUCCESS;
- }
|