曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5073|回复: 3
打印 上一主题 下一主题

stat, fstat,lstat

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2008-11-16 23:14:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
名字:
      stat()--得到文件的状态

包含头文件:
      
      #include <sys/stat.h>
      #include <sys/types.h>
   
原型:
       int stat(const char *path, struct stat *buf);

参数:
       path     文件名(包括路径)
       buf      指向状态结构体的指针

返回值:
  
       -1       遇到错误
       0        成功返回

举例:

#include <stdio.h>
#include <sys/stat.h>

int main()
{
    struct stat infobuf;

    if( stat("/etc/passwd", &infobuf) == -1 )
    perror("/etc/passwd");

    else
    printf(" The size of /etc/passwd is %d\n", infobuf.st_size);
}

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-2-8 09:33:08 | 只看该作者
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int fstat(int fildes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);

注意:在 sys/types.h 里所包含的内容是可选的,但建议当进行系统调用时使用它们,因为里面一些定义使用了在日后可能改变的标准类型的别名。

stat 和 lstat 的功能基本相同,它们都返回文件的状态信息。它们产生相同的结果,除了文件是一个符号链接。lstat 返回链接本身的信息,而 stat 返回链接指向的文件的信息。

stat 结构信息
struct stat {
     dev_t     st_dev;     /* ID of device containing file */
     ino_t     st_ino;     /* inode number */
     mode_t    st_mode;    /* protection 文件类型和许可权限*/
     nlink_t   st_nlink;   /* number of hard links 硬链接数*/
     uid_t     st_uid;     /* user ID of owner 用户所有者的ID*/
     gid_t     st_gid;     /* group ID of owner 所属组的ID*/
     dev_t     st_rdev;    /* device ID (if special file) */
     off_t     st_size;    /* total size, in bytes 所占的字节数*/
     blksize_t st_blksize; /* blocksize for filesystem I/O */
     blkcnt_t  st_blocks;  /* number of blocks allocated */
     time_t    st_atime;   /* time of last access 文件最后访问时间*/
     time_t    st_mtime;   /* time of last modification文件最后修改时间*/
     time_t    st_ctime;   /* time of last status change 文件属性最后改变时间*/
};

在 stat 中返回的 st_mode 也包含有一组宏,这些宏定在在头文件 sys/stat.h 中。这些宏包含权限的名字,文件类型标志,和一些对特定类型和权限进行测试有帮助的掩码。

文件类型(File-type)标志
S_IFBLK -- 块设备入口
S_IFDIR -- 目录入口
S_IFCHR -- 字符设备入口
S_IFIFO -- FIFO 入口(named pipe)
S_IFREG -- 普通文件(regular file)
S_IFLNK -- 符号链接入口(symbolic link)

其他模式标志
S_ISUID -- Entry has setUID on execution(在执行上有setUID权限的入口 ) 
S_ISGID -- Entry has setGID on execution(在执行上有setGID权限的入口)

mask 起来以解释 st_mode 标志
S_IFMT -- 文件类型
S_IRWXU -- user读/写/执行权限
S_IRWXG -- group读/写/执行权限
S_IRWXO -- other 读/写/执行权限

一些用来确定文件类型的宏
S_ISBLK -- 测试块文件
S_ISCHR -- 测试字符文件
S_ISDIR -- 测试目录
S_ISFIFO -- 测试FIFO
S_ISREG -- 测试普通文件
S_ISLNK -- 测试符号链接

例如,测试一个不是目录且仅拥有者有执行权限的文件,可以如下使用:
struct stat statbuf;
mode_t modes

stat( "filaname", &statbuf );
modes = statbuf.st_mode;

if(!S_ISDIR(modes) && (modes & S_IRWXU) == S_IXUSR)
   ...

