Apue第一章
2017-05-21 23:04
148 查看
第一章主要介绍了关于linux体系的整体的结构,牵涉了许多计算机理论的知识,但是本书做的最好的地方是隐藏了许多计算机内部的细节,直接用简单的程序进行说明,言简意赅。
不过我们还是要简易说一下关于linux的体系。
首先linux是以根目录的形式进行目录的划分,这点和windows有很大的区别,linux的shell做的很完美,对于用户的交互功能做的很好。
关于linux的目录体系结构我们会在程序中演示
这个程序是用来打印目录下的所有文件的,很简单。
首先是一大堆头文件,有兴趣的朋友可以自己去查阅关于这些头文件的具体实现。
其次是DIR结构体和struct dirent结构体,这俩东西都是在dirent.h头文件中定义好的,我们只需要去关注我们程序中用到的细节。DIR类似于FILE,用于保存正在被读取的目录的有关信息,结构体我就我就不粘贴了。然后struct
dirent可以储存关于文件的信息。
在此程序中dp就类似于一个目录,那我们如何去索引这个目录下的所有文件呢?那就用dirp来储存吧。
其中还用到了两个函数opendir和readdir,建议你先man一下(不要问我man是什么)。
从名字你也能看出来这两个函数是干嘛用的,打开和读取呗。之后就是一个while的遍历输出,遍历目录下每一个索引号。有一个dirp->d_name参数,d_name就是struct
dirent结构体里面的一个变量,用于保存文件的名字。最后close目录退出程序。
以下是运行输出结果
接下来是一个标准输入输出的程序
这个程序就更简单了,read是一个不带有缓冲区的函数,需要你自己去定义buffer的值,我这里定义的是4096关于缓冲区我们后面的博客会讲到。然后read里面有一个STDIN_FILENO,write里面有一个STDOUT_FILENO,这样写是为了便于去增强程序的可读性,这个值是POSIX标准定义的,他们是0和1。这种数叫做幻数,有兴趣可以去查一查。我们先只需要记住只需要记住stdin的类型是FILE*,STDIN_FILENO的类型是int就可以了,用多了自然就明白了。我们后面还会学到read和write的用法,之后还会讲解。
以下是运行输出结果
这是也是一个标准输入输出程序
这个就是循环去标准输入中使用getc读取一个个字符,会产生阻塞,阻塞的概念我们后面会讲,然后这个程序就不再叙述,因为很简单啦,学过c的人应该都明白。
接下来是一个关于进程的程序
这个程序很有意思啦,功能大概是你自己写了一个shell,其实你是调用了linux的命令程序而已。关于进程的相关概念我们就用最简单的语言来描述吧,在windows下打开任务管理器是最直白的说明了,linux下使用命令ps
aux,现在我们只需要直到每个程序都有属于自己的进程就可以了。Fork函数就是把自己的资源复制了一份给儿子,返回值0表示子进程,返回值小于0表示fork错误。Execl函数和Waitpid函数请先man,在这里先不去讲解,后续会有说明。
下面这个程序只是多了一个信号处理的功能,当你按下ctrl+c的时候会向计算机发出一个SIGINT信号,程序有对应的sig_int函数去处理信号的到来。信号这个概念也只是抛砖引玉
下面是error处理的一个简单程序
错误的处理在linux编程中是非常重要的,处理各种不同的错误的提示信息对一个程序的健壮性是必不可少的,这个程序没什么说的看输出结果吧。
好了,第一章就这样吧,详细的还是大家自己去看书吧。
Ps:推荐一本书《linux程序设计》
不过我们还是要简易说一下关于linux的体系。
首先linux是以根目录的形式进行目录的划分,这点和windows有很大的区别,linux的shell做的很完美,对于用户的交互功能做的很好。
关于linux的目录体系结构我们会在程序中演示
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> int main(int argc, char *argv[]) { DIR *dp; struct dirent *dirp; if(argc != 2) printf("cannot use\n"); if((dp = opendir(argv[1])) == NULL) printf("open error\n"); while ((dirp = readdir(dp)) != NULL) { printf("%s\t", dirp->d_name); } closedir(dp); exit(0); }
这个程序是用来打印目录下的所有文件的,很简单。
首先是一大堆头文件,有兴趣的朋友可以自己去查阅关于这些头文件的具体实现。
其次是DIR结构体和struct dirent结构体,这俩东西都是在dirent.h头文件中定义好的,我们只需要去关注我们程序中用到的细节。DIR类似于FILE,用于保存正在被读取的目录的有关信息,结构体我就我就不粘贴了。然后struct
dirent可以储存关于文件的信息。
在此程序中dp就类似于一个目录,那我们如何去索引这个目录下的所有文件呢?那就用dirp来储存吧。
其中还用到了两个函数opendir和readdir,建议你先man一下(不要问我man是什么)。
从名字你也能看出来这两个函数是干嘛用的,打开和读取呗。之后就是一个while的遍历输出,遍历目录下每一个索引号。有一个dirp->d_name参数,d_name就是struct
dirent结构体里面的一个变量,用于保存文件的名字。最后close目录退出程序。
以下是运行输出结果
接下来是一个标准输入输出的程序
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #define BUFFSIZE 4096 int main(int argc, char *argv[]) { int n; char buf[BUFFSIZE]; while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) { if(write(STDOUT_FILENO, buf, n) != n) perror("write error"); } if(n < 0) perror("read error\n"); exit(0); }
这个程序就更简单了,read是一个不带有缓冲区的函数,需要你自己去定义buffer的值,我这里定义的是4096关于缓冲区我们后面的博客会讲到。然后read里面有一个STDIN_FILENO,write里面有一个STDOUT_FILENO,这样写是为了便于去增强程序的可读性,这个值是POSIX标准定义的,他们是0和1。这种数叫做幻数,有兴趣可以去查一查。我们先只需要记住只需要记住stdin的类型是FILE*,STDIN_FILENO的类型是int就可以了,用多了自然就明白了。我们后面还会学到read和write的用法,之后还会讲解。
以下是运行输出结果
这是也是一个标准输入输出程序
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> int main(int argc, char *argv[]) { int c; while((c = getc(stdin)) != EOF) if(putc(c, stdout) == EOF) perror("output error\n"); if(ferror(stdin)) perror("input error\n"); exit(0); }
这个就是循环去标准输入中使用getc读取一个个字符,会产生阻塞,阻塞的概念我们后面会讲,然后这个程序就不再叙述,因为很简单啦,学过c的人应该都明白。
接下来是一个关于进程的程序
#include <unistd.h> #include <stdio.h> 4000 #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #include<sys/wait.h> #define MAXLINE 4096 int main(int argc, char *argv[]) { char buf[MAXLINE]; pid_t pid; int status; printf("%%"); while (fgets(buf, MAXLINE, stdin)) { if(buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; if((pid = fork()) < 0) perror("fork error"); else if(pid == 0){ //printf("i am child\n"); execlp(buf, buf, (char *)0); exit(127); } if(pid = waitpid(pid, &status, 0) < 0) perror("waitpid error\n"); printf("%% "); } exit(0); }
这个程序很有意思啦,功能大概是你自己写了一个shell,其实你是调用了linux的命令程序而已。关于进程的相关概念我们就用最简单的语言来描述吧,在windows下打开任务管理器是最直白的说明了,linux下使用命令ps
aux,现在我们只需要直到每个程序都有属于自己的进程就可以了。Fork函数就是把自己的资源复制了一份给儿子,返回值0表示子进程,返回值小于0表示fork错误。Execl函数和Waitpid函数请先man,在这里先不去讲解,后续会有说明。
下面这个程序只是多了一个信号处理的功能,当你按下ctrl+c的时候会向计算机发出一个SIGINT信号,程序有对应的sig_int函数去处理信号的到来。信号这个概念也只是抛砖引玉
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #include <signal.h> #include<sys/wait.h> #define MAXLINE 4096 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) perror("signal error\n"); printf("%%"); while (fgets(buf, MAXLINE, stdin)) { if(buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0; if((pid = fork()) < 0) perror("fork error"); else if(pid == 0){ //printf("i am child\n"); execlp(buf, buf, (char *)0); exit(127); } if(pid = waitpid(pid, &status, 0) < 0) perror("waitpid error\n"); printf("%% "); } exit(0); } void sig_int(int signo) { printf("interrupt\n%% "); }
下面是error处理的一个简单程序
#include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #include<errno.h> int main(int argc, char *argv[]) { fprintf(stderr, "EACCES: %s\n", strerror(EACCES)); errno = ENOENT; perror(argv[0]); exit(0); }
错误的处理在linux编程中是非常重要的,处理各种不同的错误的提示信息对一个程序的健壮性是必不可少的,这个程序没什么说的看输出结果吧。
好了,第一章就这样吧,详细的还是大家自己去看书吧。
Ps:推荐一本书《linux程序设计》
相关文章推荐
- apue第一章 (2)
- 读书笔记----APUE(第一章)
- APUE学习第一章
- 《APUE》 第一章 图1-7 程序代码中execlp()部分解析
- APUE学习: 第一章, Unix基础知识
- APUE第一章
- APUE学习之旅-第一章:UNIX System Over view
- 【UNIX——01】APUE第一章
- 【转】apue《UNIX环境高级编程第三版》第一章答案详解
- 《APUE》笔记--第一章
- APUE第一章笔记
- apue学习第四天——第一章的其它内容
- 《APUE》笔记--第一章
- APUE第一章
- APUE第一章_课后习题
- apue第一章 (3)
- apue《UNIX环境高级编程第三版》第一章答案详解
- UNIX基础知识--《APUE》第一章笔记
- APUE-第一章学习-UNIX基础知识-习题
- apue第一章 (1)