栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux系统编程 50 -stat和stat函数 穿透和非穿透

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux系统编程 50 -stat和stat函数 穿透和非穿透

学习笔记
修改程序,用于判断文件类型

$cat mystat.c
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    struct stat sbuf;
    int ret = stat(argv[1],&sbuf);
    if( -1 == ret )
    {
        perror("stat error");
        exit(1);
    }

//    printf("file size:%ldn",sbuf.st_size);

    if(S_ISREG(sbuf.st_mode))
    {
        printf("it is a regularn");
    }
    else if (S_ISDIR(sbuf.st_mode))
    {
        printf("it is a dictory!n");
    }
    else if(S_ISFIFO(sbuf.st_mode))
    {
        printf("it is a pipen");
    }
    else if(S_ISLNK(sbuf.st_mode))
    {
        printf("it is a sym linkn");
    }
    return 0;
}

makefile 文件为

$cat makefile 
src=$(wildcard ./*.c) 
target=$(patsubst %.c,%,$(src)) 
myArgs= -Wall -g
All:${target}
%:%.c
    gcc  $< -o $@ $(myArgs)
clean:
    -rm -rf $(target) a.out 
.PHONY: clean All


make下

make mystat
gcc  mystat.c -o mystat -Wall -g

普通文件

$./mystat f.c
it is a regular


文件夹

$mkdir newdir
$./mystat newdir
it is a dictory!

管道文件

$mkfifo myfifo
$./mystat myfifo 
it is a pipe

软链接

$ln -s f.c f.soft
$ll
total 48
drwxrwxr-x 3 ubuntu ubuntu  4096 12月 24 20:47 ./
drwxrwxr-x 9 ubuntu ubuntu  4096 12月 24 20:15 ../
-rwxr--r-- 1 ubuntu ubuntu   500 12月 24 20:15 f.c*
lrwxrwxrwx 1 ubuntu ubuntu     3 12月 24 20:47 f.soft -> f.c*
-rwxr--r-- 1 ubuntu ubuntu   178 12月 24 20:15 makefile*
prw-rw-r-- 1 ubuntu ubuntu     0 12月 24 20:46 myfifo|
-rwxrwxr-x 1 ubuntu ubuntu 20560 12月 24 20:45 mystat*
-rw-rw-r-- 1 ubuntu ubuntu   600 12月 24 20:45 mystat.c
drwxrwxr-x 2 ubuntu ubuntu  4096 12月 24 20:45 newdir/

$./mystat f.soft 
it is a regular


提示软链接是普通文件!!!
也可以个目录创建软链接(但是不能给目录创建硬链接)

$ln -s newdir newdir.soft
$ls
f.c  f.soft  makefile  myfifo  mystat  mystat.c  newdir  newdir.soft
$ll
total 48
drwxrwxr-x 3 ubuntu ubuntu  4096 12月 24 20:53 ./
drwxrwxr-x 9 ubuntu ubuntu  4096 12月 24 20:15 ../
-rwxr--r-- 1 ubuntu ubuntu   500 12月 24 20:15 f.c*
lrwxrwxrwx 1 ubuntu ubuntu     3 12月 24 20:47 f.soft -> f.c*
-rwxr--r-- 1 ubuntu ubuntu   178 12月 24 20:15 makefile*
prw-rw-r-- 1 ubuntu ubuntu     0 12月 24 20:46 myfifo|
-rwxrwxr-x 1 ubuntu ubuntu 20560 12月 24 20:45 mystat*
-rw-rw-r-- 1 ubuntu ubuntu   600 12月 24 20:45 mystat.c
drwxrwxr-x 2 ubuntu ubuntu  4096 12月 24 20:45 newdir/
lrwxrwxrwx 1 ubuntu ubuntu     6 12月 24 20:53 newdir.soft -> newdir/
$./mystat newdir.soft
it is a dictory!

也同样提示目录的软链接是文件夹!!!

为什么没有提示是链接呢?
问题出在stat身上。

这种现象称之为stat穿透(穿透符号链接),

不想穿透的话,使用lstat函数(不会穿透符号链接)

修改程序:

$cat mylstat.c
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    struct stat sbuf;
    int ret =lstat(argv[1],&sbuf);
    if( -1 == ret )
    {
        perror("stat error");
        exit(1);
    }

//    printf("file size:%ldn",sbuf.st_size);

    if(S_ISREG(sbuf.st_mode))
    {
        printf("it is a regularn");
    }
    else if (S_ISDIR(sbuf.st_mode))
    {
        printf("it is a dictory!n");
    }
    else if(S_ISFIFO(sbuf.st_mode))
    {
        printf("it is a pipen");
    }
    else if(S_ISLNK(sbuf.st_mode))
    {
        printf("it is a sym linkn");
    }
    return 0;
}
$make mylstat
gcc  mylstat.c -o mylstat -Wall -g
$./mylstat newdir.soft
it is a sym link
$./mylstat f.soft 
it is a sym link


穿透和不穿透

$ls -l f.soft
lrwxrwxrwx 1 ubuntu ubuntu 3 12月 24 20:47 f.soft -> f.c

这里面的3 代表 f.c文件名的长度
ls -l 不穿透符号链接

$cat f.c
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112a$
$cat f.soft
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112a$


所以cat 穿透符号链接,看到本尊(f.c)。


获取文件的大小:sbuf.st_size
获取文件的类型:sbuf.st_mode
获取文件的权限:sbuf.st_mode


man 查看函数说明的时候,对应重要的函数
一般会有demo,使用G,就可以调到demo那里

#include 
#include 
#include 
#include 
#include 
#include 

int
main(int argc, char *argv[])
{
    struct stat sb;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if (lstat(argv[1], &sb) == -1) {
        perror("lstat");
        exit(EXIT_FAILURE);
    }

    printf("ID of containing device:  [%lx,%lx]n",
         (long) major(sb.st_dev), (long) minor(sb.st_dev));

    printf("File type:                ");
   switch (sb.st_mode & S_IFMT) {
    case S_IFBLK:  printf("block devicen");            break;
    case S_IFCHR:  printf("character devicen");        break;
    case S_IFDIR:  printf("directoryn");               break;
    case S_IFIFO:  printf("FIFO/pipen");               break;
    case S_IFLNK:  printf("symlinkn");                 break;
    case S_IFREG:  printf("regular filen");            break;
    case S_IFSOCK: printf("socketn");                  break;
    default:       printf("unknown?n");                break;
    }

    printf("I-node number:            %ldn", (long) sb.st_ino);

    printf("Mode:                     %lo (octal)n",
            (unsigned long) sb.st_mode);

    printf("link count:               %ldn", (long) sb.st_nlink);
    printf("Ownership:                UID=%ld   GID=%ldn",
            (long) sb.st_uid, (long) sb.st_gid);

    printf("Preferred I/O block size: %ld bytesn",
            (long) sb.st_blksize);
    printf("File size:                %lld bytesn",
            (long long) sb.st_size);
    printf("Blocks allocated:         %lldn",
            (long long) sb.st_blocks);
    printf("Last status change:       %s", ctime(&sb.st_ctime));
    printf("Last file access:         %s", ctime(&sb.st_atime));
    printf("Last file modification:   %s", ctime(&sb.st_mtime));

    exit(EXIT_SUCCESS);
}

问题:如何查看 man中 宏定义的具体指 比如 S_IFMT


我的方法(自己发现):
1.在查stat的系统调用

man 2 stat

2.查看具体成员

st_mode
       This field contains the file type and mode.  See inode(7) for further information.


       
3. 根据提示inode(7)
在shell中,输入

man 7 inode

S_IFMT     0170000   bit mask for the file type bit field

S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO

S_ISUID     04000   set-user-ID bit (see execve(2))
S_ISGID     02000   set-group-ID bit (see below)
S_ISVTX     01000   sticky bit (see below)

S_IRWXU     00700   owner has read, write, and execute permission
S_IRUSR     00400   owner has read permission
S_IWUSR     00200   owner has write permission
S_IXUSR     00100   owner has execute permission

S_IRWXG     00070   group has read, write, and execute permission
S_IRGRP     00040   group has read permission
S_IWGRP     00020   group has write permission
S_IXGRP     00010   group has execute permission

S_IRWXO     00007   others  (not  in group) have read, write, and
                    execute permission
S_IROTH     00004   others have read permission
S_IWOTH     00002   others have write permission
S_IXOTH     00001   others have execute permission


S_IFMT     就是位掩码

 
文件类型加上未知,总共8种。

特殊权限的最后一位叫做黏着位。


对应stat/lstat需要掌握 文件大小 文件类型 符号穿透

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/675485.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号