《Linux/Unix系统编程手册》读书笔记 目录

最近这一个月在看《Linux/Unix系统编程手册》,在学习关于Linux的系统编程。之前学习Linux的时候就打算写关于Linux的学习记录,因为觉得自己学得不好,老是写不出东西。但是现在觉得学习记录应该坚持写,慢慢就会有收获,坚持写才可以锻炼自己的表达能力。

《Linux/Unix系统编程手册》这本书的评价很高,但是个人觉得翻译得不太好。其实终究是因为自己的英文阅读能力太差和没什么钱,只能看翻译版。看了接近一个月,觉得这本书介绍的接口很详细,程序清单基本会提及到介绍的接口。个人觉得作为入门书应该是可以的,起码看完一遍会有初步的认识,而且作为参考手册也不错。打算看完这本书之后,继续学习《UNIX环境高级编程》,学无止境。

第1章:

介绍了一些历史,关于Linux、Unix和C;还有一些标准POSIXSUS

第2章:

介绍Linux和Unix的一些基本概念。

1.操作系统的两个含义:一,包含管理和分配计算机资源的核心层软件和附带的所有标准软件;二,仅仅指管理和分配计算机资源的核心层软件。

2.内核的作用:进程调度、内存管理、文件系统、创建和终止进程、对设备的访问、联网、提供API。其实就是抽象,用户通过内核来使用硬件,而不用直接与硬件打交道。

3.用户态和内核态。

。。。。。。。。。。。。。。。。还有一堆的概念。。。。。。。。。。。。。。。。。。。

第3章

介绍系统编程的概念。

系统调用(systerm calls)是用户程序与操作系统之间的接口,系统调用在内核态。库函数(library functions),一些库函数是通过系统调用来实现,好处是提供了比底层系统调用更方便的接口。

还有本书的代码所需的一些函数、头文件。。。。。。。。。。。

见链接:http://www.man7.org/tlpi/

第4章

介绍了文件I/O。

文件描述符,用来表示已经打开的文件(所有类型),是一非负整数。最基本的文件描述符0(标准输入)、1(标准输出)、2(标准错误)。

I/O操作:首先通过调用open获取一个文件描述符,再对该文件描述符进行read或者write操作,最后使用close释放文件描述符和相关资源。

open()调用,打开一个文件或者创建一个文件。

 #include <sys/stat.h>
#include <fcntl.h> int open(const char *pathname, int flags, .../* mode_t mode */);

成功调用返回文件描述符,失败返回-1;

1、pathname为打开文件的文件名; flags为位掩码,用于指定文件的访问模式;mode为位掩码参数,用于指定文件的访问权限(可选)。

2、flags位掩码的标志分为文件访问模式标志、文件创建标志、已打开文件的状态标志;其中文件访问模式标志如下表,这些标志不能同时使用。

访问模式 描述
 O_RDONLY 以只读方式打开文件 
O_WRONLY 以只写方式打开文件
O_RDWR 以读写方式打开文件

比较常用的标志还有O_APPEND(总是在文件尾部添加数据)、O_CREAT(如果要打开的文件不存在就新建一个空文件)、O_EXCL(与O_CREAT结合使用表明如果文件已经存在,就不会打开文件)。

3、open()函数的错误:省略。

read()调用,从文件描述符对应的文件中读取数据。

#include <unistd.h>

ssize_t read(int fd, void *buffer, size_t count);

fd为文件描述符;buffer为存储数据的缓冲区;count为最多能读取的字节数。

成功调用返回实际读取字节数,遇到文件结束符返回0,出现错误返回-1。

PS:要在缓冲区最后添加一个表示终止的空字符。

write()调用,往文件描述符对应的文件写入数据。

 #include <unistd.h>

 ssize_t write(int fd, void *buffer, size_t count);

fd为文件描述符;buffer为存储数据的缓冲区;count为准备从buffer写入到文件的数据的字节数。

成功调用返回实际写入文件的字节数, 失败返回-1。

close()调用,关闭已经打开的文件描述符。

 #include <unistd.h>

 int close(int fd);

fd为文件描述符。

成功调用返回0,失败返回-1 。

所有类型的文件和设备驱动都实现了相同的I/O接口,所以无需针对特殊的文件编写代码。

文件偏移量:读写偏移量或指针,是执行下一个read和write操作的文件起始位置(相对与文件头部起始点)。

lseek(),改变文件偏移量。

 #include <unistd.h>

 off_t lseek(int fd, off_t offset, int whence);

fd为文件描述符,offset为偏移量(字节),whence为表明解释offset参数的方法。

whence参数:

SEEK_SET 将文件偏移量设置为从文件头起始点开始的offset个字节
SEEK_CUR 相对于当前文件偏移量,再加上offset个字节
SEEK_END 将文件偏移量设置为起始于文件尾部的offset个字节

