77范文网 - 专业文章范例文档资料分享平台

UNIX系统程序设计教程(2)

来源:网络收集 时间:2019-02-15 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

去。这个时候,原来shell的进程就是getenv进程的父进程。envp的参数是从父进程中取得的。现在你知道上一节中为什么有那两个带p的函数了?

上一回做的ssh这个外壳的命令是带不了参数的。因为咱们的程序不知道要去读参数。这回不妨做一个能读参数的试试

#include #define SP 0 #define NOSP 1

void getarg( char *argv[] , char *p ); //取得各个参数 int main() {

static char prompt[64]=> ;

char command[256], *argv[256], *p; int st;

fprintf( stderr , %s , prompt );

while( (p=gets(command))!=NULL ) {

getarg( argv , p ); if( fork()==0 ) {

if( execv(argv[0],argv)==(-1) ) exit(1); } else {

wait( &st );

fprintf( stderr , %s , prompt); } }

return 0; }

void getarg( char *argv[] , char *p ) {

int i , sp_flag ;

sp_flag=SP; //SP代表空格,NOSP代表非空格的意思 for( i=0 ; *p!='\\0' ; p++ ) {

if( sp_flag==SP && *p!=' ' )

//如果现在状态是读过空格,但现在这个字母是非空格 //那很显然,读到一个新的参数 {

argv[i]=p; i++;

sp_flag=NOSP; }

if( *p==' ' ) {

*p='\\0'; sp_flag=SP; } }

argv[i]=(char *)0; }

这篇文章东西说得比较少。给大家出个问题吧:

看到了吧。C能做的事情很多。谁说C不支持多进程?那是因为DOS。呵呵

上回做的ssh,必须输入绝对路径才能执行。现在要求,咱们做一个只输入命令以及参数,程序自动在$PATH里定义的各路径查找这个命令。找到就执行,找不到就报错的外壳出来试试?有做出来的,请贴程序。

2003-7-27 关于进程状态的一些补足:

众所周知,UNIX是一个多用户多任务的操作系统。所谓多任务,就是指在同一个时间内,看上去有许多任务在同时执行。这一点是与DOS不同的。所以Turbo C下找不到fork()函数。当然。大家知道,实际上CPU同一个时间只能处理一件事。它是在轮流执行这些进程,由于速度很快。所以看起来像是所有进程在一起跑。同样,一个进程,它有使用CPU的时候,也有等待使用CPU的时候。这就决定了进程的几种状态。 进程大致可以分为“执行中”,“准备执行”,“睡眠中”三种状态。 执行中:进程在占用CPU。

准备执行:想要使用CPU,但是CPU被别的进程占用中,所以等待CPU空闲。 睡眠中:等待事件发生的进程。比方说,等待输入输出结束的进程。

我们用fork()生成一个新的进程,或者用exec函数组覆盖当前进程后。当这个子进程结束的时候要给父进程送去一个信号(signal,后述),然后转为zombie状态。zombie状态是指一个进程已经结束,所占内存空间等等已经返还给系统,但是在系统的进程列表中仍然存在的这么一个状态。当父进程执行wait()后,子进程才真正完全结束。如果父进程先一步结束了,那么由init代替父进程。所以,wait()不只是等待子进程结束。它还有上面所说的这个任务。 我们写个程序来看一下:

/* zombie */ #include int main() { int st;

if( fork()==0 ) {

exit(1); //子进程生成后直接结束 }

else {

sleep( 300 ); //休眠300秒 wait( &st );

printf(Return code=%d\\n,i); }

return 0; }

编译后执行 %./zombie &

这个时候,程序在后台运行 %ps -ef | grep zombie

看一下,是不是有一个进程处在zombie状态?

第四章:文件系统

UNIX所管理的机器一般是大型机而不是PC。所管理的硬盘一般也非常大。所以一般分成几个区,每个区都有其单独的文件系统。比方说你能大概能找到这样的一些文件 /dev/sd/c0t0d0s0 /dev/sd/c0t0d0s1 ... ...

