ftw.c
来自「一个C源代码分析器」· C语言 代码 · 共 217 行
C
217 行
/* Copyright (C) 1992 Free Software Foundation, Inc.This file is part of the GNU C Library.Contributed by Ian Lance Taylor (ian@airs.com).The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with the GNU C Library; see the file COPYING.LIB. Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA. */#include <ansidecl.h>#include <errno.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <dirent.h>#include <sys/types.h>#include <sys/stat.h>#include <ftw.h>#ifndef PATH_MAX#define PATH_MAX 1024 /* XXX */#endif/* Traverse one level of a directory tree. */static intDEFUN (ftw_dir, (dirs, level, descriptors, dir, len, func), DIR **dirs AND int level AND int descriptors AND char *dir AND size_t len AND int EXFUN((*func), (CONST char *file, struct stat *status, int flag))){ int got; struct dirent *entry; got = 0; errno = 0; while ((entry = readdir (dirs[level])) != NULL) { struct stat s; int flag, ret, newlev; ++got; if (entry->d_name[0] == '.' && (entry->d_namlen == 1 || (entry->d_namlen == 2 && entry->d_name[1] == '.'))) { errno = 0; continue; } if (entry->d_namlen + len + 1 > PATH_MAX) {#ifdef ENAMETOOLONG errno = ENAMETOOLONG;#else errno = ENOMEM;#endif return -1; } dir[len] = '/'; memcpy ((PTR) (dir + len + 1), (PTR) entry->d_name, entry->d_namlen + 1); if (stat (dir, &s) < 0) { if (errno != EACCES) return -1; flag = FTW_NS; } else if (S_ISDIR (s.st_mode)) { newlev = (level + 1) % descriptors; if (dirs[newlev] != NULL) closedir (dirs[newlev]); dirs[newlev] = opendir (dir); if (dirs[newlev] != NULL) flag = FTW_D; else { if (errno != EACCES) return -1; flag = FTW_DNR; } } else flag = FTW_F; ret = (*func) (dir, &s, flag); if (flag == FTW_D) { if (ret == 0) ret = ftw_dir (dirs, newlev, descriptors, dir, entry->d_namlen + len + 1, func); if (dirs[newlev] != NULL) { int save; save = errno; closedir (dirs[newlev]); errno = save; dirs[newlev] = NULL; } } if (ret != 0) return ret; if (dirs[level] == NULL) { int skip; dir[len] = '\0'; dirs[level] = opendir (dir); if (dirs[level] == NULL) return -1; skip = got; while (skip-- != 0) { errno = 0; if (readdir (dirs[level]) == NULL) return errno == 0 ? 0 : -1; } } errno = 0; } return errno == 0 ? 0 : -1;}/* Call a function on every element in a directory tree. */intDEFUN(ftw, (dir, func, descriptors), CONST char *dir AND int EXFUN((*func), (CONST char *file, struct stat *status, int flag)) AND int descriptors){ DIR **dirs; size_t len; char buf[PATH_MAX + 1]; struct stat s; int flag, ret; int i; if (descriptors <= 0) descriptors = 1; dirs = (DIR **) __alloca (descriptors * sizeof (DIR *)); i = descriptors; while (i-- > 0) dirs[i] = NULL; if (stat (dir, &s) < 0) { if (errno != EACCES) return -1; flag = FTW_NS; } else if (S_ISDIR (s.st_mode)) { dirs[0] = opendir (dir); if (dirs[0] != NULL) flag = FTW_D; else { if (errno != EACCES) return -1; flag = FTW_DNR; } } else flag = FTW_F; len = strlen (dir); memcpy ((PTR) buf, (PTR) dir, len + 1); ret = (*func) (buf, &s, flag); if (flag == FTW_D) { if (ret == 0) ret = ftw_dir (dirs, 0, descriptors, buf, len, func); if (dirs[0] != NULL) { int save; save = errno; closedir (dirs[0]); errno = save; } } return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?