• myownftw.c(4.21)


    //Having read code for a long time, finally i get it written down, and it doesn't seem that hard, you can do it!!
     
    #include "apue.h"
    #include <dirent.h>
    #include <limits.h>
     
     
    #ifdef        PATH_MAX
    static int  pathmax = PATH_MAX;
    #else
    static int  pathmax = 0;
    #endif
     
    #define SUSV3 200112L
     
    static long        posix_version = 0;
     
    /* If PATH_MAX is 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 = pathconf("/", _PC_PATH_MAX)) < 0) {
          if (errno == 0)
             pathmax = PATH_MAX_GUESS;       /* it's indeterminate */
          else
             err_sys("pathconf error for _PC_PATH_MAX");
        } else {
          pathmax++;          /* add one since it's relative to root */
        }
      }
      if (posix_version < SUSV3)
        size = pathmax + 1;
      else
        size = pathmax;
     
      if ((ptr = malloc(size)) == NULL)
        err_sys("malloc error for pathname");
     
      if (sizep != NULL)
        *sizep = size;
      return(ptr);
    }
     
     
    typedef int Myfunc(const char *,const struct stat *, int);
     
    static Myfunc myfunc;
    static int dopath(Myfunc *);
    static int myftw(const char *, Myfunc *);
     
    static int nreg, ndir, nblk, nchr, nsock, nslink, nfifo, ntot;
     
    int main(int argc, char *argv[]){
      int ret;
     
      if(argc != 2)
        err_quit("<usage> %s pathname", argv[0]);
     
      ret = myftw(argv[1], myfunc);
     
      ntot = nreg + nblk + nchr + ndir + nsock + nslink + nfifo;
      if(ntot == 0)
        ntot = 1;
     
      printf("regular files       = %7ld, %5.2f%%\n",  nreg, nreg*100.0/ntot);
      printf("directories         = %7ld, %5.2f%%\n",  ndir, ndir*100.0/ntot);
      printf("character special   = %7ld, %5.2f%%\n",  nchr, nchr*100.0/ntot);
      printf("block sepcial       = %7ld, %5.2f%%\n",  nblk, nblk*100.0/ntot);
      printf("sockets             = %7ld, %5.2f%%\n",  nsock, nsock*100.0/ntot);
      printf("symbolic link       = %7ld, %5.2f%%\n",  nslink, nslink*100.0/ntot);
      printf("FIFOs               = %7ld, %5.2f%%\n",  nfifo, nfifo*100.0/ntot);
     
      exit(ret);
    }
     
    static char *fullpath;
     
    static int myftw(const char *pathname, Myfunc func){
      int len, ret;
      fullpath = path_alloc(&len);
     
      strncpy(fullpath, pathname, len);
      fullpath[len-1] = 0;
     
      return(dopath(func));
    }
     
    #define FTW_F 1
    #define FTW_D 2
    #define FTW_NS 3
    #define FTW_DNR 4
     
    static int dopath(Myfunc func){
      struct stat statbuf;
      DIR *dp;
      struct dirent *dirp;
      int ret;
      char *ptr;
     
     
      if(lstat(fullpath, &statbuf) < 0)
        return(func(fullpath, &statbuf, FTW_NS));
      if(S_ISDIR(statbuf.st_mode) == 0)
        return(func(fullpath, &statbuf, FTW_F));
     
      if((ret = func(fullpath, &statbuf, FTW_D)) < 0)
        return(ret);
     
      ptr = fullpath + strlen(fullpath);
      *ptr++ = '/';
      *ptr = 0;
     
      if((dp = opendir(fullpath)) == NULL)
        return(func(fullpath, &statbuf, FTW_DNR));
      while((dirp = readdir(dp)) != NULL){
        if(!strcmp(dirp->d_name, ".") ||
           !strcmp(dirp->d_name, ".."))
          continue;
        // not "strcat(fullpath, dirp->d_name)"
        strcpy(ptr, dirp->d_name);
        if((ret = dopath(func)) < 0)
          break;
      }
     
      ptr[-1] = 0;
      if(closedir(dp) < 0)
        err_ret("close dir %s error", fullpath);
     
      return ret;
    }
     
     
    static int
    myfunc(const char *pathname, const struct stat *statbuf, int type){
      switch(type){
      case FTW_F:
        switch(statbuf->st_mode & S_IFMT){
        case S_IFREG: nreg++; break;
        case S_IFCHR: nchr++; break;
        case S_IFBLK: nblk++; break;
        case S_IFIFO: nfifo++; break;
        case S_IFSOCK: nsock++; break;
        case S_IFLNK: nslink++; break;
        case S_IFDIR:
          err_dump("for S_IFDIR for %s", pathname);
        }
        break;
     case FTW_D:
       ndir++;
       break;
     case FTW_NS:
       err_ret("stat error for %s", pathname);
       break;
     case FTW_DNR:
       err_ret("can't read directory %s", pathname);
       break;
     default:
       err_dump("unknown type %d for pathname %s", type, pathname);
     
       return(0);
      }
    }
  • 相关阅读:
    go语言】Goroutines 并发模式
    Mysql Innodb 引擎优化 参数(innodb_buffer_pool_size)
    多key业务,数据库水平切分架构一次搞定
    Goroutine是如何工作的?
    PHP进程之信号捕捉中的declare(ticks=1)
    php多进程总结
    mysql强制性操作
    rabbitMQ高可用
    服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
    mysql在innodb索引下b+树的高度问题。
  • 原文地址:https://www.cnblogs.com/beanmoon/p/2731690.html
Copyright © 2020-2023  润新知