Linux程序设计:目录维护

一、相关系统调用

1.1 chmod

改变访问权限。

#include <sys/stat.h>
int chmod(const char *path, mode_t mode)

1.2 chown

改变文件的owner。(没想到有什么用= =)

#include <sys/types.h>
#include <unistd.h> int chown(const char *pathname, uid_t owner, gid_t group);

其中,owner可以通过getuid(),group可以通过getgid()。

1.3 unlink、link、symlink

  • unlink用于删除文件,成功0,失败-1。(前提是必须拥有文件所属目录的写r和执行权限x)
  • link
  • symlink

(待补充)

1.4 mkdir、rmdir

建立和删除目录。

#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
#include <unistd.h>
int rmdir(const char *pathname);

1.5 chdir、getcwd

chdir切换程序的工作目录。

getcwd:get current working dir

#include <unistd.h>
int chdir(const char *path);
char *getcwd(char *buf, size_t size);

1.6 opendir、readdir

#include <sys/types.h>     
#include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);

opendir打开一个目录,返回一个DIR指针(失败NULL),用于读取目录相关数据项。

readdir()返回参数dir 目录流的下个目录进入点。结构dirent 定义如下:

struct dirent
{
    long d_ino;                /* inode number 索引节点号 */
    off_t d_off;               /* offset to this dirent 在目录文件中的偏移 */
    unsigned short d_reclen;   /* length of this d_name 文件名长 */
    unsigned char d_type;      /* the type of d_name 文件类型 */
    char d_name[NAME_MAX + 1]; /* file name (null-terminated) 文件名,最长256字符 */
}

1.7 telldir、seekdir、closedir

#include <dirent.h>
long telldir(DIR *dirp);

#include <dirent.h>
void seekdir(DIR *dirp, long loc);

#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
  • telldir:返回目录流的当前位置。
  • seekdir:设置当前目录流的目录项指针,loc是设置的位置,可通过telldir获得。
  • closedir:关闭目录流。

二、tree命令的实现

depth:控制缩进,每进一层目录,缩进加4空格。

void test2()
{
    char buffer[BUFSIZ];
    getcwd(buffer, BUFSIZ);

    puts(buffer);
    tree("/home/sin/desktop/workspace/OSLab/MiniShell", 0);
    
    memset(buffer, 0, sizeof(buffer));
    getcwd(buffer, BUFSIZ);
    puts(buffer);

}
void tree(char *dir, int depth)
{
    char cwd_buff[128];
    getcwd(cwd_buff, sizeof(cwd_buff));

    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;
    if ((dp = opendir(dir)) == NULL)
    {
        fprintf(stderr, "open failed
");
        return;
    }
    chdir(dir);
    while ((entry = readdir(dp)) != NULL)
    {
        lstat(entry->d_name, &statbuf);
        if (S_ISDIR(statbuf.st_mode))
        {
            if (strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 || entry->d_name[0] == '.')
            {
                continue;
            }
            printf("%*s%s/
", depth, "", entry->d_name);
            tree(entry->d_name, depth + 4);
        }
        else
        {
            printf("%*s%s
", depth, "", entry->d_name);
        }
    }
    chdir(cwd_buff); //switch to original dir
    closedir(dp);
}

运行结果:

sin@ubuntu:~/desktop/workspace/OSLab/MiniShell$ make test 
gcc test.c -o a.out
./a.out
/home/sin/desktop/workspace/OSLab/MiniShell
src/
    string/
        mystring.c
    process/
        buildin_cmd.c
        external_cmd.c
    shell/
        shellmain.c
        ui.c
Makefile
test.c
README.md
.gitignore
a.out
include/
    macro.h
    mystring.h
    process.h
    types.h
    shell.h
build/
    bin/
        MiniShell
    obj/
        string/
            mystring.o
        process/
            external_cmd.o
            buildin_cmd.o
        shell/
            ui.o
            shellmain.o
/home/sin/desktop/workspace/OSLab/MiniShell
原文地址:https://www.cnblogs.com/sinkinben/p/10797724.html