微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用S_ISREG()和S_ISDIR()POSIX宏?

这是一个C程序,用于递归地导航和输出目录和常规文件.它在我的 Linux机器上编译并运行正常.但是在Solaris上,dit-> d_type == 8检查和其他类似的检查不起作用,因为没有d_type字段.我读到这个问题的答案是使用S_ISREG()和S_ISDIR()宏,但是它们在我的代码当中没有任何办法.我评论了在我的Linux机器上工作的线条.
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

void helper(DIR *,struct dirent *,struct stat,char *,int,char **);
void dircheck(DIR *,char **);

int main(int argc,char *argv[]){

  DIR *dip;
  struct dirent *dit;
  struct stat statbuf;
  char currentPath[FILENAME_MAX];
  int depth = 0; /*Used to correctly space output*/

  /*Open Current Directory*/
  if((dip = opendir(".")) == NULL)
    return errno;

  /*Store Current Working Directory in currentPath*/
  if((getcwd(currentPath,FILENAME_MAX)) == NULL)
    return errno;

  /*Read all items in directory*/
  while((dit = readdir(dip)) != NULL){
    /*Skips . and ..*/
    if(strcmp(dit->d_name,".") == 0 || strcmp(dit->d_name,"..") == 0)
      continue;

    if(stat(currentPath,&statbuf) == -1){
      perror("stat");
      return errno;
    }

    /*Checks if current item is of the type file (type 8) and no command line arguments
      if(dit->d_type == 8 && argv[1] == NULL)*/
    if(S_ISREG(statbuf.st_mode) && argv[1] == NULL)
      printf("%s (%d bytes)\n",dit->d_name,(int)statbuf.st_size);

      /*If a command line argument is given,checks for filename match
    if(dit->d_type == 8 && argv[1] != NULL)*/
    if(S_ISREG(statbuf.st_mode) && argv[1] != NULL)
      if(strcmp(dit->d_name,argv[1]) == 0)
        printf("%s (%d bytes)\n",(int)statbuf.st_size);

      /*Checks if current item is of the type directory (type 4)
      if(dit->d_type == 4)*/
    if(S_ISDIR(statbuf.st_mode))
      dircheck(dip,dit,statbuf,currentPath,depth,argv);

  }
  closedir(dip);
  return 0;
}

/*Recursively called helper function*/
void helper(DIR *dip,struct dirent *dit,struct stat statbuf,char currentPath[FILENAME_MAX],int depth,char *argv[]){
  int i = 0;

  if((dip = opendir(currentPath)) == NULL)
    printf("Error: Failed to open Directory ==> %s\n",currentPath);

  while((dit = readdir(dip)) != NULL){

    if(strcmp(dit->d_name,"..") == 0)
      continue;

    stat(currentPath,&statbuf);

    /*if(dit->d_type == 8 && argv[1] == NULL){*/
    if(S_ISREG(statbuf.st_mode) && argv[1] == NULL){
      for(i = 0; i < depth; i++)
        printf("    ");
      printf("%s (%d bytes)\n",(int)statbuf.st_size);
    }

    /*if(dit->d_type == 8 && argv[1] != NULL){*/
    if(S_ISREG(statbuf.st_mode) && argv[1] != NULL){
      if(strcmp(dit->d_name,argv[1]) == 0){
    for(i = 0; i < depth; i++)
      printf("    ");
    printf("%s (%d bytes)\n",(int)statbuf.st_size);
      }
    }

    /*if(dit->d_type == 4)*/
    if(S_ISDIR(statbuf.st_mode))
      dircheck(dip,argv);

  }
}

void dircheck(DIR *dip,char *argv[]){
  int i = 0;

  strcat(currentPath,"/");
  strcat(currentPath,dit->d_name);

  /*If two directories exist at the same level the path
    is built wrong and needs to be corrected*/
  if((chdir(currentPath)) == -1){
    chdir("..");
    getcwd(currentPath,FILENAME_MAX);
    strcat(currentPath,"/");
    strcat(currentPath,dit->d_name);

    for(i = 0; i < depth; i++)
      printf ("    ");
    printf("%s (subdirectory)\n",dit->d_name);
    depth++;
    helper(dip,argv);
  }

  else{
    for(i =0; i < depth; i++)
      printf("    ");
    printf("%s (subdirectory)\n",dit->d_name);
    chdir(currentPath);
    depth++;
    helper(dip,argv);
  }

}

解决方法

你正在使用S_ISREG()和S_ISDIR(),你只是用错了的东西.

在你的while((dit = readdir(dip))!= NULL)循环中,你正在一遍又一遍地调用currentPath上的stat,而不改变currentPath:

if(stat(currentPath,&statbuf) == -1) {
    perror("stat");
    return errno;
}

您不应该将斜杠和dit-> d_name附加到currentPath以获取统计文件的完整路径? Methinks也需要与其他统计调用类似的更改.

原文地址:https://www.jb51.cc/c/110768.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