int _access( const char * _Filename, int _AccessMode)

本文详细介绍了使用access函数检查文件访问模式的方法,包括文件是否存在、是否可运行、可写访问、可读访问及可读/写访问等五种模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

access(filename, 0)=0 表示判断文件是否存在 
  
  finename 文件名称 mode 模式,共5种模式: 
  
  0-检查文件是否存在 
  
  1-检查文件是否可运行 
  
  2-检查文件是否可写访问 
  
  4-检查文件是否可读访问 
  
  6-检查文件是否可读/写访问
// 补全状态结构(优化版) typedef struct { char **matches; // 所有匹配项 int count; // 匹配项总数 char *base_dir; // 当前基础目录 char *original_prefix; // 原始前缀 char *current_text; // 当前输入文本 int last_state; // 上一次使用的state值 int current_level; // 当前目录层级 char *persistent_path; // 持久化路径(同时作为初始化标志) int is_directory; int max_level; // 最大允许层级(关键新增) } CompletionState; static CompletionState comp_state = { .matches = NULL, .count = 0, .base_dir = NULL, .original_prefix = NULL, .current_text = NULL, .last_state = -1, .current_level = 0, .persistent_path = NULL, .is_directory = 0, .max_level = -1 }; // 重置补全状态 void reset_completion_state() { if (comp_state.matches) { for (int i = 0; i < comp_state.count; i++) { XFREE(MTYPE_TMP, comp_state.matches[i]); } XFREE(MTYPE_TMP, comp_state.matches); comp_state.matches = NULL; } if (comp_state.original_prefix) { XFREE(MTYPE_TMP, comp_state.original_prefix); } if (comp_state.base_dir) { XFREE(MTYPE_TMP, comp_state.base_dir); } if (comp_state.current_text) { XFREE(MTYPE_TMP, comp_state.current_text); } if (comp_state.persistent_path) { XFREE(MTYPE_TMP, comp_state.persistent_path); } comp_state.count = 0; comp_state.original_prefix = NULL; comp_state.base_dir = NULL; comp_state.current_text = NULL; comp_state.last_state = -1; comp_state.current_level = 0; comp_state.persistent_path = NULL; // 关键:清除持久化路径 comp_state.is_directory = 0; comp_state.max_level = -1; } // 路径比较函数(目录优先) int compare_paths(const void *a, const void *b) { const char *sa = *(const char **)a; const char *sb = *(const char **)b; // 目录优先 int is_dir_a = (sa[strlen(sa)-1] == '/'); int is_dir_b = (sb[strlen(sb)-1] == '/'); if (is_dir_a && !is_dir_b) return -1; if (!is_dir_a && is_dir_b) return 1; return strcmp(sa, sb); } // 修复的路径解析函数 void parse_input_text(const char *text, char **base_dir, char **prefix, int *level) { *level = 0; const char *ptr = text; while (*ptr) { if (*ptr == '/') (*level)++; ptr++; } const char *last_slash = strrchr(text, '/'); const char *last_char = text + strlen(text) - 1; if (last_slash) { if (last_char == last_slash) { // 以斜杠结尾:整个路径作为基础目录 *base_dir = XSTRDUP(MTYPE_TMP, text); *prefix = XSTRDUP(MTYPE_TMP, ""); } else { // 路径中包含文件名 size_t base_len = last_slash - text + 1; *base_dir = (char *)XCALLOC(MTYPE_TMP, base_len + 1); strncpy(*base_dir, text, base_len); (*base_dir)[base_len] = '\0'; *prefix = XSTRDUP(MTYPE_TMP, last_slash + 1); } } else { // 无斜杠:当前目录 *base_dir = XSTRDUP(MTYPE_TMP, ""); *prefix = XSTRDUP(MTYPE_TMP, text); } printf("parse_input_text: text = %s, base_dir = %s, prefix = %s, level = %d\n", text, *base_dir, *prefix, *level); } int is_same_completion_context(const char *text) { if (!comp_state.persistent_path || comp_state.max_level == -1) { return 0; } char *temp_base = NULL; char *temp_prefix = NULL; int current_level = 0; parse_input_text(text, &temp_base, &temp_prefix, &current_level); int same_path = strncmp(text, comp_state.persistent_path, strlen(comp_state.persistent_path)) == 0; // 只有在当前路径是持久化路径的子目录或匹配时才继续 int within_level = (current_level <= comp_state.max_level); XFREE(MTYPE_TMP, temp_base); XFREE(MTYPE_TMP, temp_prefix); printf("is_same_completion_context: same_path=%d, within_level=%d\n", same_path, within_level); return same_path && within_level; } char **generate_current_dir_paths(const char *base_dir, const char *prefix, int add_empty) { const char *scan_dir = base_dir; if (!scan_dir || !*scan_dir) { scan_dir = "."; } printf("[generate] Scanning directory: '%s' with prefix: '%s'\n", scan_dir, prefix ? prefix : "(none)"); DIR *dir = opendir(scan_dir); if (!dir) { if (add_empty) { char **matches = (char **)XCALLOC(MTYPE_TMP, sizeof(char *)); matches[0] = XSTRDUP(MTYPE_TMP, ""); return matches; } return NULL; } int capacity = 32; int count = 0; char **matches = (char **)XCALLOC(MTYPE_TMP, capacity*sizeof(char *)); struct dirent *entry; while ((entry = readdir(dir)) != NULL) { const char *name = entry->d_name; // 跳过 '.' 和 '..' if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { continue; } // 前缀匹配 if (prefix && *prefix && strncmp(name, prefix, strlen(prefix)) != 0) { continue; } // 构造补全项 int is_dir = (entry->d_type == DT_DIR); if (entry->d_type == DT_UNKNOWN) { char full_path[PATH_MAX]; snprintf(full_path, sizeof(full_path), "%s/%s", scan_dir, name); struct stat statbuf; if (stat(full_path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { is_dir = 1; } } char *new_name; if (is_dir) { new_name = (char *)XCALLOC(MTYPE_TMP, strlen(name) + 2); snprintf(new_name, strlen(name) + 2, "%s/", name); } else { new_name = XSTRDUP(MTYPE_TMP, name); } // 动态扩展数组 if (count >= capacity) { capacity *= 2; matches = (char **)XREALLOC(MTYPE_TMP, matches, capacity * sizeof(char *)); } matches[count++] = new_name; } closedir(dir); // 排序补全结果 if (count > 0) { qsort(matches, count, sizeof(char *), compare_paths); } // NULL 终止 matches = (char **)XREALLOC(MTYPE_TMP, matches, (count + 2) * sizeof(char *)); matches[count] = NULL; // 如果非顶层补全,添加空字符串作为补全结束标志 if (!add_empty) { matches[count] = XSTRDUP(MTYPE_TMP, ""); matches[count + 1] = NULL; } printf("[generate] Found %d matches.\n", count); return matches; } // 修复的智能文件补全函数 char *filename_completion_function(const char *text, int state) { printf("\n[COMP] Entering: text='%s', state=%d, last_state=%d\n", text, state, comp_state.last_state); // 初始化新补全 if (state == 0) { printf(" Starting new completion\n"); int same_context = is_same_completion_context(text); printf(" Same context: %d\n", same_context); if (!same_context) { reset_completion_state(); char *current_base = NULL; char *current_prefix = NULL; int current_level = 0; parse_input_text(text, &current_base, &current_prefix, &current_level); comp_state.base_dir = current_base; comp_state.current_text = XSTRDUP(MTYPE_TMP, text); comp_state.original_prefix = XSTRDUP(MTYPE_TMP, current_prefix); comp_state.current_level = current_level; comp_state.max_level = current_level + 3; // 可配置最大补全层级 // 检查是否用户已经明确进入了子目录 int ends_with_slash = text[strlen(text) - 1] == '/'; if (ends_with_slash) { // 用户明确进入子目录,允许下层补全 comp_state.persistent_path = XSTRDUP(MTYPE_TMP, text); comp_state.max_level = current_level + 3; } else { // 用户未进入子目录,只补全当前目录项 comp_state.persistent_path = XSTRDUP(MTYPE_TMP, current_base); comp_state.max_level = current_level; } // 生成当前目录的补全项 comp_state.matches = generate_current_dir_paths(current_base, current_prefix, current_level == 0); comp_state.count = 0; if (comp_state.matches) { while (comp_state.matches[comp_state.count]) { comp_state.count++; } printf(" Generated %d matches\n", comp_state.count); } else { comp_state.count = 0; } comp_state.last_state = -1; // 重置索引 } } // 没有匹配项 if (!comp_state.matches || comp_state.count == 0) { printf("[COMP] No matches found\n"); return NULL; } // 获取下一个匹配项 int next_index = (comp_state.last_state + 1) % comp_state.count; comp_state.last_state = next_index; char *match = comp_state.matches[next_index]; // 构建完整路径 char *full_path = NULL; if (comp_state.base_dir && strlen(comp_state.base_dir) > 0) { int base_len = strlen(comp_state.base_dir); int needs_slash = base_len > 0 && comp_state.base_dir[base_len - 1] != '/'; full_path = (char *)XCALLOC(MTYPE_TMP, strlen(match) + base_len + 2); if (needs_slash) { snprintf(full_path, strlen(match) + base_len + 2, "%s/%s", comp_state.base_dir, match); } else { snprintf(full_path, strlen(match) + base_len + 2, "%s%s", comp_state.base_dir, match); } } else { full_path = XSTRDUP(MTYPE_TMP, match); } printf("[COMP] Returning: '%s'\n", full_path); return full_path; } 保持这个逻辑,进行优化
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值