S_ISLNK S_ISREG S_ISDIR S_ISCHR S_ISBLK S_ISFIFO S_ISSOCK等宏的介

stat函数讲解:

表头文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
  • 定义函数: int stat(const char *file_name, struct stat *buf);
  • 函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
  • 返回值: 执行成功则返回0,失败返回-1,错误代码存于errno
  • 错误代码:
ENOENT 参数file_name指定的文件不存在
ENOTDIR 路径中的目录存在但却非真正的目录
ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT 参数buf为无效指针,指向无法存在的内存空间
EACCESS 存取文件时被拒绝
ENOMEM 核心内存不足
ENAMETOOLONG 参数file_name的路径名称太长
  • 接口函数
int stat(const char *file_name,struct stat *buf); 
int fstat(int filedes,struct stat *buf); 
  • stat 结构定义于:/usr/include/sys/stat.h 文件中
struct stat {
  mode_t st_mode; //文件对应的模式,文件,目录等
  ino_t st_ino; //i-node节点号
  dev_t st_dev; //设备号码
  dev_t st_rdev; //特殊设备号码
  nlink_t st_nlink; //文件的连接数
  uid_t st_uid; //文件所有者
  gid_t st_gid; //文件所有者对应的组
  off_t st_size; //普通文件,对应的文件字节数
  time_t st_atime; //文件最后被访问的时间
  time_t st_mtime; //文件内容最后被修改的时间
  time_t st_ctime; //文件状态(属性)改变时间
  blksize_t st_blksize; //文件内容对应的块大小
  blkcnt_t st_blocks; //文件内容对应的块数量
};
  • stat用来判断没有打开的文件,而fstat用来判断打开的文件.我们使用最多的属性是st_mode.通过着属性我们可以判断给定的文件是一个普通文件还是一个目录,连接等等.
  • 常用宏
S_ISLNK(st_mode):是否是一个连接.
S_ISREG是否是一个常规文件.
S_ISDIR是否是一个目录
S_ISCHR是否是一个字符设备.
S_ISBLK是否是一个块设备
S_ISFIFO是否是一个FIFO文件.
S_ISSOCK是否是一个SOCKET文件. 
  • 下面的程序中有一小撮有用到S_ISFIFO
#include <stdio.h>
#include <unistd.h>
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <fcntl.h>              /* Obtain O_* constant definitions */
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <error.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>

void client(int,int),server(int,int);
#define MAXLINE     4096    /* max text line length */
#define FIFO_NAME "/tmp/mplayer.fifo"
int main(int argc,char *argv[]){

    int pipe1[2],pipe2[2],r,fd;
    pid_t childpid;
    int check_up=0;
    check_up=pipe(pipe1);
    assert(check_up>=0);
    check_up=pipe(pipe2);
    assert(check_up>=0);
    r = mkfifo(FIFO_NAME, 0755);
    if( -1 == r){
        assert(errno == EEXIST);
    }
    fd = open(FIFO_NAME, O_RDWR);
    assert(fd!=-1);

    struct stat buf;
    fstat(pipe1[0],&buf);
    if(check_up=S_ISFIFO(buf.st_mode)){//这里的返回值是1
        printf("check_up=%d,pipe1[0] is a fifo file\n",check_up);
    }else{
        printf("it is ...\n");
    }
    fstat(fd,&buf);
    if(check_up=S_ISFIFO(buf.st_mode)){//这里的返回值为什么也是1,有大佬能解释一下吗
                                    //如果都一样怎么区分管道和FIFO
        printf("check_up=%d,fd is a fifo file\n",check_up);
    }else{
        printf("it is ...\n");
    }

    childpid=fork();
    assert(childpid>=0);
    if(childpid==0){
        close(pipe1[1]);//用1读
        close(pipe2[0]);//用2写

        server(pipe1[0],pipe2[1]);
        exit(0);
    }
    close(pipe1[0]);//用1写
    close(pipe2[1]);//用2读
    client(pipe2[0],pipe1[1]);
    exit(0);
}
void client(int readfd, int writefd)
{
    size_t  len;
    ssize_t n;
    char    buff[MAXLINE];

        /* 4read pathname */
    fgets(buff, MAXLINE, stdin);
    len = strlen(buff);     /* fgets() guarantees null byte at end */
    if (buff[len-1] == '\n')
        len--;              /* delete newline from fgets() */

        /* 4write pathname to IPC channel */
    write(writefd, buff, len);

        /* 4read from IPC, write to standard output */
    while ( (n = read(readfd, buff, MAXLINE)) > 0)
        write(STDOUT_FILENO, buff, n);
}
void server(int readfd, int writefd)
{
    int     fd;
    ssize_t n;
    char    buff[MAXLINE+1];

        /* 4read pathname from IPC channel */
    if ( (n = read(readfd, buff, MAXLINE)) == 0){
        printf("end-of-file while reading pathname");
        exit(0);
    }
    buff[n] = '\0';     /* null terminate pathname */

    if ( (fd = open(buff, O_RDONLY)) < 0) {
            /* 4error: must tell client */
        snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n",
                 strerror(errno));
        n = strlen(buff);
        write(writefd, buff, n);

    } else {
            /* 4open succeeded: copy file to IPC channel */
        while ( (n = read(fd, buff, MAXLINE)) > 0)
            write(writefd, buff, n);
        close(fd);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值