﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-创的技术博客-随笔分类-读书笔记</title><link>http://www.cppblog.com/converse/category/5839.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 02 Sep 2008 16:12:08 GMT</lastBuildDate><pubDate>Tue, 02 Sep 2008 16:12:08 GMT</pubDate><ttl>60</ttl><item><title>APUE2读书笔记(三):不可重入函数</title><link>http://www.cppblog.com/converse/archive/2008/09/02/60712.html</link><dc:creator>创</dc:creator><author>创</author><pubDate>Tue, 02 Sep 2008 09:18:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2008/09/02/60712.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/60712.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2008/09/02/60712.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/60712.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/60712.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/converse/archive/2008/09/02/60712.html'>阅读全文</a><img src ="http://www.cppblog.com/converse/aggbug/60712.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">创</a> 2008-09-02 17:18 <a href="http://www.cppblog.com/converse/archive/2008/09/02/60712.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>APUE2读书笔记(二):为什么有了wait函数族还需要SIGCHLD信号</title><link>http://www.cppblog.com/converse/archive/2007/12/28/39870.html</link><dc:creator>创</dc:creator><author>创</author><pubDate>Fri, 28 Dec 2007 15:39:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2007/12/28/39870.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/39870.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2007/12/28/39870.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/39870.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/39870.html</trackback:ping><description><![CDATA[首先,在谈这个问题时,先说说unix中僵尸进程的含义,APUE2中如下定义:<br>In UNIX System terminology, a process that has terminated, but whose parent has not yet waited for it, is called a zombie. <br>也就是说,但凡是父进程没有调用wait函数获得子进程终止状态的子进程在终止之后都是僵尸进程,这个概念的关键一点就是父进程是否调用了wait函数.<br><br>而关于SIGCHLD信号,APUE2中又如是说:<br>Whenever a process terminates or stops, the SIGCHLD signal is sent to the parent. By default, this signal is ignored, so the parent must catch this signal if it wants to be notified whenever a child's status changes. The normal action in the signal-catching function is to call one of the wait functions to fetch the child's process ID and termination status.<br>简单的说,子进程退出时父进程会收到一个SIGCHLD信号,默认的处理是忽略这个信号,而常规的做法是在这个信号处理函数中调用wait函数获取子进程的退出状态.<br><br>这里存在一个疑问,既然在SIGCHLD信号的处理函数中要调用wait函数族,为什么有了wait函数族还需要使用SIGCHLD信号?<br><br>我们知道,unix中信号是异步处理某事的机制,好比说你准备去做某事,去之前跟邻居张三说如果李四来找你的话就通知他一声,这让你可以抽身出来去做这件事,而李四真正来访时会有人通知你,这个就是异步信号一个较为形象的比喻.<br><br>一般的,父进程在生成子进程之后会有两种情况,一种是父进程继续去做别的事情,类似上面举的例子,另一种是父进程啥都不做,一直在wait子进程退出.SIGCHLD信号就是为这第一种情况准备的,它让父进程去做别的事情,而只要父进程注册了处理该信号的函数,在子进程退出时就会调用该函数,在函数中wait子进程得到终止状态之后再继续做父进程的事情.<br><br>也就是说,明确以下几点:<br>1)凡父进程不调用wait函数族获得子进程终止状态的子进程在退出时都会变成僵尸进程.<br>2)SIGCHLD信号可以异步的通知父进程有子进程退出.<br>
<img src ="http://www.cppblog.com/converse/aggbug/39870.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">创</a> 2007-12-28 23:39 <a href="http://www.cppblog.com/converse/archive/2007/12/28/39870.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>APUE2读书笔记(一):real user ID, effective user ID,saved set-user-ID </title><link>http://www.cppblog.com/converse/archive/2007/12/20/39166.html</link><dc:creator>创</dc:creator><author>创</author><pubDate>Thu, 20 Dec 2007 15:24:00 GMT</pubDate><guid>http://www.cppblog.com/converse/archive/2007/12/20/39166.html</guid><wfw:comment>http://www.cppblog.com/converse/comments/39166.html</wfw:comment><comments>http://www.cppblog.com/converse/archive/2007/12/20/39166.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/converse/comments/commentRss/39166.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/converse/services/trackbacks/39166.html</trackback:ping><description><![CDATA[<p>Unix中常见的几个概念,下面做一个解释.<br><br>首先需要明确一点,这几个概念都是和进程相关的.<br>real user ID表示的是实际上进程的执行者是谁,effective user ID主要用于校验该进程在执行时所获得的文件访问权限,也就是说当进程访问文件时检查权限时实际上检查的该进程的"effective user ID",saved set-user-ID 仅在effective user ID发生改变时保存.<br><br>一般情况下,real user ID就是进程的effective user ID,但是当要运行的可执行程序设置了"<span class=docEmphasis>set-user-ID</span>"位之后,进程的effective user ID变成该文件的属主用户id,同时该进程的"saved set-user-ID"变成此时进程的"effective user ID",也就是该可执行程序的属主用户ID,该进程在执行一些与文件访问权限相关的操作时系统检查的是进程的effective user ID.<br><br>为什么需要一个"saved set-user-ID"?因为当进程没有超级用户权限的时候,进程在设置"effective user ID"时需要将需要设置的ID和该进程的"real user ID"或者"saved set-user-ID"进行比较.<br><br>APUE2中进行的解释是:<br>1)If the process has superuser privileges, the setuid function sets the real user ID, effective user ID, and saved set-user-ID to uid.</p>
<p>2)If the process does not have superuser privileges, but uid equals either the real user ID or the saved set-user-ID, setuid sets only the effective user ID to uid. The real user ID and the saved set-user-ID are not changed.</p>
<p>3)If neither of these two conditions is true, errno is set to EPERM, and 1 is returned<br>也就是说:<br>1)当用户具有超级用户权限的时候,setuid 函数设置的id对三者都起效.<br>2)否则,仅当该id为real user ID 或者saved set-user-ID时,该id对effective user ID起效.<br>3)否则,setuid函数调用失败.<br><br>也就是说,这个saved set-user-ID更多的作用是在进程切换自己的effective user ID起作用.<br><br>需要特别提醒的是:并没有任何的API可以获取到进程的saved set-user-ID,它仅仅是系统在调用setuid函数时进行比较而起作用的.<br>APUE2中关于此事的原话如下:<br>Note that we can obtain only the current value of the real user ID and the effective user ID with the functions <tt>getuid</tt> and <tt>geteuid</tt> from Section 8.2. We can't obtain the current value of the saved set-user-ID.</p>
<p><br>举一个例子说明问题,假设这样的一种情况,系统中有两个用户A,B,还有一个由B创建的可执行程序proc,该可执行程序的set-<br>user-id位已经进行了设置.<br><br>当A用户执行程序proc时,<br>程序的real user ID = A的用户ID,effective user ID = B的用户ID,&nbsp; saved set-user-ID=B的用户ID.<br><br>假如在该进程结束了对某些限制只能由用户B访问的文件操作后,程序将effective user ID设置回A,也就是说此时:<br>程序的real user ID = A的用户ID,effective user ID = A的用户ID,&nbsp; saved set-user-ID=B的用户ID.<br><br>这个改动之所以能成功,原因在于上面列举出的情况2):该ID为进程的real user ID.<br><br>最后,假设由于种种原因进程需要再次切换effective user ID为B,可是因为不能通过API获取进程的saved set-user-ID(该值为B的用户ID),所以只能通过两种途径获得(可能还有别的途径):<br>a)在设置effective user ID变回A之前保存effective user ID,它的值为B的用户ID.<br>b)调用函数getpwnam( "B"),在返回的struct passwd *指针中成员pw_uid存放的就是用户B的ID.<br>这样,这个调用setuid(B的用户ID)就会成功,原因也在于上面说的情况2):该ID与进程的saved set-user-ID相同.<br><br>APUE2中关于这几个值的相关解释在section4.4和section8.11中都有涉及.<br><br><br><br><br><br><br></p>
<img src ="http://www.cppblog.com/converse/aggbug/39166.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/converse/" target="_blank">创</a> 2007-12-20 23:24 <a href="http://www.cppblog.com/converse/archive/2007/12/20/39166.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>