免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: kukucm
打印 上一主题 下一主题

请问errno的问题 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2005-11-20 10:48 |只看该作者
原帖由 zy116 于 2005-11-20 10:45 发表


连linux帮助文档都没敢说得很确定, 又何必非要刨根问底呢?



恩,明白了,多谢啊

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
22 [报告]
发表于 2005-11-20 13:02 |只看该作者
原帖由 er 于 2005-11-20 09:06 发表

请参见WROX出版社的《Linux程序设计

首先,世界上并非只有 Linux,请把目光放长远些,否则会被咒骂为“浅薄”。
其次,即使是 Linux,它也是变化的、发展的。而且,曾经出现过的 Linux 版本,没有一个是把 C 语言的 errno 实现为操作系统的一个变量的。没必要,而且是违反标准的。至于你认为的情形,也许会在未来的 Linux 版本中出现?那我就不得而知了。

论坛徽章:
0
23 [报告]
发表于 2005-11-20 13:07 |只看该作者
ft, 当然不可能是多进程操作系统的全局变量了,这种不用想都应该知道,否则不是混乱了!

论坛徽章:
0
24 [报告]
发表于 2005-11-20 16:30 |只看该作者
原帖由 hightman 于 2005-11-20 13:07 发表
ft, 当然不可能是多进程操作系统的全局变量了,这种不用想都应该知道,否则不是混乱了!



怪我太菜了,可是操作系统的各种资源不能共享吗?如果进行系统调用,为什么不可以呢?我只是猜想,,,,
我打印了environ的地址,各个变量指针的地址,各个指针内容的地址,发现linux是在高地址,和apue中说的一样,而windows2003vc下根本不是高地址处。

这些在哪儿我都不关心,我只是不明白这个地址连接器是从什么地方得到的///  
我觉得environ和errno类似。而且我写了程序调试了也不知道。。。
望各位高手再指点一二。 也可以说一个可能的情况,比如某个系统下。
虽然可以不知道,但是现在没有心情去干别的了
先谢谢了

论坛徽章:
0
25 [报告]
发表于 2005-11-20 17:26 |只看该作者
自己up一下

论坛徽章:
0
26 [报告]
发表于 2005-11-21 04:38 |只看该作者
这么热闹。。。
apue里应该有一段讲到errno,也提过最好不要直接访问errno,因为多线程的环境下errno可以是用宏来实现的。
你关心链接器是如何找到它的地址的,我试着简单解释一下,如果说的不对请其他人指正。
简单起见,先假设errno就是一个int型的全局变量,位于glibc库里,链接的时候自然就解决了符号引用。同样简单起见,静态链接,这个变量就位于你程序的二进制映像(在磁盘上的时候叫文件,在内存中就是进程)中,这样,每个进程有自己的errno,不会混乱。
再来解决这个全局变量什么时候被谁设置的问题。当你调用一个系统调用的时候,实际会执行到glibc里的一小段包裹代码,比如你写pid=fork(),那个所谓的fork函数看起来可能是这个样子的:
mov eax,2 (内核中一个跳转表的下标,比如2代表fork)
int 80h
这样才能进入以ring 0运行的kernel space去执行fork的实际代码。
从int 80h回到user space之后,返回值在eax里,
如果eax>=0,则fork成功,eax里就是pid,return eax。
如果eax<0,则fork失败,eax里是错误代码,令errno=-eax, return -1。
综上所述,我坚持我的观点,errno是C的定义,虽然和操作系统密切相关,但是从代码位置和错误码的含义来看,都不属于特定的内核。最简单的例子,dos下的turbo c也有errno的定义,而且可能不是EPERM、EINTR等等,那么dos的内核在哪里保存这个extern int errno?
最后,关于多线程环境下的errno,因为线程使用的是同一个进程空间,为了避免线程间的冲突,线程库必须根据不同的线程设置不同的errno,所以要用宏来实现。extern int errno并不意味这它就不可以是宏,宏也可以作左值。比如这么写:
#define MAX_THREADS 2
static int threaded_errno[MAX_THREADS] = {0,0};
static int thread_id = 1;
#define myerrno (threaded_errno[thread_id])
然后
myerrno = 22;
printf("%dn", myerrno);

论坛徽章:
0
27 [报告]
发表于 2005-11-21 08:47 |只看该作者
谢了
你的想法跟我猜的差不多,但是我不明白你说的fork的返回值怎么证明你的想法是对的.

我看了基本书,特别是操作系统设计与实现那本,里面的环境变量是shell自己的,通过自己的地址空间的内容(比如最高地址)放到子进程的空间中去,编程时默认一个位置表示环境变量所在的地方,比如逻辑地址的最高处开始.
我猜想应该是这样的
可能这直接在库中了,就象你说的那样.

论坛徽章:
0
28 [报告]
发表于 2005-11-21 14:21 |只看该作者
在同一个系统中,就有可能是宏和 EXTENT INT(条件编译),同多线索没有什么关系,要看errno是不是可以重入的,多线索并不意味着errno就是可以和必须重入的.当然如果没有多线索,也就不应该有什么重入的了.我个人觉得可能也就是PTHREAD环境设计到重入的问题,至于由系统内核支持的多线索,内核自己应该可以自己处理的.


从理论上讲(实现肯定有各种方式的),C库没有必要设置这么个变量.EXTENT INT 形式可以说是内核的全局变量(LINUX是的),系统调用的时候不需要保护.不可能出现ERRNO重入的现象.内核可以重入并不意味着系统调用可以重入.A进程的C系统调用的返回错误值不可能被B进程的D系统调用的返回错误值修改的,在同一个进程里面更不存在这种情况.

论坛徽章:
0
29 [报告]
发表于 2005-11-21 14:36 |只看该作者
觉得只要定下"errno是线程固有“的这个标准,在什么层次实现,就不是用户程序需要考虑的了...

论坛徽章:
0
30 [报告]
发表于 2005-11-22 00:59 |只看该作者
menp9999 zalem
请问我27楼对的吗?
我觉得flw斑竹有道理,errno并不是全局变量.但是menp9999说是,我真蒙了
环境变量内核能感知到吗?好象不能吧,如果不能errno又和environ不一样了.实际上内河完全也可以不知道 errno,直接告诉进程:"把错误好放到0xbffff**去了自己去找吧/:,"我越来越觉得是这样的.
一切只能裁了,谁帮我去comp.unix.问问,  我翻译不出来.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP