unix环境高级编程 学习笔记4

//unix系统调用的文件操作函数是一般不带f开头的,当既有不带,也有带的时候,带的通常是有以文件描述符为参数的函数。如:stat、fstat

第四章   文件和目录  [仅作学习笔记,其中可能有误解]

1.		文件的属性
stat、fstat、lstat

struct stat{
	mode_t	st_mode;	// 文件类型和权限( 如:S_IFEG and S_IRUSR)  
	ino_t	st_ino;		// inode
	dev_t 	st_dev;		// 文件系统所在的设备号
	dev_t 	st_rdev;	// 特定文件(字符、块设备)的设备号
	nlink_t st_nlink;	// 链接的数目
	uid_t 	st_uid;		// 用户ID
	gid_t 	st_gid;		// 组ID
	off_t 	st_size;	// 普通文件的大小
	time_t 	st_atime;	// 最后访问时间
	time_t 	st_mtime;	// 最后修改数据时间
	time_t 	st_ctime;	// 最后修改状态时间
}
以下的内容均是围绕该结构体展开

#include <sys/stat.h>
int stat(const char * restrict pathname, struct stat * restrict buf);

#include <sys/stat.h>
int fstat(int filedes, struct stat * buf);

#include <sys/stat.h>
int lstat(const char * restrict pathname, struct stat * restrict buf);

三个函数都是获取文件的状态信息,存放在buf里,其中lstat当pathname是符号链接时,返回的是符号链接的信息而不是文件的。

2.		文件类型[包含在stat结构的st_mode成员中]
		+普通文件,包括文本和二进制,unix内核对其不区分					S_ISREG()
		+目录文件,包含其他文件的名字以及指向其他文件的相关信息的指针		S_ISDIR()
		+块特殊文件,提供对设备带缓冲的访问,每次以固定长度进行			S_ISBLK()
		+字符特殊文件,提供对设备不带缓冲的访问,长度可变,设备文件只分块和字符	S_ISCHR()
		+FIFO,进程间通信			S_ISFIFO()
		+套接字,网络通信			S_ISSOCK()
		+符号链接,指向另一个文件	S_ISLNK()
_GNU_SOURCE


3.		用户ID与组ID 
3.1 	与进程相关的用户ID和组ID
		+我们实际是谁
			+实际用户ID	
			+实际组ID	
		+用于文件访问权限检查
			+有效用户ID
			+有效组ID
			+附加组ID
		+由exec函数保存:保存了在执行一个程序时包含了有效用户ID和有效组ID的副本 S_ISUID S_ISGID
			+保存的设置用户ID
			+保存的设置组ID

		执行一个程序文件时,进程的有效用户(组)ID 通常就是实际用户(组)ID
		例外: S_ISUID S_ISGID
			可以在st_mode[标志文件类型和模式]设置一个特殊标志,使得当执行此文件时,
			将进程的有效用户ID设置为文件所有者ID,这样可以使得本来不能非有效用户也能
			有权限去执行该文件,组的话也可用另一个标志,这两个位被称为设置用户ID
			[set-user-ID]和 设置组ID [set-group-ID],好像跟上面的
			+保存的设置用户ID
			+保存的设置组ID
			是不一样的。最起码作用不一样,具体如何??????

		例子:设置用户ID为root,开始是a.out无权限访问/etc/shadow,设置用户ID 为root,则可直接
		./a.out 运行,而不需要sudo ./a.out
		ls -l
		-rwxr-xr-x
		chown root a.out #change the owner of file a.out
		chmod u+s  a.out #open and set set-user-id
		ls -l
		-rwsr-xr-x

3.2		每一个文件都有一个所有者和组所有者
                                                                                                 

4.		文件访问权限
4.1		所有文件类型都有访问权限
		S_IRUSR
		S_IWUSR
		S_IXUSR

		S_IRGRP
		S_IWGRP
		S_IXGRP

		S_IROTH
		S_IWOTH
		S_IXOTH
4.2		对目录的读权限和执行权限是不同的,读权限允许我们获得该目录的所有文件名的列表
		执行权限才允许我们进入目录进行访问搜索,对一目录具有写和执行权限则可对目录内的文件
		进行删除\创建,而不需要对文件具有读写权限

4.3		进程、文件访问权测试
		+涉及文件的所有者[st_uid,st_gid]、进程有效ID[有效用户ID,有效组ID]以及附加组ID
		+若进程的有效用户ID 是0,则允许
		+若进程有效用户ID 是文件所有者ID,那么所有这被设置的访问权限位起作用
		+若进程的有效组ID或进程的附加组ID之一等于文件组ID,则根据组的访问权限设置来
		+最后跟据其他用户的访问权限
		以上四步按顺序来处理。
	
4.4		新文件和目录的所有权
		新文件和目录的用户ID是进程的有效用户ID.
		组ID可以是进程的组ID 或它所在目录的组ID.

4.5		访问权限测试函数
#include <unistd.h>
int access(const char * pathname,int mode);//mode: R_OK,W_OK,X_OK,F_OK
		+F_OK用于测试文件是否存在
		+内核以有效用户ID 和组ID 为基础今次那个测试访问权限
		+access以实际用户ID 和组ID 为基础
		+还是以上面的四步测试一样,只是将有效变为实际


4.6 	访问权限位[创建屏蔽字]
#include <sys/stat.h>
mode_t umask(mode_t cmask);
		+当创建文件的时候,就一定会使用文件模式创建屏蔽字,open和create都有mode_t参数,我尝试后发现默认的创建出来的为---xr-x--x,比较奇怪。
		+当设置umask时,正如屏蔽字所指,对应的位被设置就会将其权限屏蔽,umask为8进制,第一个0不知道是干嘛的,后面三个数对应于rwxrwxrwx。

