资源描述
---------------------------------------------2011-07-27---------------------------------------------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
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)“,与此类似,把进程的有效组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,即超级用户,则允许存取。
b) 若进程有效ID等于文件的所有者,即进程拥有此文件,则适当的所有者存取许可权位被设置,则允许存取。
c) 若进程的有效组ID或进程的添加组ID之一等于文件组ID,若适当的组存取许可权位设置,则允许存取。
d) 若适当的其他用户存取许可权位被设置,则允许存取。
---------------------------------------------2011-08-01---------------------------------------------
(1) 新文件的用户ID和组ID
新文件设置的用户ID为进程的有效用户ID,组ID设置为进城的有效组ID或者它所在的目录的ID(设置了设置—组—ID位)。
(2) 进程ID和文件访问权的问题
与进程相关的ID有六个,如下:
而每个文件都有一个相关的所有者和组所有者。通常进程有效ID=实际用户ID。当使用open打开一个函数的时候内核进程以有效用户ID和有效组ID为基础检查文件的存取许可权。但是也有的时候希望以实际用户ID和实际组ID来测试文件的存取许可权。此时可以使用access
(3) umask()是从权限中“拿走”相应的位,且文件创建时不能赋予执行权限,在设置之后通常在下一次设置或者退出SHELL之后失效。创建文件时,如果umask中设置了某些文件存取权限位,那么create或者open函数指定的mode中的权限位和umask中相同则是不设置此权限的。
---------------------------------------------2011-08-02---------------------------------------------
(1) chmod(fielpathname,mode)
fchmod(files,mode),其中mode常数如下:
Ls命令在显示执行时设置组ID表示为l,如:
(2) 文件截短
#include<unistd.h>
#include<sys/types.h>
Int truncate(pathname,length);
Int ftruncate(filedes,length);将文件截短为length长度。
(3) UNIX文件系统
去除自举块和超级块之后的文件系统如下:
目录块由若干的目录项组成,目录项由文件名和i节点编号数组成。由于目录也是文件所以文件名就是目录名。任何一个叶目录其连接数总是2,一个是命名该目录的目录项(testdir)和 . 项。从图中可以看出1267是一个目录。
---------------------------------------------2011-08-04---------------------------------------------
(1) link()、unlink()函数浅析
因此
---------------------------------------------2011-08-05---------------------------------------------
(1) rename(oldname,newname)函数浅析
a. 如果oldname是文件,newname已经存在,且是目录,则失败,返回-1
b. 如果oldname是目录,newname已经存在且是目录,则如果不是空目录(只有.和..)则失败,如果是空目录,则先删除,在将oldname->newname。
c. 如果oldname和newname都是目录,则newname不能包含oldname作为前缀,因为在更新目录前先要删除oldname,这样就不能建立newname。
---------------------------------------------2011-09-10---------------------------------------------
(1) tempname
(2) 系统数据文件操作函数:
(3) 系统时间:
#include <time.h>
time_t time(time_tc a *l p t r) ;
(4) Unix 进程的环境之启动和终止:
(5) 一般认为在c中分为这几个存储区
1栈 - 由编译器自动分配释放
2堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束释放
4另外还有一个专门放常量的地方。 - 程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。
(6) 自动变量潜在问题:
(7) 僵死进程的产生和父进程如何获取子进程的终止状态:
(8) exec系列函数之间的关系:
(9) 实际用户ID、有效用户ID、保存的设置用户ID三者的区别和联系:
具体内容参见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. 用户输入用户名,getty调用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)
展开阅读全文