fcntl函数提供了对文件描述符的各种控制操作。另外一个常见的控制文件描述符属性和行为的系统调用是ioctl,而且ioctl比fcntl能够执行更多的控制。但是对于控制文件描述符常用的属性和行为,fcntl函数是由POSIX规范指定的首选方法,函数定义如下:
#include<fcntl.h>
int fcntl(int fd,int cmd,...)
fd参数是被操作的文件描述符,cmd参数指定执行何种类型的操作。根据操作类型的不同,该函数可能还需要第三个可选参数arg。fcntl函数支持的常用操作及其参数如下表所示:
fcntl函数成功时返回值如表所示,失败则返回-1并设置errno。
在网络编程中,fcntl函数通常用来将一个文件描述符设置为非阻塞的,示例代码如下:
此外,SIGIO和SIGURG这两个信号与其他linux信号不同,它们必须与某个文件描述符相关联方可使用:当被关联的文件描述符可读或可写的时候,系统将出发SIGIO信号;当被关联的文件描述符(而且必须是一个socket)上有带外数据可读的时候,系统将触发SIGURG信号。将信号和文件描述符关联的方法就是使用fcntl函数为目标文件描述符指定宿主进程或进程组,那么被指定的宿主进程或进程组将捕获这两个信号。使用SIGIO时,还需要利用fcntl设置O_ASYNC标志(异步IO标志,不过SIGIO信号模型并非真正意义上的异步IO模型)。
mmap函数用于申请一段内存空间。我们可以将这段内存作为进程间通信的共享内存,也可以将文件直接映射其中。munmap函数则释放有mmap创建的这段内存空间,它们的定义如下:
#include<sys/mman.h>
void* mmap(void*start,size_t length,int prot ,int flags, int fd,off_t offset);
int munmap(void* start size_t length);
start参数允许用户使用某个特定的地址作为这段内存的起始位置。如果它被设置为NULL,则系统自动分配一个地址。
length参数指定内存段的长度。
proto参数用来设置内存段的访问权限,它可以去以下几个值的按位与:
flags参数控制内存段内容被修改后程序的行为。它可以被设置为图6-1中的某些值(这里仅仅列出了常用的值)的按位或(其中MAP_SHARED和MAP_PRIVATE是互斥的,不能同时指定)