On Sun, Sep 5, 2010 at 10:28 PM, Sergey Naumov <[email protected]> wrote:
> I have prepared and attached new version of my applet:
>
>> Please put all things (help/config/applet/kbuild) into one file.
> Done.
>
> Code proposals applied except of
>> ->ioc can be uint16_t (IIRC all ioctl constants fin into 16 bits).
> It breaks --getsize64, --getbsz, --setbsz commands (IOCTL exits with
> "Invalid argument" error), ->ioc still has long type.
>
> Help slightly extended by return codes (I think someone could benefit
> from distinguishing "no such device" and "ioctl failure" errors).
> Error code 1 reserved for libbb functions and is named "usage error".

I tried blockdev (util-linux-ng 2.17.2) and it always exits with 1 on any error.
We should follow suit.

Please review attached version.

function                                             old     new   delta
blockdev_main                                          -     287    +287
bdcommands                                             -     160    +160
packed_usage                                       27203   27298     +95
applet_names                                        2297    2306      +9
applet_main                                         1352    1356      +4
applet_nameofs                                       676     678      +2
applet_install_loc                                   169     170      +1
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 5/0 up/down: 558/0)             Total: 558 bytes

-- 
vda
/*
 * blockdev implementation for busybox
 *
 * Copyright (C) 2010 Sergey Naumov <[email protected]>
 *
 * Licensed under GPLv2, see file License in this tarball for details.
 */

//applet:IF_BLOCKDEV(APPLET(blockdev, _BB_DIR_SBIN, _BB_SUID_DROP))

//kbuild:lib-$(CONFIG_BLOCKDEV) += blockdev.o

//config:config BLOCKDEV
//config:       bool "blockdev"
//config:       default y
//config:       help
//config:         Performs some ioctls with block devices.

//usage:#define blockdev_trivial_usage
//usage:        "OPTION [OPTARG] DEVICE"
//usage:#define blockdev_full_usage "\n\n"
//usage:       "Options:"
//usage:     "\n        --setro         Set ro"
//usage:     "\n        --setrw         Set rw"
//usage:     "\n        --getro         Get ro"
//usage:     "\n        --getss         Get sector size"
//usage:     "\n        --getbsz        Get block size"
//usage:     "\n        --setbsz BYTES  Set block size"
//usage:     "\n        --getsize       Get device size in 512-byte sectors"
//usage:     "\n        --getsize64     Get device size in bytes"
//usage:     "\n        --flushbufs     Flush buffers"
//usage:     "\n        --rereadpt      Reread partition table"


#include "libbb.h"
#include <linux/fs.h>

enum {
        ARG_NONE   = 0,
        ARG_INT    = 1,
        ARG_ULONG  = 2,
        ARG_ULLONG = 3,
        ARG_MASK   = 3,

        FL_USRARG   = 4, /* argument is provided by user */
        FL_NORESULT = 8,
};

struct bdc {
        uint32_t   ioc;                       /* ioctl code */
        const char name[sizeof("flushbufs")]; /* "--setfoo" wothout "--" */
        uint8_t    flags;
        int8_t     argval;                    /* default argument value */
};

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 = BLKGETSIZE,
                .name = "getsize",
                .flags = ARG_ULONG,
                .argval = -1,
        },{
                .ioc = BLKGETSIZE64,
                .name = "getsize64",
                .flags = ARG_ULLONG,
                .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)
{
        int j;
        if (*s++ == '-')
                if (*s++ == '-')
                        for (j = 0; j < ARRAY_SIZE(bdcommands); j++)
                                if (strcmp(s, bdcommands[j].name) == 0)
                                        return &bdcommands[j];
        bb_show_usage();
}

int blockdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int blockdev_main(int argc, char **argv)
{
        const struct bdc *bdcmd;
        void *ioctl_ptr;
        int fd;
        int iarg;
        unsigned long lu;
        unsigned long long llu;

        if ((unsigned)(argc - 3) > 1) /* must have 2 or 3 args */
                bb_show_usage();

        bdcmd = find_cmd(*++argv);

        llu = (int)bdcmd->argval;
        if (bdcmd->flags & FL_USRARG)
                llu = xatoi_positive(*++argv);
        lu = llu;
        iarg = llu;

        if (!*++argv)
                bb_show_usage();
        fd = xopen(*argv, O_RDONLY);

        ioctl_ptr = NULL;
        switch (bdcmd->flags & ARG_MASK) {
        case ARG_INT:
                ioctl_ptr =  &iarg;
                break;
        case ARG_ULONG:
                ioctl_ptr = &lu;
                break;
        case ARG_ULLONG:
                ioctl_ptr = &llu;
                break;
        }

        if (ioctl(fd, bdcmd->ioc, ioctl_ptr) == -1)
                bb_simple_perror_msg_and_die(*argv);

        switch (bdcmd->flags & (ARG_MASK+FL_NORESULT)) {
        case ARG_INT:
                /* Smaller code when we use long long
                 * (gcc tail-merges printf call)
                 */
                printf("%lld\n", (long long)iarg);
                break;
        case ARG_ULONG:
                llu = lu;
                /* FALLTHROUGH */
        case ARG_ULLONG:
                printf("%llu\n", llu);
                break;
        }

        if (ENABLE_FEATURE_CLEAN_UP)
                close(fd);
        return EXIT_SUCCESS;
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to