1、函数 1:path_alloc 函数为路径名动态地分配空间/*这个跟版本关系很大*/#include “apue.h“ #include #include #ifdef PATH_MAX /*如果定义了路径名的最大长度*/static int pathmax = PATH_MAX; /*将它赋予我们自己定义的变量 pathmax*/#else static int pathmax = 0; /*否则该位置 0*/#endif /*上面那个 if 结束 */#define SUSV3 200112L static long posix_version = 0; /* If PATH_MAX is
2、 indeterminate, no guarantee this is adequate */ #define PATH_MAX_GUESS 1024 char * path_alloc(int *sizep) /* also return allocated size, if nonnull */ char *ptr; int size; if (posix_version = 0) posix_version = sysconf(_SC_VERSION); if (pathmax = 0) /* first time through */ errno = 0; if (pathmax =
3、 pathconf(“/“, _PC_PATH_MAX) #include #include #include #include “ourhdr.h“typedef int Myfunc(const char *, const struct stat *, int);/* function type thats called for each filename */static Myfunc myfunc;static int myftw(char *, Myfunc *);static int dopath(Myfunc *);static long nreg, ndir, nblk, nc
4、hr, nfifo, nslink, nsock, ntot;intmain(int argc, char *argv)int ret;if (argc != 2) /*输入的参数个数不为 2,提醒输入的格式*/err_quit(“usage: ftw “);ret = myftw(argv1, myfunc); /* 解析整个完整的路径 */if ( (ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock) = 0) /*一个文件也没有,这个类每个都是 0*/ntot = 1;/*特殊技巧,分母为 0,置 1 也无妨,只要非 0
5、即可 0/1=0*/printf(“regular files = %7ld, %5.2f %n“, nreg, nreg*100.0/ntot);printf(“directories = %7ld, %5.2f %n“, ndir, ndir*100.0/ntot);printf(“block special = %7ld, %5.2f %n“, nblk, nblk*100.0/ntot);printf(“char special = %7ld, %5.2f %n“, nchr, nchr*100.0/ntot);printf(“FIFOs = %7ld, %5.2f %n“, nfif
6、o, nfifo*100.0/ntot);printf(“symbolic links = %7ld, %5.2f %n“, nslink,nslink*100.0/ntot);printf(“sockets = %7ld, %5.2f %n“, nsock, nsock*100.0/ntot);exit(ret);/* Descend through the hierarchy, starting at “pathname“.* The callers func() is called for every file.*/#define FTW_F 1 /* 不是目录的文件 */#define
7、 FTW_D 2 /* 目录*/#define FTW_DNR 3 /* 不可以读的文件 */#define FTW_NS 4 /* 不能被 stat 的文件 */static char *fullpath; /* 包含每个文件的完整路径名 */static int /* 我们返回任何 func()函数返回的*/myftw(char *pathname, Myfunc *func)fullpath = path_alloc(NULL); /这里采用默认的 path_alloc 大小*/*这里调用 path_alloc 函数,所以要 gcc 2.c error.c path_alloc.c -o
8、 2*/strcpy(fullpath, pathname);/不用像课本那样,strcpy 自动在结束的位置补上/n/* 为 fullpath 变量初始化 */return(dopath(func);/* 通过层次进行下降操作,我们从全路径开始* 如果是一个绝对的路径而非一个目录,我们调用 lstat 函数* call func(), and return. For a directory, we call ourself* recursively for each name in the directory.*/static int dopath(Myfunc* func)struct s
9、tat statbuf; /*statbuf 是 stat 结构体的实例*/struct dirent *dirp; /*为获取文件夹目录所用的结构体 */DIR *dp; /*与目录有关的指针*/int ret;char *ptr; /*保存要显示的字符串*/if (lstat(fullpath, /*忽略.和*/strcpy(ptr, dirp-d_name); /* append name after slash */if ( (ret = dopath(func) != 0)/* recursive */break; /* time to leave */ptr-1 = 0; /* e
10、rase everything from slash onwards */if (closedir(dp) st_mode break;case S_IFBLK: nblk+; break;case S_IFCHR: nchr+; break;case S_IFIFO: nfifo+; break;case S_IFLNK: nslink+; break;case S_IFSOCK: nsock+; break;case S_IFDIR:err_dump(“for S_IFDIR for %s“, pathname);/* directories should have type = FTW_
11、D */break;case FTW_D:ndir+;break;case FTW_DNR:err_ret(“cant read directory %s“, pathname);break;case FTW_NS:err_ret(“stat error for %s“, pathname);break;default:err_dump(“unknown type %d for pathname %s“, type, pathname);return(0);3.lstat 函数int lstat(const char *pathname, struct stat *buf); 文件类型用中说明
12、的文件类型宏测试S_ISREG(mode) = 1 正规文件(S_IFREG)S_ISDIR(mode) = 1 目录文件(S_IFDIR)S_ISCHR(mode) = 1 字符特殊文件(S_IFCHR)S_ISBLK(mode) = 1 块特殊文件(S_IFBLK)S_ISFIFO(mode) = 1 管道或 FIFO 文件(S_IFFIFO)S_ISLNK(mode) = 1 符号链接(S_IFLNK)S_ISSOCK(mode) = 1 套接口(S_IFSOCK)针对每个命令参数打印其文件类型#include #include #include “ourhdr.h“int main(i
13、nt argc, char *argv)int i;struct stat buf;char *ptr;for (i = 1; i argc; i+)printf(“%s: “, argvi);if (lstat(argvi, continue;if (S_ISREG(buf.st_mode) ptr = “regular“;else if (S_ISDIR(buf.st_mode) ptr = “directory“;else if (S_ISCHR(buf.st_mode) ptr = “character special“);else if (S_ISBLK(buf.st_mode) ptr = “block special“;else if (S_ISFIFO(buf.st_mode) ptr = “fifo“;else if (S_ISLNK(buf.st_mode) ptr = “symbolic link“;else if (S_ISSOCK(buf.st_mode) ptr = “socket“;else ptr = “* unknown mode *“;/*不是以上这几类,那是未知模式*/printf(“%sn“, ptr);/*打印类型字符串*/exit(0);