LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 691|回复: 2

这个自定义函数什么时候会返回非零值?

[复制链接]
发表于 2010-6-27 11:12:31 | 显示全部楼层 |阅读模式
  1. #include "apue2.h"
  2. #include <dirent.h>
  3. #include <limits.h>
  4. typedef int Myfunc(const char *, const struct stat *, int);//函数指针
  5.                                 /* function type that's called for each filename */
  6. static Myfunc        myfunc;
  7. static int      myftw(char *, Myfunc *);
  8. static int        dopath(Myfunc *);
  9. static long         nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
  10. int
  11. main(int argc, char *argv[])
  12. {
  13.         int                ret;
  14.         if (argc != 2)
  15.                 err_quit("usage:  ftw  <starting-pathname>");
  16.         ret = myftw(argv[1], myfunc);                /* does it all */
  17.         if ( (ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock) == 0)
  18.                 ntot = 1;                /* avoid divide by 0; print 0 for all counts */
  19.         printf("regular files  = %7ld, %5.2f %%\n", nreg,  nreg*100.0/ntot);
  20.         printf("directories    = %7ld, %5.2f %%\n", ndir,  ndir*100.0/ntot);
  21.         printf("block special  = %7ld, %5.2f %%\n", nblk,  nblk*100.0/ntot);
  22.         printf("char special   = %7ld, %5.2f %%\n", nchr,  nchr*100.0/ntot);
  23.         printf("FIFOs          = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);
  24.         printf("symbolic links = %7ld, %5.2f %%\n", nslink,nslink*100.0/ntot);
  25.         printf("sockets        = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);
  26.         exit(ret);
  27. }
  28. /*
  29. * Descend through the hierarchy, starting at "pathname".
  30. * The caller's func() is called for every file.
  31. */
  32. #define        FTW_F        1                /* file other than directory */
  33. #define        FTW_D        2                /* directory */
  34. #define        FTW_DNR        3                /* directory that can't be read */
  35. #define        FTW_NS        4                /* file that we can't stat */
  36. static char        *fullpath;                /* contains full pathname for every file */
  37. static int                                        /* we return whatever func() returns */
  38. myftw(char *pathname, Myfunc *func)
  39. {
  40.         fullpath = path_alloc(NULL);        /* malloc's for PATH_MAX+1 bytes */
  41.                                                                         /* ({Prog pathalloc}) */
  42.         strcpy(fullpath, pathname);                /* initialize fullpath */
  43.         return(dopath(func));
  44. }
  45. /*
  46. * Descend through the hierarchy, starting at "fullpath".
  47. * If "fullpath" is anything other than a directory, we lstat() it,
  48. * call func(), and return.  For a directory, we call ourself
  49. * recursively for each name in the directory.
  50. */
  51. static int                                        /* we return whatever func() returns */
  52. dopath(Myfunc* func)
  53. {
  54.         struct stat                statbuf;
  55.         struct dirent        *dirp;
  56.         DIR                                *dp;
  57.         int                                ret;
  58.         char                        *ptr;
  59.         if (lstat(fullpath, &statbuf) < 0)
  60.                 return(func(fullpath, &statbuf, FTW_NS));        /* stat error */
  61.         if (S_ISDIR(statbuf.st_mode) == 0)
  62.                 return(func(fullpath, &statbuf, FTW_F));        /* not a directory */
  63.         /*
  64.          * It's a directory.  First call func() for the directory,
  65.          * then process each filename in the directory.
  66.          */
  67. /******************************************************
  68. /*接下的这句话,func什么时候会返回非零值呢?下面的实现都只有返回0吖。。。******************
  69. ********************************************************/
  70.         if ( (ret = func(fullpath, &statbuf, FTW_D)) != 0)
  71.                 return(ret);
  72.         ptr = fullpath + strlen(fullpath);        /* point to end of fullpath */
  73.         *ptr++ = '/';
  74.         *ptr = 0;
  75.         if ( (dp = opendir(fullpath)) == NULL)
  76.                 return(func(fullpath, &statbuf, FTW_DNR));
  77.                                                                                 /* can't read directory */
  78.         while ( (dirp = readdir(dp)) != NULL) {
  79.                 if (strcmp(dirp->d_name, ".") == 0  ||
  80.                     strcmp(dirp->d_name, "..") == 0)
  81.                                 continue;                /* ignore dot and dot-dot */
  82.                 printf("%s\n", fullpath);
  83.                 strcpy(ptr, dirp->d_name);        /* append name after slash */
  84.                 if ( (ret = dopath(func)) != 0)                /* recursive */
  85.                         break;        /* time to leave */
  86.         }
  87.         ptr[-1] = 0;        /* erase everything from slash onwards */
  88.         if (closedir(dp) < 0)
  89.                 err_ret("can't close directory %s", fullpath);
  90.         return(ret);
  91. }
  92. static int
  93. myfunc(const char *pathname, const struct stat *statptr, int type)
  94. {
  95.         switch (type) {
  96.         case FTW_F:
  97.                 switch (statptr->st_mode & S_IFMT) {
  98.                 case S_IFREG:        nreg++;                break;
  99.                 case S_IFBLK:        nblk++;                break;
  100.                 case S_IFCHR:        nchr++;                break;
  101.                 case S_IFIFO:        nfifo++;        break;
  102.                 case S_IFLNK:        nslink++;        break;
  103.                 case S_IFSOCK:        nsock++;        break;
  104.                 case S_IFDIR:
  105.                         err_dump("for S_IFDIR for %s", pathname);
  106.                                         /* directories should have type = FTW_D */
  107.                 }
  108.                 break;
  109.         case FTW_D:
  110.                 ndir++;
  111.                 break;
  112.         case FTW_DNR:
  113.                 err_ret("can't read directory %s", pathname);
  114.                 break;
  115.         case FTW_NS:
  116.                 err_ret("stat error for %s", pathname);
  117.                 break;
  118.         default:
  119.                 err_dump("unknown type %d for pathname %s", type, pathname);
  120.         }
  121.         return(0);
  122. }
复制代码
 楼主| 发表于 2010-6-27 12:24:21 | 显示全部楼层
if ( (ret = func(fullpath, &statbuf, FTW_D)) != 0)
这个的ret是myfunc的返回值,可以是非零值,但是下面的实现却只有一个return 0;这个非零值是作为递归结束的条件的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-27 16:20:10 | 显示全部楼层
好像我说错了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表