22. mkdir - 创建目录 链接到标题

函数介绍 链接到标题

mkdir系统调用用于创建新的目录。可以指定目录的访问权限,新创建的目录权限会受到进程的umask值影响。

函数原型 链接到标题

#include <sys/stat.h>
#include <sys/types.h>

int mkdir(const char *pathname, mode_t mode);

功能 链接到标题

创建指定路径名的新目录。

参数 链接到标题

  • const char *pathname: 要创建的目录路径名
  • mode_t mode: 目录的访问权限(如0755)

返回值 链接到标题

  • 成功时返回0
  • 失败时返回-1,并设置errno:
    • EACCES: 权限不足
    • EDQUOT: 磁盘配额超限
    • EEXIST: 目录已存在
    • EINVAL: 参数无效
    • ELOOP: 符号链接循环
    • EMLINK: 链接数超限
    • ENAMETOOLONG: 路径名过长
    • ENOENT: 父目录不存在
    • ENOSPC: 磁盘空间不足
    • ENOTDIR: 路径前缀不是目录
    • EROFS: 文件系统只读

相似函数 链接到标题

  • mkdirat(): 相对路径版本
  • umask(): 设置文件权限掩码

示例代码 链接到标题

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
#include <time.h>

int main() {
    char buffer[PATH_MAX];
    mode_t old_umask;
    
    printf("=== Mkdir函数示例 ===\n");
    
    // 示例1: 基本的目录创建操作
    printf("\n示例1: 基本的目录创建操作\n");
    
    // 创建简单的目录
    const char *simple_dir = "test_mkdir_simple";
    if (mkdir(simple_dir, 0755) == -1) {
        if (errno == EEXIST) {
            printf("目录 %s 已存在\n", simple_dir);
        } else {
            perror("创建简单目录失败");
        }
    } else {
        printf("成功创建目录: %s (权限 0755)\n", simple_dir);
        
        // 验证目录创建
        if (access(simple_dir, F_OK) == 0) {
            printf("目录存在验证成功\n");
            
            // 获取目录信息
            struct stat dir_stat;
            if (stat(simple_dir, &dir_stat) == 0) {
                printf("目录信息:\n");
                printf("  inode: %ld\n", dir_stat.st_ino);
                printf("  大小: %ld 字节\n", dir_stat.st_size);
                printf("  权限: %o\n", dir_stat.st_mode & 0777);
                printf("  创建时间: %s", ctime(&dir_stat.st_ctime));
            }
        }
    }
    
    // 示例2: 不同权限的目录创建
    printf("\n示例2: 不同权限的目录创建\n");
    
    // 保存当前umask
    old_umask = umask(0);
    printf("当前umask: %03o\n", old_umask);
    
    // 恢复umask
    umask(old_umask);
    
    struct {
        const char *name;
        mode_t mode;
        const char *description;
    } dirs[] = {
        {"dir_rwx_rwx_rwx", 0777, "完全权限"},
        {"dir_rwx_r_x___", 0750, "所有者完全权限,组用户读执行"},
        {"dir_rwx_______", 0700, "仅所有者有权限"},
        {"dir_r_x_r_x_r_x", 0555, "只读执行权限"}
    };
    
    for (int i = 0; i < 4; i++) {
        // 添加唯一标识避免重名
        char unique_name[100];
        snprintf(unique_name, sizeof(unique_name), "%s_%d", dirs[i].name, (int)time(NULL) % 1000);
        
        if (mkdir(unique_name, dirs[i].mode) == -1) {
            if (errno == EEXIST) {
                printf("目录 %s 已存在\n", unique_name);
            } else {
                perror("创建目录失败");
            }
        } else {
            printf("创建目录: %s (权限 %03o - %s)\n", 
                   unique_name, dirs[i].mode, dirs[i].description);
            
            // 验证实际权限(考虑umask)
            struct stat stat_buf;
            if (stat(unique_name, &stat_buf) == 0) {
                mode_t actual_mode = stat_buf.st_mode & 0777;
                printf("  实际权限: %03o\n", actual_mode);
            }
            
            // 清理测试目录
            rmdir(unique_name);
        }
    }
    
    // 示例3: 多级目录创建
    printf("\n示例3: 多级目录创建\n");
    
    // 创建深层目录结构
    const char *deep_path = "level1/level2/level3";
    printf("创建深层目录: %s\n", deep_path);
    
    // 需要逐级创建
    if (mkdir("level1", 0755) == -1 && errno != EEXIST) {
        perror("创建level1失败");
    } else {
        printf("创建目录: level1\n");
        
        if (mkdir("level1/level2", 0755) == -1 && errno != EEXIST) {
            perror("创建level1/level2失败");
        } else {
            printf("创建目录: level1/level2\n");
            
            if (mkdir("level1/level2/level3", 0755) == -1 && errno != EEXIST) {
                perror("创建level1/level2/level3失败");
            } else {
                printf("创建目录: level1/level2/level3\n");
                
                // 验证目录结构
                if (access(deep_path, F_OK) == 0) {
                    printf("深层目录创建验证成功\n");
                }
            }
        }
    }
    
    // 示例4: 错误处理演示
    printf("\n示例4: 错误处理演示\n");
    
    // 尝试创建已存在的目录
    if (mkdir(simple_dir, 0755) == -1) {
        if (errno == EEXIST) {
            printf("创建已存在目录: %s\n", strerror(errno));
        }
    }
    
    // 尝试创建嵌套目录(父目录不存在)
    if (mkdir("nonexistent_parent/child", 0755) == -1) {
        if (errno == ENOENT) {
            printf("创建父目录不存在的目录: %s\n", strerror(errno));
        }
    }
    
    // 尝试在只读文件系统创建目录
    if (mkdir("/proc/test_dir", 0755) == -1) {
        if (errno == EROFS || errno == EACCES) {
            printf("在只读文件系统创建目录: %s\n", strerror(errno));
        }
    }
    
    // 尝试使用过长的路径名
    char long_path[PATH_MAX + 100];
    memset(long_path, 'a', sizeof(long_path) - 1);
    long_path[sizeof(long_path) - 1] = '\0';
    if (mkdir(long_path, 0755) == -1) {
        if (errno == ENAMETOOLONG) {
            printf("使用过长路径名: %s\n", strerror(errno));
        }
    }
    
    // 示例5: 实际应用场景
    printf("\n示例5: 实际应用场景\n");
    
    // 场景1: 应用程序数据目录创建
    printf("场景1: 应用程序数据目录创建\n");
    const char *app_dirs[] = {
        ".myapp",
        ".myapp/config",
        ".myapp/data",
        ".myapp/logs",
        ".myapp/cache"
    };
    
    printf("创建应用程序目录结构:\n");
    for (int i = 0; i < 5; i++) {
        mode_t mode = (i == 0) ? 0700 : 0755;  // 主目录更严格的权限
        if (mkdir(app_dirs[i], mode) == -1) {
            if (errno == EEXIST) {
                printf("  目录已存在: %s\n", app_dirs[i]);
            } else {
                printf("  创建 %s 失败: %s\n", app_dirs[i], strerror(errno));
            }
        } else {
            printf("  创建目录: %s (权限 %03o)\n", app_dirs[i], mode);
        }
    }
    
    // 场景2: 临时目录创建
    printf("场景2: 临时目录创建\n");
    char temp_dir_template[] = "/tmp/mkdir_test_XXXXXX";
    char *temp_dir = mkdtemp(temp_dir_template);
    if (temp_dir == NULL) {
        perror("创建临时目录失败");
    } else {
        printf("创建临时目录: %s\n", temp_dir);
        
        // 在临时目录中创建子目录
        char subdir[PATH_MAX];
        snprintf(subdir, sizeof(subdir), "%s/subdir", temp_dir);
        if (mkdir(subdir, 0755) == -1) {
            perror("创建临时子目录失败");
        } else {
            printf("在临时目录中创建子目录: %s\n", subdir);
        }
        
        // 清理临时目录
        rmdir(subdir);
        rmdir(temp_dir);
    }
    
    // 场景3: 日志目录管理
    printf("场景3: 日志目录管理\n");
    time_t now = time(NULL);
    struct tm *local_time = localtime(&now);
    char log_dir[100];
    snprintf(log_dir, sizeof(log_dir), "logs_%04d%02d%02d", 
             local_time->tm_year + 1900, 
             local_time->tm_mon + 1, 
             local_time->tm_mday);
    
    if (mkdir(log_dir, 0755) == -1) {
        if (errno == EEXIST) {
            printf("日志目录已存在: %s\n", log_dir);
        } else {
            perror("创建日志目录失败");
        }
    } else {
        printf("创建日志目录: %s\n", log_dir);
        
        // 创建按小时分类的子目录
        for (int hour = 0; hour < 24; hour += 6) {
            char hour_dir[150];
            snprintf(hour_dir, sizeof(hour_dir), "%s/hour_%02d", log_dir, hour);
            if (mkdir(hour_dir, 0755) == -1 && errno != EEXIST) {
                printf("创建小时目录 %s 失败: %s\n", hour_dir, strerror(errno));
            } else {
                printf("  创建小时目录: %s\n", hour_dir);
            }
        }
    }
    
    // 示例6: 权限和umask交互
    printf("\n示例6: 权限和umask交互\n");
    
    // 保存并设置不同的umask值进行测试
    mode_t original_umask = umask(0);
    printf("原始umask: %03o\n", original_umask);
    
    struct {
        mode_t umask_val;
        mode_t dir_mode;
        const char *desc;
    } umask_tests[] = {
        {0000, 0755, "umask 0000"},
        {0022, 0755, "umask 0022"},
        {0077, 0755, "umask 0077"},
        {0027, 0750, "umask 0027"}
    };
    
    for (int i = 0; i < 4; i++) {
        // 设置umask
        umask(umask_tests[i].umask_val);
        printf("设置umask为 %03o\n", umask_tests[i].umask_val);
        
        // 创建测试目录
        char test_dir[50];
        snprintf(test_dir, sizeof(test_dir), "umask_test_%d", i);
        if (mkdir(test_dir, umask_tests[i].dir_mode) == -1 && errno != EEXIST) {
            perror("创建测试目录失败");
        } else {
            // 检查实际权限
            struct stat stat_buf;
            if (stat(test_dir, &stat_buf) == 0) {
                mode_t actual_mode = stat_buf.st_mode & 0777;
                mode_t expected_mode = umask_tests[i].dir_mode & ~(umask_tests[i].umask_val);
                printf("  请求权限: %03o, umask: %03o, 实际权限: %03o, 期望权限: %03o\n",
                       umask_tests[i].dir_mode, umask_tests[i].umask_val, 
                       actual_mode, expected_mode);
            }
            
            // 清理
            rmdir(test_dir);
        }
    }
    
    // 恢复原始umask
    umask(original_umask);
    
    // 示例7: 目录创建性能测试
    printf("\n示例7: 目录创建性能测试\n");
    
    const int iterations = 1000;
    char perf_dir_base[] = "perf_test_XXXXXX";
    char perf_dir[100];
    
    // 创建基准目录
    if (mkdtemp(perf_dir_base) != NULL) {
        printf("在 %s 中进行性能测试\n", perf_dir_base);
        
        clock_t start = clock();
        for (int i = 0; i < iterations; i++) {
            snprintf(perf_dir, sizeof(perf_dir), "%s/dir_%d", perf_dir_base, i);
            if (mkdir(perf_dir, 0755) == -1 && errno != EEXIST) {
                printf("创建目录失败: %s\n", strerror(errno));
                break;
            }
        }
        clock_t creation_time = clock() - start;
        
        // 删除目录
        start = clock();
        for (int i = 0; i < iterations; i++) {
            snprintf(perf_dir, sizeof(perf_dir), "%s/dir_%d", perf_dir_base, i);
            rmdir(perf_dir);
        }
        clock_t deletion_time = clock() - start;
        
        printf("%d次目录创建耗时: %f 秒\n", 
               iterations, ((double)creation_time) / CLOCKS_PER_SEC);
        printf("%d次目录删除耗时: %f 秒\n", 
               iterations, ((double)deletion_time) / CLOCKS_PER_SEC);
        printf("平均每次操作耗时: %f 毫秒\n", 
               (((double)creation_time) / CLOCKS_PER_SEC * 1000) / iterations);
        
        // 清理基准目录
        rmdir(perf_dir_base);
    }
    
    // 示例8: 安全考虑
    printf("\n示例8: 安全考虑\n");
    
    // 场景: 安全的临时目录创建
    printf("安全的临时目录创建:\n");
    char secure_temp[] = "/tmp/secure_app_XXXXXX";
    char *secure_dir = mkdtemp(secure_temp);
    if (secure_dir == NULL) {
        perror("创建安全临时目录失败");
    } else {
        printf("创建安全临时目录: %s\n", secure_dir);
        printf("特点: 唯一名称,避免竞态条件\n");
        
        // 设置严格的权限
        if (chmod(secure_dir, 0700) == -1) {
            perror("设置严格权限失败");
        } else {
            printf("设置目录权限为 0700 (仅所有者可访问)\n");
        }
        
        // 清理
        rmdir(secure_dir);
    }
    
    // 示例9: 符号链接处理
    printf("\n示例9: 符号链接处理\n");
    
    // 创建测试目录
    if (mkdir("symlink_test_dir", 0755) == -1 && errno != EEXIST) {
        perror("创建符号链接测试目录失败");
    } else {
        printf("创建符号链接测试目录\n");
        
        // 创建符号链接
        if (symlink("symlink_test_dir", "symlink_to_dir") == -1 && errno != EEXIST) {
            perror("创建符号链接失败");
        } else {
            printf("创建符号链接: symlink_to_dir -> symlink_test_dir\n");
            
            // 尝试在符号链接上创建目录(会失败)
            if (mkdir("symlink_to_dir/subdir", 0755) == -1) {
                printf("通过符号链接创建子目录失败: %s\n", strerror(errno));
                printf("说明: 不能通过符号链接创建子目录\n");
            }
            
            // 清理
            unlink("symlink_to_dir");
        }
        
        rmdir("symlink_test_dir");
    }
    
    // 清理测试资源
    printf("\n清理测试资源...\n");
    
    // 删除基本测试目录
    if (access(simple_dir, F_OK) == 0) {
        if (rmdir(simple_dir) == -1) {
            printf("删除目录 %s 失败: %s\n", simple_dir, strerror(errno));
        } else {
            printf("删除目录: %s\n", simple_dir);
        }
    }
    
    // 删除深层目录结构
    if (access("level1/level2/level3", F_OK) == 0) {
        rmdir("level1/level2/level3");
        rmdir("level1/level2");
        rmdir("level1");
        printf("删除深层目录结构\n");
    }
    
    // 删除应用程序目录
    for (int i = 4; i >= 0; i--) {
        if (access(app_dirs[i], F_OK) == 0) {
            rmdir(app_dirs[i]);
        }
    }
    printf("删除应用程序目录结构\n");
    
    // 删除日志目录
    char hour_dir[150];
    for (int hour = 18; hour >= 0; hour -= 6) {
        snprintf(hour_dir, sizeof(hour_dir), "%s/hour_%02d", log_dir, hour);
        if (access(hour_dir, F_OK) == 0) {
            rmdir(hour_dir);
        }
    }
    if (access(log_dir, F_OK) == 0) {
        rmdir(log_dir);
        printf("删除日志目录\n");
    }
    
    return 0;
}