当UNIX启动的时候,分区被挂装(mount)并统一成一个树状的文件系统 分区的物理构造咱们暂且放在一边,先写个程序,读一下分区信息试试。

/* ndf.c 计算参数所指定的分区的剩余空间比率 */ #include #include #include

int main(int argc , char *argv[]) {

struct statvfs buf[1]; sync();

if( statvfs(argv[1],buf)!=0 ) {

fprintf(stderr , Cannot read super block !\\n); exit(1); }

fprintf(stderr , %4.1f %% free\\n,

(float)buf[0].f_bfree / buf[0].f_blocks*100 ); return 0; }

编译执行: %./ndf / 49.8 % free

这里用了一个statvfs函数。其具体如下: #include #include

int statvfs( char *path , struct statvfs *buf ); 返回值: 成功时: 0 失败时: -1

还有一个sync()函数。用来更新分区的super block; void sync();

UNIX系统为了加快处理速度,将分区的super block信息读到内存中保存。sync()函数就是把在内存中保存的super block信息再写回到硬盘上去。

UNIX系统使用好几种文件系统。有S5,ufs,VxFS等等。虽然这些文件系统的构造非常不同,但一通百通,咱们在这几篇贴子里只讨论一下比较容易理解,而且“经典的”S5文件系统。(别的我也不会。呵呵) S5: 文件名最长14字节,构造简单

ufs: 文件名最长255字节,BSD所用的文件系统。

VxFS: Veritas Softwave公司开发的文件系统。出现错误时可以快速恢复。由于这种文件系统保证文件在硬盘上连续存放,所以处理速度很快。

现在说一下S5分区的构造

一个分区包含如下四部分(按顺序): [ boot block ] [ super block ] [ i node block ] [ data block ]

boot block :

这个部分在分区的最开始处,用来存放引导程序。就算是不能引导的分区一样有boot block,这个时候这部分就没有用了。不过一般这部分也不大。大多数只有512或者1024字节。

super block :

super block在boot block之后,用来存放这个分区全体的管理信息。上面那个ndf.c就是读的这部分所存储的信息。里边存放了i node block的大小,free block数组等等。根据这些信息可以得知data block的开始位置。 i node block :

i node是index node的缩写。i node block就是存放i node的部分 UNIX把一切都看成是个文件。包括目录以及设备等等的所有的文件都有一个i node号,作为这个文件的管理信息。文件本身存在于数据区,但是i node号存在i node block里。主要包含文件的模式,链接数,文件所有者,文件大小,在硬盘上的位置,最后读写时

间,最后更新时间等信息。

为了加快存储速度,系统会把一定数量的i node存至内存。UNIX系统不一样,存多少也就不一样。 data block :

这部分就是存放数据本身的了。这部分被分成一定大小的块,如同DOS的扇区一样。一般大小是1024字节,分到4096的也有。

解说到这里,我们再来写个程序。打开一个目录,然后把这个目录下所有的文件的i node号及文件名输出来。

/* nls.c */ #include

#define DIRSIZ 14

int main( int argc , char *argv[] ) {

struct dir {

int i_no;

char f_name; };

struct dir dir_data[1]; FILE *fp;

fp=fopen(argv[1],r);

while( fscanf(fp,%i%s,&(dir_data[0].i_no),dir_data[0].f_name)!=EOF ) {

printf(%i %s\\n , dir_data[0].i_no , dir_data[0].f_name ); }

fclose(fp); return 0; }

%./nls / ... ... 2048 usr 2049 home ... ...

别忘了,在UNIX下,目录也当成文件。 最近,为了使目录的格式变得通用而不再依赖于操作系统,程序中大多使用统一的格式。这种情况下,我们最好就不直接用fopen()打开目录,而使用opendir(),readdir()等函数比较好。重写一下上面的程序。

/* nls2.c */ #include

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库UNIX系统程序设计教程(2)在线全文阅读。

UNIX系统程序设计教程(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/474333.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: