首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改文件的属性

更改文件的属性
EN

Code Review用户
提问于 2022-05-22 12:40:00
回答 1查看 62关注 0票数 2

我编写了一个改变文件属性的程序。我怎样才能提高程序的效率?请找出程序问题。我如何改进这个程序?

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fs.h>

typedef enum {
    ActionNone_e,
    ADD_e, REMOVE_e, SET_e,
    ActionEnd_e,
} Action_e;

static void usage (const char *cmd_p);
static void process_mode (const char *modeStr_p, Action_e *actionRet_p, int *attrRet_p);

int
main (int argc, char *argv[])
{
    Action_e action;
    int attr, i, fd, ret, oldAttr;

    if (argc <= 2) {
        usage (argv[0]);
        return 1;
    }

    process_mode (argv[1], &action, &attr);
    if ((action <= ActionNone_e) || (action >= ActionEnd_e)) {
        printf ("mode must start with an action, which must be one of [-+=]\n");
        usage (argv[0]);
        return 1;
    }

    for (i=2; i<argc; ++i) {
        fd = open (argv[i], 0);
        if (fd == -1) {
            perror ("open()");
            return 1;
        }

        if ((action == ADD_e) || (action == REMOVE_e)) {
            ret = ioctl (fd, FS_IOC_GETFLAGS, &oldAttr);
            if (ret == -1) {
                perror ("ioctl(GET)");
                return 1;
            }
            if (action == ADD_e)
                attr |= oldAttr;
            if (action == REMOVE_e)
                attr = oldAttr & ~attr;
        }
        ret = ioctl (fd, FS_IOC_SETFLAGS, &attr);
        if (ret == -1)
            perror ("ioctl(SET)");
    }

    return 0;
}

static void
process_mode (const char *modeStr_p, Action_e *actionRet_p, int *attrRet_p)
{
    size_t len, i;
    Action_e action;
    int attr;

    if (modeStr_p == NULL)
        return;
    action = ActionNone_e;
    attr = 0;

    len = strlen (modeStr_p);
    if (len > 16)
        return;

    for (i=0; i<len; ++i) {
        switch (modeStr_p[i]) {
            case '+':
                action = ADD_e;
                break;

            case '-':
                action = REMOVE_e;
                break;

            case '=':
                action = SET_e;
                break;

            case 'a':
                attr |= FS_APPEND_FL;
                break;

            case 'c':
                attr |= FS_COMPR_FL;
                break;

            case 'D':
                attr |= FS_DIRSYNC_FL;
                break;

            case 'i':
                attr |= FS_IMMUTABLE_FL;
                break;

            case 'j':
                attr |= FS_JOURNAL_DATA_FL;
                break;

            case 'A':
                attr |= FS_NOATIME_FL;
                break;

            case 'd':
                attr |= FS_NODUMP_FL;
                break;

            case 't':
                attr |= FS_NOTAIL_FL;
                break;

            case 's':
                attr |= FS_SECRM_FL;
                break;

            case 'S':
                attr |= FS_SYNC_FL;
                break;

            case 'T':
                attr |= FS_TOPDIR_FL;
                break;

            case 'u':
                attr |= FS_UNRM_FL;
                break;

            case 'e':
                attr |= FS_EXTENT_FL;
                break;

            default:
                printf ("unknown flag: '%c' (0x%08x)\n", modeStr_p[i], modeStr_p[i]);
                break;
        }
    }

    if (actionRet_p != NULL)
        *actionRet_p = action;
    if (attrRet_p != NULL)
        *attrRet_p = attr;

}

static void
usage (const char *cmd_p)
{
    printf ("usage: %s <mode> <files...>\n", cmd_p);
    printf ("  change file attributes on a Linux file system\n");
    printf ("  <mode> -> +-=[acdeijstuADST]\n");
    printf ("    + -> adds mode\n");
    printf ("    - -> removes mode\n");
    printf ("    = -> sets mode\n");
    printf ("    a -> append only\n");
    printf ("    c -> compressed\n");
    printf ("    d -> no dump\n");
    printf ("    e -> extent format\n");
    printf ("    i -> immutable\n");
    printf ("    j -> data journalling\n");
    printf ("    s -> secure deletion\n");
    printf ("    t -> no tail-merging\n");
    printf ("    u -> undeletable\n");
    printf ("    A -> no atime updates\n");
    printf ("    D -> synchronous directory updates\n");
    printf ("    S -> synchronous updates\n");
    printf ("    T -> top of directory hierarchy\n");
} 
EN

回答 1

Code Review用户

发布于 2022-05-22 20:56:24

  • 错误消息"mode must start with an action, which must be one of [-+=]\n"是误导性的。processMode愉快地在参数中的任何位置找到一个动作字符,而不一定是在开始时。我建议使用两个命令行参数,操作和模式,并独立处理它们。
  • printfs在usage()中的一堆在代码大小和执行时间上都是次优的。一个对printf的调用就足够了: printf(“使用:%s \n”)“更改Linux文件系统上的文件属性\n”.);编译器将将这些相邻字符串连接到一个单独的字符串中。
  • 我不确定检查论点的长度是否正确。具体来说,我非常不喜欢神奇的数字16。如果您想要允许更多的标志(如当前缺少的FS_NOCOW_FLFS_PROJINHERIT_FL ),则必须将16更改为其他标记。避免双重维修。
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/276757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档