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

$cat mystat.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>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:%ld\n",sbuf.st_size);if(S_ISREG(sbuf.st_mode)){printf("it is a regular\n");}else if (S_ISDIR(sbuf.st_mode)){printf("it is a dictory!\n");}else if(S_ISFIFO(sbuf.st_mode)){printf("it is a pipe\n");}else if(S_ISLNK(sbuf.st_mode)){printf("it is a sym link\n");}return 0;
}

makefile 文件为

$cat makefile
src=$(wildcard ./*.c)
target=$(patsubst %.c,%,$(src))
myArgs= -Wall -g
All:${target}
%:%.cgcc  $< -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>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:%ld\n",sbuf.st_size);if(S_ISREG(sbuf.st_mode)){printf("it is a regular\n");}else if (S_ISDIR(sbuf.st_mode)){printf("it is a dictory!\n");}else if(S_ISFIFO(sbuf.st_mode)){printf("it is a pipe\n");}else if(S_ISLNK(sbuf.st_mode)){printf("it is a sym link\n");}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 <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>int
main(int argc, char *argv[])
{struct stat sb;if (argc != 2) {fprintf(stderr, "Usage: %s <pathname>\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 device\n");            break;case S_IFCHR:  printf("character device\n");        break;case S_IFDIR:  printf("directory\n");               break;case S_IFIFO:  printf("FIFO/pipe\n");               break;case S_IFLNK:  printf("symlink\n");                 break;case S_IFREG:  printf("regular file\n");            break;case S_IFSOCK: printf("socket\n");                  break;default:       printf("unknown?\n");                break;}printf("I-node number:            %ld\n", (long) sb.st_ino);printf("Mode:                     %lo (octal)\n",(unsigned long) sb.st_mode);printf("Link count:               %ld\n", (long) sb.st_nlink);printf("Ownership:                UID=%ld   GID=%ld\n",(long) sb.st_uid, (long) sb.st_gid);printf("Preferred I/O block size: %ld bytes\n",(long) sb.st_blksize);printf("File size:                %lld bytes\n",(long long) sb.st_size);printf("Blocks allocated:         %lld\n",(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_modeThis 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 fieldS_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   FIFOS_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 permissionS_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 permissionS_IRWXO     00007   others  (not  in group) have read, write, andexecute 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需要掌握 文件大小 文件类型 符号穿透

Linux系统编程 50 -stat和stat函数 穿透和非穿透相关推荐

  1. 【Linux系统编程】可重入函数和不可重入函数

    在实时系统的设计中,经常会出现多个任务调用同一个函数的情况.如果有一个函数不幸被设计成为这样:那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果.这样的函数是不安全的 ...

  2. 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)

    文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...

  3. Linux系统编程总结

    day2 vim的三种工作模式 命令模式 vi hello.c zz 保存退出 2.编辑模式 i a o s (有大写)可以写东西 3.末行模式: 文本和末行模式不能直接切换 要切换回命令模式 再到末 ...

  4. linux系统编程之文件与I/O(六):fcntl 函数与文件锁

    2013-05-14 11:26 8290人阅读 评论(2) 收藏 举报  分类: linux系统编程(19)  版权声明:本文为博主原创文章,未经博主允许不得转载. 一.fcntl函数 功能:操纵文 ...

  5. linux系统发送信号的系统调用是,linux系统编程之信号:信号发送函数sigqueue和信号安装函数sigaction...

    信号发送函数sigqueue和信号安装函数sigaction sigaction函数用于改变进程接收到特定信号后的行为. sigqueue()是比较新的发送信号系统调用,主要是针对实时信号提出的(当然 ...

  6. 【Linux系统编程】vfork() 函数详解

    00. 目录 文章目录 00. 目录 01. vfork函数 02. fork和vfork区别 03. 父子进程地址空间 04. 附录 01. vfork函数 函数分析 #include <sy ...

  7. 【Linux系统编程】fork()函数详解

    00. 目录 文章目录 00. 目录 01. 进程创建函数 02. 父子进程结构 03. 父子进程地址空间 04. 附录 01. 进程创建函数 #include <sys/types.h> ...

  8. linux系统编程学习_(2)进程控制-- fork函数、exec函数族、回收子进程--孤儿进程僵尸进程、wait函数

    linux系统编程学习_(2)进程控制-- fork函数.exec函数族.回收子进程–孤儿进程僵尸进程.wait函数 进程控制 fork()函数 创建一个子进程. pid_t fork(void); ...

  9. Linux系统编程 37 -makefile2个函数和clean

    Linux系统编程 37 -makefile2个函数和clean 学习笔记 一个makefile 就是用一个个规则凑在一起 2个函数 wildcard patsubst wildcard 百搭牌,通配 ...

最新文章

  1. 浏览器设置是否显示图片,可随时切换
  2. queue java 判断重复值_java集合类深入分析之Queue篇(Q,DQ)
  3. Java Code Examples for java.net.Authenticator
  4. python读取mysql数据_如何将mysql的数据读取python
  5. java netty socket_Java-彻底弄懂netty-原来netty是这样启动的-知识铺
  6. java addcallback函数_java中怎么使用callback函数?
  7. 苹果Swift语言入门教程【中文版】
  8. Netty设计模式应用
  9. TestNG基础教程 - IntelliJ IDEA中配置TestNG.xml, 查看TestNG Report
  10. ipv6有必要打开吗_路由器中的IPv6功能需不需要开启?
  11. 181008 逆向-inctf(load3r、Decoy)
  12. mybatis批量新增和修改
  13. Unity3D基础3:贴图与材质球
  14. 数据挖掘工具主要有哪几种?
  15. 简单明了的java反射机制
  16. python爬京东联盟_Python+Selenium+Chrome抓取京东商品信息
  17. 如何经营咖啡加盟店和独立咖啡店?用好国外成功经营咖啡馆四大法则
  18. VisualStudio/VS在一个项目中添加多个c++文件
  19. AE脚本:AE导入SubRip/SRT/TXT/VTT字幕
  20. 一种简单的图形旋转算法

热门文章

  1. 服务器组装 华硕主板,华硕主板装机教程 华硕主板装机步骤
  2. 电脑表格日期怎么修改原有日期_如何在Excel表中自动生成记录数据的日期和时间...
  3. 固定IP地址及其重启后地址更改的解决方法
  4. 分享 10 个高星的创意项目!
  5. Unity VR切换场景闪退
  6. YDOOK: Putty 下载安装详细教程 可用 已解决
  7. openwrt源码分析_Luci流程分析(openwrt下)
  8. 软件测试工程师的前景如何,软件测试工程师工资一般多少,前景怎么样
  9. 三、硬盘分类与操作系统的启动流程
  10. 百度网盘网页版视频在线倍速播放