文件空洞 :当文件的偏移量大于文件的当前长度时,文件结尾到新写入数据之间的空间称为文件空洞。读取文件空洞的内容会返回以0填充的缓冲区。

     “空洞是否占用磁盘空间由文件系统决定”----《百度百科》

     “如果空洞的边界落在块内,而非恰好落在块的边界上,则会分配一个完整的块来存储数据,块中与空洞相关的部分则以空字节填充”----书本提示

     

练习:

4-1:tee命令是从标准输入中读取数据,直至文件结尾,随后将数据写入标准输入和命令行参数所指定的文件。请使用I/O系统调用实现tee命令,默认情况下,若已存在命令行参数指定文件同名的文件tee命令会将其覆盖。如文件以存在,请实现-a命令行选项(tee -a file)在文件结尾出追加数据。

 /*
* =====================================================================================
*
* Filename: my_tee.c
*
* Description: tee
*
* Version: 1.0
* Created: 2014年03月14日 18时23分04秒
* Revision: none
* Compiler: gcc
*
* Author: alan (), alan19920626@gmail.com
* Organization:如果输入为my_tee -a会出现错误而不是程序自动停止而且报错!!!!需要改进!!!
*
* =====================================================================================
*/ #include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include "tlpi_hdr.h" #define MAX_READ 20 int main(int argc, char *argv[]){
int fd, opt;
char buf[MAX_READ + ];
ssize_t numRead;
off_t offset; if(argc < || strcmp(argv[], "--help") == )
usageErr("%s [-a] file"); fd = open(argv[argc-], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if(fd == -)
errExit("open"); offset = lseek(fd, , SEEK_SET);
while((opt = getopt(argc, argv, ":a")) != -){
switch(opt){
case 'a':
//file = optarg;
offset = lseek(fd, -, SEEK_END);
break;
case '?':
default:
fprintf(stderr, "%s option: '-%c' is invalid: ignore\n", argv[], optopt);
exit(EXIT_FAILURE);
break;
}
} while((numRead = read(STDIN_FILENO, buf, MAX_READ)) > ){
buf[numRead] = '\0'; if(write(STDOUT_FILENO, buf, numRead+) != (numRead+))
fatal("couldn't write whole buf");
if(write(fd, buf, numRead) != (numRead))
fatal("couldn't write whole buf");
} if(numRead == -)
errExit("read"); if(close(fd) == -)
errExit("close file"); exit(EXIT_SUCCESS);
}

测试:

lancelot@debian:~/Code/tlpi$ cat > t1
This is the first line.
lancelot@debian:~/Code/tlpi$ cat t1
This is the first line.
lancelot@debian:~/Code/tlpi$ ./my_tee t1
This is the second line.
This is the second line.
This is the third line.
This is the third line. lancelot@debian:~/Code/tlpi$ cat t1
This is the second line.
This is the third line. lancelot@debian:~/Code/tlpi$ ./my_tee -a t1
This is the append line.
This is the append line.
lancelot@debian:~/Code/tlpi$ cat t1
This is the second line.
This is the third line.
This is the append line.

4-2:编写一个类似cp命令的程序,当使用该程序复制一个包含空洞(连续的空字节)的普通文件时,要求目标文件的空的与源文件保持一致。

 /*
* =====================================================================================
*
* Filename: my_cp.c
*
* Description:
*
* Version: 1.0
* Created: 2014年04月03日 17时02分43秒
* Revision: none
* Compiler: gcc
*
* Author: alan (), alan19920626@gmail.com
* Organization:
*
* =====================================================================================
*/ #include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include "tlpi_hdr.h" #define BUF_SIZE 1024 int main(int argc, char *argv[]){
int inputFd, outputFd, openFlags;
mode_t filePerms;
ssize_t numRead;
char buf[BUF_SIZE]; if(argc != || strcmp(argv[], "--help") == )
usageErr("%s old-file new-file\n", argv[]); inputFd = open(argv[], O_RDONLY);
if(inputFd == -)
errExit("open file %s", argv[]); openFlags = O_CREAT | O_WRONLY | O_TRUNC;
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
outputFd = open(argv[], openFlags, filePerms);
if(outputFd == -)
errExit("open file %s", argv[]); while((numRead = read(inputFd, buf, BUF_SIZE)) > )
if(write(outputFd, buf, numRead) != numRead)
fatal("couldn't write whole buffer");
if(numRead == -)
errExit("read");
if(close(inputFd) == -)
errExit("close input");
if(close(outputFd) == -)
errExit("close output"); exit(EXIT_SUCCESS);
}

测试:首先通过书本的程序清单提供的seek_io.c来使t2出现空洞。

