博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
遨游Unix--APUE课程笔记【1】
阅读量:5816 次
发布时间:2019-06-18

本文共 3991 字,大约阅读时间需要 13 分钟。

写在最前面:其实这是一个上课作业,我觉得我不能就这么简单的实现了而不给后人留下点什么糟粕。所以下面有兴趣的同学就跟着我误入歧途吧。我没想按着APUE这本书一章一章来,我认为既然是我自己读完了这本书并要实现东西,就需要有我自己的节奏,这种节奏不仅仅让我自己,也要让各位看客感到轻松,并偶有所获~我就十分开心了。

Preface

这学期报了一门课叫《Unix环境高级编程》,本来打算水水过去的,没想到老师需要我们每个人完成一份大作业,作业内容就是艰深复杂的各种调用底层API实现的shell。

怎么说呢?从严格意义上,操作系统可以定义为一种软件,它控制计算机硬件资源,提供程序运行环境,我们将这种软件成为内核(也就是kernel),内核的接口被称为系统调用,公用函数库构建在系统调用接口之上,应用程序既可以使用公用函数库,也可以使用系统调用。shell是一个特殊的应用程序,为运行其他程序提供了一个接口。

我们要实现的shell就是这么一个东西。

这么大段的定义还不如说【oh-my-zsh ,zsh ,bash】 来的实在,以上三种就是我们常见的shell,我现在最喜欢的就是 oh-my-zsh 了,其优点太多了,tabtab可以自动提示参数,配色好看几百倍等等等等。

废话不多说,要开车了哦。

准备工作

首先

  1. 一台Linux系统的计算机(比较方便,在windows下需要配置很多的环境,因为windows没有Unix的很多库函数,我使用的是 Ubuntu 16.04)

  2. 下载apue源码 

  3. 解压源码文件 tar -zxvf *.tar.gz

  4. cd apue.3e/ & make

    在这个过程中,你会看到最后由于can,t find-lbsd而不能make成功,解决办法是添加libbsd.a的静态链接库
    sudo apt-get install libbsd-dev

5. 重新 make 然后再

sudocp  ./include/apue.h   /usr/include/     sudocp  ./lib/libapue.a   /usr/local/lib/

有时候以上步骤完成后就可以随便找书上的例子开始装逼了,但是我的电脑不行,因为里面有很多err_sys之类的报错函数未定义,那么还需要再执行一步。

复制下面的代码,并保存成 /usr/include/myerr.h

以后你写的例子里需要用到err_sys之类的函数,你需要 #include "myerr.h"

#include "apue.h"#include 
/* for definition of errno */#include
/* ISO C variable aruments */static void err_doit(int, int, const char *, va_list);/** Nonfatal error related to a system call.* Print a message and return.*/voiderr_ret(const char *fmt, ...){ va_list ap; va_start(ap, fmt); err_doit(1, errno, fmt, ap); va_end(ap);}/** Fatal error related to a system call.* Print a message and terminate.*/voiderr_sys(const char *fmt, ...){ va_list ap; va_start(ap, fmt); err_doit(1, errno, fmt, ap); va_end(ap); exit(1);}/** Fatal error unrelated to a system call.* Error code passed as explict parameter.* Print a message and terminate.*/voiderr_exit(int error, const char *fmt, ...){ va_list ap; va_start(ap, fmt); err_doit(1, error, fmt, ap); va_end(ap); exit(1);}/** Fatal error related to a system call.* Print a message, dump core, and terminate.*/voiderr_dump(const char *fmt, ...){ va_list ap; va_start(ap, fmt); err_doit(1, errno, fmt, ap); va_end(ap); abort(); /* dump core and terminate */ exit(1); /* shouldn't get here */}/** Nonfatal error unrelated to a system call.* Print a message and return.*/voiderr_msg(const char *fmt, ...){ va_list ap; va_start(ap, fmt); err_doit(0, 0, fmt, ap); va_end(ap);}/** Fatal error unrelated to a system call.* Print a message and terminate.*/voiderr_quit(const char *fmt, ...){ va_list ap; va_start(ap, fmt); err_doit(0, 0, fmt, ap); va_end(ap); exit(1);}/** Print a message and return to caller.* Caller specifies "errnoflag".*/static voiderr_doit(int errnoflag, int error, const char *fmt, va_list ap){ char buf[MAXLINE]; vsnprintf(buf, MAXLINE, fmt, ap); if (errnoflag) snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s", strerror(error)); strcat(buf, " "); fflush(stdout); /* in case stdout and stderr are the same */ fputs(buf, stderr); fflush(NULL); /* flushes all stdio output streams */}

尾声

既然是第一章,当然我们轻松点,那么就来一个最最开始的1-7程序吧,这个程序搭建了最基本的功能,也就是输入,连命令也不是去解析调API而是直接用原始bash的命令~

//// Created by jasperyang on 17-6-6.//#include "apue.h"#include 
#include "myerr.h"int main(void) { char buf[MAXLINE]; /* from apue.h */ pid_t pid; int status; printf("%% "); /* print prompt (printf requires %% to print %) */ while(fgets(buf,MAXLINE,stdin) != NULL) { if(buf[strlen(buf) -1] == '\n'){ buf[strlen(buf)-1]=0; /* replace newline with null */ } if((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0){ /* child */ execlp(buf,buf,(char*)0); err_ret("couldn't execute: %s",buf); exit(127); } /* parent */ if((pid = waitpid(pid,&status,0)) < 0) err_sys("waitpid error"); printf("%% "); } exit(0);}

简单易懂老少皆宜,这段程序输入命令,并fork一个child去执行命令,执行命令用的是execlp这个函数,执行失败与否子程序都exit(127),127倒没什么特殊的含义。

转载地址:http://xdqbx.baihongyu.com/

你可能感兴趣的文章
在Word2010文档中设置和显示隐藏文字
查看>>
powerdesigner that name already exists
查看>>
Boost入门二之thread遇到的坑
查看>>
iptables的conntrack表满了导致访问网站很慢
查看>>
排序-归并排序
查看>>
植入式攻击入侵检测解决方案
查看>>
ios打包问题
查看>>
互联网创业公司是否需要技术外包?
查看>>
软件行业的QA与QC的区别
查看>>
SqlServer数据库兼容级别查询与修改
查看>>
PHP初级学习一
查看>>
如何实现qq在线聊天功能
查看>>
Android自定义Dialog
查看>>
用JS实现简单的神经网络算法
查看>>
读书笔记:A Philosophy of Software Design (二)
查看>>
java使用jeids实现redis2.6的String操作(4)
查看>>
并发与并行
查看>>
在CentOS7 下安装 ffmpeg,mplayer,swftools
查看>>
c++ 文件的输入输出流
查看>>
PHP中curl的CURLOPT_POSTFIELDS参数使用细节
查看>>