#include <sys/stat.h>
int chmod(const char * pathname, mode_t mode);
// mode: S_IS[UG]ID, S_ISVTX, S_I[RWX](USR|GRP|OTH),S_[UGO]RWX
// SUID 设置用户ID
// SVTX save text bit 保存正文位[粘住位]
#include <sys/stat.h>
int fchmod(int filedes, mode_t mode);
// mode: S_IS[UG]ID, S_ISVTX, S_I[RWX](USR|GRP|OTH),S_[UGO]RWX
		+粘住位:将可执行文件在第一次执行结束后依然保存在交换区,现在系统
				  大多有虚拟存储等技术,基本不用了
		+粘住位只有root才可以设置,否则自动关闭
		+组ID也会因为不是调用进程所属组,如4.4所说的目录的组ID,而被关闭设置组ID

5.		更改用户

#include <unistd.h>
int chown(const char * pathname, uid_t owner, gid_t group);

#include <unistd.h>
int fchown(int filedes, uid_t owner, gid_t group);

#include <unistd.h>
int lchown(const char * pathname ,uid_t owner, gid_t group);
通常只有超级用户能更改用户

6.		文件长度
6.1		符号链接的文件长度是文件名的实际字节书
6.2		ls	统计空洞[read]
		wc -c	统计空洞[read]
		du	不统计空洞,统计实际所分配的最小物理块[st_blocks]的块数
		+	st_blksize 是对文件I/O较合适的块长度

7.		文件截断

#include <unistd.h>
int truncate(const char * pathname, off_t length);
#include <unistd.h>
int ftruncate(int filedes, off_t length);

将文件截断到只剩length字节

8.		文件系统
8.1 文件系统
	磁盘=|分区|分区|分区|  每个分区可以有一个文件系统
	分区=|自举块(引导区)|超级块|柱面组0|柱面组1|柱面组2|
	柱面组 = |超级块副本|配置信息(组描述符)|inode图|块位图|根目录|i节点|数据块|
	|i节点|数据块| = |i节点数组|数据块|数据块|目录块|数据块|
	目录 = |i节点|文件名|

	+从根目录开始,得到i节点,i节点指向其他数据块或目录块,目录块又指向其他inode,从而能访问所有的目录
	+一个文件(包括普通或目录)对应一个inode,inode节点有有间接指针指向其他inode
	+超级块:记录文件系统的整体信息,如:
	inode 的总数
	数据块的总数
	数据块的大小
	空闲数据块的总数
	空闲inode的总数
	第一个数据块,根目录
	每组的数据块数
	每组的inode数
	+组描述符号:记录组内的信息
	+inode位图和块位图是用来记录i节点和数据块是否已使用
	+根目录,是开始的目录,通过[i节点|文件名]指向inode,非目录inode指向数据块,目录inode指向目录块,实际上目录块也是数据块,只不过存放的是[i节点|文件名],从而可递归访问下去。
	
8.2 硬链接
	则不同文件指向同一个inode,例如目录1的..和它的父目录的. 是指向同一inode节点
	+链接数减为一才能删除
	+一般不能对目录(实际是目录对应的inode)执行添加链接,可能形成循环,导致文件无法删除
	+当文件打开时,也不能删除
	+ln exist hardlink 

#include <unistd.h>
int link(const char * existingpath, const char * newpath);
newpath引用existingpath

#include <unistd.h>
int unlink(const char * pathname);
pathname对应的inode的链接数目减一
// 临时文件可以在创建后马上调用unlink,此时由于进程打开文件,并不会删除文件,等进程结束(包括异常崩溃的情况),能保证将临时文件删除

#include <stdio.h>
int remove(const char * pathname);
// 对于文件,remove=unlink
// 对于目录,remove=rmdir

#include <stdio.h>
int rename(const char * oldname, const char *newname);
// 对于newname已经存在的情况下,会删除存在的newname文件,然后将oldname改为newname

8.3 软链接(符号链接)
	类似于windows的快捷方式一样
	+可以跨文件系统
	+无需root权限
	+有的函数跟随符号链接,有的不跟随,跟随表示处理真正的文件
	+ln -s exist hardlink 
	+用ls -l可以看到符号链接

#include <unistd.h>
int symlink(const char *actualpath, const char *syspath);
// actualpath  可以没有	  

#include <unistd.h>
int readlink(const char * restrict pathname, char * restrict buf, size_t bufsize);
// 将真正的文件名读到buf

9. 	文件的时间
9.1 有三个时间:
	+st_atime ls -u last time of access最后访问的时间   read()
	+st_mtime ls    last time of modificationof data 最后一次数据的修改  write()
#include <utime.h>
int utime(const char (pathname, const struct utimbuf *times);
struct utimebuf {
time_t actime  ;
time_t modtime ;
};

只是修改st_atime和st_mtime

10.  目录处理
#include <sys/stat.h>
int mkdir(const char * pathname, mode_t mode
#include <unistd.h>
int rmdir(const char * pathname);

#include <direct.h>
DIR * opendir(const char * pathname);

struct dirent *readdir(DIR * dir);
struct dirent{
	char d_name[NAME_MAX+1];
}

void rewinddir(DIR *dir);
int closedir(DIR *dir);
void seekdir(DIR *dir, long loc);
long leekdir(DIR *dir);

#include <unistd.h>
int chdir(const char * pathname);

#include <unistd.h>
int fchdir(int filedes);

#include <unistd.h>
char * getcwd(char * buf, size_t size);


11.		设备特殊文件
每个文件系统所在的存储设备都由其主、次设备号表示。
宏 major 和 minor 可以确定哪个是主,哪个是从。
[转载请表明]http://blog.csdn.net/kangquan2008
 
[转载请表明]http://blog.csdn.net/kangquan2008

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值