分类: LINUX
2009-08-22 13:06:39
(5) F I F O。这种文件用于进程间的通信,有时也将其称为命名管道。
(6) 套接口( s o c k e t )。这种文件用于进程间的网络通信。套接口也可用于在一台宿主机上的进程之间的非网络通信。
(7) 符号连接(symbolic link)。这种文件指向另一个文件。
宏文件类型
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 ( ) 符号连接( P O S I X . 1或S V R 4无此类型)
S _ I S S O C K ( ) 套接字(P O S I X . 1或S V R 4无此类型)
1. 当用o p e n函数打开一个文件时,内核以进程的有效用户I D和有效组I D为基
础执行其存取许可权测试。有时,进程也希望按其实际用户I D和实际组I D来测试其存取能力。
例如当一个进程使用设置-用户- I D,或设置-组- I D特征作为另一个用户(或组)运行时,这就可
能需要。即使一个进程可能已经设置-用户- I D为根,它仍可能想验证实际用户能否存取一个给
定的文件。a c c e s s函数是按实际用户I D和实际组I D进行存取许可权测试的。
2. 粘住位
S _ I S V T X位有一段有趣的历史。在U N I X的早期版本中,有一位被称为粘住位(sticky bit)。如果一个可执行程序文件的这一位被设置了,那么在该程序第一次执行并结束时,该程序正文的一个文本被保存在交换区。(程序的正文部分是机器指令部分。)这使得下次执行该程序时能较快地将其装入内存区。其原因是:在交换区,该文件是被连续存放的,而在一般的U N I X文
件系统中,文件的各数据块很可能是随机存放的。对于常用的应用程序,例如文本编辑程序和
编译程序的各部分常常设置它们所在文件的粘住位。自然,对交换区中可以同时存放的设置了
粘住位的文件数有一定限制,以免过多占用交换区空间,但无论如何这是一个有用的技术。因
为在系统再次自举前,文件的正文部分总是在交换区中,所以使用了名字“粘住”。后来的
U N I X版本称之为保存-正文位( saved-text bit),因此也就有了常数S _ I S V T X。现今较新的
U N I X系统大多数都具有虚存系统以及快速文件系统,所以不再需要使用这种技术。
S V R 4和4 . 3 + B S D中粘住位的主要针对目录。如果对一个目录设置了粘住位,则只有对该
目录具有写许可权的用户并且满足下列条件之一,才能删除或更名该目录下的文件:
• 拥有此文件。
• 拥有此目录。
• 是超级用户。
目录/ t m p和/ v a r / s p o o l / u u c p p u b l i c是设置粘住位的候选者—这两个目录是任何用户都可在其中创建文件的目录。这两个目录对任一用户(用户、组和其他)的许可权通常都是读、写和执行。但是用户不应能删除或更名属于其他人的文件,为此在这两个目录的文件方式中都设置了粘住位。
注: 如果我们试图设置普通文件的粘住位( S _ I S V T X ),而且又没有超级用户优先权,那么m o d e中的粘住位自动被关闭。这意味着只有超级用户才能设置普通文件的粘住位。这样做的理由是可以防止不怀好意的用户设置粘住位,并试图以此方式填满交换区(如果系统支持保存-正文特征的话)。 |
[格式:]
# include
int fd;
fd=open(filename,flags,perms)
filename 文件及路径名
flags 打开文件的模式 ******* 请参考3
perms 访问权限 ********可选,当与O_CREAT合用时要确定文件的权限
成功返回文件描述符,不成功则返回-1
UNIX进程(每个进程)最多可以同时使用20个文件描述符(0-19),其中0-2 分别为stdin,stdout,stderr,所以在进程中打开的文件由3开始。
[标志:]
O_RDONLY、O_WRONLY、O_RDWR的取值分别为0、1、2,它们之间不能用OR的方法联合使用。下面再介绍一些标志值:
l O_CREAT:当文件不存在时,将建立该文件,此时会用到open的第三个参数。
l O_EXCL:当该标志与O_CREAT一起使用,且如果文件存在,这次open系统调用将失败。(不能确定文件是否存在,而且要在文件不在时建立此文件,则要此参数与O_CREAT合用)
★ 注意:在NFS文件系统上用O_EXCL程序会产生问题,因为程序执行时依赖的锁可能将引起竞争。
l O_NOCTTY:当文件名(可以包含路径,即第一个参数pathname)指向一个终端设备,它将不再是进程控制的终端,即使该进程没有一个终端设备。
l O_TRUNC:如果文件存在,则该文件将被截断,即长度截断为0。(就是文件被清空)注意,文件没有以写方式打开也可以截断;截断后文件的属主和属性不变。
l O_APPEND:文件以追加的方式打开,每次进行写操作时,文件指针都会被放置到文件末尾。注意,O_APPEND在NFS(网络文件系统)上可能会导致异常,当多于一个进程对该文件同时追加数据时,可能得到不可预测的结果。这是因为NFS并不支持对一个文件的追加,所以这就需要客户端核心来模拟它,但必须有锁的支持,才能很好地解决竞争。
l O_NONBLOCK或O_NDELAY:当文件以非阻塞方式打开后,对于open及随后的对该文件的文件操作,都会及时返回,而无需进程等待。这对于普通文件和目录文件没有作用,但对于管道等进程间通信的操作很有用。
较早的系统V版本引入了O _ N D E L AY(不延迟)标志,它与O _ N O N B L O C K (不阻塞)选择项类似,但在读操作的返回值中具有两义性。如果不能从管道、 F I F O或设备读得数据,则不延迟选择项使r e a d返回0,这与表示已读到文件尾端的 返回值0相冲突。S V R 4仍支持这种语义的不延迟选择项,但是新的应用程序应当 使用不阻塞选择项以代替之。 |
l O_SYNC或O_FSYNC:文件以同步I/O的方式打开。任何的写操作都会使得进程被阻塞,直到物理的写动作完成为止。
l O_WSYNC,有的系统没有该标志。
[格式:]
read(int fd,char *buf,int buflen)
write(int fd,char *buf,int buflen)
[说明:]
ü read,write 执行失败返回-1,而 read在碰到EOF时返回0
ü 如果write写入对象是文本文件时,在遇到换行符时,它会输出换行符和回车符(0D
而read刚好反,它将换行符和回车符转换为换行符。
注:read,write在对管道作用,其方式和作用于一般文件不同,物别是配O_NDELAY标识后。
如r e a d成功,则返回读到的字节数。如已到达文件的尾端,则返回0。
有多种情况可使实际读到的字节数少于要求读字节数:
. 读普通文件时,在读到要求字节数之前已到达了文件尾端。例如,若在到达文件尾端之
前还有3 0个字节,而要求读1 0 0个字节,则r e a d返回3 0,下一次再调用r e a d时,它将返回0 (文件尾端)。
l 当从终端设备读时,通常一次最多读一行。
l 当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。
l 某些面向记录的设备,例如磁带,一次最多返回一个记录。
[格式:]
可以调用l s e e k显式地定位一个打开文件。
#include
#include
off_t lseek(int f i l e d e s, off_t o f f s e t, int w h e n c e) ;
返回:若成功为新的文件位移,若出错为- 1
对参数offset (偏移量)的解释与参数w h e n c e的值有关。
• 若w h e n c e是S E E K _ S E T,则将该文件的位移量设置为距文件开始处offset 个字节。
• 若w h e n c e是S E E K _ C U R,则将该文件的位移量设置为其当前值加offset, offset可为正或负。
• 若w h e n c e是S E E K _ E N D,则将该文件的位移量设置为文件长度(文件尾)加offset, offset可为正或负。
若l s e e k成功执行,则返回新的文件位移量,为此可以用下列方式确定一个打开文件的当前
位移量:
off_t currpos;
currpos = lseek(fd, 0, SEEK_CUR);
这种方法也可用来确定所涉及的文件是否可以设置位移量。如果文件描述符引用的是一个管道或F I F O,则l s e e k返回-1,并将e r r n o设置为E P I P E。 |
! EXAMPLE:
# include
# include
# include
main()
{
/***省略文件打开等操作*******/
if(lseek(fd,0,SEEK_CUR)==-1) {
fprintf(stderr,”can’t lseek\n”)
close(fd);
}else{
fprintf(stderr,”lseek OK\n”);
/*处理文件*/
}
}
通常,文件的当前位移量应当是一个非负整数,但是,某些设备也可能允许负的位移量。 但对于普通文件,则其位移量必须是非负值。因为位移量可能是负值,所以在比较l s e e k的返回值时应当谨慎,不要测试它是否小于0,而要测试它是否等于-1。 |
[格式:]
int link(char *oldlink,char *newlink)
char *oldlink
char *newlink
删除文件链接unlink()
int unlink(char * filename)
[说明]
unlink()把文件filename链接数目减1,如果执行减1操作后文件的链接数目为零该文件将被删除。 执行成功返回值是0,否则返回值是-1.
[格式]
# include
# include
int fcntl(int fd,int cmd,int oparg)
[说明]
fcntl()函数调用可以修改正在使用的文件的属性,这些属性包括文件描述字,文件状态,close-on-exec标志等。
fd 文件描述字
CMD fcntl()命令
• 复制一个现存的描述符(c m d=F _ D U P F D)。
• 获得/设置文件描述符标记(c m d = F _ G E T F D或F _ S E T F D)。
• 获得/设置文件状态标志(c m d = F _ G E T F L或F _ S E T F L)。
• 获得/设置异步I / O有权(c m d = F _ G E TO W N或F _ S E TO W N)。
• 获得/设置记录锁(c m d = F _ G E T L K , F _ S E T L K或F _ S E T L K W)。
CMD 共有五类格式:
F_DUPFD |
使用该命令时,fcntl()的返回值为一个文件描述符,该文件描述符是通过复制参数FD而得到的.这个命令的作用与DUP类似 |
F_GETFD |
返回文件的”close-on-exec”标志,如果这个标志被置为”on”,在执行exec()命令之后,文件描述字fd所指向的文件会被自动关閉,否则,文件处于继续打开的状态 |
F_SETFD |
设定”close-on-exec”标志 |
F_GETFL |
返回文件描述符字fd所指向文件的状态标志.例如:是否为只读,是否可写等等. |
F_SETFL |
设定参数oparg中的标志,标志包括O_NDELAY或者O_APPEND |
! EXAMPLE:
# include
# include
# DEFINE DUMVY 0
main()
{
int fd,flags,num;
char name[10];
if((fd=open(“/tmp/filename”,O_RDONLY))==-1){
fprintf(stderr,”open file error\n”);
exit (-1);
}
sleep(5);
flags=fcntl(fd,F_GETFL,DUMVY);
flags&=O_RDWR;
fcntl(fd,F_SETFL,flags);
exit(0);
}
另一个例子
struct flock dataflock;
dataflock.l_type=F_WRLCK;
dataflock.l_start=0;
dataflock.l_whence=SEEK_SET;
dataflock.l_len=0;
if(fcntl(fd,F_SETKW,&dataflock)<0){
……
}
/**** flock in fcntl.h***********
struct flock{
short l_type;
short l_whence;
off_t l_start;
off_t l_len;
#if defined(_M_I386)
short l_sysid;
pid_t l_pid;
#else
short l_pid;
short l_sysid;
# endif
}
# define F_RDLCK 01 /*Read lock*/
# define F_WRLCK 02 /*Write lock*/
# define F_UNLCK 03 /*Remove LOCK(S)*/