Linux 系统调用 ftok

函数ftok()用来生成 IPC key,而 IPC key 可以用来创建 IPC 对象,或者说创建 IPC
对象时可能会用到 IPC key。

ftok()函数

1
2
3
4
#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id);

ftok()会接受两个参数,第一个是一个文件路径,必须是一个存在的文件,因为 IPC key
的生成需要文件结点的信息。第二个参数proj_id是自己指定的,个人理解这个参数可以
使得一个文件可以生成多个 key,而不用出现为了一个生成 key 就建一个文件的情况。手
册上说proj_id的最低 8 比特不能为 0,但是我尝试传入 0 也能调用成功。

pathnameproj_id相同时,ftok()的返回值也相同,而当它们不同时,也能保证
不相同,这点很重要。

下面是一个小的例子程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>

#define PROJ_ID 0x11
#define PATHNAME "/tmp/abc"

int main(int argc, char *argv[])
{
struct stat sb;
key_t ret;
ret = ftok(PATHNAME, PROJ_ID);

if (ret == -1) {
perror("ftok error");
exit(1);
}
if (stat(PATHNAME, &sb) == -1) {
perror("stat error");
exit(2);
}
printf("ftok: %#x,\nsb.st_dev: %#lx,\nsb.st_ino: %#lx\n",
ret, sb.st_dev, sb.st_ino);
printf("------------------------------\n");
ret = ftok(PATHNAME, 0x22);
printf("ftok: %#x,\nsb.st_dev: %#lx,\nsb.st_ino: %#lx\n",
ret, sb.st_dev, sb.st_ino);
return 0;
}

从结果也可以看出,ftok()的返回值跟proj_id`st_devst_ino`有很大的关系。

struct ipc_perm结构体

1
2
3
4
5
6
7
8
9
struct ipc_perm {
key_t __key; /* Key supplied to msgget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};

命令man msgctl man semctl man shmctl都可以查看到上述定义。每一个 IPC 对象都
对应一个ipc_perm结构体。其中uid gid mode是可以由函数msgctl() semctl()
shmctl()来修改的。

0%