示例程序
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
     int i;
     struct stat buf;
     char *ptr;
     for (i = 0; i < argc; i++) {
         printf ("%s: ", argv[i]);
         if (lstat (argv[i], &buf) < 0) {
             perror ("lstat");
             continue;
         }
         if (S_ISREG(buf.st_mode))
             ptr = "regular file";
         else if (S_ISDIR(buf.st_mode))
             ptr = "directory fle";
         else if (S_ISCHR(buf.st_mode))
             ptr = "character special file";
         else if (S_ISBLK(buf.st_mode))
             ptr = "block special file";
         else if (S_ISFIFO(buf.st_mode))
             ptr = "fifo file";
#ifdef S_ISLNK
         else if (S_ISLNK(buf.st_mode))
             ptr = "symbolic link";
#endif

#ifdef S_ISSOCK
         else if (S_ISSOCK(buf.st_mode))
             ptr = "socket";
#endif
         else
             ptr = "** unknown mode **";
         
         printf ("%s\\n", ptr);
     }
     return (0);
}
运行与输出
./lstat dir_test
./lstat: regular file
dir_test: directory fle

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
板凳
 楼主| 发表于 2008-11-17 14:16:03 | 只看该作者
例2:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>


int main(int ac, char *av[])
{
    struct stat info;

    if(ac>1)
    if( stat(av[1], &info) != -1 ){
        show_stat_info( av[1],&info);
        return 0;
    }
    else
        perror(av[1]);
    return 1;
}

show_stat_info(char *filename, struct stat *buf)
{
    printf("    mode: %o\\n", buf->st_mode);
    printf("   links: %d\\n", buf->st_nlink);
    printf("     usr: %d\\n", buf->st_uid);
    printf("   group: %d\\n", buf->st_gid);
    printf("    size: %d\\n", buf->st_size);
    printf(" modtime: %d\\n", buf->st_mtime);
    printf("    name: %s\\n", filename);
}

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
地板
 楼主| 发表于 2008-11-17 14:40:30 | 只看该作者
在 struct stat 结构中的 st_mode 里,存储着 文件类型许可权限,形式如下:

type3
type2
type1
type0
suid
sgid
sticky
r
w
x
r
w
x
r
w
x


在 <sys/stat.h> 中定义

# define S_IFMT        __S_IFMT
....

再看 <bits/stat.h> 中的定义:

/* Encoding of the file mode.  */

#define    __S_IFMT    0170000    /* These bits determine file type.  */

-----------------------------------------------------------------------
/* File types.  */

#define    __S_IFDIR    0040000    /* Directory.  */

#define    __S_IFCHR    0020000   
/* Character device.  */

#define    __S_IFBLK    0060000   
/* Block device.  */

#define    __S_IFREG    0100000   
/* Regular file.  */

#define    __S_IFIFO    0010000   
/* FIFO.  */

#define    __S_IFLNK    0120000   
/* Symbolic link.  */

#define    __S_IFSOCK    0140000   
/* Socket.  */

这些都是掩码,用来过滤出文件类型;
如 S_IFREG 代表普通文件,S_IFDIR 表示目录文件。下面的代码:

if( ( info.st_mode & 0170000 ) == 0040000 )
    printf("This is a directory:);

通过掩码把其他无关的部分置0,再与表示目录的代码比较,从而判断这是否是一个目录。

更方便的是,使用 <sys/stat.h> 中提供的宏来代替上述代码:


/* Test macros for file types.    */

#define    __S_ISTYPE(mode, mask)    (((mode) & __S_IFMT) == (mask))

#define    S_ISDIR(mode)     __S_ISTYPE((mode), __S_IFDIR)
#define    S_ISCHR(mode)     __S_ISTYPE((mode), __S_IFCHR)
#define    S_ISBLK(mode)     __S_ISTYPE((mode), __S_IFBLK)
#define    S_ISREG(mode)     __S_ISTYPE((mode), __S_IFREG)
#ifdef __S_IFIFO
# define S_ISFIFO(mode)     __S_ISTYPE((mode), __S_IFIFO)
#endif
#ifdef __S_IFLNK
# define S_ISLNK(mode)     __S_ISTYPE((mode), __S_IFLNK)
#endif

由上面的宏定义,可把代码写成:

if( S_ISDIR( info.st_mode ) )
    printf("This is a directory");
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 23:19 , Processed in 0.076793 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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