Unix System Overview
一.Unix 体系结构
由上图可以看出,内核居于最里层,Shell,Libary routines,以及Application通过系统调用(system calls)访问内核提供的功能。注意系统调用与函数调用的关系,两者不是一个东西。应用程序可以通过Shell和库访问内核功能,也可以直接通过系统调用访问内核。
二.登录
1.登录
我们使用用户名和密码登录Unix系统,系统会在/etc/passwd文件中校验我们的用户名,在/etc/shadow中校验密码。/etc/passwd文件内容格式如下:
root:x:0:0:root:/root:/bin/bash
其中各项用:隔开,分别代表:用户名,密码保存位置,UserID,GroupID,注释,家目录,使用的shell.
/etc/shadow文件内容格式如下:
root:x:16097:0:99999:7::::
各项用:分开,分别代表:用户名,加密密码,上次更改密码的时间,最短密码期限等
2.shell
使用的shell 由登录文件的最后一项决定,一般是/bin/bash,常见的shell除了bash ,还有C Shell,B shell,K shell,T Shell
三.文件和目录
1.文件系统
Unix系统文件结构由目录与文件构成的树构成,/为根目录。目录是包含目录项的文件,目录项是由包含文件名以及描述文件属性的结构组成。文件属性一般有文件的所有者,文件的访问权限,文件的大小,存储位置等。
2.文件名
文件名由字母,_,数字组成,/和NULL不可出现在文件名中。.与..在创建任何目录的时候自动创建,分别代表当前目录以及父目录。
3.路径名
由/开始并由/分隔开来的多个文件名组成的字符串称为路径名,比如/root/test,路径分为绝对路径和相对路径。绝对路径指从根目录/出发一直到访问目的目录,否则即为相对路径。
下面的代码实现一个简单的ls
<span style="font-size:18px;"><span style="font-size:18px;">/*************************************************************************
> File Name: ls.c
> Author: CodingPeasant
> Mail: 1612853779@qq.com
> Created Time: Mon 11 Aug 2014 06:10:09 AM PDT
************************************************************************/ #include<stdio.h>
#include <stdlib.h>
#include <dirent.h> int main(int argc,char * argv[])
{
DIR* dp;
struct dirent *dirp; if(argc != 2)
{
printf("usage:myls directory_name");
exit(-1);
} if( (dp = opendir(argv[1])) == NULL )
{
printf("can not open %s",argv[1]);
exit(-1);
}
while((dirp = readdir(dp)) != NULL)
{
printf("%s\n",dirp->d_name);
} closedir(dp); return 0;
}
</span></span>
3.工作目录
工作目录也叫当前工作目录,是进程的一个属性,进程可以使用chdir系统调用更改自己的工作目录。
4.家目录
我们登录后的第一个目录就是当前用户的家目录,家目录由登录文件/etc/passwd最后一项决定。
四.输入与输出
1.文件描述符:内核用于标记被进程访问的文件的的小正整数,由open()或者create()返回,用于其他文件访问的参数。
2.Shell在执行新程序的时候,打开标准输入,标准输出,标准出错输出,默认三者都指向终端文件。
3.非缓冲IO:所有IO操作都在内核空间中完成,open,read,write,seek,close是基本操作,这几个系统调用都和文件描述符(file descibe)相关联。
下面是一个拷贝到小程序:
<span style="font-size:18px;">/*************************************************************************
> File Name: cp.c
> Author: CodingPeasant
> Mail: 1612853779@qq.com
> Created Time: Tue 12 Aug 2014 06:27:16 AM PDT
************************************************************************/ #include<stdio.h>
#include<unistd.h>
#include<stdlib.h> #define BUFFSIZE 4096 int main()
{
int n;
char buf[BUFFSIZE]; while( ( n = read(STDIN_FILENO,buf,BUFFSIZE)) > 0 )
{
if(write(STDOUT_FILENO,buf,n)!= n)
{
printf("write error");
exit(-1);
}
} if (n < 0)
{
printf("read error");
exit(-1);
}
exit(0);
}
</span>
假设生成的文件为mycp,则执行mycp < input_file,输入为input_file,输出为终端,出错输出也为终端。
执行mycp <input_file >out_file 则复制input_file内容到out_file。
4.标准IO:提供带有缓冲机制的IO访问函数,不需要自己管理缓冲区大小。
五.进程
1.程序和进程:程序指存在磁盘上的可执行文件,是静态的行为。当程序被内核以exec函数执行的时候,就变成了进程,进程是动态行为。
2.进程ID:每个进程都有一个非负数标识,叫做进程ID。
下面的小程序获取进程ID:
<span style="font-size:18px;">/*************************************************************************
> File Name: pid.c
> Author: CodingPeasant
> Mail: 1612853779@qq.com
> Created Time: Tue 12 Aug 2014 06:59:38 AM PDT
************************************************************************/ #include<stdio.h>
#include<unistd.h>
#include<sys/types.h> int main()
{
pid_t pid; printf("current process id:%ld\n",(long)getpid()); return 0;
}
</span>
3.进程管理:fork创建子进程,exec函数族执行新程序,waitpid,wait进行子进程善后处理。下面是一个简易版shell:
<span style="font-size:18px;">/*************************************************************************
> File Name: shell.c
> Author: CodingPeasant
> Mail: 1612853779@qq.com
> Created Time: Tue 12 Aug 2014 07:12:58 AM PDT
************************************************************************/ #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<unistd.h> #define MAXLINE 100
int main(int argc,char* argv[])
{
char buf[MAXLINE];
pid_t pid;
int status; printf("%%");
while(fgets(buf,MAXLINE,stdin)!= NULL)
{
if(buf[strlen(buf)-1] == '\n')
{
buf[strlen(buf)-1] = 0; /*replace \n to NULL*/
} if((pid = fork()) < 0)
{
printf("fork error\n");
exit(-1);
}else if(pid == 0)//child process
{
execlp(buf,buf,(char*)0);//exec new progromme
printf("can not execute :%s",buf);
exit(127);
} //parent
if((pid = waitpid(pid,&status,0)) < 0)
{
printf("waitpid error");
exit(-1);
}
printf("%%");
} }
</span>
关于程序的几点说明:
1.因为exec函数最后一个参数需要(char*)0,所以将读入的字符串的newline符号改为NULL
2.execlp第一个参数为文件名,系统会在环境变量中查找该文件,如果文件不是可执行文件,尝试用shell执行之。如果文件没找到报错
3.waitpid进行子进程资源回收以及执行状态获取。
线程:是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。进程中的所有线程共享进程的地址空间,文件描述符,栈以及其他进程属性。
线程ID:用于唯一标识一个线程,只在同一个进程中有意义。
六.错误处理
1.在Unix中一般函数调用出错返回值小于0,并且设置errno,用了表示发生了什么错误。
2.<errno.h> 定义了错误号的宏
3.通过char* strerror(int errnum);可以返回errnum对应的字符串标识
4.通过void perror(const char* msg);打印提示信息msg:error message
七.用户标识
1.User ID:由root分配用于系统唯一标识一个用户的数字,我们不可以改变。系统使用UserID测试我们是否可以访问相关资源。
2.Group ID:由root分配用于系统唯一标识一个组的数字。
3.附加组ID(Supplementary Group IDs):一个用户可以属于其他 组,用附加组ID表示这些组。
获取UserID 和 Group ID的小程序:
<span style="font-size:18px;">#include <sys/types.h>
#include <unistd.h>
#include <stdio.h> int main()
{
printf("uid:%d,gid:%d",getuid(),getgid());
exit(0);
}</span>
八.信号
1.信号:用来通知进程某些条件发生的一种机制
2.对信号的处理方式:(1)忽略信号 (2)按照默认行为处理 (2)设置信号处理函数
3.增加了信号处理的简单shell:
<span style="font-size:18px;">/*************************************************************************
> File Name: shell.c
> Author: CodingPeasant
> Mail: 1612853779@qq.com
> Created Time: Tue 12 Aug 2014 07:12:58 AM PDT
************************************************************************/ #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<unistd.h>
#include<signal.h> #define MAXLINE 100 //deal with intrupt signal
static void sig_int(int); int main(int argc,char* argv[])
{
char buf[MAXLINE];
pid_t pid;
int status; if(signal(SIGINT,sig_int) == SIG_ERR)
{
printf("signal error");
return -1;
}
printf("%%");
while(fgets(buf,MAXLINE,stdin)!= NULL)
{
if(buf[strlen(buf)-1] == '\n')
{
buf[strlen(buf)-1] = 0; /*replace \n to NULL*/
} if((pid = fork()) < 0)
{
printf("fork error\n");
exit(-1);
}else if(pid == 0)//child process
{
execlp(buf,buf,(char*)0);//exec new progromme
printf("can not execute :%s",buf);
exit(127);
} //parent
if((pid = waitpid(pid,&status,0)) < 0)
{
printf("waitpid error");
exit(-1);
}
printf("%%");
} } void sig_int(int signo)
{
//just print signo
printf("interrupt:%d\n",signo);
}
</span>
九.时间值
1.时间值分为:(1)日历时间,用time_t 结构表示,表示从1970 -1-1 00:00 到当前的秒数 (2)进程时间,用clock_t 结构标识,标识进程执行花了多少时钟
2.进程时间通常用三种值来衡量:(1)User CPU time :执行用户指令花费的时钟数(2)Sytem CPU time :执行系统指令花费的时钟数(3) clock time:进程执行花了多少时钟,受到其他进程的影响,通常指单一进程花费的时间
十.系统调用和库函数调用
1.进程执行分为用户态和内核态
2.系统调用和库函数调用区别:
函数库调用 |
系统调用 |
在所有的ANSI C编译器版本中,C库函数是相同的 |
各个操作系统的系统调用是不同的 |
它调用函数库中的一段程序(或函数) |
它调用系统内核的服务 |
与用户程序相联系 |
是操作系统的一个入口点 |
在用户地址空间执行 |
在内核地址空间执行 |
它的运行时间属于“用户时间” |
它的运行时间属于“系统”时间 |
属于过程调用,调用开销较小 |
需要在用户空间和内核上下文环境间切换,开销较大 |
在C函数库libc中有大约300个函数 |
在UNIX中大约有90个系统调用 |
典型的C函数库调用:system fprintf malloc |
典型的系统调用:chdir fork write brk; |
Unix System Overview的更多相关文章
- 【APUE】Chapter1 UNIX System Overview
这章内容就是“provides a whirlwind tour of the UNIX System from a programmer's perspective”. 其实在看这章内容的时候,已经 ...
- Linux/Unix System Level Attack、Privilege Escalation(undone)
目录 . How To Start A System Level Attack . Remote Access Attack . Local Access Attack . After Get Roo ...
- SharePoint Security and Permission System Overview
转:http://www.sharepointblues.com/2010/09/01/sharepoint-security-and-permission-system-overview/ Shar ...
- [MODX] 0. Mangement System Overview
In Modex, there are three tabs: Resoources, Elements & Files First: 'Files' is the place where t ...
- Build System 和Test Framework overview总结
良好的自动化系统可以帮助Dev/Tester快速发现product/test code issue. 正好上一个项目结束,上个项目在自动化系统上面做得非常好.从产品开始时半年release一次到后面每 ...
- we are experimenting with a new init system and it is fun
http://0pointer.de/blog/projects/systemd.html Rethinking PID 1 If you are well connected or good at ...
- 分布式系统(Distributed System)资料
这个资料关于分布式系统资料,作者写的太好了.拿过来以备用 网址:https://github.com/ty4z2008/Qix/blob/master/ds.md 希望转载的朋友,你可以不用联系我.但 ...
- [计算机、网络相关历史]unix简史
本文2001年由台湾“网络农夫”所写,其人生平不祥,此文受鸟哥大力推崇,两人应该相识.文章写得很不错,应该是查了很多资料整理而成的,美中不足的是好多语句不通顺,国考语文绝对不及格,哈哈. 0.我的准备 ...
- Dennis与Ken爷爷的UNIX/C世界
沉寂了很久了,时间在不断地逝去,转眼又到了新的一年,2013的发生了太多,Beta版本.辞职.职位转换.ARM.Driver.初级厨艺.Dx11.GPU.CPU.登山.GNU/Linux.Cross ...
随机推荐
- IntelliJ IDEA14 安装
一.官网下载 IntelliJ IDEA的官网:https://www.jetbrains.com/idea/ 进入选择Get IntelliJ IDEA Now ,进入下载页:https://www ...
- js解决checkbox全选和反选的问题
function SelectAll() { var checkboxs=document.getElementsByName("chk_list"); for (var i=0; ...
- PAT-乙级-1001. 害死人不偿命的(3n+1)猜想 (15)
1001. 害死人不偿命的(3n+1)猜想 (15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 卡拉兹(Ca ...
- hdu 1272
并查集 要判断这个图是连通的 就是只有一个父节点 #include <cstdio> #include <cstring> #define maxn 100005 int f ...
- spoj 665
直接判 没什么算法 也没什么技巧 水水~~ #include <cstdio> #include <cstring> #include <algorithm> ...
- Tiny6410 交叉编译helloworld程序
在工作目录下建立helloworld.c文件 #include <stdio.h> main() { printf("helloworld!\n"); } 保存关闭后. ...
- struts2文件下载 火狐浏览器的文件名乱码问题
这是一个文件下载的action,红色部分为火狐浏览器需要特地做的事情. @Controller @Scope(value = "prototype") public class F ...
- Random Integer Generator
先占坑.以后再修改 昨天遇到一道题, Given int Rand(1) = 0或者 1- uniformly distributed, write a function to implemen ...
- Fast Matrix Operations
A Simple Problem with Integers 每次将区间向下更新,或是用之前的方法,统计当前节点到父节点处的覆盖数目. #include <cstdio> #include ...
- YII数据库操作中打印sql
配置如下: 'components' => array( 'db'=>array( 'enableParamLogging' => true, ), 'log'=>array( ...