ftok key值冲突

前两天遇到的关于ftok()函数的问题,当时发了帖子求助,解决后整理于此!

帖子在这儿:ftok产生的key冲突了

最近遇到一个问题,在用户b下创建共享内存失败,跟踪代码发现shmget的errno为17(要创建的这个共享内存已经存在了),可是在该用户下通过ipcs查看确实没有共享内存啊,后来发现,用户a下已经创建的共享内存与用户b要创建的共享内存冲突了,准确的说是key值冲突了,key值是通过ftok函数生成的。

上网查询了一个,ftok是根据文件i节点和调用ftok时的id值产生的,而且还给出了例子加以说明,如下:

在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,

换算成16进制为 0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。

b用户下有目录trnlog,通过ls -i命令查看tt的i节点为 2228246

ftok 得到的key值为 16908310  <==>  0x1020016

a用户下有文件comm,通过ls -i命令查看xx的i节点为 2097174

ftok 得到的key值为 16908310  <==>  0x1020016

问题来了:

1)两个用户下的文件i节点不同,通过ftok函数得到的key值是相同的,为什么呢?

2)用户a创建的共享内存对其他用户有影响吗?也就是说进程创建共享内存的时候系统会全系统检查该key值有没有创建过共享内存?

小弟恳请大神点拨说明,感谢万分!

用户a和b 文件i节点及程序调试查看ftok产生的key值如下

用户a:

C/C++ code

?


1

2

a-/home/a/etc/ipckey>ls -li

2097174 -rwxrw-r--. 1 a a    0 Sep 22  2013 comm

程序调试:

C/C++ code

?


1

2

3

4

5

6

7

64        sprintf(strPath,"%s/etc/ipckey/comm",getenv("HOME"));

(gdb) p strPath

$1 = "/home/a/etc/ipckey/comm"‘\000‘ <repeats 91 times>

(gdb) n

67        if ((ilShareKey = ftok(strPath,1)) == (key_t)-1)

(gdb) p ilShareKey

$2 = 16908310

用户b:

C/C++ code

?


1

2

b-/home/b/etc/ipckey>ls -li

2228246 drwxr-xr-x. 2 b b 4096 Sep 22  2013 trnlog

程序调试:

C/C++ code

?


1

2

3

4

5

6

7

64        sprintf(strPath,"%s/etc/ipckey/trnlog",getenv("HOME"));

(gdb) p strPath

$1 = "/home/b/etc/ipckey/trnlog"‘\000‘ <repeats 89 times>

(gdb) n

67        if ((ilShareKey = ftok(strPath,1)) == (key_t)-1)

(gdb) p ilShareKey

$2 = 16908310

好吧,没人解答我来说说吧!

翻看了ftok的实现源码,得知ftok就是通过文件的一些属性加上id值得到的key值,的确存在不同文件同一id值生成相同key值的可以,比如我遇到的这种情况。

先列出ftok的实现,精简如下:

C/C++ code

?


1

key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((proj_id & 0xff) << 24));

用户a:

C/C++ code

?


1

2

a-/home/a/etc/ipckey>stat -c "%i %d" comm

2097174 64770

用户b:

C/C++ code

?


1

2

b-/home/b/etc/ipckey>stat -c "%i %d" trnlog

2228246 64770

按照ftok的实现经过计算,的确得出相同的结果。

所以说,ftok的使用不只是大家所说的,如果生成key值的文件在使用,不允许删除重建,否则会出现意想不到的问题;而且,相同的机器,我们也需要注意我遇到的这种情况。

通过以上,我明白了ftok产生的问题,让我纠结了几天的问题。 ~~~结贴~~~

时间: 2024-10-15 12:04:42

ftok key值冲突的相关文章

iOS 中plist文件中配置key值冲突的现象

