1、-2011-07-27-#include #include #include int creat(const char* pathname, mode_t mode) 函数功能等效于open(pathname,O_WRONLY|O_TRUNC|O_CREAT,mode)所以很少使用 creat()。-2011-07-30-(1) 当执行一个程序文件时,进程有效用户 ID 通常就是实际用户 ID,进程有效组 ID 就是实际组 ID,但是可以在文件方式字(st_mode)中设置一个特殊标志,其定义就是“当执行其文件时,把进程的有效用户 ID 设置为文件的所有者(st_uid) “,与此类似,把进程
2、的有效组 ID 设置为文件的组所有者(st_gid),在文件方式字中这两位称之为设置 -用户-ID (set-user-id)和设置-组-ID(set-group-id ) 。(2) 文件存储许可权 st_mode,共 9 位:(3) 为了删除一个文件,必须对包含这个文件的目录具有写和执行权限,而对于文件本身则不需要读写权限。(4) 进程每次打开,创建或者删除一个文件时,内核就会进行文件存取许可权测试。而这可能涉及文件的所有者(st_uid,st_gid) ,进程的有效ID(有效用户 ID 和有效组 ID) ,以及进程的添加组 ID(若支持的话) 。a) 进程的有效用户 ID 是 0,即超级用
3、户,则允许存取。b) 若进程有效 ID 等于文件的所有者,即进程拥有此文件,则适当的所有者存取许可权位被设置,则允许存取。c) 若进程的有效组 ID 或进程的添加组 ID 之一等于文件组 ID,若适当的组存取许可权位设置,则允许存取。d) 若适当的其他用户存取许可权位被设置,则允许存取。-2011-08-01-(1) 新文件的用户 ID 和组 ID新文件设置的用户 ID 为进程的有效用户 ID,组 ID 设置为进城的有效组ID 或者它所在的目录的 ID(设置了设置组ID 位) 。(2) 进程 ID 和文件访问权的问题与进程相关的 ID 有六个,如下:而每个文件都有一个相关的所有者和组所有者。通
4、常进程有效 ID=实际用户 ID。当使用 open 打开一个函数的时候内核进程以有效用户 ID 和有效组 ID 为基础检查文件的存取许可权。但是也有的时候希望以实际用户ID 和实际组 ID 来测试文件的存取许可权。此时可以使用 access(3) umask()是从权限中 “拿走”相应的位,且文件创建时不能赋予执行权限,在设置之后通常在下一次设置或者退出 SHELL 之后失效。创建文件时,如果 umask 中设置了某些文件存取权限位,那么 create 或者 open 函数指定的 mode 中的权限位和 umask 中相同则是不设置此权限的。-2011-08-02-(1) chmod(fiel
5、pathname,mode)fchmod(files,mode),其中 mode 常数如下:Ls 命令在显示执行时设置组 ID 表示为 l,如:(2) 文件截短#include#includeInt truncate(pathname,length);Int ftruncate(filedes,length);将文件截短为 length 长度。(3) UNIX 文件系统去除自举块和超级块之后的文件系统如下:目录块由若干的目录项组成,目录项由文件名和 i 节点编号数组成。由于目录也是文件所以文件名就是目录名。任何一个叶目录其连接数总是2,一个是命名该目录的目录项(testdir)和 . 项。从图
6、中可以看出 1267是一个目录。-2011-08-04-(1) link()、unlink() 函数浅析因此-2011-08-05-(1) rename(oldname,newname)函数浅析a. 如果 oldname 是文件,newname 已经存在,且是目录,则失败,返回-1b. 如果 oldname 是目录,newname 已经存在且是目录,则如果不是空目录(只有.和.)则失败,如果是空目录,则先删除,在将 oldname-newname。c. 如果 oldname 和 newname 都是目录,则 newname 不能包含 oldname 作为前缀,因为在更新目录前先要删除 oldn
7、ame,这样就不能建立newname。-2011-09-10-(1) tempname(2) 系统数据文件操作函数:(3) 系统时间:#include time_t time(time_tc a *l p t r) ;(4) Unix 进程的环境之启动和终止:(5) 一般认为在 c 中分为这几个存储区 1 栈 - 由编译器自动分配释放 2 堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收 3 全局区(静态区) ,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束释放 4
8、另外还有一个专门放常量的地方。 - 程序结束释放 在函数体中定义的变量通常是在栈上,用 malloc, calloc, realloc 等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了 static 修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的 static 变量表示在该文件中有效,不能 extern 到别的文件用,在函数体内定义的 static 表示只在该函数体内有效。(6) 自动变量潜在问题:(7) 僵死进程的产生和父进程如何获取子进程的终止状态:(8) exec 系列函数之间的关系:(9) 实际用户 ID、有效用户 ID、保存的设置用户 ID
9、三者的区别和联系:具体内容参见 apue(第二版) 8.11 更改用户 ID 和组 ID(10)关于 system()函数:具体内容参见 apue(第二版) 8.13 system 函数 (11)BSD 终端登录过程详解:a. 读取/etc/ttys 文件,文件中一行说明设备名和传递给 getty 程序的参数,init 进程为每一个终端调用一次 fork,生成的子进程 exec getty 程序。b. getty 为终端设备调用 open 函数,以读写方式将终端打开,一旦设备打开,则文件描述符 0、1、2 就被设置到终端,然后 getty 输出:“login”之类的信息c. 用户输入用户名,g
10、etty 调用 login,其中 init 以空的环境调用getty,getty 以终端名和文件 gettytab 中说明的环境字符串为 login 创建一个环境:execle(“/bin/login”,”login”,”-p”,”username”,(char*)0,envp)d. login()调用 getpwnam()获取口令文件登录项,然后调用 getpass(3)提示“passed” ,然后调用 crypt(3)将用户嵌入的口令加密并和阴影口令中密码进行比较e. 登录成功之后,login 负责: 将当前的工作目录设置为该用户的家目录 调用 chown 改变终端所有权,使登录用户成为它的所有者 改变终端的访问权限为用户读写 调用 setgid 和 initgroups 设置进程组 id 利用 login 得到的信息初始化环境变量 将进程 ID 设置为用户 ID,并调用该用户的登录 shell(12)进程组:(13)孤儿进程组中的进程并不都是孤儿进程(个人理解) ,孤儿进程组的产生和终端有关。内核会向已停止的进程发送 SIGHUP(挂起)信号和SIGCONT(继续),系统默认操作是终止进程,但是如果忽略此信号或者对其进行处理,则此停止进程仍可以继续执行。apue 上关于创建孤儿进程组的例子只是模拟了内核对于孤儿进程组的处理过程。(14)