分类目录归档:APUE

学习日志

stat、lstat、fstat文件状态函数

man 2 stat
struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               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; /* blocksize for file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };
#include 
#include 
#include 
#include 

int main(int argc, char* argv[])
{
	int i;
	struct stat buf;
	char *ptr;

	for(i = 1; i < argc; ++i)
	{
		printf("%s: ",argv[i]);
		// 使用stat则不会观察到符号链接
		if(lstat(argv[i],&buf) < 0)
		{
			printf("lstat error\n");
			continue;
		}
		
		if(S_ISREG(buf.st_mode))
			ptr = "regular";
		else if(S_ISDIR(buf.st_mode))
			ptr = "directory";
		else if(S_ISCHR(buf.st_mode))
			ptr = "character special";
		else if(S_ISBLK(buf.st_mode))
			ptr = "block special";
		else if(S_ISFIFO(buf.st_mode))
			ptr = "fifo";
		else if(S_ISLNK(buf.st_mode))
			ptr = "symbolic link";
		else if(S_ISSOCK(buf.st_mode))
			ptr = "socket";
		else
			ptr = "*** unknown mode ***";

		printf("%s\n",ptr);
	}

	return 0;
}

lseek与空洞文件

确定打开文件的当前偏移量

#include 
#include 
#include 

int main(int argc, char* argv[])
{
	off_t offset;
	if((offset = lseek(STDIN_FILENO, 0, SEEK_CUR)) == -1)
		printf("cannot seek\n");
	else
		printf("seek OK,offset = %lu\n",offset);

	return 0;
}

空洞文件:文件中的空洞并不要求在磁盘上占用储存区。当lseek定位超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于原文件尾端和新开始写位置之间的部分则不需要分配磁盘块。其在磁盘中的表现都为0

// 创建空洞文件
#include 
#include 
#include 
#include 
#include 

char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";

int main(void)
{
	int fd;

	if((fd = creat("file.hole", S_IRWXU | S_IRWXG | S_IRWXG)) < 0)
	{
		printf("creat failed\n");
		return -1;
	}

	if(write( fd, buf1, 10) != 10)
	{
		printf("buf1 write error\n");
		return -1;
	}
	// offset now = 10
	
	if(lseek(fd, 16384, SEEK_SET) == -1)
	{
		printf("lseek failed\n");
		return -1;
	}
	// offset now = 16384
	
	if(write(fd, buf2, 10) != 10)
	{
		printf("buf2 write failed\n");
		return -1;
	}
	// offset now = 16394
	
	return 0;
}

将标准输入复制到标准输出

将标准输入复制到标准输出
STDIN_FILENO 0
STDOUT_FILENO 1
STDERR_FILENO 2
三个宏在unistd.h头文件中定义

#include 
#include 

#define BUFFSIZE 4096

int main(int argc,char* argv[])
{
	int n;
	char buf[BUFFSIZE] = {};

	while((n = read(STDIN_FILENO,buf,BUFFSIZE)) > 0)
	{
		if(write(STDOUT_FILENO,buf,n) != n)
		{
			printf("write error\n");
			return -1;
		}
	}

	if(n < 0)
	{
		printf("read error\n");
		return -1;
	}

	return 0;
}