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

来源:互联网 发布:文明5 mac 修改器 编辑:程序博客网 时间:2024/04/30 05:04
//unix系统调用的文件操作函数是一般不带f开头的,当既有不带,也有带的时候,带的通常是有以文件描述符为参数的函数。如:stat、fstat第四章   文件和目录  [仅作学习笔记,其中可能有误解]1.文件的属性stat、fstat、lstatstruct stat{mode_tst_mode;// 文件类型和权限( 如:S_IFEG and S_IRUSR)  ino_tst_ino;// inodedev_t st_dev;// 文件系统所在的设备号dev_t st_rdev;// 特定文件(字符、块设备)的设备号nlink_t st_nlink;// 链接的数目uid_t st_uid;// 用户IDgid_t st_gid;// 组IDoff_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_SOURCE3.用户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.outls -l-rwxr-xr-xchown root a.out #change the owner of file a.outchmod u+s  a.out #open and set set-user-idls -l-rwsr-xr-x3.2每一个文件都有一个所有者和组所有者                                                                                                 4.文件访问权限4.1所有文件类型都有访问权限S_IRUSRS_IWUSRS_IXUSRS_IRGRPS_IWGRPS_IXGRPS_IROTHS_IWOTHS_IXOTH4.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,而被关闭设置组ID5.更改用户#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.2ls统计空洞[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改为newname8.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);// 将真正的文件名读到buf9. 文件的时间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_mtime10.  目录处理#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