Linux操作系统编程-ls命令实现

Linux操作系统编程-ls命令实现

功能

  • 获取当前工作目录路径并对该目录实现遍历;
  • 以列表形式列出当前工作目录下的所有文件(包括子目录),并显示每个文件的属性信息(文件类型、文件权限、文件硬链接数、文件所有者用户名、文件所有者所在组用户名、文件大小、文件最后修改时间)
  • 根据命令行参数决定是否显示当前目录本身“.”和上级目录“…”
  • 根据命令行参数决定是否显示隐藏文件(文件名以“.”作为开始的文件)
  • 根据命令行参数决定是显示符号链接文件本身的属性还是符号链接指向文件的文件属性。

源码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>

char* join (char *a, char *catb, char *c) {
    char *ret;
    int i = strlen (a), j = strlen (catb), k = strlen (c), n;
    ret = (char*) malloc (sizeof (char) * (i + j + k + 1));
    for (n = 0; n < i; n++)
        ret[n] = a[n];
    for (n = 0; n < j; n++)
        ret[i + n] = catb[n];
    i += j;
    for (n = 0; n < k; n++)
        ret[i + n] = c[n];
    ret[i + n] = 0;
    return ret;   
}

void printMode (mode_t mode) {
    static char map[3][2] = {"r", "w", "x"};
    if (S_ISREG (mode))
        printf ("-");
    else if (S_ISDIR (mode))
        printf ("d");
    else if (S_ISCHR (mode))
        printf ("c");
    else if (S_ISBLK (mode))
        printf ("b");
    else if (S_ISFIFO (mode))
        printf ("f");
    else if (S_ISSOCK (mode))
        printf ("s");
    else if (S_ISLNK (mode))
        printf ("l");
    else printf ("!");
    int n = (int) mode, i, j;
    for (i = 8; i > -1;)
        for (j = 0; j < 3; j++)
            printf ((n >> i--) & 1 == 1 ? map[j] : "-");
}

void printTime (time_t mtime) {
    char *s = ctime (&mtime);
    int i = 0;
    while (s[i] != '\n') i++;
    s[i] = 0;
    printf ("%s ", s);
}
/* stat list */

typedef struct _statnode {
    char name[256];
    struct stat st;
    struct _statnode *next;
} StatNode;

typedef struct _statList {
    int size;
    StatNode *head, *tail;
} StatList;

StatList* createStatList () {
    StatList *statList = (StatList*) malloc (sizeof (StatList));
    bzero (statList, sizeof (StatList));
    statList->tail = statList->head = (StatNode*) malloc (sizeof (StatNode));
    bzero (statList->tail, sizeof (StatNode));
    return statList;
}

StatNode* newStatNode (StatList *statList) {
    StatNode *node = (StatNode*) malloc (sizeof (StatNode));
    statList->tail->next = node;
    statList->tail = node;
    statList->size++;
    return node;
}

void printStatList (StatList *statList) {
    int nNlink = 0, nUserName = 0, nGroupName = 0, nSize = 0, tmp;
    StatNode *node = statList->head->next;
    char buf[256] = {0};
    struct passwd *pw;
    struct group *gr;
    while (node != NULL) {
        sprintf (buf, "%d", node->st.st_nlink);
        if ((tmp = strlen (buf)) > nNlink) nNlink = tmp;

        pw = getpwuid (node->st.st_uid);
        sprintf (buf, "%s", pw->pw_name);
        if ((tmp = strlen (buf)) > nUserName) nUserName = tmp;
        gr = getgrgid (node->st.st_gid);

        sprintf (buf, "%s", gr->gr_name);
        if ((tmp = strlen (buf)) > nGroupName) nGroupName = tmp;
        sprintf (buf, "%d", node->st.st_size);

        if ((tmp = strlen (buf)) > nSize) nSize = tmp;
        node = node->next;
    }
    node = statList->head->next;
    sprintf (buf, ". %%%dd %%%ds %%%ds %%%dd ", nNlink, nUserName, nGroupName, nSize);
    while (node != NULL) {
        printMode (node->st.st_mode);
        pw = getpwuid (node->st.st_uid);
        gr = getgrgid (node->st.st_gid);
        printf (buf, node->st.st_nlink, pw->pw_name, gr->gr_name, node->st.st_size);
        printTime (node->st.st_mtime);
        printf ("%s\n", node->name);
        node = node->next;
    }
}

void destroyStatList (StatList *statList) {
    if (statList != NULL) {
        StatNode *node = statList->head, *next;
        while (node != NULL) {
            next = node->next;
            free (node);
            node = next;
        }
        statList->tail = statList->head = NULL;
        statList->size = -1;
        free (statList);
    }
}

/* main */

void printUsage () {
    printf ("usage:\n");
    printf ("  -h: help\n");
    printf ("  -a: show all files\n");
    printf ("  -c: hide current directory and its parent directory\n");
    printf ("  -l: show symbolic link itself\n");
}

int main(int argc, char **argv) {
    int op_a = 0, op_c = 0, op_l = 0;
    if (argc > 1) {
        int i;
        for (i = 1; i < argc; i++) {
            if (strcmp (argv[i], "-a") == 0) op_a = 1;
            else if (strcmp (argv[i], "-c") == 0) op_c = 1;
            else if (strcmp (argv[i], "-l") == 0) op_l = 1;
            else {
                printUsage ();
                return 0;
            }
        }
    }

    DIR *cwd;
    struct dirent *cdp;
    char *cwdPath = getcwd (NULL, 0);
    StatList *statList = createStatList();
    if ((cwd = opendir (cwdPath)) != NULL) {
        while ((cdp = readdir (cwd)) != NULL) {
            if (!op_c && (strcmp (cdp->d_name, ".") == 0 || strcmp (cdp->d_name, "..") == 0))
                continue;
            if (!op_a && cdp->d_name[0] == '.' && cdp->d_name[1] != '.' && strlen (cdp->d_name) > 1)
                continue;
            char *fullpath = join (cwdPath, "/", cdp->d_name);
            StatNode *node = newStatNode (statList);
            strcpy (node->name, cdp->d_name);
            if (op_l)
                lstat (fullpath, &node->st);
            else
                stat (fullpath, &node->st);
            if (S_ISLNK (node->st.st_mode)) {
                int n = strlen (fullpath);
                if ((n = readlink (fullpath, fullpath, n)) != -1) {
                    fullpath[n] = 0;
                    char *tmp = join (cdp->d_name, " -> ", fullpath);
                    strcpy (node->name, tmp);
                    free (tmp);
                }
            }
            free (fullpath);
        }
        printStatList (statList);
    }
    else printf ("failed to open cwd\n");
    destroyStatList (statList);
    free (cwd);
}

运行实例

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值