iOS开发一些特殊的软件需要在项目中配置对应的key值,然而近期在项目中发现一个有意思的现象,苹果官方文档中提供的key值很多,但其实有一些彼此可能有冲突,当你同时配置了彼此冲突的key值,可能会出现一些奇葩的现象,而且不容易发现问题所在,下面我就我遇到的情况和大家分享一下: 因为项目需要,需要配置定位相关的key值,同时需要后台长时间运行,所以在应用中我配置了NSLocationWhenInUseUsageDescription这个定位的key值,为了在使用时获取用户的位置信息:同时我用申请了

IPC机制key值的各位组成

key_t ftok(const char *_pathname, int _proj_id) key值的第31~24位为ftok()第二个参数的低8位: key值的第23~16位为ftok()第一个参数文件属性的st_dev成员的低8位: key值的第15~0位为ftok()第一个参数文件属性的st_ino属性的低16位. #include <sys/ipc.h> #include <sys/types.h> #include <stdio.h> #include &

java中key值可以重复的map:IdentityHashMap

在Java中,有一种key值可以重复的map,就是IdentityHashMap.在IdentityHashMap中,判断两个键值k1和 k2相等的条件是 k1 == k2 .在正常的Map 实现(如 HashMap)中,当且仅当满足下列条件时才认为两个键 k1 和 k2 相等:(k1==null ? k2==null : e1.equals(e2)). IdentityHashMap类利用哈希表实现 Map 接口,比较键(和值)时使用引用相等性代替对象相等性.该类不是 通用 Map 实现!此类

JavaScript对象根据Key值排序

近日在工作中遇到了一个挺有意思的问题.对JS的对象按Key值排序.如下面的obj对象 var obj ={"中国(100)":"'beijing','sichuan' ,'jilin'","英国大不列颠(2)" :"'london','airland'","美国加州(5)":"'phonix','atalata'","德意志(4)":"'berlin','e

通过靶机网站的编辑器存在的漏洞,拿到靶机上的KEY.txt文件,并把文件中的内容作为key值进行提交

实验环境: 类别 ip 靶机-windows 172.16.1.110 攻击机-kali 172.16.1.111 攻击机-windows 172.16.1.112 题目:通过靶机网站的编辑器存在的漏洞,拿到靶机上的KEY.txt文件,并把文件中的内容作为key值进行提交. 解题过程: 刚看到这个题目是时候是一脸懵逼,当启动完虚拟机以后想到了应该是fck一类的编辑器漏洞, 首先用kali扫描一下,看到了这个就应该明白网站应该是asp的网站,并且是IIS6.0,有解析漏洞 去windows里用浏览

Map/HashMap 获取Key值的方法

1.通过  KeySet()方法 Map<String,Student> newmap = new HashMap<String,Student>(); //newmap HaspMap类型的集合 有唯一的Key,一个Key对应相应的学生 Student stu = new Student("11","Mary","79"); //创建一个学生对象 学号11; 姓名 Mary 成绩 79 newmap.put("

iOS 判断字典是否包含特定Key值

当面向字典开发或服务器返回的数据为字典时,应当判断字典内是否有对应的key值,从而避免返回key值为空而导致程序奔溃: NSDictionary *dict = self.datas[indexPath.row]; if([[dict allKeys] containsObject:@"key"]) { cell.textLabel.text = [dict valueForKey:@"ke y"]; } else { cell.textLabel.text = @

php里少用到的session_module_name,以及session的key值限制,简单将session存储为json的方法

这个函数的作用就是动态的设置php.ini里的session_save_handler,配合session_set_savepath可以在程序里自由配置session的后台方式. session_cache_expire与session_cache_limiter函数是配置session缓存时间与头信息的,比如private,public,nocache 与ini_set函数类似 都要在session_start()之前调用 session.save_handler = files sessio

Js中获取对象的所有key值

假如现在有一个对象 var obj = { A:2 ,B:"Ray" ,C:true ,D:function(){} } 如果想遍历对象obj中的所有键值,一般是用以下方式 for(var key in obj){ console.log(key,obj[key]) } 输出: A 2 B Ray C true D function (){} 如果只是想获取所有的key值,用上面的方法也行得通. 但有更简单的方式:Object.keys(...),返回值是包含key的数组 如 cons