stat实现

int stat(const char *pathname, struct stat *statbuf);

将会得到一个struct stat类型的变量statbuf。

struct stat是一个结构体类型

struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               nlink_t   st_nlink;       /* Number of hard links */
               uid_t     st_uid;         /* User ID of owner */
               gid_t     st_gid;         /* Group ID of owner */
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */
               blksize_t st_blksize;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };

其中文件的类型由st_mode与S_IFMT做&运算得到具体的类型。

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

文件的权限由st_mode与每个组对应的变量做&运算,一共9位,看是否有权限
 

S_IRUSR     00400   owner has read permission
S_IWUSR     00200   owner has write permission
S_IXUSR     00100   owner has execute permission

S_IRGRP     00040   group has read permission
S_IWGRP     00020   group has write permission
S_IXGRP     00010   group has execute permission

S_IROTH     00004   others have read permission
S_IWOTH     00020   others have write permission
S_IXOTH     00001   others have execute permission

实现stat的算法

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

#define BUFSIZE 128

dev_t file_dev(struct stat res);
ino_t file_inode(struct stat res);
nlink_t file_link(struct stat res);
off_t file_size(struct stat res);
blkcnt_t file_blocks(struct stat res);
blksize_t file_io_block(struct stat res);
char file_type(struct stat res);
int file_mode(struct stat res, char **mode);
int get_file_uid_name(struct stat res, uid_t *uid, char **uname);
int get_file_gid_name(struct stat res, gid_t *gid, char **gname);
int get_file_mtime(struct stat res, char *buf, int size);
int get_file_atime(struct stat res, char *buf, int size);
int get_file_ctime(struct stat res, char *buf, int size);

int main(int argc, char *argv[])
{
	struct stat statbuf;
	char *s = NULL;
	uid_t myid;
	gid_t grid;
	char *myname = NULL;
	char *grname = NULL;
	char buf[BUFSIZE];

	if(argc < 2)
		return 1;
	if(-1 == stat(argv[1], &statbuf))
	{
		perror("stat()");
		return 1;
	}

	file_mode(statbuf, &s);
	get_file_uid_name(statbuf, &myid, &myname);
	get_file_gid_name(statbuf, &grid, &grname);
	printf("  文件:%s\n", argv[1]);
	printf("  大小:%ld\t\t块:%ld\t\tIO块:%ld\t\t类型:%c\n", \
			file_size(statbuf), file_blocks(statbuf), \
			file_io_block(statbuf), file_type(statbuf));
	printf("设备:%ld\t\tInode:%ld\t\t硬连接:%ld\n", \
			file_dev(statbuf), file_inode(statbuf), \
			file_link(statbuf));
	printf("权限:(%s)\tUid:( %d/\t%s)\tGid:( %d/\t%s)\n",\
		   	s, myid, myname, grid, grname);
	get_file_mtime(statbuf, buf, BUFSIZE);
	printf("最近访问:%s\n", buf);
	get_file_atime(statbuf, buf, BUFSIZE);
	printf("最近更改:%s\n", buf);
	get_file_ctime(statbuf, buf, BUFSIZE);
	printf("最近改动:%s\n", buf);
	free(s);
	s = NULL;
	free(myname);
	myname = NULL;
	free(grname);
	grname = NULL;

	return 0;
}
dev_t file_dev(struct stat res)
{
	return res.st_dev;
}
ino_t file_inode(struct stat res)
{
	return res.st_ino;
}
nlink_t file_link(struct stat res)
{
	return res.st_nlink;
}
off_t file_size(struct stat res)
{
	return res.st_size;
}
blkcnt_t file_blocks(struct stat res)
{
	return res.st_blocks;
}
blksize_t file_io_block(struct stat res)
{
	return res.st_blksize;
}
char file_type(struct stat res)
{
	char c;

	switch(res.st_mode & S_IFMT)
	{
		case S_IFSOCK:
			c = 's';
			break;

      	case S_IFLNK:
			c = 'l';
		  	break;
		case S_IFREG:
			c = '-';
	  		break;	
		case S_IFBLK:
		  	c = 'b';
			break;	
		case S_IFDIR:
			c = 'd';
			break;
		case S_IFCHR:
			c = 'c';
			break;
		case S_IFIFO:
			c = 'p';
			break;
		default:
			c = '?';
			break;
	}
	return c;
}
int file_mode(struct stat res, char **mode)
{
	int all_mode[] = {S_IRUSR, S_IWUSR, S_IXUSR, \
		S_IRGRP, S_IWGRP, S_IXGRP, \
		S_IROTH, S_IWOTH, S_IXOTH\
	};
	int i;

	*mode = calloc(10, sizeof(char));
	if(*mode == NULL)
		return -1;
	strncpy(*mode, "rwxrwxrwx", 10);
	for(i = 0; i < 9; i++)
	{
		if(!(res.st_mode & all_mode[i]))
			(*mode)[i] = '-';
	}

	return 0;
}
int get_file_uid_name(struct stat res, uid_t *uid, char **uname)
{
	struct passwd *pwd = NULL;

	*uid = res.st_uid;

	pwd = getpwuid(*uid);
	if(NULL == pwd)
		return -1;
	*uname = malloc(strlen(pwd->pw_name) + 1);
	strcpy(*uname, pwd->pw_name);

	return 0;
}
int get_file_gid_name(struct stat res, gid_t *gid, char **gname)
{
	struct group *gop = NULL;

	*gid = res.st_gid;
	gop = getgrgid(*gid);
	*gname = malloc(strlen(gop->gr_name) + 1);
	if(NULL == *gname)
		return -1;
	strcpy(*gname, gop->gr_name);

	return 0;
}
static int __time_change(struct timespec tim, char *buf, int size)
{
	struct tm *tmp = NULL;

	tmp = localtime(&tim.tv_sec);
	if(NULL == tmp)
		return -1;
	strftime(buf, size, "%Y-%y-%d %H:%M:%S", tmp);

	return 0;
}
int get_file_mtime(struct stat res, char *buf, int size)
{
	__time_change(res.st_mtim, buf, size);
}
int get_file_atime(struct stat res, char *buf, int size)
{
	__time_change(res.st_atim, buf, size);
}
int get_file_ctime(struct stat res, char *buf, int size)
{
	__time_change(res.st_ctim, buf, size);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值