`
weiyinchao88
  • 浏览: 1194968 次
文章分类
社区版块
存档分类
最新评论

Unix下如何写安全的C程序

 
阅读更多
UNIX系统为程序员提供了许多子程序,这些子程序可存取各种安全属性.有
些是信息子程序,返回文件属性,实际的和有效的UID,GID等信息.有些子程序可
改变文件属性.UID,GID等有些处理口令文件和小组文件,还有些完成加密和解密.

本文主要讨论有关系统子程序,标准C库子程序的安全,如何写安全的C程序
并从root的角度介绍程序设计(仅能被root调用的子程序).
1.系统子程序
(1)I/O子程序
*creat():建立一个新文件或重写一个暂存文件.
需要两个参数:文件名和存取许可值(8进制方式).如:
creat(""/usr/pat/read_write"",0666) /* 建立存取许可方式为0666的文件 */
调用此子程序的进程必须要有建立的文件的所在目录的写和执行许可,置
给creat()的许可方式变量将被umask()设置的文件建立屏蔽值所修改,新
文件的所有者和小组由有效的UID和GID决定.
返回值为新建文件的文件描述符.
*fstat():见后面的stat().
*open():在C程序内部打开文件.
需要两个参数:文件路径名和打开方式(I,O,I&O).
如果调用此子程序的进程没有对于要打开的文件的正确存取许可(包括文
件路径上所有目录分量的搜索许可),将会引起执行失败.
如果此子程序被调用去打开不存在的文件,除非设置了O_CREAT标志,调用
将不成功.此时,新文件的存取许可作为第三个参数(可被用户的umask修
改).
当文件被进程打开后再改变该文件或该文件所在目录的存取许可,不影响
对该文件的I/O操作.
*read():从已由open()打开并用作输入的文件中读信息.
它并不关心该文件的存取许可.一旦文件作为输入打开,即可从该文件中读
取信息.
*write():输出信息到已由open()打开并用作输出的文件中.同read()一样
它也不关心该文件的存取许可.
(2)进程控制
*exec()族:包括execl(),execv(),execle(),execve(),execlp()和execvp()
可将一可执行模快拷贝到调用进程占有的存贮空间.正被调用进
程执行的程序将不复存在,新程序取代其位置.
这是UNIX系统中一个程序被执行的唯一方式:用将执行的程序复盖原有的
程序.
安全注意事项:
. 实际的和有效的UID和GID传递给由exec()调入的不具有SUID和SGID许
可的程序.
. 如果由exec()调入的程序有SUID和SGID许可,则有效的UID和GID将设
置给该程序的所有者或小组.
. 文件建立屏蔽值将传递给新程序.
. 除设了对exec()关闭标志的文件外,所有打开的文件都传递给新程序.
用fcntl()子程序可设置对exec()的关闭标志.
*fork():用来建立新进程.其建立的子进程是与调用fork()的进程(父进程)
完全相同的拷贝(除了进程号外)
安全注意事项:
. 子进程将继承父进程的实际和有效的UID和GID.
. 子进程继承文件方式建立屏蔽值.
. 所有打开的文件传给子进程.
*signal():允许进程处理可能发生的意外事件和中断.
需要两个参数:信号编号和信号发生时要调用的子程序.
信号编号定义在signal.h中.
信号发生时要调用的子程序可由用户编写,也可用系统给的值,如:SIG_IGN
则信号将被忽略,SIG_DFL则信号将按系统的缺省方式处理.
如许多与安全有关的程序禁止终端发中断信息(BREAK和DELETE),以免自己
被用户终端终止运行.
有些信号使UNIX系统的产生进程的核心转储(进程接收到信号时所占内存
的内容,有时含有重要信息),此系统子程序可用于禁止核心转储.
(3)文件属性
*access():检测指定文件的存取能力是否符合指定的存取类型.
需要两个参数:文件名和要检测的存取类型(整数).
存取类型定义如下:
0: 检查文件是否存在
1: 检查是否可执行(搜索)
2: 检查是否可写
3: 检查是否可写和执行
4: 检查是否可读
5: 检查是否可读和执行
6: 检查是否可读可写可执行
这些数字的意义和chmod命令中规定许可方式的数字意义相同.
此子程序使用实际的UID和GID检测文件的存取能力(一般有效的UID和GID
用于检查文件存取能力).
返回值: 0:许可 -1:不许可.
*chmod():将指定文件或目录的存取许可方式改成新的许可方式.
需要两个参数:文件名和新的存取许可方式.
*chown():同时改变指定文件的所有者和小组的UID和GID.(与chown命令不
同).
由于此子程序同时改变文件的所有者和小组,故必须取消所操作文件的SUID
和SGID许可,以防止用户建立SUID和SGID程序,然后运行chown()去获得别
人的权限.
*stat():返回文件的状态(属性).
需要两个参数:文件路径名和一个结构指针,指向状态信息的存放
的位置.
结构定义如下:
st_mode: 文件类型和存取许可方式
st_ino: I节点号
st_dev: 文件所在设备的ID
st_rdev: 特别文件的ID
st_nlink: 文件链接数
st_uid: 文件所有者的UID
st_gid: 文件小组的GID
st_size: 按字节计数的文件大小
st_atime: 最后存取时间(读)
st_mtime: 最后修改时间(写)和最后状态的改变
st_ctime: 最后的状态修改时间
返回值: 0:成功 1:失败
*umask():将调用进程及其子进程的文件建立屏蔽值设置为指定的存取许可.
需要一个参数: 新的文件建立屏值.
(4)UID和GID的处理
*getuid():返回进程的实际UID.
*getgid():返回进程的实际GID.
以上两个子程序可用于确定是谁在运行进程.
*geteuid():返回进程的有效UID.
*getegid():返回进程的有效GID.
以上两个子程序可在一个程序不得不确定它是否在运行某用户而不是运行
它的用户的SUID程序时很有用,可调用它们来检查确认本程序的确是以该
用户的SUID许可在运行.
*setuid():用于改变有效的UID.
对于一般用户,此子程序仅对要在有效和实际的UID之间变换的SUID程序才
有用(从原有效UID变换为实际UID),以保护进程不受到安全危害.实际上该
进程不再是SUID方式运行.
*setgid():用于改变有效的GID.
2.标准C库
(1)标准I/O
*fopen():打开一个文件供读或写,安全方面的考虑同open()一样.
*fread(),getc(),fgetc(),gets(),scanf()和fscanf():从已由fopen()打
开供读的文件中读取信息.它们并不关心文件的存取许可.这一点
同read().
*fwrite(),put(),fputc(),puts,fputs(),printf(),fprintf():写信息到
已由fopen()打开供写的文件中.它们也不关心文件的存取许可.
同write().
*getpass():从终端上读至多8个字符长的口令,不回显用户输入的字符.
需要一个参数: 提示信息.
该子程序将提示信息显示在终端上,禁止字符回显功能,从/dev/tty读取口
令,然后再恢复字符回显功能,返回刚敲入的口令的指针.
*popen():将在(5)运行shell中介绍.
(2)/etc/passwd处理
有一组子程序可对/etc/passwd文件进行方便的存取,可对文件读取到入口
项或写新的入口项或更新等等.
*getpwuid():从/etc/passwd文件中获取指定的UID的入口项.
*getpwnam():对于指定的登录名,在/etc/passwd文件检索入口项.
以上两个子程序返回一指向passwd结构的指针,该结构定义在
/usr/include/pwd.h中,定义如下:
struct passwd {
char * pw_name; /* 登录名 */
char * pw_passwd; /* 加密后的口令 */
uid_t pw_uid; /* UID */
gid_t pw_gid; /* GID */
char * pw_age; /* 代理信息 */
char * pw_comment; /* 注释 */
char * pw_gecos;
char * pw_dir; /* 主目录 */
char * pw_shell; /* 使用的shell */
};
*getpwent(),setpwent(),endpwent():对口令文件作后续处理.
首次调用getpwent(),打开/etc/passwd并返回指向文件中第一个入口项的
指针,保持调用之间文件的打开状态.
再调用getpwent()可顺序地返回口令文件中的各入口项.
调用setpwent()把口令文件的指针重新置为文件的开始处.
使用完口令文件后调用endpwent()关闭口令文件.
*putpwent():修改或增加/etc/passwd文件中的入口项.
此子程序将入口项写到一个指定的文件中,一般是一个临时文件,直接写口
令文件是很危险的.最好在执行前做文件封锁,使两个程序不能同时写一个
文件.算法如下:
. 建立一个独立的临时文件,即/etc/passnnn,nnn是PID号.
. 建立新产生的临时文件和标准临时文件/etc/ptmp的链,若建链失败,
则为有人正在使用/etc/ptmp,等待直到/etc/ptmp可用为止或退出.
. 将/etc/passwd拷贝到/etc/ptmp,可对此文件做任何修改.
. 将/etc/passwd移到备份文件/etc/opasswd.
. 建立/etc/ptmp和/etc/passwd的链.
. 断开/etc/passnnn与/etc/ptmp的链.
注意:临时文件应建立在/etc目录,才能保证文件处于同一文件系统中,建
链才能成功,且临时文件不会不安全.此外,若新文件已存在,即便建
链的是root用户,也将失败,从而保证了一旦临时文件成功地建链后
没有人能再插进来干扰.当然,使用临时文件的程序应确保清除所有
临时文件,正确地捕捉信号.
(3)/etc/group的处理
有一组类似于前面的子程序处理/etc/group的信息,使用时必须用include
语句将/usr/include/grp.h文件加入到自己的程序中.该文件定义了group
结构,将由getgrnam(),getgrgid(),getgrent()返回group结构指针.
*getgrnam():在/etc/group文件中搜索指定的小组名,然后返回指向小组入
口项的指针.
*getgrgid():类似于前一子程序,不同的是搜索指定的GID.
*getgrent():返回group文件中的下一个入口项.
*setgrent():将group文件的文件指针恢复到文件的起点.
*endgrent():用于完成工作后,关闭group文件.
*getuid():返回调用进程的实际UID.
*getpruid():以getuid()返回的实际UID为参数,确定与实际UID相应的登录
名,或指定一UID为参数.
*getlogin():返回在终端上登录的用户的指针.
系统依次检查STDIN,STDOUT,STDERR是否与终端相联,与终端相联的标准输
入用于确定终端名,终端名用于查找列于/etc/utmp文件中的用户,该文件
由login维护,由who程序用来确认用户.
*cuserid():首先调用getlogin(),若getlogin()返回NULL指针,再调用
getpwuid(getuid()).
*以下为命令:
*logname:列出登录进终端的用户名.
*who am i:显示出运行这条命令的用户的登录名.
*id:显示实际的UID和GID(若有效的UID和GID和实际的不同时也显示有效的
UID和GID)和相应的登录名.
(4)加密子程序
1977年1月,NBS宣布一个用于美国联邦政府ADP系统的网络的标准加密法:数
据加密标准即DES用于非机密应用方面.DES一次处理64BITS的块,56位的加
密键.
*setkey(),encrypt():提供用户对DES的存取.
此两子程序都取64BITS长的字符数组,数组中的每个元素代表一个位,为0
或1.setkey()设置将按DES处理的加密键,忽略每第8位构成一个56位的加
密键.encrypt()然后加密或解密给定的64BITS长的一块,加密或解密取决
于该子程序的第二个变元,0:加密 1:解密.
*crypt():是UNIX系统中的口令加密程序,也被/usr/lib/makekey命令调用.
crypt()子程序与crypt命令无关,它与/usr/lib/makekey一样取8个字符长
的关键词,2个salt字符.关键词送给setkey(),salt字符用于混合encrypt()
中的DES算法,最终调用encrypt()重复25次加密一个相同的字符串.
返回加密后的字符串指针.
(5)运行shell
*system():运行/bin/sh执行其参数指定的命令,当指定命令完成时返回.
*popen():类似于system(),不同的是命令运行时,其标准输入或输出联到由
popen()返回的文件指针.
二者都调用fork(),exec(),popen()还调用pipe(),完成各自的工作,因而
fork()和exec()的安全方面的考虑开始起作用.
3.写安全的C程序
一般有两方面的安全问题,在写程序时必须考虑:
(1)确保自己建立的任何临时文件不含有机密数据,如果有机密数据,设置
临时文件仅对自己可读/写.确保建立临时文件的目录仅对自己可写.
(2)确保自己要运行的任何命令(通过system(),popen(),execlp(),
execvp()运行的命令)的确是自己要运行的命令,而不是其它什么命
令,尤其是自己的程序为SUID或SGID许可时要小心.
第一方面比较简单,在程序开始前调用umask(077).若要使文件对其他人可
读,可再调chmod(),也可用下述语名建立一个""不可见""的临时文件.
creat(""/tmp/xxx"",0);
file=open(""/tmp/xxx"",O_RDWR);
unlink(""/tmp/xxx"");
文件/tmp/xxx建立后,打开,然后断开链,但是分配给该文件的存储器并未删
除,直到最终指向该文件的文件通道被关闭时才被删除.打开该文件的进程
和它的任何子进程都可存取这个临时文件,而其它进程不能存取该文件,因
为它在/tmp中的目录项已被unlink()删除.
第二方面比较复杂而微妙,由于system(),popen(),execlp(),execvp()执行
时,若不给出执行命令的全路径,就能""骗""用户的程序去执行不同的命令.因
为系统子程序是根据PATH变量确定哪种顺序搜索哪些目录,以寻找指定的命
令,这称为SUID陷井.最安全的办法是在调用system()前将有效UID改变成实
际UID,另一种比较好的方法是以全路径名命令作为参数.execl(),execv(),
execle(),execve()都要求全路径名作为参数.有关SUID陷井的另一方式是
在程序中设置PATH,由于system()和popen()都启动shell,故可使用shell句
法.如:
system(""PATH=/bin:/usr/bin cd"");
这样允许用户运行系统命令而不必知道要执行的命令在哪个目录中,但这种
方法不能用于execlp(),execvp()中,因为它们不能启动shell执行调用序列
传递的命令字符串.
关于shell解释传递给system()和popen()的命令行的方式,有两个其它的问
题:
*shell使用IFS shell变量中的字符,将命令行分解成单词(通常这个
shell变量中是空格,tab,换行),如IFS中是/,字符串/bin/ed被解释成单词
bin,接下来是单词ed,从而引起命令行的曲解.
再强调一次:在通过自己的程序运行另一个程序前,应将有效UID改为实际的
UID,等另一个程序退出后,再将有效UID改回原来的有效UID.
SUID/SGID程序指导准则
(1)不要写SUID/SGID程序,大多数时候无此必要.
(2)设置SGID许可,不要设置SUID许可.应独自建立一个新的小组.
(3)不要用exec()执行任何程序.记住exec()也被system()和popen()调用.
. 若要调用exec()(或system(),popen()),应事先用setgid(getgid())
将有效GID置加实际GID.
. 若不能用setgid(),则调用system()或popen()时,应设置IFS:
popen(""IFS= ;export IFS;/bin/ls"",""r"");
. 使用要执行的命令的全路径名.
. 若不能使用全路径名,则应在命令前先设置PATH:
popen(""IFS= ;export IFS;PATH=/bin:/usr/bin;/bin/ls"",""r"");
. 不要将用户规定的参数传给system()或popen();若无法避免则应检查
变元字符串中是否有特殊的shell字符.
. 若用户有个大程序,调用exec()执行许多其它程序,这种情况下不要将
大程序设置为SGID许可.可以写一个(或多个)更小,更简单的SGID程序
执行必须具有SGID许可的任务,然后由大程序执行这些小SGID程序.
(4)若用户必须使用SUID而不是SGID,以相同的顺序记住(2),(3)项内容,并
相应调整.不要设置root的SUID许可.选一个其它户头.
(5)若用户想给予其他人执行自己的shell程序的许可,但又不想让他们能
读该程序,可将程序设置为仅执行许可,并只能通过自己的shell程序来
运行.
编译,安装SUID/SGID程序时应按下面的方法
(1)确保所有的SUID(SGID)程序是对于小组和其他用户都是不可写的,存取
权限的限制低于4755(2755)将带来麻烦.只能更严格.4111(2111)将使
其他人无法寻找程序中的安全漏洞.
(2)警惕外来的编码和make/install方法
. 某些make/install方法不加选择地建立SUID/SGID程序.
. 检查违背上述指导原则的SUID/SGID许可的编码.
. 检查makefile文件中可能建立SUID/SGID文件的命令.
4.root程序的设计
有若干个子程序可以从有效UID为0的进程中调用.许多前面提到的子程序,
当从root进程中调用时,将完成和原来不同的处理.主要是忽略了许可权限的检
查.
由root用户运行的程序当然是root进程(SUID除外),因有效UID用于确定文
件的存取权限,所以从具有root的程序中,调用fork()产生的进程,也是root进程.
(1)setuid():从root进程调用setuid()时,其处理有所不同,setuid()将把有
效的和实际的UID都置为指定的值.这个值可以是任何整型数.而对非root
进程则仅能以实际UID或本进程原来有效的UID为变量值调用setuid().
(2)setgid():在系统进程中调用setgid()时,与setuid()类似,将实际和有效
的GID都改变成其参数指定的值.
* 调用以上两个子程序时,应当注意下面几点:
. 调用一次setuid()(setgid())将同时设置有效和实际UID(GID),独立分
别设置有效或实际UID(GID)固然很好,但无法做到这点.
. setuid()(setgid())可将有效和实际UID(GID)设置成任何整型数,其数
值不必一定与/etc/passwd(/etc/group)中用户(小组)相关联.
. 一旦程序以一个用户的UID了setuid(),该程序就不再做为root运行,也
不可能再获root特权.
(3)chown():当root进程运行chown()时,chown()将不删除文件的SUID和/或
SGID许可,但当非root进程运行chown()时,chown()将取消文件的SUID和/
或SGID许可.
(4)chroot():改变进程对根目录的概念,调用chroot()后,进程就不能把当前
工作目录改变到新的根目录以上的任一目录,所有以/开始的路径搜索,都
从新的根目录开始.
(5)mknod():用于建立一个文件,类似于creat(),差别是mknod()不返回所打开
文件的文件描述符,并且能建立任何类型的文件(普通文件,特殊文件,目录
文件).若从非root进程调用mknod()将执行失败,只有建立FIFO特别文件
(有名管道文件)时例外,其它任何情况下,必须从root进程调用mknod().由
于creat()仅能建立普通文件,mknod()是建立目录文件的唯一途径,因而仅

有root能建立目录,这就是为什么mkdir命令具有SUID许可并属root所有.
一般不从程序中调用mknod().通常用/etc/mknod命令建立特别设备文件而
这些文件一般不能在使用着时建立和删除,mkdir命令用于建立目录.当用
mknod()建立特别文件时,应当注意确从所建的特别文件不允许存取内存,
磁盘,终端和其它设备.
(6)unlink():用于删除文件.参数是要删除文件的路径名指针.当指定了目录
时,必须从root进程调用unlink(),这是必须从root进程调用unlink()的唯
一情况,这就是为什么rmdir命令具有root的SGID许可的原因.
(7)mount(),umount():由root进程调用,分别用于安装和拆卸文件系统.这两
个子程序也被mount和umount命令调用,其参数基本和命令的参数相同.调
用mount(),需要给出一个特别文件和一个目录的指针,特别文件上的文件
系统就将安装在该目录下,调用时还要给出一个标识选项,指定被安装的文
件系统要被读/写(0)还是仅读(1).umount()的参数是要一个要拆卸的特别
文件的指针.
分享到:
评论

相关推荐

    这样学习Unix下C语言编程最有效.doc

    "精通 Unix 下 C 语言编程" Unix 下 C 语言编程是一种相对稳定的开发平台下的开发语言,掌握了它,就可以轻松完成当前 Unix 服务器下疯狂增长的各式各样的功能需求。为什么选择 Unix 编程? Unix 操作系统具有安全...

    C语言程序设计教程完整版资料.ppt

    在Turbo C中,可以创建、编辑和编译C语言程序,并可以对程序进行调试和执行。 6. C语言的优缺点 C语言是一种功能很强的语言,但是,它也有一些不足之处:C语言的语法限制不太严格,程序安全性较低,运算符功能强但...

    UNIX操作系统概述

    移植性好 UNIX操作系统的源代码绝大部分用C语言写成,非常便于移植到其它计算机上,再加上初期UNIX组织对UNIX源代码宽松的管理政策,促进了UNIX的发展和普及。 很早以前,就应用到几乎所有16位及以上的计算机上,...

    基于C语言实现类似unix的文件系统源码+课程设计报告与程序设计文档+项目说明(操作系统课设).zip

    基于C语言实现类似unix的文件系统源码+课程设计报告与程序设计文档+项目说明(操作系统课设).zip基于C语言实现类似unix的文件系统源码+课程设计报告与程序设计文档+项目说明(操作系统课设).zip基于C语言实现类似unix...

    C语言程序设计第1章引言.pptx

    C语言程序设计第1章引言 C语言程序设计是计算机科学领域中一种广泛应用的程序设计语言,具有多种数据类型、灵活的控制语句、丰富的运算符等特点。在本章中,我们将对C语言的基本概念、发展历史、特点、简单程序等...

    Unix操作系统详解课件

    外壳由Shell解释程序,支持程序设计的各种语言,编译程序和解释程序,实用程序和系统调用接口等组成UNIX系统大部分是由C语言编写的,这使得系统易读,易修改,易移植。 UNIX提供了丰富的,精心挑选的系统调用,整个...

    C语言程序设计第四版ppt课件.ppt

    C语言程序设计第四版ppt课件 本资源主要介绍C语言程序设计的基本概念、语法和特点,并对C语言的发展历史、特点和基本概念进行了详细的讲解。 C语言发展历史 C语言的发展历史可以追溯到1972年, Ken.Thompson和...

    Linux和Unix安全编程HOW TO(中文版)

    本文对在Linux和Unix系统下编写安全程序给出了一组设计和实现的指导原则。这样的程序包括用来浏览远端数据的应用程序、CGI脚本程序、网络服务器和setuid/setgid程序。本文还包含了针对C、C++、Java、Perl、Python和...

    unix大全(涵盖了UNIX学习的方方面面)

    31. UNIX 下设备驱动程序开发 32. OpenServer下的终端监控系统-Spy FileSystem 33.X常用的系统调用 34.X系统下部分控制代码介绍及其应用 35.用工具badtrk检查磁盘坏道? 36.x C 编程问题精粹 37.输入输出函数 38....

    UnixLinux基础讲义.doc

    Unix/Linux 操作系统是计算机系统中承上启下的关键组件,它向下封装硬件,向上提供操作接口。 Unix/Linux 操作系统的目标是使计算机系统易于使用、以更有效的方式使用计算机系统资源、方便用户有效开发、测试和引进...

    C语言编程之__UNIX常用库函数.doc

    本文主要讨论有关系统子程序、标准 C 库子程序的安全,如何写安全的 C 程序,并从 root 的角度介绍程序设计(仅能被 root 调用的子程序)。 1. 系统子程序 * creat():建立一个新文件或重写一个暂存文件。需要两个...

    Unix/Linux基础讲义.doc

    Unix/Linux 基础讲义 Unix/Linux 是一种多用户、多...Unix/Linux 操作系统是计算机系统的核心,它提供了多用户、多任务、实时处理、高效、安全、方便、功能强大的特点,为用户提供了便捷、高效、安全的计算机环境。

    (word完整版)C语言程序设计课后习题1-8参考答案.doc

    "C语言程序设计课后习题1-8参考答案" 本资源提供了C语言程序设计课后习题1-8的参考答案,涵盖了计算机基础知识、C语言特点、C语言应用、程序设计语言等方面的内容。 计算机基础知识 冯诺依曼计算机模型由五大功能...

    unix学习笔记

    1.可移植性强--Unix操作系统大量代码为C语言编写,C语言具有跨平台的特性。 2.多用户、多任务的分时操作系统--人机间实时交互数据;多个用户可同时使用一台主机; 每个用户可同时执行多个任务。 3.软件复用--...

    c语言的优缺点

    2. 语法限制不太严格:C 语言的语法限制不太严格,对变量的类型约束不严格,影响程序的安全性,对数组下标越界不作检查等。 3. 指针操作不安全:C 语言的指针操作也给它带来了很多不安全的因素。C++ 在这方面做了很...

    UNIX基础知识.ppt

    UNIX 的特点包括多任务、多用户、管道、强大的 Shell、安全保护机制、稳定性好、图形用户界面和强大的网络支持。 UNIX 流派和标准 UNIX 的流派有 System V 和 BSD UNIX,两者都有其特点和优势。System V 是 UNIX ...

    UnixLinux基础讲义

    1971 年,两人在贝尔实验室共同发明了 C 语言,并于 1973 用 C 语言重写了 Unix。1974 年,UNIX 第一次出现在贝尔实验室以外。 Unix 家族的发展过程中,出现了两个主要的版本线:BSD UNIX 和 AT&T 的 Unix,两者的...

    操作系统实验_项目三Unix_shell的和历史特点.docx

    Unix Shell 是一个命令行接口,允许用户与操作系统交互,执行各种命令和程序。以下是 Unix Shell 和历史特点的知识点: 一、 Unix Shell 的历史特点 Unix Shell 的历史可以追溯到 1960年代,Ken Thompson 和 ...

    Cygwin (Windows下的UNIX环境)

    Windows下的UNIX环境Cygwin 一、简介 Cygwin是一个在windows平台上运行的unix模拟环境,是cygnus solutions公司开发的自由软件(现已被Redhat收购)。Cygwin是一个全功能的Win32应用,它是UNIX应用的一个Porting层...

    UNIX 高级教程系统技术内幕

    2.4 内核态下运行 2.4.1 系统调用接口 2.4.2 中断处理 2.5 同步 2.5.1 阻塞操作 2.5.2 中断 2.5.3 多处理器 2.6 进程调度 2.7 信号 2.8 新进程和程序 2.8.1 fork 和exec 2.8.2 进程创建 2.8.3 fork 优化 2.8.4 执行...

Global site tag (gtag.js) - Google Analytics