The Linux Programming Interface 15 File Attributes 文件属性

The Linux Programming Interface

File Attributes

(01) 主要内容

In this chapter, we investigate various attributes of file (file metadata).

stat()函数返回一个文件结构体,包含许多文件的属性。

(02)几个获取文件属性的函数

The stat(), lstat(), and fstat() system calls retrieve information about a file, mostly drawn from the file i-node.

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

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

int fstat(int fd, struct stat *statbuf);

(03)stat和lstat的区别

lstat: If the named file is a symbolic link, information about the link itself is return.

(04) struct stat结构

struct stat {
	dev_t st_dev;		/* IDs of device on which file resides */
	ino_t st_ino;		/* I-node number file */
	mode_t st_mode;		/* File type and permissions */
	nlink_t st_nlink;	/* Number of (hard) links to file */
	uid_t st_uid;		/* User ID of file owner */
	gid_t st_gid;
	dev_t st_rdev;		/* IDs for device special files */
	off_t st_size;		/* Total file size (bytes) */
	blksize_t st_blksize;	/* Optimal block size for I/O (bytes) */
	blkcnt_t st_blocks;	/* Number of (512B) blocks allocated */
	time_t st_atime;	/* Time of last file access */
	time_t st_mtime;	/* Time of last file modification */
	time_t st_ctime;	/* Time of lat status changes */
}

The combination of st_dev and st_ino uniquely identifies a file across all file systems.

(05) 文件类型和权限示意图

The file type can be extracted from this field by ANDing & with the constant S_IFMT.

if (( statbuf.st_mode & S_IFMT) == S_IFREG)

    printf("regular file\n");

if (S_ISREG(statbuf.st_mode))

    printf("regular file\n"); 两者是相同的结果。

(06)使用stat及其生成的结构体举例

#define _BSD_SOURCE	/* Get major() and minor() from <sys/types.h> */
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include "file_perms.h"
#include "tlpi_hdr.h"

static void displayStatInfo(const struct stat *sb) {
	printf("File type:			");
	switch(sb->st_mode & S_IFMT) {
	case S_IFREG:	printf("regular file\n");	break;
	case S_IFDIR:	printf("directory\n");		break;
	case S_IFCHR:	printf("character device\n"); break;
	case S_IFBLK:	printf("block device");		break;
	case S_IFLNK:	printf("symbolic (soft) link\n"); break;
	case S_IFIFO:	printf("FIFO or pipe\n");	break;
	case S_IFSOCK:	printf("socket\n");			break;
	default:
		printf("unknown file type?\n");			break;
	}

	printf("Device containing i-node: major = %ld	minor = %ld\n",
		(long) major(sb->st_dev), (long) minor(sb->st_dev));
	
	printf("I-node number	%ld\n", (long) sb->st_ino);

	printf("Mode:		%lo (%s)\n",
		(unsigned long) sb->st_mode, filePermStr(sb->st_mode, 0));
	
	if (sb->st_mode & (S_ISUID | S_ISGID | S_ISVTX))
		printf("	special bits set: 	%s%s%s\n",
			(sb->st_mode & S_ISUID) ? "set-UID " : "",
			(sb->st_mode & S_ISGID) ? "set-GID " : "",
			(sb->st_mode & S_ISVTX) ? "sticky "	 : "");

	printf("Number of (hard) links:   %ld\n", (long)sb->st_nlink);

	printf("Ownership:		UID = %ld,		GID = %ld\n",
		(long)sb->st_uid, (long)sb->st_gid);
	
	if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode))
		printf("Devie number (st_rdev): major = %ld; minor = %ld\n",
			(long)major(sb->st_rdev), (long)minor(sb->st_rdev));
	
	printf("File size:					%lld bytes\n", (long long) sb->st_size);
	printf("Optimal I/O block size: 	%ld bytes\n", (long)sb->st_blksize);
	printf("512B blocks allocated:		%lld\n", (long long) sb->st_blocks);
	printf("Last file access:			%s", ctime(&sb->st_atime));
	printf("Last file modification:		%s", ctime(&sb->st_mtime));
	printf("Last status change:			%s", ctime(&sb->st_ctime));
}

int main(int argc, char *argv[]) {
	struct stat sb;
	Boolean statLink;		/* True if "-l" specified */
	statLink = (argc > 1) && strcmp(argv[1], "-l") == 0;

	int fname = statLink ? 2 : 1;

	if (fname >= argc || (argc > 1 && strcmp(argv[1], "--help") == 0))
		usageErr("%s [-l] file\n  -l = use lstat() instead of stat()\n", argv[0]);

	if (statLink)
		if (lstat(argv[fname], &sb)  == -1)
			errExit("lstat");
	else
		if (stat(argv[fname], &sb) == -1)
			errExit("stat");
	
	displayStatInfo(&sb);

	exit(EXIT_FAILURE);
}
输出:

wang@wang:~/test/tlpi-dist/lib$ gcc t_stat.c error_functions.c file_perms.c -o t_stat
wang@wang:~/test/tlpi-dist/lib$ echo 'All operating systems provide services for programs they rum' > apue
wang@wang:~/test/tlpi-dist/lib$ chmod g+s apue
wang@wang:~/test/tlpi-dist/lib$ cat apue
All operating systems provide services for programs they rum
wang@wang:~/test/tlpi-dist/lib$ ./t_stat apue
File type:            unknown file type?
Device containing i-node: major = 28857    minor = 4293801600
I-node number    140732713187696
Mode:        20002716 (rwx--xrw-)
    special bits set:     set-GID
Number of (hard) links:   4131212846
Ownership:        UID = 0,        GID = 4294967295
File size:                    139762236944888 bytes
Optimal I/O block size:     139762243065024 bytes
512B blocks allocated:        139762243076552
Last file access:            Thu Jan  1 08:00:00 1970
Last file modification:        Wed Feb 18 22:53:49 1970
Last status change:            Thu Jan  1 08:00:00 1970
(07) 文件时间戳

The st_atime, st_mtime, and st_ctime fields of the stat structure contain file timestamps.

These fields record, respectively, the time of last file access, last file modification, and last file status change.

以下列表显示哪些函数可以改变时间戳

(08)使用utime() 和 utimes改变时间戳

讲得太细致。

(09)改变文件属性

The chown(), lchown(), and fchown() system calls change the owner and group of a file.

int chown(const char *pathname, uid_t ownre, gid_t group);

(10)举例,改变文件属性需要有root权限,否则更改不成功。

  1 #include <pwd.h>
  2 #include <grp.h>
  3 #include "ugid_functions.h"
  4 
  5 #include "tlpi_hdr.h"
  6 
  7 int main(int argc, char *argv[]) {
  8     uid_t uid;
  9     gid_t gid;
 10     int j;
 11     Boolean errFnd;
 12 
 13     if (argc < 3 || strcmp(argv[1], "--help") == 0)
 14         usageErr("%s owner group [file...]\n"
 15             "       owner or group can be '-', "
 16             "meaning leave unchanged\n", argv[0]);
 17     if (strcmp(argv[1], "-") == 0)
 18         uid = -1;
 19     else {
 20         uid = userIdFromName(argv[1]);
 21         if (uid == -1)
 22             fatal("No such user (%s)", argv[1]);
 23     }
 24     if (strcmp(argv[2], "-") == 0) {    /* "-" don't change group */
 25         gid = -1;
 26     } else {
 27         gid = groupIdFromName(argv[2]);
 28         if (gid == -1)
 29             fatal("No group user (%s)", argv[1]);
 30     }
 31 
 32     /* change ownership of all files named in remaining arguments */
 33     errFnd = FALSE;
 34     for (j = 3; j < argc; j++) {
 35         if (chown(argv[j], uid, gid) == -) {
 36             errMsg("chown: %s", argv[j]);
 37             errFnd = TRUE;
 38         }
 39     }
 40     exit(errFnd ? EXIT_FAILURE : EXIT_SUCCESS);
 41 }
输出:

wang@wang:~/test/tlpi-dist/lib$ sudo su
[sudo] password for wang:
root@wang:/home/wang/test/tlpi-dist/lib# ./t_chown linux linux text.txt
root@wang:/home/wang/test/tlpi-dist/lib# ll

-rw-rw-r--  1 linux linux          38  3月  7 15:26 text.txt

(11)文件权限

The bottom 12 bits of the st_mode field of the stat structure define the permission for a file.

The first 3 of these bits are special bits known as the set-user-ID, set-group-ID, and sticky bits.

(12) 路径名检查

The kernel checks file permissions whenever we specify a pathname in a system call that accesses file or directory.

(13) 检查文件时候可读写

The access() system call checks the accessibility of the file specified in pathname based on a process's real user and group IDs.

文件的这些属性需要用的时候再学吧,现在跳过去,那么多函数已经那么多的自定义变量确实头疼,不过还是得把总结敲一遍。

(14)总结

The stat() system call retrieves information about a file (metadata), most of which is drawn from the file i-node. This information includes file ownership, file permissions, and file timestamps.

    A program can update a file's last access time and last modification time using utime(), utimes(), and various similar interfaces.

    Each file has an associated user ID (owner) and group ID, as well as a set of permission bits. For permission purposes, file users are divided into three categories: owner(also known as user), group, and other. Three permissions may be granted to each category of user: read, write, and execute. The same scheme is used with directory, although the permission bits have slightly different meaning. The chown() and chmod() system calls change the ownership and permission of a file. The umask() system call sets a mask of permission bits that are always turned off when the calling process creates a file.

    I-node flags control the various behaviors of files and directories. Although originally define for ext2, these flags are now supported on several other file systems.

(15)习题


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值