免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1691 | 回复: 2
打印 上一主题 下一主题

[Linux] stat函数无法读取文件信息?求助! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-30 22:35 |只看该作者 |倒序浏览
本帖最后由 丨乌托邦丶 于 2013-12-30 22:37 编辑

在看《unix/linux编程实践》这本书,有个实现linux命令ls -l 的程序ls2,情况是这样的:如果在当前目录下运行ls2程序:./ls2,可以正常打印文件信息,就如ls -l命令实现的功

能一样,但是当显示指定目录信息时就出问题了,如:./ls2 /tmp,这样运行程序后就提示/tmp下的所有文件No such file or directory,而.和..确可以正常显示,

我添加测试代码后,觉得应该是在stat函数读取文件信息的时候出了问题,但是没能找出问题的解决方法,求各位指点下:
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <dirent.h>
  4. #include <sys/stat.h>
  5. #include <string.h>

  6. void do_ls (char []);
  7. void dostat (char *);
  8. void show_file_info (char *, struct stat *);
  9. void mode_to_letters (int , char []);
  10. char *uid_to_name (uid_t );
  11. char *gid_to_name (gid_t );

  12. int main (int ac, char *av[])
  13. {
  14.         if (ac == 1)
  15.           do_ls (".");
  16.         else
  17.         {
  18.                 while (--ac)
  19.                 {
  20.                         printf ("%s:\n", * ++av);
  21.                         do_ls (*av);
  22.                 }
  23.         }
  24.         return 0;
  25. }

  26. void do_ls (char dirname[])
  27. {
  28.         DIR *dir_ptr;
  29.         struct dirent *direntp;

  30.         if ((dir_ptr = opendir (dirname)) == NULL)
  31.           fprintf (stderr, "ls1: cannot open %s\n", dirname);
  32.         else
  33.         {
  34.                 while ((direntp = readdir (dir_ptr)) != NULL)
  35.                   dostat (direntp -> d_name);
  36.                 closedir (dir_ptr);
  37.         }
  38. }

  39. void dostat (char *filename)
  40. {
  41.         struct stat info;
  42.        
  43.         if (stat (filename, &info) == -1)   //我觉得应该是这里的stat函数出现了问题,但是不知道具体是什么原因?
  44.           perror (filename);
  45.         else
  46.           show_file_info (filename, &info);
  47. }

  48. void show_file_info (char *filename, struct stat *info_p)
  49. {
  50.         char *uid_to_name(), *ctime(), *gid_to_name(), *filemode();
  51.         void mode_to_letters();
  52.         char modestr[11];

  53.         mode_to_letters (info_p -> st_mode, modestr);

  54.         printf ("%s ", modestr);
  55.         printf ("%4d ", (int)info_p -> st_nlink);
  56.         printf ("%-8s ", uid_to_name (info_p -> st_uid));
  57.         printf ("%-8s ", gid_to_name (info_p -> st_gid));
  58.         printf ("%8ld ", (long)info_p -> st_size);
  59.         printf ("%.12s ", 4+ctime (&info_p -> st_mtime));
  60.         printf ("%s\n", filename);
  61. }

  62. void mode_to_letters (int mode, char str[])
  63. {
  64.         strcpy (str, "----------");

  65.         if (S_ISDIR (mode)) str[0] = 'd';
  66.         if (S_ISCHR (mode)) str[0] = 'c';
  67.         if (S_ISBLK (mode)) str[0] = 'b';

  68.         if (mode & S_IRUSR) str[1] = 'r';
  69.         if (mode & S_IWUSR) str[2] = 'w';
  70.         if (mode & S_IXUSR) str[3] = 'x';

  71.         if (mode & S_IRGRP) str[4] = 'r';
  72.         if (mode & S_IWGRP) str[5] = 'w';
  73.         if (mode & S_IXGRP) str[6] = 'x';

  74.         if (mode & S_IROTH) str[7] = 'r';
  75.         if (mode & S_IWOTH) str[8] = 'w';
  76.         if (mode & S_IXOTH) str[9] = 'x';
  77. }

  78. #include <pwd.h>

  79. char *uid_to_name (uid_t uid)
  80. {
  81.         struct passwd *getpwuid(), *pw_ptr;
  82.         static char numstr[10];

  83.         if ((pw_ptr = getpwuid (uid)) == NULL)
  84.         {
  85.                 sprintf (numstr, "%d", uid);
  86.                 return numstr;
  87.         }
  88.         else
  89.           return pw_ptr -> pw_name;
  90. }

  91. #include <grp.h>

  92. char *gid_to_name (gid_t gid)
  93. {
  94.         struct group *getgrgid(), *grp_ptr;
  95.         static char numstr[10];

  96.         if ((grp_ptr = getgrgid(gid)) == NULL)
  97.         {
  98.                 sprintf (numstr, "%d", gid);
  99.                 return numstr;
  100.         }
  101.         else
  102.           return grp_ptr -> gr_name;
  103. }
复制代码

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2013-12-31 09:30 |只看该作者
回复 1# 丨乌托邦丶


    stat(3) 的第一个参数是个 file path,如果你只给个 filename,那么它就从当前目录下查找该文件,一般情况下是找不到的,由于 . 和 .. 每个目录下都有,自然找得到。

要改正这个问题,有两种方法:调用 stat(3) 之前先切换到目标目录下;或者在调用 stat(3) 时给 filename 前附上目标目录名构成一个绝对路径。

论坛徽章:
0
3 [报告]
发表于 2013-12-31 12:49 |只看该作者
回复 2# MMMIX

谢谢!
说着感觉好忧桑,搞IT的居然有点惧怕英语,发现问题所在了也没能去好好看看stat的联机帮助,唉,以后得多多注意下才行啊~


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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP