A sample program for stat()

jarodwang, 11 December 2008, No comments
Categories: Linux, Programming
Tags: , ,

stat() is a Unix system call that returns useful data about a file inode.

今天在看一个 strace 的输出时,看到下面的一行:

19:42:00.545797 stat64(“/cdctest/orahome”, {st_mode=S_IFDIR|0755, st_size=8192, …}) = 0

Google 之后发现 stat64 背后就是 stat() 系统调用,这里有详细的介绍。

于是一时手痒,想自己写一个简单的程序来实验一下,就在自己的 PC 机(跑的是 Debian “etch” 4.0r5)上动手。

首先是搭建编译环境:

# apt-get install gcc build-essential

然后coding如下:

#include 
#include 
#include 
#include 
#include 

int main()
{
	struct stat *buf;
	const char *path = "/home/ftp/upload";

	buf = (struct stat *) malloc(sizeof(struct stat));
	memset(buf, 0, sizeof(struct stat));

	int ret; 

	ret = stat("/home/ftp/upload", buf);

	if (ret == EACCES)
	{
		printf("EACCES\n");
		free(buf);
		buf = NULL;
		exit(-EACCES);
	}

	printf("%d\n", buf->st_mode);

	if (S_ISDIR(buf->st_mode))
	{
		printf("%s is a diretory.\n", path);
	}
	else
		printf("%s is NOT a directory.\n", path);

	free(buf);
	buf=NULL;

	return 0;
}

编译生成可执行文件

jarod@zhenwan:~$ gcc -o test_stat test_stat.c

运行之:

jarod@zhenwan:~$ ./test_stat
16895
/home/ftp/upload is a diretory.

大功告成。

最后还可以自己 strace 一把:

jarod@zhenwan:~$ strace ./test_stat
execve(“./test_stat”, ["./test_stat"], [/* 27 vars */]) = 0
uname({sys=”Linux”, node=”zhenwan”, …}) = 0
brk(0)                                  = 0x804a000
access(“/etc/ld.so.nohwcap”, F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ee9000
access(“/etc/ld.so.preload”, R_OK)      = -1 ENOENT (No such file or directory)
open(“/etc/ld.so.cache”, O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=45513, …}) = 0
mmap2(NULL, 45513, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7edd000
close(3)                                = 0
access(“/etc/ld.so.nohwcap”, F_OK)      = -1 ENOENT (No such file or directory)
open(“/lib/tls/i686/cmov/libc.so.6″, O_RDONLY) = 3
read(3, “\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1″…, 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1241392, …}) = 0
mmap2(NULL, 1247388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7dac000
mmap2(0xb7ed3000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0×127) = 0xb7ed3000
mmap2(0xb7eda000, 10396, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7eda000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7dab000
mprotect(0xb7ed3000, 20480, PROT_READ)  = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7dab8e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xb7edd000, 45513)               = 0
brk(0)                                  = 0x804a000
brk(0x806b000)                          = 0x806b000
stat64(“/home/ftp/upload”, {st_mode=S_IFDIR|0777, st_size=4096, …}) = 0
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 5), …}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ee8000
write(1, “16895\n”, 616895
)                  = 6
write(1, “/home/ftp/upload is a diretory.\n”, 32/home/ftp/upload is a diretory.
) = 32
munmap(0xb7ee8000, 4096)                = 0
exit_group(0)                           = ?
Process 32729 detached
jarod@zhenwan:~$

可以看出来其中红色的一行即是由程序中的 stat() 系统调用所产生。

Comments

Leave a Reply:

Name *

Mail (hidden) *

Website