1、文件和目录,stat、fstat 和lstat 格式,#include #include int stat(const char * p a t h n a m e, struct stat * b u f) ; int lstat(const char * p a t h n a m e, struct stat * b u f) ; 函数的返回:若成功则为0,若出错则为-1,stat、fstat 和lstat说明,给定一个p a t h n a m e,s t a t函数返回一个与此命名文件有关的信息结构, f s t a t函数获得已在描述符f i l e d e s上打开的文件的有关信
2、息。l s t a t函数类似于s t a t,但是当命名的文件是一个符号连接时,l s t a t返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息,文件类型,U N I X系统的大多数文件是普通文件或目录,也有另外文件类型: (1) 普通文件(regular file)。这是最常见的文件类型,这种文件包含了某种形式的数据。至于这种数据是文本还是二进制数据对于内核而言并无区别。对普通文件内容的解释由处理该文件的应用程序进行。 (2) 目录文件(directory file)。这种文件包含了其他文件的名字以及指向与这些文件有关信息的指针。对一个目录文件具有读许可权的任一进程都可以读该
3、目录的内容,但只有内核可以写目录文件。 (3) 字符特殊文件(character special file)。这种文件用于系统中某些类型的设备。 (4) 块特殊文件(block special file)。这种文件典型地用于磁盘设备。系统中的所有设备或者是字符特殊文件,或者是块特殊文件。 ( 5 ) F I F O。这种文件用于进程间的通信,有时也将其称为命名管道。1 4 . 5节将对其进行说明。 (6) 套接口( s o c k e t )。这种文件用于进程间的网络通信。套接口也可用于在一台宿主机上的进程之间的非网络通信。 (7) 符号连接(symbolic link)。这种文件指向另一个文
4、件。,macros are defined to check the file type:,S _ I S R E G ( ) 普通文件 S _ I S D I R ( ) 目录文件 S _ I S C H R ( ) 字符特殊文件 S _ I S B L K ( ) 块特殊文件 S _ I S F I F O ( ) 管道或F I F O S _ I S L N K ( ) 符号连接 S _ I S S O C K ( ) 套接字,文件存取许可权,c h m o d ( 1 )命令用于修改这9个许可权位。该命令允许我们用u表示用户(所有者),用g表示组,用o表示其他。每一类用户有三种权限。读
5、、写、执行。文件权限:rwx(s)rwx(s)rwx(t),St_mode字段的值S_IFMT 0170000 bitmask for the file type bitfieldsS_IFSOCK 0140000 socketS_IFLNK 0120000 symbolic linkS_IFREG 0100000 regular fileS_IFBLK 0060000 block deviceS_IFDIR 0040000 directoryS_IFCHR 0020000 character deviceS_IFIFO 0010000 fifoS_ISUID 0004000 set UID
6、bitS_ISGID 0002000 set GID bit (see below),S_ISVTX 0001000 sticky bit (see below)S_IRWXU 00700 mask for file owner permissionsS_IRUSR 00400 owner has read permissionS_IWUSR 00200 owner has write permissionS_IXUSR 00100 owner has execute permissionS_IRWXG 00070 mask for group permissionsS_IRGRP 00040
7、 group has read permissionS_IWGRP 00020 group has write permissionS_IXGRP 00010 group has execute permissionS_IRWXO 00007 mask for permissions for others (not in group)S_IROTH 00004 others have read permissionS_IWOTH 00002 others have write permissonS_IXOTH 00001 others have execute permission,St_mo
8、de 两个特殊位,执行修改位(u.g (s)chmod u+(-) s ,g+(-)s 粘住位chmod o+(-)t 粘住位的主要针对目录。如果对一个目录设置了粘住位,则只有对该目录具有写许可权的用户并且满足下列条件之一,才能删除或更名该目录下的文件: 拥有此文件。 拥有此目录。 是超级用户。 目录/ t m p和/ v a r / s p o o l / u u c p p u b l i c是设置粘住位的候选者,设置-用户- I D和设置-组- I D,实际用户I D和实际组I D标识我们究竟是谁。 有效用户I D,有效组I D以及添加组I D决定了我们的文件访问权。保存的设置-用户-
9、I D和设置-组- I D在执行一个程序时包含了有效用户I D和有效组I D的副本。 可以用s e t u i d函数设置实际用户I D和有效用户I D。与此类似,可以用s e t g i d函数设置实际组I D和有效组I D。 #include #include int setuid(uid_t u i d) ; int setgid(gid_t g i d) ;,每个文件有一个所有者和组所有者,所有者由s t a t结构中的s t _ u i d表示,组所有者则由s t _ g i d成员表示。 当执行一个程序文件时,进程的有效用户I D通常就是实际用户I D,有效组I D通常是实际组I
10、D。但是可以在文件方式字( s t _ m o d e )中设置一个特殊标志,其定义是“当执行此文件时,将进程的有效用户I D设置为文件的所有者( s t _ u i d )”。与此相类似,在文件方式字中可以设置另一位,它使得执行此文件的进程的有效组I D设置为文件的组所有者( s t _ g i d )。在文件方式字中的这两位被称之为设置-用户- I D ( s e t - u s e r- I D )位和设置-组- I D ( s e t - g r o u p - I D )位。 例如,若文件所有者是超级用户,而且设置了该文件的设置-用户- I D位,然后当该程序由一个进程运行时,则该进
11、程具有超级用户优先权。不管执行此文件的进程的实际用户I D是什么,都作这种处理。作为一个例子, U N I X程序p a s s w d ( 1 )允许任一用户改变其口令,该程序是一个设置-用户- I D程序。因为该程序应能将用户的新口令写入口令文件中(一般是/ e t c / p a s s w d或/etc/shadow), 而只有超级用户才具有对该文件的写许可权,所以需要使用设置-用户- I D特征。,改变三个用户I D的不同方法,UNIX文件系统,文件链接,#include int link(const char * e x i s t i n g p a t h, const cha
12、r * n e w p a t h) ; int symlink(const char * a c t u a l p a t h, const char * s y m p a t h) ; int unlink(const char * p a t h n a m e) ;,硬连接与符号连接,硬连接直接指向文件的i节点。引进符号连接的原因是为了避免硬连接的一些限制: ( a )硬连接通常要求连接和文件位于同一文件系统中, ( b )只有超级用户才能创建到目录的硬连接。 对符号连接以及它指向什么没有文件系统限制,任何用户都可创建指向目录的符号连接。符号连接一般用于将一个文件或整个目录结构移到
13、系统中其他某个位置。,目录操作,创建和删除 #include #include int mkdir(const char * p a t h n a m e, mode_t m o d e) ; int rmdir(const char * p a t h n a m e) ;,打开、读取和关闭 #include #include DIR *opendir(const char * p a t h n a m e) ; struct dirent *readdir(DIR * d p)int closedir(DIR * d p),struct dirent ino_t d_ino; /*i-
14、node number*/ char d_name N A M E _ M A X + 1; /*null-terminated filename*/,当前目录操作 #include int chdir(const char * p a t h n a m e) ; char *getcwd(char * b u f, size_t s i z e); 向此函数传递两个参数,一个是缓存地址b u f,另一个是缓存的长度s i z e。该缓存必须有足够的长度以容纳绝对路径名再加上一个n u l l终止字符,否则返回出错,目录操作例题,显示指定目录中的内容(listdir.c),低级I/O控制,#
15、include ,主要函数,#include int tcgetattr(int filedes, struct termios * termptr) ; int tcsetattr(int filedes, int opt, const struct termios * termptr) ; 这两个函数都有一个指向t e r m i o s结构的指针作为其参数,它们返回当前终端的属性,或者设置该终端的属性。 t c s e t a t t r的参数o p t使我们可以指定在什么时候新的终端属性才起作用。o p t可以指定为下列 常数中的一个: TCSANOW 更改立即发生。 TCSADRAI
16、N 发送了所有输出后更改才发生。若更改输出参数则应使用此选择项。 TCSAFLUSH 发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入 数据都被删除(刷清)。,规范方式,规范方式很简单发一个读请求,当一行已经输入后,终端驱动程序即返回。许多条件造成读返回: 要求的字节数已读到时读即返回。 读到一个行定界符时,读返回,实例g e t p a s s函数,下面说明g e t p a s s函数,它读入用户在终端上键入的口令。此函数由UNIX login(1)和c r y p t ( 1 )程序调用。为了读口令,该函数必须禁止回送,但仍可使终端以规范方式进行工作,因为用户在键入口令后,一定要键入回车,这样也就构成了一个完整行。,非规范方式,将t e r m i o s结构中c _ l f l a g字段的I C A N O N标志关闭就使终端处于非规范方式。在非规范方式中,输入数据不装配成行,不处理下列特殊字符: E R A S E、K I L L、E O F、N L、E O L、E O L 2、C R、R E P R I N T、S TAT U S和W E R A S E。 使用了t e r m i o s结构中c _ c c数组的两个变量: M I N和T I M E。确定何时将数据返回。,