You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac平台C语言目录遍历工具输入无效目录时卡顿无响应问题排查

目录遍历工具问题修复方案

问题根源

输入不存在的目录时程序卡顿,核心原因是主函数中错误的do-while循环逻辑:每次chdir(input)失败后就执行chdir(".."),只要当前目录不是根目录,chdir("..")就会返回0,导致无限循环,永远无法进入后续的错误处理流程。

同时代码还存在其他冗余与错误:

  • recursive_list中重复调用opendir,导致目录指针泄漏
  • 错误提示信息不清晰(如perror("-1"))
  • 违反需求使用了fgets读取输入

修复后的代码

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>

// 使用系统定义的PATH_MAX,避免自定义值与系统实际限制冲突
#ifndef PATH_MAX
#define PATH_MAX 256
#endif

void recursive_list(const char *directory) {
    DIR *dir = opendir(directory);
    if (dir == NULL) {
        perror("Failed to open directory");
        return;
    }

    struct dirent *ent;
    while ((ent = readdir(dir)) != NULL) {
        printf("%s\n", ent->d_name);
    }

    closedir(dir);
}

void myls(const char *directory) {
    if (!directory) {
        fprintf(stderr, "Error: Null directory pointer\n");
        exit(EXIT_FAILURE);
    }

    struct stat st;
    // 直接验证路径是否存在且为目录
    if (stat(directory, &st) == -1 || !S_ISDIR(st.st_mode)) {
        perror("Invalid directory");
        return;
    }

    printf("%s\n", directory);
    recursive_list(directory);
}

int main() {
    char cwd[PATH_MAX];
    char input[PATH_MAX];
    ssize_t read_len;

    if (!getcwd(cwd, sizeof(cwd))) {
        perror("getcwd() failed");
        return EXIT_FAILURE;
    }

    printf("Directory: ");
    // 使用read读取输入,满足"不使用fgets等函数"的需求
    read_len = read(STDIN_FILENO, input, sizeof(input) - 1);
    if (read_len == -1) {
        perror("Failed to read input");
        return EXIT_FAILURE;
    }

    // 处理输入:截断换行符,处理空输入
    input[read_len] = '\0';
    size_t input_len = strlen(input);
    if (input_len > 0 && input[input_len - 1] == '\n') {
        input[input_len - 1] = '\0';
        input_len--;
    }

    if (input_len == 0) {
        // 无输入时使用当前目录
        myls(cwd);
    } else {
        // 直接验证输入目录有效性,无需错误的chdir循环
        myls(input);
    }

    return EXIT_SUCCESS;
}

关键修改点

  • 移除错误的do-while循环:改用stat函数直接验证输入路径是否为有效目录,逻辑简洁且避免无限循环
  • 修复资源泄漏:recursive_list中只调用一次opendir,确保目录指针被正确关闭
  • 替换输入读取方式:用read替代fgets,满足需求限制
  • 优化错误提示:使用清晰的错误信息,便于定位问题
  • 对齐系统定义:使用系统原生的PATH_MAX,避免自定义值引发的兼容性问题

验证逻辑说明

  1. 读取输入后自动处理换行符,判断是否为空输入,为空则使用当前目录
  2. 非空输入时,通过stat函数做两层校验:
    • 校验路径是否存在、是否有权限访问
    • 校验路径对应的文件类型是否为目录
  3. 有效目录则调用遍历函数输出条目,无效则直接打印错误信息

内容的提问来源于stack exchange,提问作者Raúl Armas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 10:13:14