lancelot@debian:~/Code/tlpi$ cat t2
This is the first line.
This is the second line.
This is the third line.
lancelot@debian:~/Code/tlpi$ gcc -o seek_io seek_io.c error_functions.c get_num.c
lancelot@debian:~/Code/tlpi$ ./seek_io t2 s100000 wabc
s100000: seek succeeded
wabc: wrote bytes
lancelot@debian:~/Code/tlpi$ cat t2
This is the first line.
This is the second line.
This is the third line.
abclancelot@debian:~/Code/tlp./seek_io t2 s50000 R5
s50000: seek succeeded
R5:

可以看到文件偏移量为50000的内容为空字节。。。。。

然后进行复制。

lancelot@debian:~/Code/tlpi$ ./my_cp t2 t3
lancelot@debian:~/Code/tlpi$ ls -l t2 t3
-rw-r--r-- lancelot lancelot 4月 : t2
-rw-r--r-- lancelot lancelot 4月 : t3
lancelot@debian:~/Code/tlpi$ ./seek_io t3 s50000 R5
s50000: seek succeeded
R5:

可以看到两个文件的大小相同,而且从t3文件偏移量为50000开始读取5个字节都为空字节。

《Linux/Unix系统编程手册》读书笔记1的更多相关文章

  1. 《Linux/Unix系统编程手册》读书笔记 目录

    <Linux/Unix系统编程手册>读书笔记1  (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2  (创建于4月9日,最后更新4月10日) ...

  2. 《Linux/Unix系统编程手册》读书笔记9(文件属性)

    <Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...

  3. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  4. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  5. 《Linux/Unix系统编程手册》读书笔记6

    <Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...

  6. 《Linux/Unix系统编程手册》读书笔记5

    <Linux/Unix系统编程手册>读书笔记 目录 第8章 本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/g ...

  7. 《Linux/Unix系统编程手册》读书笔记4

    <Linux/Unix系统编程手册>读书笔记 目录 第7章: 内存分配 通过增加堆的大小分配内存,通过提升program break位置的高度来分配内存. 基本学过C语言的都用过mallo ...

  8. 《Linux/Unix系统编程手册》读书笔记3

    <Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...

  9. 《Linux/Unix系统编程手册》读书笔记2

    <Linux/Unix系统编程手册>读书笔记 目录 第5章: 主要介绍了文件I/O更深入的一些内容. 原子操作,将一个系统调用所要完成的所有动作作为一个不可中断的操作,一次性执行:这样可以 ...

随机推荐

  1. MyException

    自定义Exception using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...

  2. uImage、zImage、bzImage、vlinzx区别

    在网络中,不少服务器采用的是Linux系统.为了进一步提高服务器的性能,可能需要根 据特定的硬件及需求重新编译Linux内核.编译Linux 内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要 ...

  3. ios按钮点击后翻转效果

    代码是网上找到的,不过找到的时候直接复制下来不能用,稍微整理下,为和我一样水平的菜鸟观摩一下下. (1)引入“QuartzCore.framework”库,头部引用. #include<Quar ...

  4. 标签跳转break和continue

    标签是后面跟有冒号的标识符,例如  label1: 在java中,标签起作用的唯一的地方刚好是在迭代语句之前. “刚好之前”的意思表明,在标签和迭代之间置入热和语句都不好. 而在迭代之前设置标签的唯一 ...

  5. SQL Server2008附加数据库之后显示为只读

    SQL Server2008附加数据库之后显示为只读时解决方法 啰嗦的话就不多说了,直入主题吧! 方案一: 碰到这中情况一般是使用的sa账户登录的,只要改为Windows身份验证,再附加数据库即可搞定 ...

  6. centos nginx,php添加到Service

    SHELL脚本: nginx vim /etc/init.d/nginx #!/bin/sh # # nginx - this script starts and stops the nginx da ...

  7. 【ZOJ】【3329】One Person Game

    概率DP/数学期望 kuangbin总结题目中的第三道 看来还是没有进入状态啊……都说是DP了……当然是要找[状态之间的转移关系]了…… 本题中dp[i]跟 dp[i-(k1+k2+k3)] 到dp[ ...

  8. 20160730noip模拟赛zld

    codeforces394E 如果没有在凸多边形内一点的限制,答案肯定是 如果不在凸多边形内,那么目标点肯定在凸多边形边上,我们枚举每条边,在每条边上求出距离平方和最小的点,在这些点中求出最小的 我们 ...

  9. uva 10303

    卡特兰数  但是个高精度 一开始用最普通的递推式 超时了 百度百科了一下 用另类递推式过了 ~~ 这个大数类是做数据结构课程设计的时候写的... #include <cstdio> #in ...

  10. POJ2104 K-th Number Range Tree

    又是区间第k大,这次选择这道题是为以后写线段树套平衡树铺路的.Range Tree可以理解成线段树套vector吧,相当于每个结点多存了对应区间的一个排好序的序列.画一下就会知道空间的消耗是nlogn ...