23. rmdir - 删除空目录 链接到标题

函数介绍 链接到标题

rmdir系统调用用于删除空目录。只能删除没有任何文件或子目录的目录,如果目录非空则操作失败。

函数原型 链接到标题

#include <unistd.h>

int rmdir(const char *pathname);

功能 链接到标题

删除指定路径名的空目录。

参数 链接到标题

  • const char *pathname: 要删除的目录路径名

返回值 链接到标题

  • 成功时返回0
  • 失败时返回-1,并设置errno:
    • EBUSY: 目录正在被使用
    • EACCES: 权限不足
    • EINVAL: 参数无效
    • ELOOP: 符号链接循环
    • ENAMETOOLONG: 路径名过长
    • ENOENT: 目录不存在
    • ENOTDIR: 路径不是目录
    • ENOTEMPTY: 目录非空
    • EPERM: 操作不被允许
    • EROFS: 文件系统只读

相似函数 链接到标题

  • unlink(): 删除文件
  • remove(): 删除文件或空目录
  • rmdirat(): 相对路径版本

示例代码 链接到标题

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
#include <dirent.h>

int main() {
    printf("=== Rmdir函数示例 ===\n");
    
    // 示例1: 基本的空目录删除操作
    printf("\n示例1: 基本的空目录删除操作\n");
    
    // 创建测试目录
    const char *test_dir = "test_rmdir_empty";
    if (mkdir(test_dir, 0755) == -1) {
        if (errno == EEXIST) {
            printf("测试目录已存在\n");
        } else {
            perror("创建测试目录失败");
            exit(EXIT_FAILURE);
        }
    } else {
        printf("创建测试目录: %s\n", test_dir);
    }
    
    // 验证目录存在
    if (access(test_dir, F_OK) == 0) {
        printf("目录存在验证成功\n");
    }
    
    // 删除空目录
    if (rmdir(test_dir) == -1) {
        perror("删除空目录失败");
    } else {
        printf("成功删除空目录: %s\n", test_dir);
        
        // 验证目录已删除
        if (access(test_dir, F_OK) != 0) {
            printf("目录删除验证成功\n");
        }
    }
    
    // 示例2: 非空目录删除(应该失败)
    printf("\n示例2: 非空目录删除(应该失败)\n");
    
    // 创建带文件的目录
    const char *non_empty_dir = "test_rmdir_nonempty";
    if (mkdir(non_empty_dir, 0755) == -1 && errno != EEXIST) {
        perror("创建非空测试目录失败");
    } else {
        printf("创建非空测试目录: %s\n", non_empty_dir);
        
        // 在目录中创建文件
        char file_path[PATH_MAX];
        snprintf(file_path, sizeof(file_path), "%s/test_file.txt", non_empty_dir);
        int fd = open(file_path, O_CREAT | O_WRONLY, 0644);
        if (fd != -1) {
            const char *content = "Test content for non-empty directory";
            write(fd, content, strlen(content));
            close(fd);
            printf("在目录中创建文件: test_file.txt\n");
        }
        
        // 尝试删除非空目录
        if (rmdir(non_empty_dir) == -1) {
            if (errno == ENOTEMPTY) {
                printf("删除非空目录失败(预期): %s\n", strerror(errno));
            } else {
                printf("删除非空目录失败(其他错误): %s\n", strerror(errno));
            }
        } else {
            printf("意外成功删除非空目录\n");
        }
        
        // 清理:先删除文件,再删除目录
        unlink(file_path);
        if (rmdir(non_empty_dir) == -1) {
            perror("清理非空目录失败");
        } else {
            printf("成功清理非空目录\n");
        }
    }
    
    // 示例3: 多级目录删除
    printf("\n示例3: 多级目录删除\n");
    
    // 创建多级目录结构
    const char *level1 = "rmdir_level1";
    const char *level2 = "rmdir_level1/level2";
    const char *level3 = "rmdir_level1/level2/level3";
    
    if (mkdir(level1, 0755) == -1 && errno != EEXIST) {
        perror("创建level1失败");
    } else {
        printf("创建目录: %s\n", level1);
        
        if (mkdir(level2, 0755) == -1 && errno != EEXIST) {
            perror("创建level2失败");
        } else {
            printf("创建目录: %s\n", level2);
            
            if (mkdir(level3, 0755) == -1 && errno != EEXIST) {
                perror("创建level3失败");
            } else {
                printf("创建目录: %s\n", level3);
            }
        }
    }
    
    // 删除目录(必须从最深层开始)
    printf("删除多级目录(从最深层开始):\n");
    
    if (rmdir(level3) == -1) {
        perror("删除level3失败");
    } else {
        printf("成功删除: %s\n", level3);
    }
    
    if (rmdir(level2) == -1) {
        perror("删除level2失败");
    } else {
        printf("成功删除: %s\n", level2);
    }
    
    if (rmdir(level1) == -1) {
        perror("删除level1失败");
    } else {
        printf("成功删除: %s\n", level1);
    }
    
    // 示例4: 特殊目录删除
    printf("\n示例4: 特殊目录删除\n");
    
    // 尝试删除当前目录(应该失败)
    if (rmdir(".") == -1) {
        printf("删除当前目录.: %s\n", strerror(errno));
    }
    
    // 尝试删除上级目录(应该失败)
    if (rmdir("..") == -1) {
        printf("删除上级目录..: %s\n", strerror(errno));
    }
    
    // 示例5: 错误处理演示
    printf("\n示例5: 错误处理演示\n");
    
    // 尝试删除不存在的目录
    if (rmdir("nonexistent_directory") == -1) {
        if (errno == ENOENT) {
            printf("删除不存在的目录: %s\n", strerror(errno));
        }
    }
    
    // 尝试删除文件而非目录
    const char *regular_file = "regular_file_for_rmdir_test.txt";
    int fd = open(regular_file, O_CREAT | O_WRONLY, 0644);
    if (fd != -1) {
        write(fd, "test", 4);
        close(fd);
        
        if (rmdir(regular_file) == -1) {
            if (errno == ENOTDIR) {
                printf("删除文件而非目录: %s\n", strerror(errno));
            }
        }
        
        unlink(regular_file);
    }
    
    // 尝试删除只读文件系统上的目录
    if (rmdir("/proc") == -1) {
        if (errno == EROFS || errno == EACCES || errno == EBUSY) {
            printf("删除系统目录/proc: %s\n", strerror(errno));
        }
    }
    
    // 尝试使用过长的路径名
    char long_path[PATH_MAX + 100];
    memset(long_path, 'a', sizeof(long_path) - 1);
    long_path[sizeof(long_path) - 1] = '\0';
    if (rmdir(long_path) == -1) {
        if (errno == ENAMETOOLONG) {
            printf("使用过长路径名: %s\n", strerror(errno));
        }
    }
    
    // 示例6: 实际应用场景
    printf("\n示例6: 实际应用场景\n");
    
    // 场景1: 临时目录清理
    printf("场景1: 临时目录清理\n");
    char temp_dir_template[] = "/tmp/rmdir_test_XXXXXX";
    char *temp_dir = mkdtemp(temp_dir_template);
    if (temp_dir != NULL) {
        printf("创建临时目录: %s\n", temp_dir);
        
        // 在临时目录中创建工作
        char work_file[PATH_MAX];
        snprintf(work_file, sizeof(work_file), "%s/work_file.txt", temp_dir);
        fd = open(work_file, O_CREAT | O_WRONLY, 0644);
        if (fd != -1) {
            const char *work_content = "Temporary work file content";
            write(fd, work_content, strlen(work_content));
            close(fd);
            printf("创建临时工作文件\n");
        }
        
        // 工作完成后清理
        unlink(work_file);  // 先删除文件
        if (rmdir(temp_dir) == -1) {
            perror("清理临时目录失败");
        } else {
            printf("成功清理临时目录\n");
        }
    }
    
    // 场景2: 应用程序缓存清理
    printf("场景2: 应用程序缓存清理\n");
    const char *cache_base = ".app_cache";
    
    // 创建缓存目录结构
    if (mkdir(cache_base, 0755) == -1 && errno != EEXIST) {
        perror("创建缓存基础目录失败");
    } else {
        printf("创建缓存基础目录: %s\n", cache_base);
        
        // 创建多个缓存子目录
        const char *cache_dirs[] = {"session", "temp", "downloads"};
        for (int i = 0; i < 3; i++) {
            char cache_subdir[100];
            snprintf(cache_subdir, sizeof(cache_subdir), "%s/%s", cache_base, cache_dirs[i]);
            if (mkdir(cache_subdir, 0755) == -1 && errno != EEXIST) {
                printf("创建缓存子目录 %s 失败: %s\n", cache_subdir, strerror(errno));
            } else {
                printf("创建缓存子目录: %s\n", cache_subdir);
            }
        }
        
        // 模拟清理过程
        printf("清理缓存目录:\n");
        for (int i = 2; i >= 0; i--) {
            char cache_subdir[100];
            snprintf(cache_subdir, sizeof(cache_subdir), "%s/%s", cache_base, cache_dirs[i]);
            if (rmdir(cache_subdir) == -1) {
                printf("删除缓存子目录 %s 失败: %s\n", cache_subdir, strerror(errno));
            } else {
                printf("成功删除缓存子目录: %s\n", cache_subdir);
            }
        }
        
        // 删除基础缓存目录
        if (rmdir(cache_base) == -1) {
            perror("删除基础缓存目录失败");
        } else {
            printf("成功删除基础缓存目录\n");
        }
    }
    
    // 场景3: 日志轮转清理
    printf("场景3: 日志轮转清理\n");
    const char *log_dir = "old_logs";
    if (mkdir(log_dir, 0755) == -1 && errno != EEXIST) {
        perror("创建日志目录失败");
    } else {
        printf("创建日志目录: %s\n", log_dir);
        
        // 创建一些旧日志文件(简化为在目录中创建标记)
        char log_marker[100];
        snprintf(log_marker, sizeof(log_marker), "%s/.old", log_dir);
        fd = open(log_marker, O_CREAT | O_WRONLY, 0644);
        if (fd != -1) {
            close(fd);
            printf("创建日志标记文件\n");
        }
        
        // 当需要清理时
        printf("清理旧日志目录:\n");
        unlink(log_marker);  // 先删除文件
        if (rmdir(log_dir) == -1) {
            printf("删除日志目录失败: %s\n", strerror(errno));
        } else {
            printf("成功删除日志目录\n");
        }
    }
    
    // 示例7: 递归删除辅助函数
    printf("\n示例7: 递归删除辅助函数\n");
    
    // 创建用于测试的复杂目录结构
    const char *complex_dir = "complex_rmdir_test";
    if (mkdir(complex_dir, 0755) == -1 && errno != EEXIST) {
        perror("创建复杂测试目录失败");
    } else {
        printf("创建复杂测试目录: %s\n", complex_dir);
        
        // 创建子目录和文件
        mkdir("complex_rmdir_test/sub1", 0755);
        mkdir("complex_rmdir_test/sub2", 0755);
        mkdir("complex_rmdir_test/sub1/subsub1", 0755);
        
        // 创建文件
        int test_fd = open("complex_rmdir_test/file1.txt", O_CREAT | O_WRONLY, 0644);
        if (test_fd != -1) close(test_fd);
        
        test_fd = open("complex_rmdir_test/sub1/file2.txt", O_CREAT | O_WRONLY, 0644);
        if (test_fd != -1) close(test_fd);
        
        test_fd = open("complex_rmdir_test/sub1/subsub1/file3.txt", O_CREAT | O_WRONLY, 0644);
        if (test_fd != -1) close(test_fd);
        
        printf("创建了复杂的目录结构用于演示\n");
        printf("注意: rmdir只能删除空目录,递归删除需要编程实现\n");
    }
    
    // 示例8: 权限相关错误
    printf("\n示例8: 权限相关错误\n");
    
    // 创建测试目录
    const char *permission_test_dir = "permission_test_dir";
    if (mkdir(permission_test_dir, 0755) == -1 && errno != EEXIST) {
        perror("创建权限测试目录失败");
    } else {
        printf("创建权限测试目录: %s\n", permission_test_dir);
        
        // 尝试在没有权限的情况下删除(需要特殊设置)
        printf("权限相关错误通常包括:\n");
        printf("  EACCES: 权限不足\n");
        printf("  EPERM: 操作不被允许\n");
        printf("  EBUSY: 目录正在被使用\n");
        
        // 清理
        if (rmdir(permission_test_dir) == -1) {
            perror("删除权限测试目录失败");
        } else {
            printf("成功删除权限测试目录\n");
        }
    }
    
    // 示例9: 性能考虑
    printf("\n示例9: 性能考虑\n");
    
    // 创建大量空目录进行删除测试
    const int dir_count = 100;
    char perf_test_base[] = "rmdir_perf_test_XXXXXX";
    char *perf_dir = mkdtemp(perf_test_base);
    
    if (perf_dir != NULL) {
        printf("在 %s 中进行性能测试\n", perf_dir);
        
        // 创建测试目录
        for (int i = 0; i < dir_count; i++) {
            char test_dir[PATH_MAX];
            snprintf(test_dir, sizeof(test_dir), "%s/test_dir_%d", perf_dir, i);
            mkdir(test_dir, 0755);
        }
        printf("创建了 %d 个测试目录\n", dir_count);
        
        // 删除目录并计时
        clock_t start = clock();
        for (int i = 0; i < dir_count; i++) {
            char test_dir[PATH_MAX];
            snprintf(test_dir, sizeof(test_dir), "%s/test_dir_%d", perf_dir, i);
            if (rmdir(test_dir) == -1) {
                printf("删除目录 %s 失败: %s\n", test_dir, strerror(errno));
            }
        }
        clock_t delete_time = clock() - start;
        
        printf("删除 %d 个空目录耗时: %f 秒\n", 
               dir_count, ((double)delete_time) / CLOCKS_PER_SEC);
        printf("平均每次删除耗时: %f 毫秒\n", 
               (((double)delete_time) / CLOCKS_PER_SEC * 1000) / dir_count);
        
        // 清理基准目录
        rmdir(perf_dir);
    }
    
    // 示例10: 与符号链接的交互
    printf("\n示例10: 与符号链接的交互\n");
    
    // 创建测试目录
    if (mkdir("symlink_rmdir_test", 0755) == -1 && errno != EEXIST) {
        perror("创建符号链接测试目录失败");
    } else {
        printf("创建符号链接测试目录\n");
        
        // 创建指向目录的符号链接
        if (symlink("symlink_rmdir_test", "symlink_to_rmdir_test") == -1 && errno != EEXIST) {
            perror("创建符号链接失败");
        } else {
            printf("创建符号链接: symlink_to_rmdir_test -> symlink_rmdir_test\n");
            
            // 尝试删除符号链接(会删除符号链接本身,而不是目标目录)
            if (rmdir("symlink_to_rmdir_test") == -1) {
                printf("删除符号链接失败: %s\n", strerror(errno));
            } else {
                printf("成功删除符号链接(不是目标目录)\n");
            }
        }
        
        // 清理原目录
        if (rmdir("symlink_rmdir_test") == -1) {
            perror("删除原目录失败");
        } else {
            printf("成功删除原目录\n");
        }
    }
    
    return 0;
}